Procházet zdrojové kódy

cores/usb: Add address matching capability

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Sylvain Munaut před 5 roky
rodič
revize
defc053b38

+ 2 - 1
cores/usb/doc/mem-map.md

@@ -10,7 +10,7 @@ Global CSRs
 ,---------------------------------------------------------------,
 | f | e | d | c | b | a | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
 |---------------------------------------------------------------|
-| p |evt| cs| ce|bsa|bra|brp|sfp| / |          addr             |
+| p |evt| cs| ce|bsa|bra|brp|sfp| m |          addr             |
 '---------------------------------------------------------------'
 ```
 
@@ -22,6 +22,7 @@ Global CSRs
   * `bra` : Bus Reset Asserted
   * `brp` : Bus Reset Pending
   * `sfp` : Start-of-Frame Pending
+  * 'm'   : Enable address matching
   * `addr`: Configure address matching
 
 

+ 5 - 2
cores/usb/rtl/usb.v

@@ -147,6 +147,7 @@ module usb #(
 	// Config / Status registers
 	reg  cr_pu_ena;
 	reg  cr_cel_ena;
+	reg  cr_addr_chk;
 	reg  [ 6:0] cr_addr;
 
 	wire cel_state;
@@ -327,6 +328,7 @@ module usb #(
 		.eps_addr_0(eps_addr_0),
 		.eps_wrdata_0(eps_wrdata_0),
 		.eps_rddata_3(eps_rddata_3),
+		.cr_addr_chk(cr_addr_chk),
 		.cr_addr(cr_addr),
 		.evt_data(evt_data),
 		.evt_stb(evt_stb),
@@ -425,7 +427,7 @@ module usb #(
 		usb_reset,
 		rst_pending,
 		sof_pending,
-		1'b0,
+		cr_addr_chk,
 		cr_addr
 	};
 
@@ -448,7 +450,8 @@ module usb #(
 		if (cr_bus_we) begin
 			cr_pu_ena  <= bus_din[15];
 			cr_cel_ena <= bus_din[12];
-			cr_addr    <= bus_din[5:0];
+			cr_addr_chk<= bus_din[7];
+			cr_addr    <= bus_din[6:0];
 		end
 
 	// Request lines for EP Status access

+ 2 - 0
cores/usb/rtl/usb_defs.vh

@@ -40,3 +40,5 @@ localparam PID_DATA1	= 4'b1011;
 localparam PID_ACK		= 4'b0010;
 localparam PID_NAK		= 4'b1010;
 localparam PID_STALL	= 4'b1110;
+
+localparam PID_INVAL	= 4'b0000;

+ 21 - 8
cores/usb/rtl/usb_trans.v

@@ -25,7 +25,9 @@
 
 `default_nettype none
 
-module usb_trans (
+module usb_trans #(
+	parameter integer ADDR_MATCH = 1
+)(
 	// TX Packet interface
 	output wire txpkt_start,
 	input  wire txpkt_done,
@@ -72,6 +74,7 @@ module usb_trans (
 	input  wire [15:0] eps_rddata_3,
 
 	// Config / Status
+	input  wire cr_addr_chk,
 	input  wire [ 6:0] cr_addr,
 
 	output wire [11:0] evt_data,
@@ -116,14 +119,13 @@ module usb_trans (
 	wire [3:0] evt_set;
 	reg  [3:0] evt;
 
+	reg  [3:0] pkt_pid;
+
 	wire rto_now;
 	reg  [9:0] rto_cnt;
 
 	// Transaction / EndPoint / Buffer infos
-	reg  [3:0] trans_pid;
 	reg        trans_is_setup;
-	reg        trans_addr_zero;
-	reg        trans_addr_match;
 	reg  [3:0] trans_endp;
 	reg        trans_dir;
 
@@ -224,7 +226,7 @@ module usb_trans (
 		if (mc_op_ld)
 			casez (mc_opcode[2:1])
 				2'b00:   mc_a_reg <= evt;
-				2'b01:   mc_a_reg <= rxpkt_pid ^ { ep_data_toggle & mc_opcode[0], 3'b000 };
+				2'b01:   mc_a_reg <= pkt_pid ^ { ep_data_toggle & mc_opcode[0], 3'b000 };
 				2'b10:   mc_a_reg <= { cel_state_i, ep_type };
 				2'b11:   mc_a_reg <= { 1'b0, bd_state };
 				default: mc_a_reg <= 4'hx;
@@ -244,6 +246,20 @@ module usb_trans (
 	assign evt_rst = {4{mc_op_evt_clr}} & mc_opcode[3:0];
 	assign evt_set = { rto_now, txpkt_done, rxpkt_done_err, rxpkt_done_ok };
 
+	// Capture Packet PID
+	if (ADDR_MATCH) begin
+		always @(posedge clk)
+			if (rxpkt_done_ok) begin
+				if (rxpkt_is_token & cr_addr_chk)
+					pkt_pid <= (rxpkt_addr == cr_addr) ? rxpkt_pid : PID_INVAL;
+				else
+					pkt_pid <= rxpkt_pid;
+			end
+	end else begin
+		always @(*)
+			pkt_pid = rxpkt_pid;
+	end
+
 	// RX Timeout counter
 	always @(posedge clk or posedge rst)
 		if (rst)
@@ -280,10 +296,7 @@ module usb_trans (
 	// Capture EP# and direction when we get a TOKEN packet
 	always @(posedge clk)
 		if (rxpkt_done_ok & rxpkt_is_token) begin
-			trans_pid        <= rxpkt_pid;
 			trans_is_setup   <= rxpkt_pid == PID_SETUP;
-			trans_addr_zero  <= rxpkt_addr == 6'h00;
-			trans_addr_match <= rxpkt_addr == cr_addr;
 			trans_endp       <= rxpkt_endp;
 			trans_dir        <= rxpkt_pid == PID_IN;
 		end