diff options
Diffstat (limited to 'usrp2/simple_gemac/ethtx_realign.v')
| -rw-r--r-- | usrp2/simple_gemac/ethtx_realign.v | 77 | 
1 files changed, 77 insertions, 0 deletions
| diff --git a/usrp2/simple_gemac/ethtx_realign.v b/usrp2/simple_gemac/ethtx_realign.v new file mode 100644 index 000000000..be53abf4c --- /dev/null +++ b/usrp2/simple_gemac/ethtx_realign.v @@ -0,0 +1,77 @@ + +//////////////////////////////////////////////////////////////////////// +// Ethernet TX - Realign +// +// - removes a 2-byte pad from the front a fifo36 stream +// - occupancy is preserved +// + +module ethtx_realign +   (input clk, input reset, input clear, +    input [35:0] datain, input src_rdy_i, output dst_rdy_o, +    output [35:0] dataout, output src_rdy_o, input dst_rdy_i); + +   reg [1:0] 	  state; +   reg [15:0] 	  held; +   reg [1:0] 	  held_occ; +   reg 		  held_sof; +    +   wire 	  xfer_in = src_rdy_i & dst_rdy_o; +   wire 	  xfer_out = src_rdy_o & dst_rdy_i; + +   wire 	  sof_in = datain[32]; +   wire 	  eof_in = datain[33]; +   wire [1:0] 	  occ_in = datain[35:34]; +   wire 	  occ_low = occ_in[1] ^ occ_in[0]; //occ is 1 or 2 + +   always @(posedge clk) +     if(reset | clear) +       begin +	  held <= 0; +	  held_occ <= 0; +	  held_sof <= 0; +       end +     else if(xfer_in) +       begin +	  held <= datain[15:0]; +	  held_occ <= occ_in; +	  held_sof <= sof_in; +       end +    +   localparam RE_IDLE = 0; +   localparam RE_HELD = 1; +   localparam RE_DONE = 2; + +   always @(posedge clk) +     if(reset | clear) +       state <= RE_IDLE; +     else +       case(state) +	 RE_IDLE : +	   if(xfer_in & eof_in) +	     state <= RE_DONE; +	   else if(xfer_in & sof_in) +	     state <= RE_HELD; + +	 RE_HELD : +	   if(xfer_in & xfer_out & eof_in) +	     if(occ_low) +	       state <= RE_IDLE; +	     else +	       state <= RE_DONE; + +	 RE_DONE : +	   if(xfer_out) +	     state <= RE_IDLE; +	  +       endcase // case (state) + +   wire sof_out = held_sof; +   wire eof_out = (state == RE_HELD)? (eof_in & occ_low) : (state == RE_DONE); +   wire [1:0] occ_out = ((state == RE_DONE)? held_occ : occ_in) ^ 2'b10; //(occ + 2)%4 + +   assign dataout = {occ_out,eof_out,sof_out,held,datain[31:16]}; +   assign src_rdy_o = (state == RE_HELD)? src_rdy_i : (state == RE_DONE); +   assign dst_rdy_o = (state == RE_HELD)? dst_rdy_i : (state == RE_IDLE); + +endmodule // ethtx_realign | 
