📄 eth_avalon_rxdma.v
字号:
if(valid_rx_wr)
state[ST_BD_WR] <= 1'b1;
else state[ST_DMA2 ] <= 1'b1;
state[ST_BD_WR]:
if(~bd_wait) state[ST_IDLE ] <= 1'b1;
else state[ST_BD_WR] <= 1'b1;
endcase
end
always @(posedge clk) begin
if(state[ST_IDLE ]) first_write <= 1'b1;
if(state[ST_DMA1 ] & valid_rx_wr) first_write <= 1'b0;
end
//Length decoder
always @(posedge clk)
if(state[ST_BD_RD]) len <= 16'd0;
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]});
//((av_byteenable[0] + av_byteenable[1]) + (av_byteenable[2] + av_byteenable[3]));
always @(posedge clk)
if(valid_rx_wr) msb_be2 <= msb_be[12:10];
//Latch Data FIFO output whenever a write to memory takes place
always @(posedge clk)
if(state[ST_DMA1] & valid_rx_wr) dff_dout_r <= dff_dout;
//****************************************************************************
//********************** Descriptor Interface Logic **************************
assign bd_read = state[ST_BD_RD];
assign bd_write = state[ST_BD_WR];
assign bd_writedata= {len[15:0],1'b0,desc[BIT_IRQ:BIT_WRAP],4'b000,eff_dout_r};
//Load pointer and descriptor data in BD Read state
always @(posedge clk) begin
if(bd_read) {ptr,desc} <= {bd_ptr,bd_desc};
if(valid_rx_wr) ptr[31:2] <= ptr[31:2] + 30'd1;
end
always @(posedge clk)
if(state[ST_DMA2 ] & valid_rx_wr)
eff_dout_r <= eff_dout;
//bd_index decoder
always @(posedge clk or posedge reset)
if(reset) bd_index <= 7'd0;
else if(~RxEn) bd_index <= 7'd0;
else if(bd_write & ~bd_wait) begin
if((bd_index == max_rx_bd) | desc[BIT_WRAP])
bd_index <= 7'd0;
else
bd_index <= bd_index + 7'd1;
end
//IRQ generation to feed back to registers module
always @(posedge clk or posedge reset)
if(reset) begin RxE_IRQ <= 1'b0;
RxB_IRQ <= 1'b0;
end else begin
RxE_IRQ <= 1'b0;
RxB_IRQ <= 1'b0;
if(state[ST_BD_WR ] & ~bd_wait) begin
RxE_IRQ <= desc[BIT_IRQ] & err_r;
RxB_IRQ <= desc[BIT_IRQ] & ~err_r;
end
end
//********************** Descriptor Interface Logic **************************
//****************************************************************************
//****************************************************************************
//****************** Dual-Clock Data and Error FIFOs *************************
//Data FIFO
eth_avalon_dma_fifo #( .DEPTH(RFD),
.WIDTH(36) ) eth_rxdma_datafifo(
.aclr (reset ),
.wrclk (rxclk ),
.wrreq (dff_wr & rx_rdy ),
.wrfull (dff_full ),
.wrusedw( ),
.data (dff_in ),
.rdclk (clk ),
.rdreq (dff_read ),
.rdempty(dff_empty ),
.rdusedw( ),
.q (dff_dout )
);
//Error FIFO
eth_avalon_dma_fifo #( .DEPTH(EFD),
.WIDTH(9) ) eth_rxdma_errfifo(
.aclr (reset ),
.wrclk (rxclk ),
.wrreq (eff_wr & rx_rdy ),
.wrfull (eff_full ),
.wrusedw( ),
.data (rx_res ),
.rdclk (clk ),
.rdreq (eff_read ),
.rdempty(eff_empty ),
.rdusedw( ),
.q (eff_dout )
);
//Set Busy IRQ if a new frame comes in and
//we're too busy to receive it.
eth_dc_reg tx_start_dc_reg(
.d (rx_sop & rx_dv & ~rx_rdy),
.inclk (rxclk ),
.outclk (clk ),
.reset (reset ),
.q (Busy_IRQ )
);
//**************** End Dual-Clock Data and Error FIFOs ***********************
//****************************************************************************
//*****************************************************************************
//********************* Streaming Interface Logic *****************************
assign rx_rdy = ~dff_full & ~eff_full;
assign dff_in = {dff_stat,dff_in_reg[3],dff_in_reg[2],dff_in_reg[1],dff_in_reg[0]};
assign dff_wr = (rx_state[RX_REC ] & rx_wr) | rx_state[RX_EOP];
assign eff_wr = rx_state[RX_EOP ];
assign rx_res = {rx_err[8:7],rx_overrun,rx_err[5:0]};
always @(posedge rxclk or posedge reset)
if(reset) begin rx_state <= 4'd0;
rx_state[RX_IDLE] <= 1'b1;
end else begin
/*default case-->*/ rx_state <= 4'd0;
case(1'b1) // synopsys parallel_case
//Wait for start of FRAME
//We'll never leave this
//state if the FIFO isn't
//ready
rx_state[RX_IDLE]:
if(rx_dv & rx_sop)
if(rx_rdy) rx_state[RX_REC ] <= 1'b1;
else rx_state[RX_IDLE] <= 1'b1;
else rx_state[RX_IDLE] <= 1'b1;
//Receiving Frame
rx_state[RX_REC ]:
if(rx_dv) begin
if(rx_eop) rx_state[RX_EOP ] <= 1'b1;
else if(~rx_rdy) rx_state[RX_DISC] <= 1'b1;
else rx_state[RX_REC ] <= 1'b1;
end else rx_state[RX_REC ] <= 1'b1;
//Throw away the frame. We
//Overran the FIFO in the
//middle of the frame. We
//discard the rest of the
//frame.
rx_state[RX_DISC]:
if(rx_eop & rx_dv) rx_state[RX_EOP ] <= 1'b1;
else rx_state[RX_DISC] <= 1'b1;
//Write last word to FIFO.
//We will sit here indefintely
//until the FIFO is ready
rx_state[RX_EOP]:
if(rx_rdy) rx_state[RX_IDLE] <= 1'b1;
else rx_state[RX_EOP ] <= 1'b1;
endcase
end
always @(posedge rxclk or posedge reset)
if(reset) rx_overrun <= 1'b0;
else if(rx_state[RX_REC]) rx_overrun <= rx_dv & ~rx_rdy;
else if(rx_state[RX_EOP] & rx_rdy) rx_overrun <= 1'b0;
//We'll allow this to overrun
always @(posedge rxclk or posedge reset)
if(reset) rx_cnt <= 2'd0;
else
case(1'b1) // synopsys parallel_case
rx_state[RX_IDLE]:
if(rx_dv & rx_sop & rx_rdy) rx_cnt <= rx_cnt + 2'd1;
else rx_cnt <= 2'd0;
rx_state[RX_REC ]:
if(rx_dv) rx_cnt <= rx_cnt + 2'd1;
rx_state[RX_EOP ]: rx_cnt <= 2'd0;
endcase
//set the write flag when all 4 bytes are received
always @(posedge rxclk or posedge reset)
if(reset) rx_wr <= 1'b0;
else
if(rx_state[RX_REC]) rx_wr <= rx_dv & (&rx_cnt);
else rx_wr <= 1'b0;
//We'll alow these to overrun
always @* begin dff_stat[2] = rx_state[RX_EOP ];
if(rx_state[RX_EOP]) dff_stat[3] = |{rx_res[8:3],rx_res[1:0]};
else dff_stat[3] = 1'b0;
end
always @(posedge rxclk)
if(rx_dv) begin dff_in_reg[rx_cnt] <= rx_data;
dff_stat[1:0] <= rx_cnt;
end
//******************* End Streaming Interface Logic ***************************
//*****************************************************************************
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -