diff options
| author | Matt Ettus <matt@ettus.com> | 2010-05-27 17:31:46 -0700 |
|---|---|---|
| committer | Matt Ettus <matt@ettus.com> | 2010-05-27 17:31:46 -0700 |
| commit | 3d06fb26c5a59451b26680b6096fca7ee37e8018 (patch) | |
| tree | ce172a14304474b2a46854bea6b47c2ed1f8380b /usrp2/udp/prot_eng_tx.v | |
| parent | 621ad7cc9e68b4e304b616d8f840d3a03a047c8b (diff) | |
| parent | b38d2424b1ac3242146fc9305d9e4ae80e21dede (diff) | |
| download | uhd-3d06fb26c5a59451b26680b6096fca7ee37e8018.tar.gz uhd-3d06fb26c5a59451b26680b6096fca7ee37e8018.tar.bz2 uhd-3d06fb26c5a59451b26680b6096fca7ee37e8018.zip | |
Merge branch 'udp' into master_merge_take2
* udp: (67 commits)
better test program for just the tx side
fix typo, no functionality difference
ignores
move dsp settings regs to reclocked setting bus. Works, gets us to within 18ps of passing timing
reverting logic clean up which should have made timing better, but made it worse instead
moved fifos around, now easier to see where they are and how big
bigger fifo on UDP TX path, to possibly fix overruns on decim=4
Xilinx ISE is incorrectly parsing the verilog case statement, this is a workaround
pps and vita time debug pins
ignore emacs backup files
more debug for fixing E's
better debug pins for going after cascading E's
copy in wrong place
copied over from quad radio
just debug pin changes
typo caused the tx udp chain to be disconnected
moved into subdir
speed up timing by ignoring the too_early error. We'll need to FIXME this later
Added set time and set time at next pps. Removed the old sync pps commands, they dont make sense to use anymore.
moved around regs, added a bit to allow for alternate PPS source
...
Diffstat (limited to 'usrp2/udp/prot_eng_tx.v')
| -rw-r--r-- | usrp2/udp/prot_eng_tx.v | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/usrp2/udp/prot_eng_tx.v b/usrp2/udp/prot_eng_tx.v new file mode 100644 index 000000000..9031011f7 --- /dev/null +++ b/usrp2/udp/prot_eng_tx.v @@ -0,0 +1,119 @@ + +// The input FIFO contents should be 16 bits wide +// The first word is 1 for fast path (accelerated protocol) +// 0 for software implemented protocol +// The second word is the number of bytes in the packet, +// and must be valid even if we are in slow path mode +// Odd means the last word is half full +// Flags[1:0] is {eop, sop} +// Protocol word format is: +// 19 Last Header Line +// 18 IP Header Checksum XOR +// 17 IP Length Here +// 16 UDP Length Here +// 15:0 data word to be sent + +module prot_eng_tx + #(parameter BASE=0) + (input clk, input reset, input clear, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + input [18:0] datain, input src_rdy_i, output dst_rdy_o, + output [18:0] dataout, output src_rdy_o, input dst_rdy_i); + + wire [2:0] flags_i = datain[18:16]; + reg [15:0] dataout_int; + reg fast_path, sof_o; + + wire [2:0] flags_o = {flags_i[2], flags_i[1], sof_o}; // OCC, EOF, SOF + + assign dataout = {flags_o[2:0], dataout_int[15:0]}; + + reg [4:0] state; + wire do_payload = (state == 31); + + assign dst_rdy_o = dst_rdy_i & (do_payload | (state==0) | (state==1) | (state==30)); + assign src_rdy_o = src_rdy_i & ~((state==0) | (state==1) | (state==30)); + + localparam HDR_WIDTH = 16 + 4; // 16 bits plus flags + localparam HDR_LEN = 32; // Up to 64 bytes of protocol + + // Store header values in a small dual-port (distributed) ram + reg [HDR_WIDTH-1:0] header_ram[0:HDR_LEN-1]; + wire [HDR_WIDTH-1:0] header_word; + + always @(posedge clk) + if(set_stb & ((set_addr & 8'hE0) == BASE)) + header_ram[set_addr[4:0]] <= set_data; + + assign header_word = header_ram[state]; + + wire last_hdr_line = header_word[19]; + wire ip_chk = header_word[18]; + wire ip_len = header_word[17]; + wire udp_len = header_word[16]; + + // Protocol State Machine + reg [15:0] length; + wire [15:0] ip_length = length + 28; // IP HDR + UDP HDR + wire [15:0] udp_length = length + 8; // UDP HDR + + always @(posedge clk) + if(reset) + begin + state <= 0; + fast_path <= 0; + sof_o <= 0; + end + else + if(src_rdy_i & dst_rdy_i) + case(state) + 0 : + begin + fast_path <= datain[0]; + state <= 1; + end + 1 : + begin + length <= datain[15:0]; + sof_o <= 1; + if(fast_path) + state <= 2; + else + state <= 30; // Skip 1 word for alignment + end + 30 : + state <= 31; + 31 : + begin + sof_o <= 0; + if(flags_i[1]) // eop + state <= 0; + end + default : + begin + sof_o <= 0; + if(~last_hdr_line) + state <= state + 1; + else + state <= 31; + end + endcase // case (state) + + wire [15:0] checksum; + add_onescomp #(.WIDTH(16)) add_onescomp + (.A(header_word[15:0]),.B(ip_length),.SUM(checksum)); + + always @* + if(ip_chk) + //dataout_int <= header_word[15:0] ^ ip_length; + dataout_int <= 16'hFFFF ^ checksum; + else if(ip_len) + dataout_int <= ip_length; + else if(udp_len) + dataout_int <= udp_length; + else if(do_payload) + dataout_int <= datain[15:0]; + else + dataout_int <= header_word[15:0]; + +endmodule // prot_eng_tx |
