⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eth_avalon_rxdma.v

📁 sopc builder 中网络的eth_ocm核
💻 V
📖 第 1 页 / 共 2 页
字号:
                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 + -