📄 pci_target32_sm.v
字号:
input wbw_fifo_empty_in ; // Indicates that WB SLAVE UNIT has no data to be written to PCI bus
input wbu_del_read_comp_pending_in ; // Indicates that WB S華VE UNIT has a delayed read pending
input wbu_frame_en_in ; // Indicates that WB SLAVE UNIT is accessing the PCI bus (important if
// address on PCI bus is also claimed by decoder in this PCI TARGET UNIT
output target_abort_set_out ; // Signal used to be set in configuration space registers
/*==================================================================================================================
END of input / output PORT DEFINITONS !!!
==================================================================================================================*/
// Delayed frame signal for determining the address phase
reg previous_frame ;
// Delayed read completed signal for preparing the data from pcir fifo
reg read_completed_reg ;
// Delayed disconnect with/without data for stop loading data to PCIW_FIFO
//reg disconect_wo_data_reg ;
wire config_disconnect ;
wire disconect_wo_data = disconect_wo_data_in || config_disconnect ;
wire disconect_w_data = disconect_w_data_in ;
// Delayed frame signal for determining the address phase!
always@(posedge clk_in or posedge reset_in)
begin
if (reset_in)
begin
previous_frame <= #`FF_DELAY 1'b0 ;
read_completed_reg <= #`FF_DELAY 1'b0 ;
end
else
begin
previous_frame <= #`FF_DELAY pci_frame_reg_in ;
read_completed_reg <= #`FF_DELAY read_completed_in ;
end
end
// Address phase is when previous frame was 1 and this frame is 0 and frame isn't generated from pci master (in WBU)
wire addr_phase = (previous_frame && ~pci_frame_reg_in && ~wbu_frame_en_in) ;
`ifdef HOST
`ifdef NO_CNF_IMAGE
// Wire tells when there is configuration (read or write) command with IDSEL signal active
wire config_access = 1'b0 ;
// Write and read progresses are used for determining next state
wire write_progress = ( (read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ||
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ;
wire read_progress = ( (read_completed_in && wbw_fifo_empty_in) ) ;
`else
// Wire tells when there is configuration (read or write) command with IDSEL signal active
wire config_access = (pci_idsel_reg_in && pci_cbe_reg_in[3]) && (~pci_cbe_reg_in[2] && pci_cbe_reg_in[1]) && // idsel asserted with correct bus command(101x)
(pci_ad_reg_in[1:0] == 2'b00) ; // has to be type 0 configuration cycle
// Write and read progresses are used for determining next state
wire write_progress = ( (norm_access_to_config_in) ||
(read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ||
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ;
wire read_progress = ( (~read_completed_in && norm_access_to_config_in) ||
(read_completed_in && wbw_fifo_empty_in) ) ;
`endif
`else
// Wire tells when there is configuration (read or write) command with IDSEL signal active
wire config_access = (pci_idsel_reg_in && pci_cbe_reg_in[3]) && (~pci_cbe_reg_in[2] && pci_cbe_reg_in[1]) && // idsel asserted with correct bus command(101x)
(pci_ad_reg_in[1:0] == 2'b00) ; // has to be type 0 configuration cycle
// Write and read progresses are used for determining next state
wire write_progress = ( (norm_access_to_config_in) ||
(read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ||
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ;
wire read_progress = ( (~read_completed_in && norm_access_to_config_in) ||
(read_completed_in && wbw_fifo_empty_in) ) ;
`endif
// Signal for loading data to medium register from pcir fifo when read completed from WB side!
wire prepare_rd_fifo_data = (read_completed_in && ~read_completed_reg) ;
// Write allowed to PCIW_FIFO
wire write_to_fifo = ((read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ||
(~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in)) ;
// Read allowed from PCIR_FIFO
wire read_from_fifo = (read_completed_in && wbw_fifo_empty_in) ;
`ifdef HOST
`ifdef NO_CNF_IMAGE
// Read request is allowed to be proceed regarding the WB side
wire read_request = (~read_completed_in && ~read_processing_in) ;
`else
// Read request is allowed to be proceed regarding the WB side
wire read_request = (~read_completed_in && ~read_processing_in && ~norm_access_to_config_in) ;
`endif
`else
// Read request is allowed to be proceed regarding the WB side
wire read_request = (~read_completed_in && ~read_processing_in && ~norm_access_to_config_in) ;
`endif
// Critically calculated signals are latched in this clock period (address phase) to be used in the next clock period
reg rw_cbe0 ;
reg wr_progress ;
reg rd_progress ;
reg rd_from_fifo ;
reg rd_request ;
reg wr_to_fifo ;
reg same_read_reg ;
always@(posedge clk_in or posedge reset_in)
begin
if (reset_in)
begin
rw_cbe0 <= #`FF_DELAY 1'b0 ;
wr_progress <= #`FF_DELAY 1'b0 ;
rd_progress <= #`FF_DELAY 1'b0 ;
rd_from_fifo <= #`FF_DELAY 1'b0 ;
rd_request <= #`FF_DELAY 1'b0 ;
wr_to_fifo <= #`FF_DELAY 1'b0 ;
same_read_reg <= #`FF_DELAY 1'b0 ;
end
else
begin
if (addr_phase)
begin
rw_cbe0 <= #`FF_DELAY pci_cbe_reg_in[0] ;
wr_progress <= #`FF_DELAY write_progress ;
rd_progress <= #`FF_DELAY read_progress ;
rd_from_fifo <= #`FF_DELAY read_from_fifo ;
rd_request <= #`FF_DELAY read_request ;
wr_to_fifo <= #`FF_DELAY write_to_fifo ;
same_read_reg <= #`FF_DELAY same_read_in ;
end
end
end
`ifdef HOST
`ifdef NO_CNF_IMAGE
wire norm_access_to_conf_reg = 1'b0 ;
wire cnf_progress = 1'b0 ;
`else
reg norm_access_to_conf_reg ;
reg cnf_progress ;
always@(posedge clk_in or posedge reset_in)
begin
if (reset_in)
begin
norm_access_to_conf_reg <= #`FF_DELAY 1'b0 ;
cnf_progress <= #`FF_DELAY 1'b0 ;
end
else
begin
if (addr_phase)
begin
norm_access_to_conf_reg <= #`FF_DELAY norm_access_to_config_in ;
cnf_progress <= #`FF_DELAY config_access ;
end
end
end
`endif
`else
reg norm_access_to_conf_reg ;
reg cnf_progress ;
always@(posedge clk_in or posedge reset_in)
begin
if (reset_in)
begin
norm_access_to_conf_reg <= #`FF_DELAY 1'b0 ;
cnf_progress <= #`FF_DELAY 1'b0 ;
end
else
begin
if (addr_phase)
begin
norm_access_to_conf_reg <= #`FF_DELAY norm_access_to_config_in ;
cnf_progress <= #`FF_DELAY config_access ;
end
end
end
`endif
// Signal used in S_WAIT state to determin next state
wire s_wait_progress = (
(~cnf_progress && rw_cbe0 && wr_progress && ~target_abort_in) ||
(~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && ~target_abort_in && ~pcir_fifo_data_err_in) ||
(~cnf_progress && ~rw_cbe0 && ~same_read_reg && norm_access_to_conf_reg && ~target_abort_in) ||
(cnf_progress && ~target_abort_in)
) ;
// Signal used in S_TRANSFERE state to determin next state
wire s_tran_progress = (
(rw_cbe0 && !disconect_wo_data) ||
(~rw_cbe0 && !disconect_wo_data && !target_abort_in && !pcir_fifo_data_err_in)
) ;
// Clock enable for PCI state machine driven directly from critical inputs - FRAME and IRDY
wire pcit_sm_clk_en ;
// FSM states signals indicating the current state
reg state_idle ;
reg state_wait ;
reg sm_transfere ;
reg backoff ;
reg state_default ;
wire state_backoff = sm_transfere && backoff ;
wire state_transfere = sm_transfere && !backoff ;
always@(posedge clk_in or posedge reset_in)
begin
if ( reset_in )
backoff <= #`FF_DELAY 1'b0 ;
else if ( state_idle )
backoff <= #`FF_DELAY 1'b0 ;
else
backoff <= #`FF_DELAY (state_wait && !s_wait_progress) ||
(sm_transfere && !s_tran_progress && !pci_frame_in && !pci_irdy_in) ||
backoff ;
end
assign config_disconnect = sm_transfere && (norm_access_to_conf_reg || cnf_progress) ;
// Clock enable module used for preserving the architecture because of minimum delay for critical inputs
pci_target32_clk_en pci_target_clock_en
(
.addr_phase (addr_phase),
.config_access (config_access),
.addr_claim_in (addr_claim_in),
.pci_frame_in (pci_frame_in),
.state_wait (state_wait),
.state_transfere (sm_transfere),
.state_default (state_default),
.clk_enable (pcit_sm_clk_en)
);
reg [2:0] c_state ; //current state register
reg [2:0] n_state ; //next state input to current state register
// state machine register control
always@(posedge clk_in or posedge reset_in)
begin
if (reset_in) // reset state machine to S_IDLE state
c_state <= #`FF_DELAY S_IDLE ;
else
if (pcit_sm_clk_en) // if conditions are true, then FSM goes to next state!
c_state <= #`FF_DELAY n_state ;
end
// state machine logic
always@(c_state)
begin
case (c_state)
S_IDLE :
begin
state_idle <= 1'b1 ;
state_wait <= 1'b0 ;
sm_transfere <= 1'b0 ;
state_default <= 1'b0 ;
n_state <= S_WAIT ;
end
S_WAIT :
begin
state_idle <= 1'b0 ;
state_wait <= 1'b1 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -