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

📄 eth_avalon_txdma.v

📁 sopc builder 中网络的eth_ocm核
💻 V
📖 第 1 页 / 共 2 页
字号:
            state[ST_STAT ]: begin // wait for status
                if(stat_ready) begin                      
                    if(tx_retry)                    state[ST_IDLE ] <= 1'b1;
                    else                            state[ST_BD_WR] <= 1'b1;
                end else                            state[ST_STAT ] <= 1'b1;
            end
            state[ST_BD_WR]: // write descriptor   
                if(~bd_wait)                        state[ST_IDLE ] <= 1'b1;
                else                                state[ST_BD_WR] <= 1'b1;
        endcase
    end


assign  next_tg_cnt = bd_len + ({1'b0,ptr[1:0]} + 3'd3);
assign  next_rd_cnt = rd_cnt + 14'd1;
assign  next_wr_cnt = wr_cnt + 14'd1;
assign  last_read   = (next_rd_cnt >= tg_cnt) | stat_ready;
assign  first_write = !wr_cnt;
assign  last_write  = last_read_r & (next_wr_cnt >= rd_cnt);
assign  valid_cnt   = first_write ? first_valid_cnt:
                    last_write  ? last_valid_cnt:
                    2'd3;

//Register last read signal
always @(posedge clk) begin
                                            valid_rdata <= av_readdatavalid;
                                            rdata       <= av_readdata;
        if(valid_rdata)                     wr_cnt      <= next_wr_cnt;
    //This really is a parallel case 
    case(1'b1) // synopsys parallel_case 
        state[ST_IDLE]: begin
                                            last_read_r <= 1'b0;                //clear last read flag
                                            rd_cnt      <= 14'd0;               //clear read count
                                            wr_cnt      <= 14'd0;               //clear write count
                                            TxB_IRQ     <= 1'b0;                //clear irq
                                            TxE_IRQ     <= 1'b0;                //clear error irq
            if(~TxEn)                       bd_index    <= 7'd0;                //clear the BD indexer
        end //state[ST_IDLE ]

        state[ST_BD_RD]: begin
            if(~bd_wait & bd_desc[BIT_READY]) begin
                                            tg_cnt      <= next_tg_cnt[15:2];   //load target count
                                            {ptr,desc}  <= {bd_ptr,bd_desc};    //load pointer and descriptor
            end
        end //state[ST_BD_RD]

        state[ST_DMA1 ]: begin
                                            first_valid_cnt <= (3'd3 - {1'b0,ptr[1:0]});
                                            last_valid_cnt  <= (bd_len[2:0] + {1'b0,ptr[1:0]}) - 3'd1;
            if(valid_tx_rd) begin 
                                            ptr[31:2]   <= ptr[31:2] + 30'd1;   //increment read address
                                            last_read_r <= last_read;           //set last read flag
                                            rd_cnt      <= next_rd_cnt;         //increment read count
            end
        end //state[ST_DMA1 ]

        state[ST_BD_WR]:
            if(~bd_wait) begin
                                            TxB_IRQ     <= desc[BIT_IRQ] & ~stat_error;
                                            TxE_IRQ     <= desc[BIT_IRQ] & stat_error;
                if(desc[BIT_WRAP] | (bd_index == max_tx_bd))
                                            bd_index    <= 7'd0;
                else                        bd_index    <= bd_index + 7'd1;
            end

    endcase
end


//***************************************************************************
//*************************** Data FIFO *************************************
assign  dff_clear       = reset | state[ST_IDLE];
assign  dff_write       = valid_rdata & ~stat_ready;
assign  dff_din[35]     = first_write;
assign  dff_din[34]     = last_write;
assign  dff_din[33:32]  = valid_cnt;
assign  dff_din[31:0]   = first_write? (rdata >> {ptr[1:0],3'd0}): rdata;
assign  dff_almost_full = dff_wrused >= FF_FULL_THRESHOLD;

//We'll read from the FIFO everytime there is a word ready or if something
//happened to put us into the WAIT state. We do this to flush the FIFO so
//any pending incoming reads from the avalon bus will make it into the FIFO 
assign  dff_read        = tx_state[TX_WAIT] | (tx_state[TX_SEND] & last_byte & tx_ack); 
eth_avalon_dma_fifo #(  .DEPTH(RFD),
                        .WIDTH(36)) data_fifo(
    .aclr       (dff_clear              ),

    .wrclk      (clk                    ),
    .data       (dff_din                ),
    .wrreq      (dff_write              ),
    .wrfull     (dff_full               ),
    .wrusedw    (dff_wrused             ),

    .rdclk      (txclk                  ),
    .rdreq      (dff_read&~dff_empty    ),
    .rdempty    (dff_empty              ),
    .rdusedw    (                       ),
    .q          (dff_dout               )
); 

//Send stat_ready signal from TX to Avalon
eth_dc_reg stat_ready_dc_reg(
	.d      (tx_state[TX_WAIT] & tx_stat_valid_r),
	.inclk  (txclk              ),
	.outclk (clk                ),
	.reset  (reset              ),
	.q      (stat_ready         )
    );

//Send stat_ack signal from Avalon to TX
eth_dc_reg stat_ack_dc_reg(
	.d      (state[ST_IDLE] ),
	.inclk  (clk            ),
	.outclk (txclk          ),
	.reset  (reset          ),
	.q      (tx_stat_ack    )
    );

//Send tx_start signal from Avalon to TX
//We start sending the data when there is either
//words in the FIFO or when the DMA transfer
//has finished.
eth_dc_reg tx_start_dc_reg(
	.d      ((dff_wrused >= 8)/*dff_almost_full*/ | state[ST_DMA2]   ),
	.inclk  (clk            ),
	.outclk (txclk          ),
	.reset  (reset          ),
	.q      (tx_start       )
);

//************************* End Data FIFO ***********************************
//***************************************************************************
            
//***************************************************************************
//************************* Streaming Interface *****************************
assign  stat_error  = |{stat[BIT_UR],stat[BIT_RL:BIT_CS]};


assign  tx_ff_data[0]   = dff_dout[7:0];
assign  tx_ff_data[1]   = dff_dout[15:8];
assign  tx_ff_data[2]   = dff_dout[23:16];
assign  tx_ff_data[3]   = dff_dout[31:24];
assign  byte_cnt        = dff_dout[33:32];
assign  last_byte       = (byte_index == byte_cnt);

assign  tx_data = tx_ff_data[byte_index];
assign  tx_dv   = tx_state[TX_SEND];
assign  tx_sop  = tx_state[TX_SEND] & !byte_index & dff_dout[35];
assign  tx_eop  = tx_state[TX_SEND] & last_byte & dff_dout[34];

assign  PerPacketPad    = desc[BIT_PAD];
assign  PerPacketCrc    = desc[BIT_CRC];
assign  TxUnderRun      = tx_state[TX_SEND] & tx_ack & dff_empty;

always @(posedge txclk or posedge reset)
    if(reset)                       tx_state            <= 3'd1;
    else begin
        /*default case-->*/         tx_state            <= 3'd0;
        case(1'b1) // synopsys parallel_case 
            tx_state[TX_IDLE]:// Wait for start
                if(tx_start)        tx_state[TX_SEND]   <= 1'b1;
                else                tx_state[TX_IDLE]   <= 1'b1;

            tx_state[TX_SEND]:// Send all data 
                if((last_byte & dff_dout[34] & tx_ack) | tx_stat_valid)
                                    tx_state[TX_WAIT]   <= 1'b1;
                else                tx_state[TX_SEND]   <= 1'b1;
                                

            tx_state[TX_WAIT]:// Wait for status
                if(tx_stat_ack)     tx_state[TX_IDLE]   <= 1'b1;
                else                tx_state[TX_WAIT]   <= 1'b1;

        endcase
    end

always @(posedge txclk) 
        if(tx_stat_valid)       stat    <= tx_stat;

always @(posedge txclk)
        if(tx_state[TX_IDLE])   tx_stat_valid_r <= 1'b0;
        else if(tx_stat_valid)  tx_stat_valid_r <= 1'b1;

always @(posedge txclk)
    case(1'b1)
        tx_state[TX_IDLE]: begin
                                            byte_index  <= 2'd0;
        end

        tx_state[TX_SEND]: begin
            if(tx_ack) begin
                if(last_byte)               byte_index  <= 2'd0;
                else                        byte_index  <= byte_index + 2'd1;
            end
        end
    endcase
//*********************** End Streaming Interface ***************************
//***************************************************************************

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -