diff options
Diffstat (limited to 'fpga/usrp2/udp')
| -rw-r--r-- | fpga/usrp2/udp/prot_eng_tx.v | 166 | ||||
| -rw-r--r-- | fpga/usrp2/udp/prot_eng_tx_tb.v | 93 | 
2 files changed, 115 insertions, 144 deletions
| diff --git a/fpga/usrp2/udp/prot_eng_tx.v b/fpga/usrp2/udp/prot_eng_tx.v index c642842f6..b4f6e55b8 100644 --- a/fpga/usrp2/udp/prot_eng_tx.v +++ b/fpga/usrp2/udp/prot_eng_tx.v @@ -1,146 +1,110 @@ -// 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: -//             21   UDP Source Port Here -//             20   UDP Dest Port Here -//             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 +    input [35:0] datain, input src_rdy_i, output dst_rdy_o, +    output [35:0] dataout, output src_rdy_o, input dst_rdy_i); -   assign dataout 	 = {flags_o[2:0], dataout_int[15:0]}; +   wire 	  src_rdy_int1, dst_rdy_int1; +   wire 	  src_rdy_int2, dst_rdy_int2; +   wire [35:0] 	  data_int1, data_int2; -   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 + 6;  // 16 bits plus flags -   localparam HDR_LEN 	 = 32;      // Up to 64 bytes of protocol +   // Shortfifo on input to guarantee no deadlock +   fifo_short #(.WIDTH(36)) head_fifo +     (.clk(clk),.reset(reset),.clear(clear), +      .datain(datain), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), +      .dataout(data_int1), .src_rdy_o(src_rdy_int1), .dst_rdy_i(dst_rdy_int1), +      .space(),.occupied() );     // 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; - -   reg [1:0] 		port_sel; -   reg [31:0] 		per_port_data[0:3]; -   reg [15:0] 		udp_src_port, udp_dst_port, chk_precompute; - -   always @(posedge clk) udp_src_port <= per_port_data[port_sel][31:16]; -   always @(posedge clk) udp_dst_port <= per_port_data[port_sel][15:0]; - +   reg [31:0] 	  header_ram[0:63]; +   reg [3:0] 	  state; +   reg [1:0] 	  port_sel; +        always @(posedge clk) -     if(set_stb & ((set_addr & 8'hE0) == BASE)) -       header_ram[set_addr[4:0]] <= set_data; +     if(set_stb & ((set_addr & 8'hC0) == BASE)) +       header_ram[set_addr[5:0]] <= set_data; -   always @(posedge clk) -     if(set_stb & (set_addr == (BASE + 14))) -       chk_precompute <= set_data[15:0]; +   wire [31:0] 	  header_word = header_ram[{port_sel[1:0],state[3:0]}]; +   reg [15:0] 	  pre_checksums [0:3];     always @(posedge clk) -     if(set_stb & ((set_addr & 8'hFC) == (BASE+24))) -       per_port_data[set_addr[1:0]] <= set_data; -    -   wire do_udp_src_port = header_word[21]; -   wire do_udp_dst_port = header_word[20]; -   wire last_hdr_line   = header_word[19]; -   wire do_ip_chk       = header_word[18]; -   wire do_ip_len       = header_word[17]; -   wire do_udp_len      = header_word[16]; +     if(set_stb & ((set_addr & 8'hCF)== (BASE+7))) +       pre_checksums[set_addr[5:4]] <= set_data[15:0]; + +   wire [15:0] 	  pre_checksum = pre_checksums[port_sel[1:0]]; -   assign header_word = header_ram[state]; -        // 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 -  +   reg 	       sof_o; +   reg [31:0]  prot_data; +        always @(posedge clk)       if(reset)         begin -	  state     <= 0; -	  fast_path <= 0; +	  state   <= 0;  	  sof_o   <= 0;         end       else -       if(src_rdy_i & dst_rdy_i) +       if(src_rdy_int1 & dst_rdy_int2)  	 case(state)  	   0 :  	     begin -		fast_path <= datain[0]; -		port_sel <= datain[2:1]; -		state <= 1; -	     end -	   1 : -	     begin -		length 	<= datain[15:0]; +		port_sel <= data_int1[18:17]; +		length 	<= data_int1[15:0];  		sof_o <= 1; -		if(fast_path) -		  state <= 2; +		if(data_int1[16]) +		  state <= 1;  		else -		  state <= 30;  // Skip 1 word for alignment +		  state <= 12;  	     end -	   30 : -	     state <= 31; -	   31 : +	   12 :  	     begin  		sof_o <= 0; -		if(flags_i[1]) // eop +		if(data_int1[33]) // eof  		  state <= 0;  	     end  	   default :  	     begin  		sof_o 	<= 0; -		if(~last_hdr_line) -		  state <= state + 1; -		else -		  state <= 31; +		state <= state + 1;  	     end  	 endcase // case (state) -   wire [15:0] checksum; +   wire [15:0] ip_checksum;     add_onescomp #(.WIDTH(16)) add_onescomp  -     (.A(chk_precompute),.B(ip_length),.SUM(checksum)); - -   reg [15:0]  checksum_reg; -   always @(posedge clk) -     checksum_reg <= checksum; +     (.A(pre_checksum),.B(ip_length),.SUM(ip_checksum)); +   reg [15:0]  ip_checksum_reg; +   always @(posedge clk) ip_checksum_reg <= ip_checksum;     always @* -     if(do_payload) -       dataout_int 	<= datain[15:0]; -     else if(do_ip_chk) -       dataout_int 	<= 16'hFFFF ^ checksum_reg; -     else if(do_ip_len) -       dataout_int 	<= ip_length; -     else if(do_udp_len) -       dataout_int 	<= udp_length; -     else if(do_udp_src_port) -       dataout_int      <= udp_src_port; -     else if(do_udp_dst_port) -       dataout_int      <= udp_dst_port; -     else -       dataout_int 	<= header_word[15:0]; +     case(state) +       1 : prot_data <= header_word;  // ETH, top half ignored +       2 : prot_data <= header_word;  // ETH +       3 : prot_data <= header_word;  // ETH +       4 : prot_data <= header_word;  // ETH +       5 : prot_data <= { header_word[31:16], ip_length }; // IP +       6 : prot_data <= header_word; // IP +       7 : prot_data <= { header_word[31:16], (16'hFFFF ^ ip_checksum_reg) }; // IP +       8 : prot_data <= header_word; // IP +       9 : prot_data <= header_word; // IP +       10: prot_data <= header_word;  // UDP  +       11: prot_data <= { udp_length, header_word[15:0]}; // UDP +       default : prot_data <= data_int1[31:0]; +     endcase // case (state) + +   assign data_int2 = { data_int1[35:33] & {3{state[3]}},  sof_o, prot_data }; +   assign dst_rdy_int1 = dst_rdy_int2 & ((state == 0) | (state == 12)); +   assign src_rdy_int2 = src_rdy_int1 & (state != 0); +    +   // Shortfifo on output to guarantee no deadlock +   fifo_short #(.WIDTH(36)) tail_fifo +     (.clk(clk),.reset(reset),.clear(clear), +      .datain(data_int2), .src_rdy_i(src_rdy_int2), .dst_rdy_o(dst_rdy_int2), +      .dataout(dataout), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i), +      .space(),.occupied() );  endmodule // prot_eng_tx diff --git a/fpga/usrp2/udp/prot_eng_tx_tb.v b/fpga/usrp2/udp/prot_eng_tx_tb.v index c8fffe605..138794e57 100644 --- a/fpga/usrp2/udp/prot_eng_tx_tb.v +++ b/fpga/usrp2/udp/prot_eng_tx_tb.v @@ -8,40 +8,45 @@ module prot_eng_tx_tb();     always #50 clk = ~clk;     reg [31:0] f36_data; -   reg [1:0] f36_occ; -   reg f36_sof, f36_eof; -    +   reg [1:0]  f36_occ; +   reg 	      f36_sof, f36_eof;     wire [35:0] f36_in = {f36_occ,f36_eof,f36_sof,f36_data}; -   reg src_rdy_f36i  = 0; -   reg [15:0] count; +   reg 	       src_rdy_f36i  = 0; +   wire        dst_rdy_f36i; +     wire [35:0] casc_do; -   wire [18:0] final_out, prot_out; +   wire        src_rdy_f36o, dst_rdy_f36o; -   wire src_rdy_final, dst_rdy_final, src_rdy_prot; -   reg dst_rdy_prot =0; -    -   wire dst_rdy_f36o ; -   fifo_long #(.WIDTH(36), .SIZE(4)) fifo_cascade36 -     (.clk(clk),.reset(rst),.clear(clear), -      .datain(f36_in),.src_rdy_i(src_rdy_f36i),.dst_rdy_o(dst_rdy_f36i), -      .dataout(casc_do),.src_rdy_o(src_rdy_f36o),.dst_rdy_i(dst_rdy_f36o)); +   wire [35:0] prot_out; +   wire        src_rdy_prot, dst_rdy_prot; -   fifo36_to_fifo19 fifo_converter -     (.clk(clk),.reset(rst),.clear(clear), -      .f36_datain(casc_do),.f36_src_rdy_i(src_rdy_f36o),.f36_dst_rdy_o(dst_rdy_f36o), -      .f19_dataout(final_out),.f19_src_rdy_o(src_rdy_final),.f19_dst_rdy_i(dst_rdy_final)); +   wire [35:0] realign_out; +   wire        src_rdy_realign; +   reg 	       dst_rdy_realign = 1; +       +   reg [15:0] count;     reg set_stb;     reg [7:0] set_addr;     reg [31:0] set_data; +   fifo_short #(.WIDTH(36)) fifo_cascade36 +     (.clk(clk),.reset(rst),.clear(clear), +      .datain(f36_in),.src_rdy_i(src_rdy_f36i),.dst_rdy_o(dst_rdy_f36i), +      .dataout(casc_do),.src_rdy_o(src_rdy_f36o),.dst_rdy_i(dst_rdy_f36o)); +     prot_eng_tx #(.BASE(BASE)) prot_eng_tx -     (.clk(clk), .reset(rst), +     (.clk(clk), .reset(rst), .clear(0),        .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), -      .datain(final_out[18:0]),.src_rdy_i(src_rdy_final),.dst_rdy_o(dst_rdy_final), -      .dataout(prot_out[18:0]),.src_rdy_o(src_rdy_prot),.dst_rdy_i(dst_rdy_prot)); -    +      .datain(casc_do),.src_rdy_i(src_rdy_f36o),.dst_rdy_o(dst_rdy_f36o), +      .dataout(prot_out),.src_rdy_o(src_rdy_prot),.dst_rdy_i(dst_rdy_prot)); + +   ethtx_realign ethtx_realign +     (.clk(clk), .reset(rst), .clear(0), +      .datain(prot_out),.src_rdy_i(src_rdy_prot),.dst_rdy_o(dst_rdy_prot), +      .dataout(realign_out),.src_rdy_o(src_rdy_realign),.dst_rdy_i(dst_rdy_realign)); +     reg [35:0] printer;     task WriteSREG; @@ -58,17 +63,22 @@ module prot_eng_tx_tb();        end     endtask // WriteSREG +   always @(posedge clk) +     if(src_rdy_realign) +       $display("Read: %h",realign_out); + +        task ReadFromFIFO36;        begin  	 $display("Read from FIFO36"); -	 #1 dst_rdy_prot <= 1; +	 #1 dst_rdy_realign <= 1;  	 while(~src_rdy_prot)  	   @(posedge clk);  	 while(1)  	   begin  	      while(~src_rdy_prot)  		@(posedge clk); -	      $display("Read: %h",prot_out); +	      $display("Read: %h",realign_out);  	      @(posedge clk);  	   end        end @@ -80,7 +90,7 @@ module prot_eng_tx_tb();        begin  	 count 	      <= 4;  	 src_rdy_f36i <= 1; -	 f36_data     <= 32'h0003_000c; +	 f36_data     <= 32'h0001_000c;  	 f36_sof      <= 1;  	 f36_eof      <= 0;  	 f36_occ      <= 0; @@ -132,37 +142,34 @@ module prot_eng_tx_tb();       begin  	#10000;  	@(posedge clk); -	ReadFromFIFO36; +	//ReadFromFIFO36;       end     initial       begin  	@(negedge rst);  	@(posedge clk); -	WriteSREG(BASE, {12'b0, 4'h0, 16'h0000}); -	WriteSREG(BASE+1, {11'b0, 5'h00, 16'h0000}); -	WriteSREG(BASE+2, {11'b0, 5'h00, 16'hABCD}); -	WriteSREG(BASE+3, {11'b0, 5'h00, 16'h1234}); -	WriteSREG(BASE+4, {11'b0, 5'h00, 16'h5678}); -	WriteSREG(BASE+5, {11'b0, 5'h00, 16'hF00D}); -	WriteSREG(BASE+6, {11'b0, 5'h00, 16'hBEEF}); -	WriteSREG(BASE+7, {11'b0, 5'h10, 16'hDCBA}); -	WriteSREG(BASE+8, {11'b0, 5'h00, 16'h4321}); -	WriteSREG(BASE+9, {11'b0, 5'h04, 16'hABCD}); -	WriteSREG(BASE+10, {11'b0, 5'h08, 16'hABCD}); +	WriteSREG(BASE, 32'h89AB_CDEF); +	WriteSREG(BASE+1, 32'h1111_2222); +	WriteSREG(BASE+2, 32'h3333_4444); +	WriteSREG(BASE+3, 32'h5555_6666); +	WriteSREG(BASE+4, 32'h7777_8888); +	WriteSREG(BASE+5, 32'h9999_aaaa); +	WriteSREG(BASE+6, 32'hbbbb_cccc); +	WriteSREG(BASE+7, 32'hdddd_eeee); +	WriteSREG(BASE+8, 32'h0f0f_0011); +	WriteSREG(BASE+9, 32'h0022_0033); +	WriteSREG(BASE+10, 32'h0044_0055); +	WriteSREG(BASE+11, 32'h0066_0077); +	WriteSREG(BASE+12, 32'h0088_0099);  	@(posedge clk); -	WriteSREG(BASE+24, 16'h6666); -	WriteSREG(BASE+25, 16'h7777); -	WriteSREG(BASE+26, 16'h8888); -	WriteSREG(BASE+27, 16'h9999); -	  	PutPacketInFIFO36(32'hA0B0C0D0,16);  	@(posedge clk);  	@(posedge clk);  	#10000;  	@(posedge clk); -	PutPacketInFIFO36(32'hE0F0A0B0,36); +	//PutPacketInFIFO36(32'hE0F0A0B0,36);  	@(posedge clk);  	@(posedge clk);  	@(posedge clk); | 
