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

📄 pci_wb_slave.v

📁 用verilog编写的pci——rtl级。
💻 V
📖 第 1 页 / 共 4 页
字号:
---------------------------------------------------------------------------------------------------------------------*/

always@(map or mrl_en or ccyc_hit or WE_I or wb_conf_hit or CAB_I or pref_en)
begin
`ifdef HOST
// only host implementation supports configuration and interrupt acknowledge commands
    if (wb_conf_hit)
    begin
        case( {ccyc_hit, WE_I} )
            2'b11:  del_bc = `BC_CONF_WRITE ;
            2'b10:  del_bc = `BC_CONF_READ ;
            2'b01:  del_bc = `BC_RESERVED0 ; // invalid combination - interrupt acknowledge cycle must be a read
            2'b00:  del_bc = `BC_IACK ;
        endcase
    end
    else
`endif
    begin
        if ( map )
        begin
            del_bc = `BC_IO_READ ;
        end
        else
        begin
            case ({(CAB_I && mrl_en), pref_en})
                2'b00: del_bc = `BC_MEM_READ ;     // if this is not burst transfer or memory read line command is disabled - use memory read
                2'b01: del_bc = `BC_MEM_READ ;     // same as previous case
                2'b10: del_bc = `BC_MEM_READ_LN ;  // burst transfer, memory read line command enabled, prefetch disabled - use memory read line command
                2'b11: del_bc = `BC_MEM_READ_MUL ; // same as previous case, except prefetch is enabled - use memory read multiple command
            endcase
        end
    end
end

reg del_in_progress ; // state machine indicates whether current read completion is in progress on WISHBONE bus

wire image_access_error = (map && burst_transfer) ; // IO write is a burst

`ifdef HOST
    reg [1:0]   wbw_data_out_sel ;
    parameter SEL_ADDR_IN = 2'b10 ;
    parameter SEL_CCYC_ADDR = 2'b11 ;
    parameter SEL_DATA_IN   = 2'b00 ;
`else
`ifdef GUEST
    reg wbw_data_out_sel ;
    parameter SEL_ADDR_IN = 1'b1 ;
    parameter SEL_DATA_IN = 1'b0 ;
`endif
`endif

`ifdef WB_DECODE_FAST
    `ifdef REGISTER_WBS_OUTPUTS
        `define PCI_WB_SLAVE_S_DEC1
    `endif
`endif

`ifdef WB_DECODE_MEDIUM
    `define PCI_WB_SLAVE_S_DEC1
`endif

`ifdef WB_DECODE_SLOW
    `define PCI_WB_SLAVE_S_DEC1
    `define PCI_WB_SLAVE_S_DEC2
`endif
// state machine logic
always@(
        c_state                     or
        wattempt                    or
        img_wallow                  or
        burst_transfer              or
        wb_hit                      or
        map                         or
        rattempt                    or
        do_dread_completion         or
        wbr_fifo_control_in         or
        wb_conf_hit                 or
        do_ccyc_req                 or
        do_ccyc_comp                or
        ccyc_hit                    or
        del_error_in                or
        do_iack_req                 or
        do_iack_comp                or
        iack_hit                    or
        image_access_error          or
        wbw_fifo_almost_full_in     or
        wbw_fifo_full_in            or
        do_del_request              or
        wbr_fifo_empty_in           or
        init_complete_in
       )
begin
    // default signal values
    // response signals inactive
    ack         = 1'b0 ;
    rty         = 1'b0 ;
    err         = 1'b0 ;

    //write signals inactive
    wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b1 ;
    wbw_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b0 ;
    wbw_fifo_control[`LAST_CTRL_BIT] = 1'b0 ;
    wbw_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ;

    wbw_fifo_wenable = 1'b0 ;
    d_incoming_ena   = 1'b0 ;

    // read signals inactive
    wbr_fifo_flush   = 1'b0 ;
    wbr_fifo_renable = 1'b0 ;
    del_req          = 1'b0 ;
    del_done         = 1'b0 ;

    // configuration space control signals inactive
    conf_wenable = 1'b0 ;
    conf_renable = 1'b0 ;

    // read is not in progress
    del_in_progress = 1'b0 ;

    decode_en = 1'b0 ;

    wbw_data_out_sel         = SEL_ADDR_IN ;

    sample_address_out = 1'b0 ;

    case (c_state)
    S_IDLE: begin
                if ( (wattempt || rattempt) & init_complete_in )
                begin
                
                `ifdef PCI_WB_SLAVE_S_DEC1
                    n_state = S_DEC1 ;
                `else
                    decode_en = 1'b1 ;
                    n_state = S_START ;
                `endif
                    
                    sample_address_out = 1'b1 ;
                end
                else
                    n_state = S_IDLE ;
            end
`ifdef PCI_WB_SLAVE_S_DEC1
    S_DEC1: begin
                if ( wattempt || rattempt )
                begin

                `ifdef PCI_WB_SLAVE_S_DEC2
                    n_state = S_DEC2 ;
                `else
                    decode_en = 1'b1 ;
                    n_state = S_START ;
                `endif

                end
                else
                    n_state = S_IDLE ;
            end
`endif
`ifdef PCI_WB_SLAVE_S_DEC2
    S_DEC2: begin

                if ( wattempt || rattempt )
                begin
                    decode_en = 1'b1 ;
                    n_state = S_START ;
                end
                else
                    n_state = S_IDLE ;
            end
`endif
    S_START:begin
                if (wb_conf_hit) // configuration space hit
                begin
                    `ifdef HOST
                        wbw_data_out_sel = SEL_CCYC_ADDR ;
                    `endif

                    if ( wattempt )
                        n_state = S_CONF_WRITE ; // go to conf. write state
                    else
                    if ( rattempt )
                    begin
                        n_state     = S_CONF_READ ; // go to conf. read state
                    end
                    else
                        n_state = S_IDLE ; // master terminated - go back to idle state

                end // wb_conf_hit
                else
                if( wb_hit && (wattempt || rattempt) )
                begin
                    wbw_data_out_sel = SEL_DATA_IN ;

                    // check error conditions for image writes or reads
                    if ( image_access_error )
                    begin
                        n_state = S_IDLE ; // go back to idle state because of an error condition
                        err     = 1'b1 ;
                    end // error conditions
                    else
                    // check for retry conditions for image writes or reads
                    if ( (wattempt && ~img_wallow) ||
                         (rattempt && ~do_dread_completion) // write to image not allowed, no read ready yet - retry
                       )
                    begin
                        n_state = S_IDLE ; // go back to IDLE

                        rty     = 1'b1 ;

                        del_req = do_del_request && rattempt ;

                    end //retry
                    else // everything OK - proceed
                    if ( wattempt )
                    begin
                        n_state = S_W_ADDR_DATA ; // goto write transfer state

                        // respond with acknowledge
                        ack              = 1'b1 ;

                        wbw_fifo_wenable = 1'b1 ;

                        // data is latched to data incoming intermidiate stage - it will be put in FIFO later
                        d_incoming_ena   = 1'b1 ;
                    end
                    else
                    begin
                        err = wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] ;
                        ack = ~wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] ;
                        wbr_fifo_renable    = 1'b1 ;
                        del_in_progress = 1'b1 ;

                        if ( wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || wbr_fifo_control_in[`LAST_CTRL_BIT] )
                        begin

                            n_state = S_IDLE ; // go back to idle state
                            // respond that read is finished
                            del_done     = 1'b1 ;

                        end // end read
                        else
                            n_state = S_READ ; // go to read state
                    end
                end
                else
                    n_state = S_IDLE ;

            end

    S_W_ADDR_DATA: begin
                        wbw_data_out_sel = SEL_DATA_IN ;
                        err = 1'b0 ;
                        rty = burst_transfer && wattempt && (wbw_fifo_almost_full_in || wbw_fifo_full_in) ;

                        if ( ~burst_transfer || wattempt && ( wbw_fifo_almost_full_in || wbw_fifo_full_in ) )
                        begin
                            n_state = S_IDLE ;

                            // write last data to FIFO and don't latch new data
                            wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ;
                            wbw_fifo_control[`LAST_CTRL_BIT] = 1'b1 ;
                            wbw_fifo_wenable = 1'b1 ;
                        end
                        else
                        begin
                            n_state = S_W_ADDR_DATA ;
                            wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ;
                            wbw_fifo_control[`LAST_CTRL_BIT] = 1'b0 ;
                            ack              = wattempt ;
                            wbw_fifo_wenable = wattempt ;
                            d_incoming_ena   = wattempt ;
                        end
                    end // S_W_ADDR_DATA

    S_READ:begin
                // this state is for reads only - in this state read is in progress all the time
                del_in_progress = 1'b1 ;

                ack = burst_transfer && rattempt && ~wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] && ~wbr_fifo_empty_in ;
                err = burst_transfer && rattempt && wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT]  && ~wbr_fifo_empty_in  ;

                // if acknowledge is beeing signalled then enable read from wbr fifo
                wbr_fifo_renable = burst_transfer && rattempt && ~wbr_fifo_empty_in ;

                if ( ~burst_transfer || rattempt && (wbr_fifo_empty_in || wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || wbr_fifo_control_in[`LAST_CTRL_BIT]) )

⌨️ 快捷键说明

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