📄 pci_wb_slave.v
字号:
---------------------------------------------------------------------------------------------------------------------*/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 endendreg del_in_progress ; // state machine indicates whether current read completion is in progress on WISHBONE buswire 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 logicalways@( 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 + -