diff options
| -rw-r--r-- | control_lib/newfifo/ll8_to_fifo19.v | 86 | ||||
| -rw-r--r-- | simple_gemac/eth_tasks_f19.v | 92 | ||||
| -rwxr-xr-x | simple_gemac/simple_gemac_wrapper19.build | 1 | ||||
| -rw-r--r-- | simple_gemac/simple_gemac_wrapper19.v | 165 | ||||
| -rw-r--r-- | simple_gemac/simple_gemac_wrapper19_tb.v | 209 | ||||
| -rw-r--r-- | top/u2_core/u2_core.v | 17 | ||||
| -rw-r--r-- | top/u2_rev3/Makefile | 13 | ||||
| -rw-r--r-- | udp/add_onescomp.v | 12 | ||||
| -rw-r--r-- | udp/fifo19_rxrealign.v | 42 | ||||
| -rw-r--r-- | udp/prot_eng_rx.v | 121 | ||||
| -rw-r--r-- | udp/prot_eng_tx.v | 119 | ||||
| -rw-r--r-- | udp/prot_eng_tx_tb.v | 167 | ||||
| -rw-r--r-- | udp/udp_wrapper.v | 78 | 
13 files changed, 1073 insertions, 49 deletions
diff --git a/control_lib/newfifo/ll8_to_fifo19.v b/control_lib/newfifo/ll8_to_fifo19.v index c65be5136..af3b91afb 100644 --- a/control_lib/newfifo/ll8_to_fifo19.v +++ b/control_lib/newfifo/ll8_to_fifo19.v @@ -10,68 +10,64 @@ module ll8_to_fifo19     output [18:0] f19_data,     output f19_src_rdy_o,     input f19_dst_rdy_i ); - +    +   localparam XFER_EMPTY       = 0; +   localparam XFER_HALF        = 1; +   localparam XFER_HALF_WRITE  = 3; +        // Why anybody would use active low in an FPGA is beyond me...     wire  ll_sof      = ~ll_sof_n;     wire  ll_eof      = ~ll_eof_n;     wire  ll_src_rdy  = ~ll_src_rdy_n;     wire  ll_dst_rdy;     assign    ll_dst_rdy_n  = ~ll_dst_rdy; - -   wire xfer_out 	   = f19_src_rdy_o & f19_dst_rdy_i; -   //  wire xfer_in 	   = ll_src_rdy & ll_dst_rdy;   Not needed -   reg 	 f19_sof, f19_eof, f19_occ; +   wire  xfer_out 	   = f19_src_rdy_o & f19_dst_rdy_i; +   wire  xfer_in 	   = ll_src_rdy & ll_dst_rdy;  +    +   reg 	 hold_sof; +   wire  f19_sof, f19_eof, f19_occ;     reg [1:0] state; -   reg [7:0] dat0, dat1; - -   always @(posedge clk) -     if(ll_src_rdy & ((state==0)|xfer_out)) -       f19_sof <= ll_sof; - +   reg [7:0] hold_reg; +        always @(posedge clk) -     if(ll_src_rdy & ((state != 2)|xfer_out)) -       f19_eof <= ll_eof; - +     if(ll_src_rdy & (state==XFER_EMPTY)) +       hold_reg 	      <= ll_data; +        always @(posedge clk) -     if(ll_eof) -       f19_occ <= ~state[0]; -     else -       f19_occ <= 0; +     if(ll_sof & (state==XFER_EMPTY)) +       hold_sof 	      <= 1; +     else if(xfer_out) +       hold_sof 	      <= 0;     always @(posedge clk) -     if(reset) -       state   <= 0; +     if(reset | clear) +       state 		      <= XFER_EMPTY;       else -       if(ll_src_rdy) -	 case(state) -	   0 :  +       case(state) +	 XFER_EMPTY : +	   if(ll_src_rdy)  	     if(ll_eof) -	       state <= 2; +	       state 	      <= XFER_HALF_WRITE;  	     else -	       state <= 1; -	   1 :  -	     state <= 2; -	   2 :  -	     if(xfer_out) -	       state 	   <= 1; -	 endcase // case(state) -       else -	 if(xfer_out) -	   state 	   <= 0; - -   always @(posedge clk) -     if(ll_src_rdy & (state==1)) -       dat1 		   <= ll_data; - -   always @(posedge clk) -     if(ll_src_rdy & ((state==0) | xfer_out)) -       dat0 		   <= ll_data; +	       state 	      <= XFER_HALF; +	 XFER_HALF : +	   if(ll_src_rdy & f19_dst_rdy_i) +	       state 	      <= XFER_EMPTY; +         XFER_HALF_WRITE : +	   if(f19_dst_rdy_i) +	     state 	<= XFER_EMPTY; +       endcase // case (state) +       +   assign ll_dst_rdy 	 = (state==XFER_EMPTY) | ((state==XFER_HALF)&f19_dst_rdy_i); +   assign f19_src_rdy_o  = (state==XFER_HALF_WRITE) | ((state==XFER_HALF)&ll_src_rdy); +    +   assign f19_sof 	 = hold_sof | (ll_sof & (state==XFER_HALF)); +   assign f19_eof 	 = (state == XFER_HALF_WRITE) | ll_eof; +   assign f19_occ 	 = (state == XFER_HALF_WRITE); -   assign    ll_dst_rdy     = xfer_out | (state != 2); -   assign    f19_data 	    = {f19_occ,f19_eof,f19_sof,dat0,dat1}; -   assign    f19_src_rdy_o  = (state == 2); +   assign f19_data 	 = {f19_occ,f19_eof,f19_sof,hold_reg,ll_data};  endmodule // ll8_to_fifo19 diff --git a/simple_gemac/eth_tasks_f19.v b/simple_gemac/eth_tasks_f19.v new file mode 100644 index 000000000..ff3ae5407 --- /dev/null +++ b/simple_gemac/eth_tasks_f19.v @@ -0,0 +1,92 @@ + + +task SendFlowCtrl; +   input [15:0] fc_len; +   begin +      $display("Sending Flow Control, quanta = %d, time = %d", fc_len,$time); +      pause_time <= fc_len; +      @(posedge eth_clk); +      pause_req <= 1; +      @(posedge eth_clk); +      pause_req <= 0; +      $display("Sent Flow Control"); +   end +endtask // SendFlowCtrl + +task SendPacket_to_fifo19; +   input [31:0] data_start; +   input [15:0] data_len; +   reg [15:0] 	count; +   begin +      $display("Sending Packet Len=%d, %d", data_len, $time); +      count   <= 2; +      tx_f19_data <= {2'b0, 1'b0, 1'b1, data_start}; +      tx_f19_src_rdy  <= 1; +      #1; +      while(count < data_len) +	begin +	   while(~tx_f19_dst_rdy) +	     @(posedge sys_clk); +	   @(posedge sys_clk); +	   //tx_f19_data[31:0] = tx_f19_data[31:0] + 32'h0101_0101; +	   count 	   = count + 4; +	   //tx_f19_data[32] <= 0; +	end +      //tx_f19_data[33] 	  <= 1; +      while(~tx_f19_dst_rdy) +	@(posedge sys_clk); +      @(posedge sys_clk); +      tx_f19_src_rdy <= 0; +   end +endtask // SendPacket_to_fifo19 + +/* +task Waiter; +   input [31:0] wait_length; +   begin +      tx_ll_src_rdy2 <= 0; +      repeat(wait_length) +	@(posedge clk); +      tx_ll_src_rdy2 <= 1; +   end +endtask // Waiter +*/ + +/* +task SendPacketFromFile_f19; +   input [31:0] data_len; +   input [31:0] wait_length; +   input [31:0] wait_time; +    +   integer count; +   begin +      $display("Sending Packet From File to LL8 Len=%d, %d",data_len,$time); +      $readmemh("test_packet.mem",pkt_rom );      + +      while(~tx_f19_dst_rdy) +	@(posedge clk); +      tx_f19_data <= pkt_rom[0]; +      tx_f19_src_rdy <= 1; +      tx_f19_eof     <= 0; +      @(posedge clk); +       +      for(i=1;i<data_len-1;i=i+1) +	begin +	   while(~tx_ll_dst_rdy2) +	     @(posedge clk); +	   tx_ll_data2 <= pkt_rom[i]; +	   tx_ll_sof2  <= 0; +	   @(posedge clk); +//	   if(i==wait_time) +//	     Waiter(wait_length); +	end +       +      while(~tx_ll_dst_rdy2) +	@(posedge clk); +      tx_ll_eof2 <= 1; +      tx_ll_data2 <= pkt_rom[data_len-1]; +      @(posedge clk); +      tx_ll_src_rdy2 <= 0; +   end +endtask +*/ diff --git a/simple_gemac/simple_gemac_wrapper19.build b/simple_gemac/simple_gemac_wrapper19.build new file mode 100755 index 000000000..4be0aac1f --- /dev/null +++ b/simple_gemac/simple_gemac_wrapper19.build @@ -0,0 +1 @@ +iverilog -Wimplict -Wportbind -y ../control_lib/newfifo/ -y ../models/ -y . -y miim -y ../coregen/ -y ../control_lib/ -o simple_gemac_wrapper19_tb simple_gemac_wrapper19_tb.v diff --git a/simple_gemac/simple_gemac_wrapper19.v b/simple_gemac/simple_gemac_wrapper19.v new file mode 100644 index 000000000..11cf7eef2 --- /dev/null +++ b/simple_gemac/simple_gemac_wrapper19.v @@ -0,0 +1,165 @@ + +module simple_gemac_wrapper19 +  #(parameter RXFIFOSIZE=9, +    parameter TXFIFOSIZE=6) +   (input clk125, input reset, +    // GMII +    output GMII_GTX_CLK, output GMII_TX_EN, output GMII_TX_ER, output [7:0] GMII_TXD, +    input GMII_RX_CLK, input GMII_RX_DV, input GMII_RX_ER, input [7:0] GMII_RXD, +     +    // Client FIFO Interfaces +    input sys_clk, +    output [18:0] rx_f19_data, output rx_f19_src_rdy, input rx_f19_dst_rdy, +    input [18:0] tx_f19_data, input tx_f19_src_rdy, output tx_f19_dst_rdy, +     +    // Wishbone Interface +    input wb_clk, input wb_rst, input wb_stb, input wb_cyc, output wb_ack, input wb_we, +    input [7:0] wb_adr, input [31:0] wb_dat_i, output [31:0] wb_dat_o, +     +    // MIIM +    inout mdio, output mdc, +    output [31:0] debug); +    +   wire [7:0] 	  rx_data, tx_data; +   wire 	  tx_clk, tx_valid, tx_error, tx_ack; +   wire 	  rx_clk, rx_valid, rx_error, rx_ack; +    +   wire [47:0] 	  ucast_addr, mcast_addr; +   wire 	  pass_ucast, pass_mcast, pass_bcast, pass_pause, pass_all; +   wire 	  pause_request_en, pause_respect_en; +   wire [15:0] 	  pause_time, pause_thresh, pause_time_req, rx_fifo_space; +    +   wire 	  tx_reset, rx_reset; +   reset_sync reset_sync_tx (.clk(tx_clk),.reset_in(reset),.reset_out(tx_reset)); +   reset_sync reset_sync_rx (.clk(rx_clk),.reset_in(reset),.reset_out(rx_reset)); +    +   simple_gemac simple_gemac +     (.clk125(clk125),  .reset(reset), +      .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),   +      .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD), +      .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),   +      .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD), +      .pause_req(pause_req), .pause_time_req(pause_time_req),  +      .pause_respect_en(pause_respect_en), +      .ucast_addr(ucast_addr), .mcast_addr(mcast_addr), +      .pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),  +      .pass_pause(pass_pause), .pass_all(pass_all), +      .rx_clk(rx_clk), .rx_data(rx_data), +      .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack), +      .tx_clk(tx_clk), .tx_data(tx_data),  +      .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack) +      ); +    +   simple_gemac_wb simple_gemac_wb +     (.wb_clk(wb_clk), .wb_rst(wb_rst), +      .wb_cyc(wb_cyc), .wb_stb(wb_stb), .wb_ack(wb_ack), .wb_we(wb_we), +      .wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o), +      .mdio(mdio), .mdc(mdc), +      .ucast_addr(ucast_addr), .mcast_addr(mcast_addr), +      .pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),  +      .pass_pause(pass_pause), .pass_all(pass_all),  +      .pause_respect_en(pause_respect_en), .pause_request_en(pause_request_en), +      .pause_time(pause_time), .pause_thresh(pause_thresh) ); + +   // RX FIFO Chain +   wire 	  rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy; +    +   wire 	  rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2; +   wire 	  rx_ll_sof2_n, rx_ll_eof2_n, rx_ll_src_rdy2_n, rx_ll_dst_rdy2_n; +    +   wire [7:0] 	  rx_ll_data, rx_ll_data2; +    +   wire [18:0] 	  rx_f19_data_int1; +   wire 	  rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1; +    +   rxmac_to_ll8 rx_adapt +     (.clk(rx_clk), .reset(rx_reset), .clear(0), +      .rx_data(rx_data), .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack), +      .ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(rx_ll_error), +      .ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy)); + +   ll8_shortfifo rx_sfifo +     (.clk(rx_clk), .reset(rx_reset), .clear(0), +      .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof), +      .error_i(rx_ll_error), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy), +      .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2), +      .error_o(rx_ll_error2), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(rx_ll_dst_rdy2)); + +   assign rx_ll_dst_rdy2  = ~rx_ll_dst_rdy2_n; +   assign rx_ll_src_rdy2_n = ~rx_ll_src_rdy2; +   assign rx_ll_sof2_n 	  = ~rx_ll_sof2; +   assign rx_ll_eof2_n 	  = ~rx_ll_eof2; +    +   ll8_to_fifo19 ll8_to_fifo19 +     (.clk(rx_clk), .reset(rx_reset), .clear(0), +      .ll_data(rx_ll_data2), .ll_sof_n(rx_ll_sof2_n), .ll_eof_n(rx_ll_eof2_n), +      .ll_src_rdy_n(rx_ll_src_rdy2_n), .ll_dst_rdy_n(rx_ll_dst_rdy2_n), +      .f19_data(rx_f19_data_int1), .f19_src_rdy_o(rx_f19_src_rdy_int1), .f19_dst_rdy_i(rx_f19_dst_rdy_int1)); + +   fifo_2clock_cascade #(.WIDTH(19), .SIZE(RXFIFOSIZE)) rx_2clk_fifo +     (.wclk(rx_clk), .datain(rx_f19_data_int1),  +      .src_rdy_i(rx_f19_src_rdy_int1), .dst_rdy_o(rx_f19_dst_rdy_int1), .space(rx_fifo_space), +      .rclk(sys_clk), .dataout(rx_f19_data),  +      .src_rdy_o(rx_f19_src_rdy), .dst_rdy_i(rx_f19_dst_rdy), .occupied(), .arst(reset)); +    +   // TX FIFO Chain +   wire 	  tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy; +   wire 	  tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2; +   wire 	  tx_ll_sof2_n, tx_ll_eof2_n, tx_ll_src_rdy2_n, tx_ll_dst_rdy2_n; +   wire [7:0] 	  tx_ll_data, tx_ll_data2; +   wire [18:0] 	  tx_f19_data_int1; +   wire 	  tx_f19_src_rdy_int1, tx_f19_dst_rdy_int1; + +   fifo_2clock_cascade #(.WIDTH(19), .SIZE(4)) tx_2clk_fifo +     (.wclk(sys_clk), .datain(tx_f19_data),  +      .src_rdy_i(tx_f19_src_rdy), .dst_rdy_o(tx_f19_dst_rdy), .space(), +      .rclk(tx_clk), .dataout(tx_f19_data_int1),  +      .src_rdy_o(tx_f19_src_rdy_int1), .dst_rdy_i(tx_f19_dst_rdy_int1), .occupied(), .arst(reset)); +    +   fifo19_to_ll8 fifo19_to_ll8 +     (.clk(tx_clk), .reset(tx_reset), .clear(clear), +      .f19_data(tx_f19_data_int1), .f19_src_rdy_i(tx_f19_src_rdy_int1), .f19_dst_rdy_o(tx_f19_dst_rdy_int1), +      .ll_data(tx_ll_data2), .ll_sof_n(tx_ll_sof2_n), .ll_eof_n(tx_ll_eof2_n), +      .ll_src_rdy_n(tx_ll_src_rdy2_n), .ll_dst_rdy_n(tx_ll_dst_rdy2_n)); + +   assign tx_ll_sof2 	    = ~tx_ll_sof2_n; +   assign tx_ll_eof2 	    = ~tx_ll_eof2_n; +   assign tx_ll_src_rdy2    = ~tx_ll_src_rdy2_n; +   assign tx_ll_dst_rdy2_n  = ~tx_ll_dst_rdy2; +    +   ll8_shortfifo tx_sfifo +     (.clk(tx_clk), .reset(tx_reset), .clear(clear), +      .datain(tx_ll_data2), .sof_i(tx_ll_sof2), .eof_i(tx_ll_eof2), +      .error_i(0), .src_rdy_i(tx_ll_src_rdy2), .dst_rdy_o(tx_ll_dst_rdy2), +      .dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof), +      .error_o(), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy)); +    +   ll8_to_txmac ll8_to_txmac +     (.clk(tx_clk), .reset(tx_reset), .clear(clear), +      .ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof), +      .ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy), +      .tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack)); + +   // Flow Control +   flow_ctrl_rx flow_ctrl_rx +     (.pause_request_en(pause_request_en), .pause_time(pause_time), .pause_thresh(pause_thresh), +      .rx_clk(rx_clk), .rx_reset(rx_reset), .rx_fifo_space(rx_fifo_space), +      .tx_clk(tx_clk), .tx_reset(tx_reset), .pause_req(pause_req), .pause_time_req(pause_time_req)); +    +   wire [31:0] 	  debug_tx, debug_rx; + +   /* +   assign debug_tx  = { { tx_ll_data }, +			{ tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy,  +			  tx_ll_sof2, tx_ll_eof2, tx_ll_src_rdy2, tx_ll_dst_rdy2 }, +			{ tx_valid, tx_error, tx_ack, tx_f19_src_rdy_int1, tx_f19_dst_rdy_int1, tx_f19_data_int1[34:32]}, +			{ tx_data} }; +   assign debug_rx  = { { rx_ll_data }, +			{ rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy,  +			  rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2, rx_ll_dst_rdy2 }, +			{ rx_valid, rx_error, rx_ack, rx_f19_src_rdy_int1, rx_f19_dst_rdy_int1, rx_f19_data_int1[34:32]}, +			{ rx_data} }; +    */ +   assign debug  = debug_rx; +    +endmodule // simple_gemac_wrapper19 diff --git a/simple_gemac/simple_gemac_wrapper19_tb.v b/simple_gemac/simple_gemac_wrapper19_tb.v new file mode 100644 index 000000000..7d57542dc --- /dev/null +++ b/simple_gemac/simple_gemac_wrapper19_tb.v @@ -0,0 +1,209 @@ + + +module simple_gemac_wrapper19_tb; +`include "eth_tasks_f19.v" +      +   reg reset   = 1; +   initial #1000 reset = 0; +   wire wb_rst 	= reset; + +   reg eth_clk     = 0; +   always #50 eth_clk = ~eth_clk; + +   reg wb_clk 	= 0; +   always #173 wb_clk = ~wb_clk; + +   reg sys_clk 	= 0; +   always #77 sys_clk = ~ sys_clk; +    +   wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK; +   wire [7:0] GMII_RXD, GMII_TXD; + +   wire rx_valid, rx_error, rx_ack; +   wire tx_ack, tx_valid, tx_error; +    +   wire [7:0] rx_data, tx_data; +    +   reg [15:0] pause_time; +   reg pause_req      = 0; + +   wire GMII_RX_CLK   = GMII_GTX_CLK; + +   reg [7:0] FORCE_DAT_ERR = 0; +   reg FORCE_ERR = 0; +    +   // Loopback +   assign GMII_RX_DV  = GMII_TX_EN; +   assign GMII_RX_ER  = GMII_TX_ER | FORCE_ERR; +   assign GMII_RXD    = GMII_TXD ^ FORCE_DAT_ERR; + + +   wire [31:0] wb_dat_o; +   reg [31:0]  wb_dat_i; +   reg [7:0]   wb_adr; +   reg 	       wb_stb=0, wb_cyc=0, wb_we=0; +   wire        wb_ack; + +   reg [18:0]  tx_f19_data=0; +   reg 	       tx_f19_src_rdy = 0; +   wire        tx_f19_dst_rdy; +   wire [35:0] rx_f36_data; +   wire        rx_f36_src_rdy; +   wire        rx_f36_dst_rdy = 1; +    +   simple_gemac_wrapper19 simple_gemac_wrapper19 +     (.clk125(eth_clk),  .reset(reset), +      .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),   +      .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD), +      .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),   +      .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD), +      //.pause_req(pause_req), .pause_time(pause_time), + +      .sys_clk(sys_clk), .rx_f36_data(rx_f36_data), .rx_f36_src_rdy(rx_f36_src_rdy), .rx_f36_dst_rdy(rx_f36_dst_rdy), +      .tx_f19_data(tx_f19_data), .tx_f19_src_rdy(tx_f19_src_rdy), .tx_f19_dst_rdy(tx_f19_dst_rdy), + +      .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(wb_stb), .wb_cyc(wb_cyc), .wb_ack(wb_ack), .wb_we(wb_we), +      .wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o), + +      .mdio(), .mdc(), +      .debug() ); +    +   initial $dumpfile("simple_gemac_wrapper19_tb.vcd"); +   initial $dumpvars(0,simple_gemac_wrapper19_tb); + +   integer i;  +   reg [7:0] pkt_rom[0:65535]; +   reg [1023:0] ROMFile; +    +   initial +     for (i=0;i<65536;i=i+1) +       pkt_rom[i] <= 8'h0; + +   initial +     begin +	@(negedge reset); +	repeat (10) +	  @(posedge wb_clk); +	WishboneWR(0,6'b111101);  +	WishboneWR(4,16'hA0B0); +	WishboneWR(8,32'hC0D0_A1B1); +	WishboneWR(12,16'h0000); +	WishboneWR(16,32'h0000_0000); +	 +	@(posedge eth_clk); +	SendFlowCtrl(16'h0007);  // Send flow control +	@(posedge eth_clk); +	#30000; +	@(posedge eth_clk); +	SendFlowCtrl(16'h0009);  // Increase flow control before it expires +	#10000; +	@(posedge eth_clk); +	SendFlowCtrl(16'h0000);  // Cancel flow control before it expires +	@(posedge eth_clk);  + +	repeat (1000) +	  @(posedge sys_clk); +	SendPacket_to_fifo19(32'hA0B0C0D0,10);    // This packet gets dropped by the filters +	repeat (1000) +	  @(posedge sys_clk); + +	SendPacket_to_fifo19(32'hAABBCCDD,100);    // This packet gets dropped by the filters +	repeat (10) +	  @(posedge sys_clk); +/* + 	SendPacketFromFile_f36(60,0,0);  // The rest are valid packets +	repeat (10) +	  @(posedge clk); + + 	SendPacketFromFile_f36(61,0,0); +	repeat (10) +	  @(posedge clk); +	SendPacketFromFile_f36(62,0,0); +	repeat (10) +	  @(posedge clk); +	SendPacketFromFile_f36(63,0,0); +	repeat (1) +	  @(posedge clk); +	SendPacketFromFile_f36(64,0,0); +	repeat (10) +	  @(posedge clk); +	SendPacketFromFile_f36(59,0,0); +	repeat (1) +	  @(posedge clk); +	SendPacketFromFile_f36(58,0,0); +	repeat (1) +	  @(posedge clk); +	SendPacketFromFile_f36(100,0,0); +	repeat (1) +	  @(posedge clk); +	SendPacketFromFile_f36(200,150,30);  // waiting 14 empties the fifo, 15 underruns +	repeat (1) +	  @(posedge clk); +	SendPacketFromFile_f36(100,0,30); + */ +	#100000 $finish; +     end + +   // Force a CRC error +    initial +     begin +	#90000; +	@(posedge eth_clk); +	FORCE_DAT_ERR <= 8'h10; +	@(posedge eth_clk); +	FORCE_DAT_ERR <= 8'h00; +     end + +   // Force an RX_ER error (i.e. link loss) +   initial +     begin +	#116000; +	@(posedge eth_clk); +	FORCE_ERR <= 1; +	@(posedge eth_clk); +	FORCE_ERR <= 0; +     end +/* +   // Cause receive fifo to fill, causing an RX overrun +   initial +     begin +	#126000; +	@(posedge clk); +	rx_ll_dst_rdy2 <= 0; +	repeat (30)          // Repeat of 14 fills the shortfifo, but works.  15 overflows +	  @(posedge clk); +	rx_ll_dst_rdy2 <= 1; +     end +  */ +   // Tests: Send and recv flow control, send and receive good packets, RX CRC err, RX_ER, RX overrun, TX underrun +   // Still need to test: CRC errors on Pause Frames, MDIO, wishbone + +   task WishboneWR; +      input [7:0] adr; +      input [31:0] value; +      begin +	 wb_adr   <= adr; +	 wb_dat_i <= value; +	 wb_stb   <= 1; +	 wb_cyc   <= 1; +	 wb_we 	  <= 1; +	 while (~wb_ack) +	   @(posedge wb_clk); +	 @(posedge wb_clk); +	 wb_stb <= 0; +	 wb_cyc <= 0; +	 wb_we 	<= 0; +      end +   endtask // WishboneWR +   /* +   always @(posedge clk) +     if(rx_ll_src_rdy2 & rx_ll_dst_rdy2) +       begin +	  if(rx_ll_sof2 & ~rx_ll_eof2) +	    $display("RX-PKT-START %d",$time); +	  $display("RX-PKT SOF %d EOF %d ERR%d DAT %x",rx_ll_sof2,rx_ll_eof2,rx_ll_error2,rx_ll_data2); +	  if(rx_ll_eof2 & ~rx_ll_sof2) +	    $display("RX-PKT-END %d",$time); +       end +   */ +endmodule // simple_gemac_wrapper19_tb diff --git a/top/u2_core/u2_core.v b/top/u2_core/u2_core.v index f9ac07a55..ada0f66db 100644 --- a/top/u2_core/u2_core.v +++ b/top/u2_core/u2_core.v @@ -419,19 +419,30 @@ module u2_core     // /////////////////////////////////////////////////////////////////////////     // Ethernet MAC  Slave #6 -   simple_gemac_wrapper #(.RXFIFOSIZE(11), .TXFIFOSIZE(6)) simple_gemac_wrapper +   wire [18:0] 	 rx_f19_data, tx_f19_data; +   wire 	 rx_f19_src_rdy, rx_f19_dst_rdy, rx_f36_src_rdy, rx_f36_dst_rdy; +    +   simple_gemac_wrapper19 #(.RXFIFOSIZE(11), .TXFIFOSIZE(6)) simple_gemac_wrapper19       (.clk125(clk_to_mac),  .reset(wb_rst),        .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),          .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),        .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),          .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),        .sys_clk(dsp_clk), -      .rx_f36_data({wr2_flags,wr2_dat}), .rx_f36_src_rdy(wr2_ready_i), .rx_f36_dst_rdy(wr2_ready_o), -      .tx_f36_data({rd2_flags,rd2_dat}), .tx_f36_src_rdy(rd2_ready_o), .tx_f36_dst_rdy(rd2_ready_i), +      .rx_f19_data(rx_f19_data), .rx_f19_src_rdy(rx_f19_src_rdy), .rx_f19_dst_rdy(rx_f19_dst_rdy), +      .tx_f19_data(tx_f19_data), .tx_f19_src_rdy(tx_f19_src_rdy), .tx_f19_dst_rdy(tx_f19_dst_rdy),        .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(s6_stb), .wb_cyc(s6_cyc), .wb_ack(s6_ack),        .wb_we(s6_we), .wb_adr(s6_adr), .wb_dat_i(s6_dat_o), .wb_dat_o(s6_dat_i),        .mdio(MDIO), .mdc(MDC),        .debug(debug_mac)); + +   udp_wrapper #(.BASE(0)) udp_wrapper +     (.clk(dsp_clk), .reset(dsp_rst), .clear(0), +      .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), +      .rx_f19_data(rx_f19_data), .rx_f19_src_rdy_i(rx_f19_src_rdy), .rx_f19_dst_rdy_o(rx_f19_dst_rdy), +      .tx_f19_data(tx_f19_data), .tx_f19_src_rdy_o(tx_f19_src_rdy), .tx_f19_dst_rdy_i(tx_f19_dst_rdy), +      .rx_f36_data({wr2_flags,wr2_dat}), .rx_f36_src_rdy_o(wr2_ready_i), .rx_f36_dst_rdy_i(wr2_ready_o), +      .tx_f36_data({rd2_flags,rd2_dat}), .tx_f36_src_rdy_i(rd2_ready_o), .tx_f36_dst_rdy_o(rd2_ready_i) );     // /////////////////////////////////////////////////////////////////////////     // Settings Bus -- Slave #7 diff --git a/top/u2_rev3/Makefile b/top/u2_rev3/Makefile index 1f8bbe304..d27469f47 100644 --- a/top/u2_rev3/Makefile +++ b/top/u2_rev3/Makefile @@ -88,7 +88,12 @@ vrt/vita_rx_control.v \  vrt/vita_rx_framer.v \  vrt/vita_tx_control.v \  vrt/vita_tx_deframer.v \ +udp/udp_wrapper.v \ +udp/fifo19_rxrealign.v \ +udp/prot_eng_tx.v \ +udp/add_onescomp.v \  simple_gemac/simple_gemac_wrapper.v \ +simple_gemac/simple_gemac_wrapper19.v \  simple_gemac/simple_gemac.v \  simple_gemac/simple_gemac_wb.v \  simple_gemac/simple_gemac_tx.v \ @@ -109,11 +114,15 @@ control_lib/newfifo/buffer_pool.v \  control_lib/newfifo/fifo_2clock.v \  control_lib/newfifo/fifo_2clock_cascade.v \  control_lib/newfifo/ll8_shortfifo.v \ -control_lib/newfifo/ll8_to_fifo36.v \  control_lib/newfifo/fifo_short.v \  control_lib/newfifo/fifo_long.v \  control_lib/newfifo/fifo_cascade.v \  control_lib/newfifo/fifo36_to_ll8.v \ +control_lib/newfifo/ll8_to_fifo36.v \ +control_lib/newfifo/fifo19_to_ll8.v \ +control_lib/newfifo/ll8_to_fifo19.v \ +control_lib/newfifo/fifo36_to_fifo19.v \ +control_lib/newfifo/fifo19_to_fifo36.v \  control_lib/longfifo.v \  control_lib/shortfifo.v \  control_lib/medfifo.v \ @@ -123,6 +132,8 @@ coregen/fifo_xlnx_512x36_2clk.v \  coregen/fifo_xlnx_512x36_2clk.xco \  coregen/fifo_xlnx_64x36_2clk.v \  coregen/fifo_xlnx_64x36_2clk.xco \ +coregen/fifo_xlnx_16x19_2clk.v \ +coregen/fifo_xlnx_16x19_2clk.xco \  extram/wb_zbt16_b.v \  opencores/8b10b/decode_8b10b.v \  opencores/8b10b/encode_8b10b.v \ diff --git a/udp/add_onescomp.v b/udp/add_onescomp.v new file mode 100644 index 000000000..048842a86 --- /dev/null +++ b/udp/add_onescomp.v @@ -0,0 +1,12 @@ + + +module add_onescomp +  #(parameter WIDTH = 16) +   (input [WIDTH-1:0] A, +    input [WIDTH-1:0] B, +    output [WIDTH-1:0] SUM); + +   wire [WIDTH:0] SUM_INT = {1'b0,A} + {1'b0,B}; +   assign SUM  = SUM_INT[WIDTH-1:0] + {{WIDTH-1{1'b0}},SUM_INT[WIDTH]}; +    +endmodule // add_onescomp diff --git a/udp/fifo19_rxrealign.v b/udp/fifo19_rxrealign.v new file mode 100644 index 000000000..35ad90951 --- /dev/null +++ b/udp/fifo19_rxrealign.v @@ -0,0 +1,42 @@ + + +//  Adds a junk line at the beginning of every packet, which the +//   following stages should ignore.  This gives us proper alignment due +//   to the 14 byte ethernet header + +// Bit 18 -- odd length +// Bit 17 -- eof +// Bit 16 -- sof +// Bit 15:0 -- data + +module fifo19_rxrealign +  (input clk, input reset, input clear, +   input [18:0] datain, input src_rdy_i, output dst_rdy_o, +   output [18:0] dataout, output src_rdy_o, input dst_rdy_i); +    +   reg 	rxre_state; +   localparam RXRE_DUMMY  = 0; +   localparam RXRE_PKT 	  = 1; +    +   assign dataout[18] 	  = datain[18]; +   assign dataout[17] 	  = datain[17]; +   assign dataout[16] 	  = (rxre_state==RXRE_DUMMY) | (datain[17] & datain[16]);  // allows for passing error signal +   assign dataout[15:0] = datain[15:0]; +    +   always @(posedge clk) +     if(reset | clear) +       rxre_state <= RXRE_DUMMY; +     else if(src_rdy_i & dst_rdy_i) +       case(rxre_state) +	 RXRE_DUMMY : +	   rxre_state <= RXRE_PKT; +	 RXRE_PKT : +	   if(datain[17])   // if eof or error +	     rxre_state <= RXRE_DUMMY; +       endcase // case (rxre_state) + +   assign src_rdy_o 	 = src_rdy_i & dst_rdy_i;   // Send anytime both sides are ready +   assign dst_rdy_o = src_rdy_i & dst_rdy_i & (rxre_state == RXRE_PKT);  // Only consume after the dummy +    +endmodule // fifo19_rxrealign + diff --git a/udp/prot_eng_rx.v b/udp/prot_eng_rx.v new file mode 100644 index 000000000..5df158b2b --- /dev/null +++ b/udp/prot_eng_rx.v @@ -0,0 +1,121 @@ + + + +// Protocol Engine Receiver +//  Checks each line (16 bits) against values in setting regs +//  3 options for each line --  +//      Error if mismatch, Slowpath if mismatch, or ignore line +//  The engine increases the length of each packet by 32 or 48 bits, +//   bringing the total length to a multiple of 32 bits.  The last line +//   is entirely new, and contains the results of the matching operation: +//      16 bits of flags, 16 bits of data.  Flags indicate error or slowpath +//      Data indicates line that caused mismatch if any. + + +//   Flags[2:0] is {occ, eop, sop} +//   Protocol word format is: +//             22   Last Header Line +//             21   SLOWPATH if mismatch +//             20   ERROR if mismatch +//             19   This is the IP checksum +//             18   This is the UDP checksum +//             17   Compute IP checksum on this word +//             16   Compute UDP checksum on this word +//           15:0   data word to be matched + +module prot_eng_rx +  #(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); + +   localparam HDR_WIDTH  = 16 + 7;  // 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 consume_input 	= src_rdy_i & dst_rdy_o; +   wire produce_output 	= src_rdy_o & dst_rdy_i; +    +   // Main State Machine +   reg [15:0] pkt_length, fail_word, dataout_int; +    +   reg slowpath, error, sof_o, eof_o, occ_o, odd; + +   assign dataout    = {occ_o, eof_o, sof_o, dataout_int}; + +   wire [15:0] calc_ip_checksum, calc_udp_checksum; +   reg [15:0] rx_ip_checksum, rx_udp_checksum; + +   always @(posedge clk)  +     if(header_word[19])  +       rx_ip_checksum  <= datain[15:0]; +   always @(posedge clk)  +     if(header_word[18])  +       rx_udp_checksum <= datain[15:0]; +    +   always @(posedge clk) +     if(reset | clear) +       begin +	  slowpath     <= 0; +	  error        <= 0; +	  state        <= 0; +	  fail_word    <= 0; +	  eof_o        <= 0; +	  occ_o        <= 0; +       end +     else if(src_rdy_i & dst_rdy_i) +       case (state) +	 0 : +	   begin +	      slowpath 	   <= 0; +	      error 	   <= 0; +	      eof_o 	   <= 0; +	      occ_o 	   <= 0; +	      state 	   <= 1; +	   end + +	 ST_SLOWPATH : +	   ; +	 ST_ERROR : +	   ; +	 ST_PAYLOAD : +	   ; +	 ST_FILLER : +	   ; +	 ST_END1 : +	   ; +	 ST_END2 : +	   ; +	 default : +	   if(header_word[21] && mismatch) +	     state <= ST_SLOWPATH; +	   else if(header_word[20] && mismatch) +	     state <= ST_ERROR; +	   else if(header_word[22]) +	     state <= ST_PAYLOAD; +	   else +	     state <= state + 1; +       endcase // case (state) +    + + +   // IP + UDP checksum state machines +   checksum_sm ip_chk +     (.clk(clk), .reset(reset), .in(datain),  +      .calc(consume_input & header_word[17]), .clear(state==0), .checksum(ip_checksum)); +    +   checksum_sm udp_chk +     (.clk(clk), .reset(reset), .in(datain),  +      .calc(consume_input & header_word[16]), .clear(state==0), .checksum(udp_checksum)); +    +endmodule // prot_eng_rx diff --git a/udp/prot_eng_tx.v b/udp/prot_eng_tx.v new file mode 100644 index 000000000..9031011f7 --- /dev/null +++ b/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 diff --git a/udp/prot_eng_tx_tb.v b/udp/prot_eng_tx_tb.v new file mode 100644 index 000000000..e7ffeb5e1 --- /dev/null +++ b/udp/prot_eng_tx_tb.v @@ -0,0 +1,167 @@ +module prot_eng_tx_tb(); + +   localparam BASE = 128; +   reg clk    = 0; +   reg rst    = 1; +   reg clear  = 0; +   initial #1000 rst = 0; +   always #50 clk = ~clk; +    +   reg [31:0] f36_data; +   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; + +   wire [35:0] casc_do; +   wire [18:0] final_out, prot_out; + +   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)); + +   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)); + +   reg set_stb; +   reg [7:0] set_addr; +   reg [31:0] set_data; +	 +   prot_eng_tx #(.BASE(BASE)) prot_eng_tx +     (.clk(clk), .reset(rst), +      .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)); +    +   reg [35:0] printer; + +   task WriteSREG; +      input [7:0] addr; +      input [31:0] data; + +      begin +	 @(posedge clk); +	 set_addr <= addr; +	 set_data <= data; +	 set_stb  <= 1; +	 @(posedge clk); +	 set_stb <= 0; +      end +   endtask // WriteSREG +   	 +   task ReadFromFIFO36; +      begin +	 $display("Read from FIFO36"); +	 #1 dst_rdy_prot <= 1; +	 while(~src_rdy_prot) +	   @(posedge clk); +	 while(1) +	   begin +	      while(~src_rdy_prot) +		@(posedge clk); +	      $display("Read: %h",prot_out); +	      @(posedge clk); +	   end +      end +   endtask // ReadFromFIFO36 +    +   task PutPacketInFIFO36; +      input [31:0] data_start; +      input [31:0] data_len; +      begin +	 count 	      <= 4; +	 src_rdy_f36i <= 1; +	 f36_data     <= 32'h0001_000c; +	 f36_sof      <= 1; +	 f36_eof      <= 0; +	 f36_occ      <= 0; +	 +	 $display("Put Packet in FIFO36"); +	 while(~dst_rdy_f36i) +	   @(posedge clk); +	 @(posedge clk); +	 $display("PPI_FIFO36: Entered First Line"); +	 f36_sof  <= 0; +	 f36_data <= data_start; +	 while(~dst_rdy_f36i) +	   @(posedge clk); +	 @(posedge clk); +	 while(count+4 < data_len) +	   begin +	      f36_data <= f36_data + 32'h01010101; +	      count    <= count + 4; +	      while(~dst_rdy_f36i) +		@(posedge clk); +	      @(posedge clk); +	      $display("PPI_FIFO36: Entered New Line"); +	   end +	 f36_data  <= f36_data + 32'h01010101; +	 f36_eof   <= 1; +	 if(count + 4 == data_len) +	   f36_occ <= 0; +	 else if(count + 3 == data_len) +	   f36_occ <= 3; +	 else if(count + 2 == data_len) +	   f36_occ <= 2; +	 else +	   f36_occ <= 1; +	 while(~dst_rdy_f36i) +	   @(posedge clk); +	 @(posedge clk); +	 f36_occ      <= 0; +	 f36_eof      <= 0; +	 f36_data     <= 0; +	 src_rdy_f36i <= 0; +	 $display("PPI_FIFO36: Entered Last Line"); +      end +   endtask // PutPacketInFIFO36 +    +   initial $dumpfile("prot_eng_tx_tb.vcd"); +   initial $dumpvars(0,prot_eng_tx_tb); + +   initial +     begin +	#10000; +	@(posedge clk); +	ReadFromFIFO36; +     end +    +   initial +     begin +	@(negedge rst); +	@(posedge clk); +	WriteSREG(BASE, {12'b0, 4'h0, 16'h0000}); +	WriteSREG(BASE+1, {12'b0, 4'h0, 16'h0000}); +	WriteSREG(BASE+2, {12'b0, 4'h0, 16'hABCD}); +	WriteSREG(BASE+3, {12'b0, 4'h0, 16'h1234}); +	WriteSREG(BASE+4, {12'b0, 4'h8, 16'h5678}); +	WriteSREG(BASE+5, {12'b0, 4'h0, 16'hABCD}); +	WriteSREG(BASE+6, {12'b0, 4'h0, 16'hABCD}); +	WriteSREG(BASE+7, {12'b0, 4'h0, 16'hABCD}); +	WriteSREG(BASE+8, {12'b0, 4'h0, 16'hABCD}); +	WriteSREG(BASE+9, {12'b0, 4'h0, 16'hABCD}); +	@(posedge clk); +	PutPacketInFIFO36(32'hA0B0C0D0,16); +	@(posedge clk); +	@(posedge clk); +	#10000; +	@(posedge clk); +	PutPacketInFIFO36(32'hE0F0A0B0,36); +	@(posedge clk); +	@(posedge clk); +	@(posedge clk); +	@(posedge clk); +	@(posedge clk); +     end + +   initial #20000 $finish; +endmodule // prot_eng_tx_tb diff --git a/udp/udp_wrapper.v b/udp/udp_wrapper.v new file mode 100644 index 000000000..490e392c5 --- /dev/null +++ b/udp/udp_wrapper.v @@ -0,0 +1,78 @@ + +module udp_wrapper +  #(parameter BASE=0, +    parameter RXFIFOSIZE=11) +   (input clk, input reset, input clear, +    input set_stb, input [7:0] set_addr, input [31:0] set_data, +    input [18:0] rx_f19_data, input rx_f19_src_rdy_i, output rx_f19_dst_rdy_o, +    output [18:0] tx_f19_data, output tx_f19_src_rdy_o, input tx_f19_dst_rdy_i, +     +    output [35:0] rx_f36_data, output rx_f36_src_rdy_o, input rx_f36_dst_rdy_i, +    input [35:0] tx_f36_data, input tx_f36_src_rdy_i, output tx_f36_dst_rdy_o +    ); +    +   wire 	 tx_int1_src_rdy, tx_int1_dst_rdy; +   wire [18:0] 	 tx_int1_data; +    +   wire 	 tx_int2_src_rdy, tx_int2_dst_rdy; +   wire [18:0] 	 tx_int2_data; +    +   // TX side +   fifo36_to_fifo19 fifo36_to_fifo19 +     (.clk(clk), .reset(reset), .clear(clear), +      .f36_datain(tx_f36_data), .f36_src_rdy_i(tx_f36_src_rdy_), .f36_dst_rdy_o(tx_f36_dst_rdy_o), +      .f19_dataout(tx_int1_data), .f19_src_rdy_o(tx_int1_src_rdy), .f19_dst_rdy_i(tx_int1_dst_rdy) ); + +   fifo_short #(.WIDTH(19)) shortfifo19_a +     (.clk(clk), .reset(reset), .clear(clear), +      .datain(tx_int1_data), .src_rdy_i(tx_int1_src_rdy), .dst_rdy_o(tx_int1_dst_rdy), +      .dataout(tx_int2_data), .src_rdy_o(tx_int2_src_rdy), .dst_rdy_i(tx_int2_dst_rdy), +      .space(), .occupied() ); +      +   prot_eng_tx #(.BASE(BASE)) prot_eng_tx +     (.clk(clk), .reset(reset), .clear(clear), +      .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data), +      .datain(tx_int2_data), .src_rdy_i(tx_int2_src_rdy), .dst_rdy_o(tx_int2_dst_rdy), +      .dataout(tx_f19_data), .src_rdy_o(tx_f19_src_rdy_o), .dst_rdy_i(tx_f19_dst_rdy_i) ); + +   // RX side +   wire rx_int1_src_rdy, rx_int1_dst_rdy; +   wire [18:0] rx_int1_data; +       +   wire rx_int2_src_rdy, rx_int2_dst_rdy; +   wire [18:0] rx_int2_data; +       +   wire rx_int3_src_rdy, rx_int3_dst_rdy; +   wire [35:0] rx_int3_data; +    +`ifdef USE_PROT_ENG +   prot_eng_rx #(.BASE(BASE)) prot_eng_rx +     (.clk(clk), .reset(reset), .clear(clear), +      .datain(rx_f19_data), .src_rdy_i(rx_f19_src_rdy_i), .dst_rdy_o(rx_f19_dst_rdy_o), +      .dataout(rx_int1_data), .src_rdy_o(rx_int1_src_rdy), .dst_rdy_i(rx_int1_dst_rdy) ); +`else +   fifo19_rxrealign fifo19_rxrealign +     (.clk(clk), .reset(reset), .clear(clear), +      .datain(rx_f19_data), .src_rdy_i(rx_f19_src_rdy_i), .dst_rdy_o(rx_f19_dst_rdy_o), +      .dataout(rx_int1_data), .src_rdy_o(rx_int1_src_rdy), .dst_rdy_i(rx_int1_dst_rdy) ); +`endif // !`ifdef USE_PROT_ENG +    +   fifo_short #(.WIDTH(19)) shortfifo19_b +     (.clk(clk), .reset(reset), .clear(clear), +      .datain(rx_int1_data), .src_rdy_i(rx_int1_src_rdy), .dst_rdy_o(rx_int1_dst_rdy), +      .dataout(rx_int2_data), .src_rdy_o(rx_int2_src_rdy), .dst_rdy_i(rx_int2_dst_rdy), +      .space(), .occupied() ); + +   fifo19_to_fifo36 fifo19_to_fifo36 +     (.clk(clk), .reset(reset), .clear(clear), +      .f19_datain(rx_int2_data), .f19_src_rdy_i(rx_int2_src_rdy), .f19_dst_rdy_o(rx_int2_dst_rdy), +      .f36_dataout(rx_int3_data), .f36_src_rdy_o(rx_int3_src_rdy), .f36_dst_rdy_i(rx_int3_dst_rdy) ); +    +   fifo_cascade #(.WIDTH(36),.SIZE(RXFIFOSIZE)) eth0_rxfifo +     (.clk(clk), .reset(reset), .clear(clear), +      .datain(rx_int3_data), .src_rdy_i(rx_int3_src_rdy), .dst_rdy_o(rx_int3_dst_rdy), +      .dataout({f36_flags_o,f36_data_o}), .src_rdy_o(f36_src_rdy_o), .dst_rdy_i(f36_dst_rdy_i), +      .space(), .occupied() ); + +    +endmodule // udp_wrapper  | 
