📄 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
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 + -