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

📄 pci_wb_master.v

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

// FF for seting and reseting burst_transfer signal
always@(posedge wb_clock_in or posedge reset_in)
begin
    if (reset_in) 
    begin
        burst_chopped         <= #`FF_DELAY 1'b0;
        burst_chopped_delayed <= #`FF_DELAY 1'b0;
        first_data_is_burst_reg <= #`FF_DELAY 1'b0 ;
    end
    else
    begin
        if (pciw_fifo_transaction_ready_in)
        begin
            if (pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT])
                burst_chopped     <= #`FF_DELAY 1'b1;
            else if (wb_ack_i || wb_err_i || wb_rty_i)
                burst_chopped     <= #`FF_DELAY 1'b0;
        end
        else
            burst_chopped         <= #`FF_DELAY 1'b0;
        burst_chopped_delayed <= #`FF_DELAY burst_chopped;
        if (last_data_transferred || first_data_is_burst)
            first_data_is_burst_reg <= #`FF_DELAY ~last_data_transferred ;
    end
end
assign  burst_transfer = first_data_is_burst || first_data_is_burst_reg ;

reg [(`WB_FSM_BITS - 1):0]  c_state ; //current state register
reg [(`WB_FSM_BITS - 1):0]  n_state ; //next state input to current state register

//##################################
// WISHBONE B3 master state machine
//##################################

// state machine register control and registered outputs (without wb_adr_o counter)
always@(posedge wb_clock_in or posedge reset_in)
begin
    if (reset_in) // reset state machine to S_IDLE state
    begin
        c_state  <= #`FF_DELAY  S_IDLE;
        wb_cyc_o <= #`FF_DELAY  1'b0;
        wb_stb_o <= #`FF_DELAY  1'b0;
        wb_we_o  <= #`FF_DELAY  1'b0;
        wb_cti_o <= #`FF_DELAY  3'h2;
        wb_bte_o <= #`FF_DELAY  2'h0;
        wb_sel_o <= #`FF_DELAY  4'h0;
        wb_dat_o <= #`FF_DELAY 32'h0;
        pcir_fifo_data_out <= #`FF_DELAY 32'h0;
        pcir_fifo_control_out <= #`FF_DELAY 4'h0;
        pcir_fifo_wenable_out <= #`FF_DELAY 1'b0;
    end
    else
    begin
        c_state  <= #`FF_DELAY  n_state;
        wb_bte_o <= #`FF_DELAY  2'h0;
        case (n_state) // synthesis parallel_case full_case
        S_WRITE:
        begin
            wb_cyc_o <= #`FF_DELAY  ~addr_into_cnt;
            wb_stb_o <= #`FF_DELAY  ~addr_into_cnt;
            wb_we_o  <= #`FF_DELAY  ~addr_into_cnt;
            // if '1' then next burst BE is not equat to current one => burst is chopped into singles
            // OR if last data is going to be transfered
            if ((wb_stb_o && wb_ack_i) || addr_into_cnt_reg || (~wb_cyc_o && (retried || burst_chopped_delayed)))
            begin
                if (burst_transfer && ~pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT] &&
                   ~(pciw_fifo_renable_out && (pciw_fifo_control_in[`LAST_CTRL_BIT] || pciw_fifo_almost_empty_in)))
                    wb_cti_o <= #`FF_DELAY  3'h2;
                else
                    wb_cti_o <= #`FF_DELAY  3'h7;
            end
            if ((pciw_fifo_renable_out && ~addr_into_cnt) || addr_into_cnt_reg)
            begin
                wb_sel_o <= #`FF_DELAY  ~pciw_fifo_cbe_in;
                wb_dat_o <= #`FF_DELAY  pciw_fifo_addr_data_in;
            end
        end
        S_WRITE_ERR_RTY:
        begin
            wb_cyc_o <= #`FF_DELAY  1'b0;
            wb_stb_o <= #`FF_DELAY  1'b0;
            wb_we_o  <= #`FF_DELAY  1'b0;
            wb_cti_o <= #`FF_DELAY  3'h2;
            // stay the same as previous
            //wb_sel_o <= #`FF_DELAY  4'h0;
            //wb_dat_o <= #`FF_DELAY 32'h0;
        end
        S_READ:
        begin
            wb_cyc_o <= #`FF_DELAY  ~addr_into_cnt;
            wb_stb_o <= #`FF_DELAY  ~addr_into_cnt;
            wb_we_o  <= #`FF_DELAY  1'b0;
            if ((wb_stb_o && wb_ack_i) || addr_into_cnt_reg || (~wb_cyc_o && retried))
            begin
                if (burst_transfer && ~read_bound_comb)
                    wb_cti_o <= #`FF_DELAY  3'h2;
                else
                    wb_cti_o <= #`FF_DELAY  3'h7;
            end
            if (burst_transfer)
                wb_sel_o <= #`FF_DELAY  4'hF;
            else
                wb_sel_o <= #`FF_DELAY  ~pci_tar_be;
            // no need to change att all
            //wb_dat_o <= #`FF_DELAY 32'h0;
        end
        S_READ_RTY:
        begin
            wb_cyc_o <= #`FF_DELAY  1'b0;
            wb_stb_o <= #`FF_DELAY  1'b0;
            wb_we_o  <= #`FF_DELAY  1'b0;
            wb_cti_o <= #`FF_DELAY  3'h2;
            // no need to change att all
            //wb_sel_o <= #`FF_DELAY  4'h0;
            //wb_dat_o <= #`FF_DELAY 32'h0;
        end
        S_TURN_ARROUND:
        begin
            wb_cyc_o <= #`FF_DELAY  1'b0;
            wb_stb_o <= #`FF_DELAY  1'b0;
            wb_we_o  <= #`FF_DELAY  1'b0;
            wb_cti_o <= #`FF_DELAY  3'h2;
            // no need to change att all
            //wb_sel_o <= #`FF_DELAY  4'h0;
            //wb_dat_o <= #`FF_DELAY 32'h0;
        end
        default: // S_IDLE:
        begin
            wb_cyc_o <= #`FF_DELAY  1'b0;
            wb_stb_o <= #`FF_DELAY  1'b0;
            wb_we_o  <= #`FF_DELAY  1'b0;
            wb_cti_o <= #`FF_DELAY  3'h2;
            // no need to change att all
            //wb_sel_o <= #`FF_DELAY  4'h0;
            //wb_dat_o <= #`FF_DELAY 32'h0;
        end
        endcase
        pcir_fifo_data_out <= #`FF_DELAY  wb_dat_i;
        pcir_fifo_control_out <= #`FF_DELAY pcir_fifo_control ;
        pcir_fifo_wenable_out <= #`FF_DELAY pcir_fifo_wenable ;
    end
end

assign  wb_adr_o = addr_cnt_out ;

// state machine logic
always@(c_state or
        wb_ack_i or 
        wb_rty_i or 
        wb_err_i or 
        w_attempt or
        r_attempt or
        retried or 
        burst_chopped or 
        burst_chopped_delayed or 
        rty_i_delayed or
        pci_tar_read_request or
        rty_counter_almost_max_value or 
        set_retry or 
        last_data_to_pcir_fifo or 
        first_wb_data_access or
        pciw_fifo_control_in or 
        pciw_fifo_empty_in or 
        burst_transfer or 
        last_data_from_pciw_fifo_reg
        )
begin
    case (c_state)
    S_IDLE:
        begin
            // Default values for signals not used in this state
            pcir_fifo_wenable = 1'b0 ;
            pcir_fifo_control = 4'h0 ;
            addr_count = 1'b0 ;
            read_count_enable = 1'b0 ;
            pci_error_sig_out = 1'b0 ;
            error_source_out = 1'b0 ;
            retried_d = 1'b0 ;
            last_data_transferred = 1'b0 ;
            wb_read_done = 1'b0 ;
            wait_for_wb_response = 1'b0 ;
            write_rty_cnt_exp_out = 1'b0 ;
            pci_error_sig_out = 1'b0 ;
            read_rty_cnt_exp_out = 1'b0 ;
            case ({w_attempt, r_attempt, retried})
            3'b101 : // Write request for PCIW_FIFO to WB bus transaction
            begin    // If there was retry, the same transaction must be initiated
                pciw_fifo_renable = 1'b0 ; // the same data
                addr_into_cnt = 1'b0 ; // the same address
                read_count_load = 1'b0 ; // no need for cache line when there is write
                n_state = S_WRITE ;
            end
            3'b100 : // Write request for PCIW_FIFO to WB bus transaction
            begin    // If there is new transaction
                if (burst_chopped_delayed)
                begin
                  addr_into_cnt = 1'b0 ; // address must not be latched into address counter
                  pciw_fifo_renable = 1'b1 ; // first location is address (in FIFO), next will be data
                end
                else
                begin
                  if (pciw_fifo_control_in[`ADDR_CTRL_BIT])
                      addr_into_cnt = 1'b1 ; // address must be latched into address counter
                  else
                      addr_into_cnt = 1'b0 ;
                  pciw_fifo_renable = 1'b1 ; // first location is address (in FIFO), next will be data
                end
                read_count_load = 1'b0 ; // no need for cache line when there is write
                n_state = S_WRITE ;
            end
            3'b011 : // Read request from PCI Target for WB bus to PCIR_FIFO transaction
            begin    // If there was retry, the same transaction must be initiated
                addr_into_cnt = 1'b0 ; // the same address
                read_count_load = 1'b0 ; // cache line counter must not be changed for retried read
                pciw_fifo_renable = 1'b0 ; // don't read from FIFO, when read transaction from WB to FIFO
                n_state = S_READ ;
            end
            3'b010 : // Read request from PCI Target for WB bus to PCIR_FIFO transaction
            begin    // If there is new transaction
                addr_into_cnt = 1'b1 ; // address must be latched into counter from separate request bus
                read_count_load = 1'b1 ; // cache line size must be latched into its counter
                pciw_fifo_renable = 1'b0 ; // don't read from FIFO, when read transaction from WB to FIFO
                n_state = S_READ ;
            end
            default : // stay in IDLE state
            begin
                pciw_fifo_renable = 1'b0 ;
                addr_into_cnt = 1'b0 ;
                read_count_load = 1'b0 ;
                n_state = S_IDLE ;
            end
            endcase
        end
    S_WRITE: // WRITE from PCIW_FIFO to WB bus
        begin
            // Default values for signals not used in this state
            pcir_fifo_wenable = 1'b0 ;
            pcir_fifo_control = 4'h0 ;
            addr_into_cnt = 1'b0 ;
            read_count_load = 1'b0 ;
            read_count_enable = 1'b0 ;
            wb_read_done = 1'b0 ;
            read_rty_cnt_exp_out = 1'b0 ;
            case ({wb_ack_i, wb_err_i, wb_rty_i})
            3'b100 : // If writting of one data is acknowledged
            begin
                addr_count = 1'b1 ; // prepare next address if there will be burst
                retried_d = 1'b0 ; // there was no retry
                pci_error_sig_out = 1'b0 ; // there was no error
                error_source_out = 1'b0 ;
                write_rty_cnt_exp_out = 1'b0 ; // there was no retry
                wait_for_wb_response = 1'b0 ;
                // if last data was transfered !
                if (last_data_from_pciw_fifo_reg) 
                begin                   
                    n_state = S_TURN_ARROUND;
                    if (~pciw_fifo_empty_in)
                        pciw_fifo_renable = 1'b0 ; // prepare next value (address when new trans., data when burst tran.)
                    else
                        pciw_fifo_renable = 1'b0 ;
                    last_data_transferred = 1'b1 ; // signal for last data transfered
                end
                // next burst data has different byte enables !
                else if (burst_transfer && burst_chopped) 
                begin                   
                    n_state = S_IDLE ;
                    pciw_fifo_renable = 1'b0 ; // next value (address when new trans., data when burst tran.)
                    last_data_transferred = 1'b0 ;
                end
                else
                begin
                    n_state = S_WRITE ;
                    pciw_fifo_renable = 1'b1 ; // prepare next value (address when new trans., data when burst tran.)
                    last_data_transferred = 1'b0 ;
                end
            end
            3'b010 : // If writting of one data is terminated with ERROR
            begin
                if (~pciw_fifo_empty_in)
                    pciw_fifo_renable = 1'b1 ; // prepare next value (address when new trans., data when cleaning FIFO)
                else
                    pciw_fifo_renable = 1'b0 ;
                addr_count = 1'b0 ; // no need for new address
                retried_d = 1'b0 ; // there was no retry
                last_data_transferred = 1'b1 ; // signal for last data transfered
                pci_error_sig_out = 1'b1 ; // segnal for error reporting
                error_source_out = 1'b0 ; // error source from other side of WB bus
                write_rty_cnt_exp_out = 1'b0 ; // there was no retry
                wait_for_wb_response = 1'b0 ;
                if (last_data_from_pciw_fifo_reg) // if last data was transfered
                    n_state = S_TURN_ARROUND ; // go to S_TURN_ARROUND for new transfere
                else // if there wasn't last data of transfere

⌨️ 快捷键说明

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