1 //////////////////////////////////////////////////////////////////////
3 //// eth_avalon_rxdma.v ////
5 //// This file is a patch used in conjunction with the ////
6 //// Ethernet IP core project. ////
7 //// http://www.opencores.org/projects/ethmac/ ////
10 //// - Jakob Jones (jrjonsie@gmail.com) ////
12 //// All additional information is available in the Readme.txt ////
15 //////////////////////////////////////////////////////////////////////
16 module eth_avalon_rxdma #
( parameter FIFO_DEPTH
= 4096) (
21 //Descriptor ram interface
22 input [6:0] max_rx_bd
, //Highest index RX Descriptor
23 input [31:0] bd_desc
, //Descriptor Control data input
24 input [31:0] bd_ptr
, //Descriptor pointer input
25 input bd_wait
, //Descriptor RAM is busy
27 output bd_write
, //write control data to BD RAM
28 output bd_read
, //read control and pointer data from BD RAM
29 output reg [6:0] bd_index
, //Which descriptor to read
30 output [31:0] bd_writedata
, //Control data to be written to descriptor
32 //Memory port interface
33 input av_waitrequest
, //Memory port is busy
35 output reg av_write
, //Memory port write
36 output reg [31:0] av_address
, //Memory port address
37 output reg [31:0] av_writedata
, //Memory port writedata
38 output reg [3:0] av_byteenable
, //Memory port byteenable
41 input RxEn
, //Receive Enable
42 input rxclk
, //Receive clock
43 input [7:0] rx_data
, //input data
44 input rx_dv
, //qualifies datain, startofpacket, and endofpacket
45 input [8:0] rx_err
, //error bits
46 input rx_sop
, //start of data packet
47 input rx_eop
, //end of data packet
48 input rx_abort
, //abort packet
56 `include "eth_avalon_functions.v"
58 //Let's determine the FIFO Depths. We use two FIFOs. One to pass data.
59 //and one to pass error information. The error FIFO does not need to be as
60 //large because it is only written to on an end of packet. We'll make the
61 //assumption that normally packets will be a minimum of 64 bytes long. So
62 //We divide the FIFO depth by 64 to get the Error FIFO depth. To be on the
63 //safe side, we double that number (really divide by 32). If Either one of
64 //these FIFOs overflow, on overrun will occur.
65 localparam MINFD
= max(FIFO_DEPTH
,128); //Minimum 128 byte FIFO depth
66 localparam RFD
= nextPow2(MINFD
)>>2; //FIFO depth next power of 2 (and divide by 4)
67 localparam EFD
= max((RFD
>>3), 4); //Minimum error FIFO depth of 4
69 //Descriptor status bit defines
70 localparam BIT_LEN_H
= 31, //Upper bit of length field
71 BIT_LEN_L
= 16, //Lower bit of length field
73 BIT_EMPTY
= 15, //Empty control bit (1=EMPTY Controller can write to it)
74 BIT_IRQ
= 14, //Generate an interrupt at end of RX
75 BIT_WRAP
= 13, //Wrap to first RX descriptor after this one
76 BIT_RSVD_H
= 12, //Upper bit of reserved field
77 BIT_RSVD_L
= 11, //Lower bit of reserved field
79 BIT_CF
= 8, //Control Frame was received
81 BIT_OR
= 6, //FIFO overrun
82 BIT_IS
= 5, //Invalid Symbol
83 BIT_DN
= 4, //Dribble Nibble
84 BIT_TL
= 3, //Frame too long
85 BIT_SF
= 2, //Frame short
86 BIT_CRC
= 1, //CRC error
87 BIT_LC
= 0; //Late Collision
89 //DMA State Machine Bits
90 localparam ST_IDLE
= 0,
96 //RX State Machine Bits
97 localparam RX_IDLE
= 0,
102 //Avalon interface signals
103 wire [31:0] pre_av_writedata
;
104 wire [3:0] pre_av_byteenable
;
106 wire [31:0] pre_av_address
;
109 reg [31:0] desc
; //Descriptor control word
110 reg [31:0] ptr
; //Write pointer (from descriptor)
111 reg [15:0] len
; //Length counter
113 //DMA controller signals
114 reg [5:0] state
; //One-hot state machine bits
115 wire [1:0] cnt
; //Valid byte count (out of FIFO);
116 wire eop
; //End of packet flag (out of FIFO)
117 wire abort
; //Abort flag (out of FIFO)
120 reg first_write
;//First write to memory
121 wire [3:0] lsb_be
; //LSB byteenable (First write)
124 wire [63:0] sdata
; //shifted data
130 wire dff_empty
; //data FIFO empty
131 wire [35:0] dff_dout
; //data FIFO output
132 reg [35:0] dff_dout_r
; //registered dff_out
133 wire dff_read
; //data FIFO read
135 wire eff_empty
; //error FIFO empty
136 wire [8:0] eff_dout
; //error FIFO output
137 reg [8:0] eff_dout_r
; //registered eff_dout
138 wire eff_read
; //error FIFO read
140 wire [35:0] dff_in
; // data fifo input data
141 reg [7:0] dff_in_reg
[3:0];// registered incoming data word (to make a x4)
142 reg [3:0] dff_stat
; // {errors,eop,#valid bytes}
143 wire dff_wr
; // write data to FIFO
144 wire dff_full
; // data FIFO full
148 //Streaming interface signals
149 reg [3:0] rx_state
; // RX state bits
150 reg [1:0] rx_cnt
; // # of valid bytes in data word
151 reg rx_wr
; // indicates normal write to FIFO
152 wire rx_rdy
; // indicates FIFO is ready to receive (not full)
153 reg rx_overrun
; // an overrun as occurred
154 reg rx_abort_r
; // latch rx_abort flag at end of packet
155 wire [8:0] rx_res
; // RX result (errors and status)
157 //*****************************************************************************
158 //************************* Avalon Interface Logic ****************************
159 always @(posedge clk
or posedge reset
)
160 if(reset
) av_write
<= 1'b0;
161 else if(~av_waitrequest
) av_write
<= pre_av_write
;
163 always @(posedge clk
)
164 if(~av_waitrequest
) begin
165 av_writedata
<= pre_av_writedata
;
166 av_address
<= pre_av_address
;
167 av_byteenable
<= pre_av_byteenable
;
169 //*********************** End Avalon Interface Logic **************************
170 //*****************************************************************************
172 //*****************************************************************************
173 //************************** DMA Interface Logic ******************************
175 assign abort
= dff_dout_r
[35];
176 assign eop
= dff_dout
[34];
177 assign cnt
= dff_dout
[33:32];
179 //Avalon Memory Master interface
180 assign pre_av_writedata
= sdata
[63:32];
181 assign pre_av_byteenable
= first_write ? lsb_be
:
182 state
[ST_DMA2
] ?
{1'b0,msb_be2
}:
185 assign pre_av_address
= {ptr
[31:2],2'b00};
186 assign pre_av_write
= rx_write
;
188 assign rx_write
= (state
[ST_DMA1
] & ~dff_empty
) |
(state
[ST_DMA2
] & ~eff_empty
);
189 assign valid_rx_wr
= rx_write
& ~av_waitrequest
;
190 assign dff_read
= state
[ST_DMA1
] & ~dff_empty
& ~av_waitrequest
;
191 assign eff_read
= state
[ST_DMA2
] & ~eff_empty
& ~av_waitrequest
;
193 //Shift data for unaligned transfers
194 assign sdata
= {dff_dout
[31:0], dff_dout_r
[31:0]} << {ptr
[1:0],3'd0};
195 //Shift byteenable for first unaligned transfer
196 assign lsb_be
= 4'b1111 << ptr
[1:0];
197 assign msb_be
= 13'b0000001111111 << ({1'b0,ptr
[1:0]} + {1'b0,cnt
});
199 //State machine (one-hot) encoding
200 always @(posedge clk
or posedge reset
)
201 if(reset
) begin state
<= 5'd0;
202 state
[ST_IDLE
] <= 1'b1;
204 /*default case-->*/ state
<= 5'd0;
205 case(1'b1) // synopsys parallel_case
207 if(RxEn
) state
[ST_BD_RD
] <= 1'b1;
208 else state
[ST_IDLE
] <= 1'b1;
210 if(~bd_wait
& bd_desc
[BIT_EMPTY
]) state
[ST_DMA1
] <= 1'b1;
211 else state
[ST_BD_RD
] <= 1'b1;
213 if(valid_rx_wr
& eop
) state
[ST_DMA2
] <= 1'b1;
214 else state
[ST_DMA1
] <= 1'b1;
217 state
[ST_BD_WR
] <= 1'b1;
218 else state
[ST_DMA2
] <= 1'b1;
220 if(~bd_wait
) state
[ST_IDLE
] <= 1'b1;
221 else state
[ST_BD_WR
] <= 1'b1;
225 always @(posedge clk
) begin
226 if(state
[ST_IDLE
]) first_write
<= 1'b1;
227 if(state
[ST_DMA1
] & valid_rx_wr
) first_write
<= 1'b0;
231 always @(posedge clk
)
232 if(state
[ST_BD_RD
]) len
<= 16'd0;
233 else if(valid_rx_wr
) len
<= len
+ ({&pre_av_byteenable
[1:0],^pre_av_byteenable
[1:0]} + {&pre_av_byteenable
[3:2],^pre_av_byteenable
[3:2]});
234 //((av_byteenable[0] + av_byteenable[1]) + (av_byteenable[2] + av_byteenable[3]));
237 always @(posedge clk
)
238 if(valid_rx_wr
) msb_be2
<= msb_be
[12:10];
240 //Latch Data FIFO output whenever a write to memory takes place
241 always @(posedge clk
)
242 if(state
[ST_DMA1
] & valid_rx_wr
) dff_dout_r
<= dff_dout
;
244 //****************************************************************************
245 //********************** Descriptor Interface Logic **************************
246 assign bd_read
= state
[ST_BD_RD
];
247 assign bd_write
= state
[ST_BD_WR
] & ~abort
;
248 assign bd_writedata
= {len
[15:0],1'b0,desc
[BIT_IRQ
:BIT_WRAP
],4'b000,eff_dout_r
};
250 //Load pointer and descriptor data in BD Read state
251 always @(posedge clk
) begin
252 if(bd_read
) {ptr
,desc
} <= {bd_ptr
,bd_desc
};
253 if(valid_rx_wr
) ptr
[31:2] <= ptr
[31:2] + 30'd1;
256 always @(posedge clk
)
257 if(state
[ST_DMA2
] & valid_rx_wr
) begin
258 eff_dout_r
<= eff_dout
;
259 err_r
<= |
{eff_dout
[8:3],eff_dout
[1:0]};
263 always @(posedge clk
or posedge reset
)
264 if(reset
) bd_index
<= 7'd0;
265 else if(~RxEn
) bd_index
<= 7'd0;
266 else if(bd_write
& ~bd_wait
) begin
267 if((bd_index
== max_rx_bd
) | desc
[BIT_WRAP
])
270 bd_index
<= bd_index
+ 7'd1;
273 //IRQ generation to feed back to registers module
274 always @(posedge clk
or posedge reset
)
275 if(reset
) begin RxE_IRQ
<= 1'b0;
280 if(bd_write
& ~bd_wait
) begin
281 RxE_IRQ
<= desc
[BIT_IRQ
] & err_r
;
282 RxB_IRQ
<= desc
[BIT_IRQ
] & ~err_r
;
285 //********************** Descriptor Interface Logic **************************
286 //****************************************************************************
288 //****************************************************************************
289 //****************** Dual-Clock Data and Error FIFOs *************************
292 eth_avalon_dma_fifo #
( .
DEPTH(RFD
),
293 .
WIDTH(36) ) eth_rxdma_datafifo(
296 .
wrreq (dff_wr
& rx_rdy
),
303 .
rdempty(dff_empty
),
309 eth_avalon_dma_fifo #
( .
DEPTH(EFD
),
310 .
WIDTH(9) ) eth_rxdma_errfifo(
313 .
wrreq (eff_wr
& rx_rdy
),
320 .
rdempty(eff_empty
),
325 //Set Busy IRQ if a new frame comes in and
326 //we're too busy to receive it.
327 eth_dc_reg
tx_start_dc_reg(
328 .
d (rx_sop
& rx_dv
& ~rx_rdy
),
335 //**************** End Dual-Clock Data and Error FIFOs ***********************
336 //****************************************************************************
338 //*****************************************************************************
339 //********************* Streaming Interface Logic *****************************
340 assign rx_rdy
= ~dff_full
& ~eff_full
;
341 assign dff_in
= {dff_stat
,dff_in_reg
[3],dff_in_reg
[2],dff_in_reg
[1],dff_in_reg
[0]};
342 assign dff_wr
= (rx_state
[RX_REC
] & rx_wr
) | rx_state
[RX_EOP
];
343 assign eff_wr
= rx_state
[RX_EOP
];
344 assign rx_res
= {rx_err
[8:7],rx_overrun
,rx_err
[5:0]};
346 always @(posedge rxclk
or posedge reset
)
347 if(reset
) begin rx_state
<= 4'd0;
348 rx_state
[RX_IDLE
] <= 1'b1;
350 /*default case-->*/ rx_state
<= 4'd0;
351 case(1'b1) // synopsys parallel_case
352 //Wait for start of FRAME
353 //We'll never leave this
354 //state if the FIFO isn't
358 if(rx_rdy
) rx_state
[RX_REC
] <= 1'b1;
359 else rx_state
[RX_IDLE
] <= 1'b1;
360 else rx_state
[RX_IDLE
] <= 1'b1;
364 if(rx_eop
) rx_state
[RX_EOP
] <= 1'b1;
365 else if(~rx_rdy
) rx_state
[RX_DISC
] <= 1'b1;
366 else rx_state
[RX_REC
] <= 1'b1;
367 end else rx_state
[RX_REC
] <= 1'b1;
368 //Throw away the frame. We
369 //Overran the FIFO in the
370 //middle of the frame. We
371 //discard the rest of the
374 if(rx_eop
& rx_dv
) rx_state
[RX_EOP
] <= 1'b1;
375 else rx_state
[RX_DISC
] <= 1'b1;
376 //Write last word to FIFO.
377 //We will sit here indefintely
378 //until the FIFO is ready
380 if(rx_rdy
) rx_state
[RX_IDLE
] <= 1'b1;
381 else rx_state
[RX_EOP
] <= 1'b1;
385 always @(posedge rxclk
or posedge reset
)
386 if(reset
) rx_overrun
<= 1'b0;
387 else if(rx_state
[RX_REC
]) rx_overrun
<= rx_dv
& ~rx_rdy
;
388 else if(rx_state
[RX_EOP
] & rx_rdy
) rx_overrun
<= 1'b0;
390 always @(posedge rxclk
)
391 if(rx_state
[RX_IDLE
]) rx_abort_r
<= 1'b0;
392 else if(rx_state
[RX_REC
] | rx_state
[RX_DISC
])
393 rx_abort_r
<= rx_dv
& rx_eop
& rx_abort
;
395 //We'll allow this to overrun
396 always @(posedge rxclk
or posedge reset
)
397 if(reset
) rx_cnt
<= 2'd0;
399 case(1'b1) // synopsys parallel_case
401 if(rx_dv
& rx_sop
& rx_rdy
) rx_cnt
<= rx_cnt
+ 2'd1;
405 if(rx_dv
) rx_cnt
<= rx_cnt
+ 2'd1;
407 rx_state
[RX_EOP
]: rx_cnt
<= 2'd0;
410 //set the write flag when all 4 bytes are received
411 always @(posedge rxclk
or posedge reset
)
412 if(reset
) rx_wr
<= 1'b0;
414 if(rx_state
[RX_REC
]) rx_wr
<= rx_dv
& (&rx_cnt
);
418 //We'll alow these to overrun
419 always @* begin dff_stat
[2] = rx_state
[RX_EOP
];
420 if(rx_state
[RX_EOP
]) dff_stat
[3] = rx_abort_r
;
421 else dff_stat
[3] = 1'b0;
424 always @(posedge rxclk
)
425 if(rx_dv
) begin dff_in_reg
[rx_cnt
] <= rx_data
;
426 dff_stat
[1:0] <= rx_cnt
;
430 //******************* End Streaming Interface Logic ***************************
431 //*****************************************************************************