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

📄 pci_master32_sm_if.v

📁 用verilog编写的pci——rtl级。
💻 V
📖 第 1 页 / 共 3 页
字号:
always@(posedge reset_in or posedge clk_in)
begin
    if (reset_in)
        del_write_req <= #`FF_DELAY 1'b0 ;
    else
        del_write_req <= #`FF_DELAY del_write_req_input ;
end

/*================================================================================================
Posted write request indicator.
Posted write starts whenever no request is in progress and one whole posted write is
stored in WBW_FIFO. It ends on error terminations ( master, target abort, retry expired) or
data transfer terminations if last data is on top of FIFO.
Continues on wait, retry, and disconnect without data.
================================================================================================*/
// posted write request FF input control
reg posted_write_req_input ;
always@(
    do_posted_write or
    del_write_req or
    posted_write_req or
    del_read_req or
    wait_in or
    //retry_in or
    rerror_in or
    mabort_in or
    //retry_expired or
    rtransfer_in or
    last_transfered
)
begin
    if (~posted_write_req)
    begin
        // posted write is not in progress
        posted_write_req_input = ~del_write_req && ~del_read_req && do_posted_write ;
    end
    else
    begin
        posted_write_req_input = wait_in ||
                                 (/*~(retry_in && retry_expired && ~rtransfer_in) &&*/
                                  ~rerror_in && ~mabort_in &&
                                  ~(last_transfered)
                                 ) ;

    end
end

// posted write request flip flop
always@(posedge reset_in or posedge clk_in)
begin
    if (reset_in)
        posted_write_req <= #`FF_DELAY 1'b0 ;
    else
        posted_write_req <= #`FF_DELAY posted_write_req_input ;

end

/*================================================================================================
Delayed read request indicator.
Delayed read starts whenever no request is in progress and delayed read request is signaled from
other side of bridge. It ends on error terminations ( master, target abort, retry expired) or
data transfer terminations if it is not burst transfer or on cache line bounds on burst transfer.
It also ends on disconnects.
Continues on wait and retry.
================================================================================================*/
// delayed read FF input control
reg del_read_req_input ;
always@(
    do_del_read or
    del_write_req or
    posted_write_req or
    del_read_req or
    last_transfered or
    wait_in or
    retry_in or
    //retry_expired or
    mabort_in or
    rtransfer_in or
    rerror_in or
    first_in or
    del_complete_out
)
begin
    if (~del_read_req)
    begin
        del_read_req_input = ~del_write_req && ~posted_write_req && ~del_complete_out && do_del_read ;
    end
    else
    begin
        del_read_req_input = wait_in ||
                             ( ~(retry_in && (~first_in /*|| retry_expired */)) &&
                               ~mabort_in && ~rerror_in &&
                               ~(last_transfered)
                             ) ;
    end
end

// delayed read request FF
always@(posedge reset_in or posedge clk_in)
begin
    if (reset_in)
        del_read_req <= #`FF_DELAY 1'b0 ;
    else
        del_read_req <= #`FF_DELAY del_read_req_input ;
end

// wire indicating last entry of transaction on top of fifo
wire wlast = wbw_fifo_control_in[`LAST_CTRL_BIT] ;

wire last_int = posted_write_req && wlast || del_write_req ;

// intermidiate data, byte enable and last registers
reg [31:0] intermediate_data ;
reg  [3:0] intermediate_be ;
reg        intermediate_last ;

wire intermediate_enable = ( posted_write_req || del_write_req ) && ( ~write_req_int || (( ~rdy_out || ~wait_in && rtransfer_in ) && ~intermediate_last)) ;

always@(posedge reset_in or posedge clk_in)
begin
    if ( reset_in )
    begin
        intermediate_data <= #`FF_DELAY 32'h0000_0000 ;
        intermediate_be   <= #`FF_DELAY 4'h0 ;
        intermediate_last <= #`FF_DELAY 1'b0 ;
    end
    else
    if ( intermediate_enable )
    begin
        intermediate_data <= #`FF_DELAY source_data ;
        intermediate_be   <= #`FF_DELAY source_be ;
        intermediate_last <= #`FF_DELAY last_int ;
    end
end

// multiplexer for next data
reg [31:0] next_data_out ;
reg [3:0] next_be_out   ;
reg write_next_last ;
reg [3:0] write_next_be ;

always@
(
    rtransfer_in            or 
    intermediate_data       or 
    intermediate_be         or 
    intermediate_last       or 
    wbw_fifo_addr_data_in   or 
    wbw_fifo_cbe_in         or 
    wlast                   or
    wait_in
)
begin
    if( rtransfer_in & ~wait_in )
    begin
        next_data_out   = wbw_fifo_addr_data_in ;
        write_next_last = wlast ;
        write_next_be   = wbw_fifo_cbe_in ;
    end
    else
    begin
        next_data_out   = intermediate_data ;
        write_next_last = intermediate_last ;
        write_next_be   = intermediate_be ;
    end
end

always@(del_read_req or source_be or write_next_be)
begin
    if (del_read_req)
        next_be_out = source_be ;
    else
        next_be_out = write_next_be ;
end
/*================================================================================================
WBW_FIFO read enable - read from WBW_FIFO is performed on posted writes, when data transfer
termination is received - transfer or disconnect with data. Reads are enabled during error
recovery also, since erroneous transaction must be pulled out of FIFO!
================================================================================================*/
// wbw_fifo read enable input control

assign wbw_renable_out = ~req_out && (do_posted_write || err_recovery) ||
                              posted_write_req && ( ~write_req_int || (~rdy_out && ~intermediate_last) || (~wait_in && rtransfer_in && ~intermediate_last)) ;

/*================================================================================================
WBR_FIFO write enable control -
writes to FIFO are possible only when delayed read request is in progress and data transfer
or error termination is signalled. It is not enabled on retry or disconnect without data.
================================================================================================*/
// wbr_fifo write enable control - enabled when transfer is in progress and data is transfered or error is signalled
assign wbr_fifo_wenable_out = del_read_req && ~wait_in && ( rtransfer_in || mabort_in || rerror_in ) ;

/*================================================================================================
WBR_FIFO control output for identifying data entries.
This is necesary because of prefetched reads, which partially succeed. On error, error entry
gets in to signal it on WISHBONE bus if WISHBONE master reads up to this entry.
================================================================================================*/
assign wbr_fifo_control_out[`ADDR_CTRL_BIT]       = 1'b0 ;
assign wbr_fifo_control_out[`LAST_CTRL_BIT]       = last_transfered ;
assign wbr_fifo_control_out[`DATA_ERROR_CTRL_BIT] = rerror_in || (mabort_in && ~conf_cyc_bc) ;
assign wbr_fifo_control_out[`UNUSED_CTRL_BIT]     = 1'b0 ;

// retry expired error for posted writes control
//assign err_rty_exp_out = posted_write_req && ~wait_in && retry_in && retry_expired && ~rtransfer_in;
assign err_rty_exp_out = 1'b0 ;

// error source and error signal output control logic - only for posted writes
assign err_source_out = mabort_in /*|| err_rty_exp_out*/ ;

assign err_signal_out = /*err_rty_exp_out || */ posted_write_req && ~wait_in && (mabort_in || rerror_in) ;

//assign del_rty_exp_out = (~wait_in && (del_read_req || del_write_req)) && (retry_in && retry_expired && ~rtransfer_in) ;
assign del_rty_exp_out = 1'b0 ;

assign del_error_out   = ~wait_in && (del_write_req || del_read_req) && ( (mabort_in && ~conf_cyc_bc) || rerror_in ) ;

wire   del_write_complete = del_write_req && ~wait_in && ( rtransfer_in || rerror_in || mabort_in ) ;
wire   del_read_complete  = del_read_req  && ~wait_in && ( rerror_in || mabort_in || last_transfered || ( retry_in && ~first_in ) ) ;

assign del_complete_out = ~wait_in && ( del_write_complete || del_read_complete ) ;

// next last output generation
assign next_last_out = del_write_req || del_read_req && ( ~del_burst_in || read_bound ) || posted_write_req && ( write_next_last ) ;
/*==================================================================================================================
Error recovery FF gets a value of one, when during posted write error occurs. It is cleared when all the data provided
for erroneous transaction is pulled out of WBW_FIFO
==================================================================================================================*/

// error recovery flip flop input - used when posted write is terminated with an error
always@(
    err_recovery or
    last_out or
    wlast or
    err_signal_out or
    intermediate_last
)
begin
    // when error recovery is not set - drive its input so it gets set
    if ( ~err_recovery )
        err_recovery_in = ~last_out && ~intermediate_last && err_signal_out ;
    else
        // when error recovery is set, wbw_fifo is enabled - clear err_recovery when last data entry of erroneous transaction is pulled out of fifo
        err_recovery_in = ~wlast ;
end

wire data_out_load = (posted_write_req || del_write_req) && ( !rdy_out || ( !wait_in && rtransfer_in ) ) ;

wire be_out_load  = (req_out && !rdy_out) || ( posted_write_req && !wait_in && rtransfer_in ) ;

wire last_load  = req_out && ( ~rdy_out || ~wait_in && wtransfer_in ) ;

always@(posedge reset_in or posedge clk_in)
begin
    if (reset_in)
        data_out <= #`FF_DELAY 32'h0000_0000 ;
    else
    if ( data_out_load )
        data_out <= #`FF_DELAY intermediate_data ;
end

always@(posedge clk_in or posedge reset_in)
begin
    if ( reset_in )
        be_out <= #`FF_DELAY 4'hF ;
    else
    if ( be_out_load )
        be_out <= #`FF_DELAY posted_write_req ? intermediate_be : source_be ;
end

always@(posedge reset_in or posedge clk_in)
begin
    if (reset_in)
        current_last <= #`FF_DELAY 1'b0 ;
    else
    if ( last_load )
        current_last <= #`FF_DELAY next_last_out ;
end

assign last_out = current_last ;
endmodule

⌨️ 快捷键说明

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