diff options
author | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2008-09-08 01:00:12 +0000 |
---|---|---|
committer | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2008-09-08 01:00:12 +0000 |
commit | 61f2f0214c5999ea42a368a4fc99f03d8eb28d1e (patch) | |
tree | e7e24a9adc05ff1422fe3ada9926a51634741b47 /eth/tx_prot_engine.v | |
download | uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.gz uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.bz2 uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.zip |
Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top-level components. Trunk passes distcheck with mb-gcc installed, but currently not without them. The key issue is that when mb-gcc is not installed, the build system skips over the usrp2/firmware directory, and the firmware include files don't get put into the dist tarball. But we can't do the usual DIST_SUBDIRS method as the firmware is a subpackage.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9528 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'eth/tx_prot_engine.v')
-rw-r--r-- | eth/tx_prot_engine.v | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/eth/tx_prot_engine.v b/eth/tx_prot_engine.v new file mode 100644 index 000000000..894d74a11 --- /dev/null +++ b/eth/tx_prot_engine.v @@ -0,0 +1,144 @@ + +module tx_prot_engine + (input clk, input rst, + + // To MAC + input Tx_mac_wa, + output Tx_mac_wr, + output [31:0] Tx_mac_data, + output [1:0] Tx_mac_BE, + output Tx_mac_sop, + output Tx_mac_eop, + + // To buffer interface + input [31:0] rd_dat_i, + output rd_read_o, + output rd_done_o, + output rd_error_o, + input rd_sop_i, + input rd_eop_i, + + // To control + input set_stb, + input [7:0] set_addr, + input [31:0] set_data, + + // Protocol Stuff + input [15:0] rx_fifo_status, + input [7:0] rx_seqnum + //input [7:0] tx_channel, + //input [7:0] tx_flags + ); + + wire [3:0] hdr_adr; + wire [31:0] hdr_dat; + wire [7:0] tx_channel; + + header_ram #(.REGNUM(32),.WIDTH(32)) tx_header_ram + (.clk(clk),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .addr(hdr_adr),.q(hdr_dat)); + + setting_reg #(.my_addr(32)) sr_channel + (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),.in(set_data), + .out(tx_channel),.changed()); + + // Might as well use a shortfifo here since they are basically free + wire empty, full, sfifo_write, sfifo_read; + wire [33:0] sfifo_in, sfifo_out; + + shortfifo #(.WIDTH(34)) txmac_sfifo + (.clk(clk),.rst(rst),.clear(0), + .datain(sfifo_in),.write(sfifo_write),.full(full), + .dataout(sfifo_out),.read(sfifo_read),.empty(empty)); + + // MAC side signals + // Inputs -- Tx_mac_wa, sfifo_out, empty + // outputs -- sfifo_read, Tx_mac_data, Tx_mac_wr, Tx_mac_BE, Tx_mac_sop, Tx_mac_eop + + // We are allowed to do one more write after we are told the FIFO is full + // This allows us to register the _wa signal and speed up timing. + reg tx_mac_wa_d1; + always @(posedge clk) + tx_mac_wa_d1 <= Tx_mac_wa; + + reg [2:0] prot_state; + localparam PROT_IDLE = 0; + localparam PROT_HDR1 = 1; + localparam PROT_HDR2 = 2; + localparam PROT_HDR3 = 3; + localparam PROT_HDR4 = 4; + localparam PROT_HDR5 = 5; + localparam PROT_PKT = 6; + + reg [7:0] tx_seqnum; + reg all_match; + always @(posedge clk) + if(rst) + tx_seqnum <= 0; + else if(set_stb & (set_addr == 36)) + tx_seqnum <= set_data[7:0]; + else if(tx_mac_wa_d1 & all_match & (prot_state == PROT_HDR5)) + tx_seqnum <= tx_seqnum + 1; + + always @(posedge clk) + if(rst) + prot_state <= PROT_IDLE; + else + if(tx_mac_wa_d1 & ~empty) + case(prot_state) + PROT_IDLE : + prot_state <= PROT_HDR1; + PROT_HDR1 : + prot_state <= PROT_HDR2; + PROT_HDR2 : + prot_state <= PROT_HDR3; + PROT_HDR3 : + prot_state <= PROT_HDR4; + PROT_HDR4 : + prot_state <= PROT_HDR5; + PROT_HDR5 : + prot_state <= PROT_PKT; + PROT_PKT : + if(sfifo_out[32] & ~empty) + prot_state <= PROT_IDLE; + default : + prot_state <= PROT_IDLE; + endcase // case(prot_state) + + assign hdr_adr = {1'b0,prot_state}; + wire match = (hdr_dat == sfifo_out[31:0]); + always @(posedge clk) + if(prot_state == PROT_IDLE) + all_match <= 1; + else if(tx_mac_wa_d1 & ~empty & + ((prot_state==PROT_HDR1)|(prot_state==PROT_HDR2)|(prot_state==PROT_HDR3))) + all_match <= all_match & match; + + localparam ETH_TYPE = 16'hBEEF; + assign Tx_mac_data = + ((prot_state == PROT_HDR5) & all_match) ? {rx_fifo_status,tx_seqnum,rx_seqnum} : + sfifo_out[31:0]; + assign sfifo_read = (prot_state != PROT_IDLE) & ~empty & tx_mac_wa_d1; + assign Tx_mac_wr = sfifo_read; + assign Tx_mac_BE = 0; // Since we only deal with packets that are multiples of 32 bits long + assign Tx_mac_sop = sfifo_out[33]; + assign Tx_mac_eop = sfifo_out[32]; + + // BUFFER side signals + reg xfer_active; + always @(posedge clk) + if(rst) + xfer_active <= 0; + else if(rd_eop_i & ~full) + xfer_active <= 0; + else if(rd_sop_i) + xfer_active <= 1; + + assign sfifo_in = {rd_sop_i, rd_eop_i, rd_dat_i}; + assign sfifo_write = xfer_active & ~full; + + assign rd_read_o = sfifo_write; + assign rd_done_o = 0; // Always send everything we're given? + assign rd_error_o = 0; // No possible error situations? + +endmodule // tx_prot_engine |