Line 40... |
Line 40... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.2 2001/10/05 08:14:29 mihad
|
|
// Updated all files with inclusion of timescale file for simulation purposes.
|
|
//
|
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad
|
// Revision 1.1.1.1 2001/10/02 15:33:46 mihad
|
// New project directory structure
|
// New project directory structure
|
//
|
//
|
//
|
//
|
|
|
// module includes pci master state machine and surrounding logic
|
// module includes pci master state machine and surrounding logic
|
`include "bus_commands.v"
|
|
`include "constants.v"
|
// synopsys translate_off
|
`include "timescale.v"
|
`include "timescale.v"
|
|
// synopsys translate_on
|
|
`include "pci_constants.v"
|
|
|
module PCI_MASTER32_SM
|
module PCI_MASTER32_SM
|
(
|
(
|
// system inputs
|
// system inputs
|
clk_in,
|
clk_in,
|
Line 96... |
Line 101... |
rdy_in,
|
rdy_in,
|
last_in,
|
last_in,
|
next_data_in,
|
next_data_in,
|
next_be_in,
|
next_be_in,
|
next_last_in,
|
next_last_in,
|
load_next_out,
|
ad_load_out,
|
|
ad_load_on_transfer_out,
|
wait_out,
|
wait_out,
|
wtransfer_out,
|
wtransfer_out,
|
rtransfer_out,
|
rtransfer_out,
|
retry_out,
|
retry_out,
|
werror_out,
|
|
rerror_out,
|
rerror_out,
|
first_out,
|
first_out,
|
mabort_out,
|
mabort_out,
|
latency_tim_val_in
|
latency_tim_val_in
|
) ;
|
) ;
|
Line 179... |
Line 184... |
// status outputs
|
// status outputs
|
output wait_out, // wait indicates to the backend that dataphases are not in progress on PCI bus
|
output wait_out, // wait indicates to the backend that dataphases are not in progress on PCI bus
|
wtransfer_out, // on any rising clock edge that this status is 1, data is transferred - heavy constraints here
|
wtransfer_out, // on any rising clock edge that this status is 1, data is transferred - heavy constraints here
|
rtransfer_out, // registered transfer indicator - when 1 indicates that data was transfered on previous clock cycle
|
rtransfer_out, // registered transfer indicator - when 1 indicates that data was transfered on previous clock cycle
|
retry_out, // retry status output - when target signals a retry
|
retry_out, // retry status output - when target signals a retry
|
werror_out, // error output - when 1 indicates that error (target abort) occured on current dataphase - heavy constraints
|
|
rerror_out, // registered error output - when 1 indicates that error was signalled by a target on previous clock cycle
|
rerror_out, // registered error output - when 1 indicates that error was signalled by a target on previous clock cycle
|
first_out , // indicates whether or not any data was transfered in current transaction
|
first_out , // indicates whether or not any data was transfered in current transaction
|
mabort_out; // master abort indicator
|
mabort_out; // master abort indicator
|
|
|
reg wait_out ;
|
reg wait_out ;
|
Line 196... |
Line 200... |
input [31:0] next_data_in ;
|
input [31:0] next_data_in ;
|
input [3:0] next_be_in ;
|
input [3:0] next_be_in ;
|
input next_last_in ;
|
input next_last_in ;
|
|
|
// clock enable for data output flip-flops - whenever data is transfered, sm loads next data to those flip flops
|
// clock enable for data output flip-flops - whenever data is transfered, sm loads next data to those flip flops
|
output load_next_out ;
|
output ad_load_out,
|
|
ad_load_on_transfer_out ;
|
|
|
// parameters - states - one hot
|
// parameters - states - one hot
|
// idle state
|
// idle state
|
parameter S_IDLE = 4'h1 ;
|
parameter S_IDLE = 4'h1 ;
|
|
|
Line 273... |
Line 278... |
wire do_write = bc_in[0] ;
|
wire do_write = bc_in[0] ;
|
|
|
// latency timer
|
// latency timer
|
reg [7:0] latency_timer ;
|
reg [7:0] latency_timer ;
|
|
|
|
wire latency_time_out = ~(
|
wire latency_timer_enable = sm_data_phases ;
|
|
wire latency_timer_load = ~sm_address && ~sm_data_phases ;
|
|
wire latency_timer_exp = ~(
|
|
(latency_timer[7] || latency_timer[6] || latency_timer[5] || latency_timer[4]) ||
|
(latency_timer[7] || latency_timer[6] || latency_timer[5] || latency_timer[4]) ||
|
(latency_timer[3] || latency_timer[2] || latency_timer_load)
|
(latency_timer[3] || latency_timer[2] || latency_timer[1] )
|
) ;
|
) ;
|
|
|
// flip flop for registering latency timer timeout
|
wire latency_timer_enable = (sm_address || sm_data_phases) && ~latency_time_out ;
|
reg latency_time_out ;
|
wire latency_timer_load = ~sm_address && ~sm_data_phases ;
|
always@(posedge clk_in or posedge reset_in)
|
|
begin
|
|
if (reset_in)
|
|
latency_time_out <= #`FF_DELAY 1'b0 ;
|
|
else
|
|
latency_time_out <= #`FF_DELAY latency_timer_exp ;
|
|
end
|
|
|
|
always@(posedge clk_in or posedge reset_in)
|
always@(posedge clk_in or posedge reset_in)
|
begin
|
begin
|
if (reset_in)
|
if (reset_in)
|
latency_timer <= #`FF_DELAY 8'hFF ;
|
latency_timer <= #`FF_DELAY 8'h00 ;
|
else
|
else
|
if ( latency_timer_load )
|
if ( latency_timer_load )
|
latency_timer <= #`FF_DELAY latency_tim_val_in ;
|
latency_timer <= #`FF_DELAY latency_tim_val_in ;
|
else
|
else
|
if ( latency_timer_enable && ~latency_time_out) // latency timer counts down until it expires - then it stops
|
if ( latency_timer_enable) // latency timer counts down until it expires - then it stops
|
latency_timer <= #`FF_DELAY latency_timer - 1'b1 ;
|
latency_timer <= #`FF_DELAY latency_timer - 1'b1 ;
|
end
|
end
|
|
|
// master abort indicators - when decode time out occurres and still no target response is received
|
// master abort indicators - when decode time out occurres and still no target response is received
|
wire do_master_abort = decode_to && pci_trdy_in && pci_stop_in && pci_devsel_in ;
|
wire do_master_abort = decode_to && pci_trdy_in && pci_stop_in && pci_devsel_in ;
|
Line 342... |
Line 337... |
|
|
// frame control logic
|
// frame control logic
|
// frame is forced to 0 (active) when state machine is in idle state, since only possible next state is address state which always drives frame active
|
// frame is forced to 0 (active) when state machine is in idle state, since only possible next state is address state which always drives frame active
|
wire force_frame = ~sm_idle ;
|
wire force_frame = ~sm_idle ;
|
// slow signal for frame calculated from various registers in the core
|
// slow signal for frame calculated from various registers in the core
|
wire slow_frame = last_in || timeout || (next_last_in && sm_data_phases) || mabort1 ;
|
wire slow_frame = last_in || (latency_time_out && pci_gnt_in) || (next_last_in && sm_data_phases) || mabort1 ;
|
// critical timing frame logic in separate module - some combinations of target signals force frame to inactive state immediately after sampled asserted
|
// critical timing frame logic in separate module - some combinations of target signals force frame to inactive state immediately after sampled asserted
|
// (STOP)
|
// (STOP)
|
FRAME_CRIT frame_iob_feed
|
FRAME_CRIT frame_iob_feed
|
(
|
(
|
.pci_frame_out (pci_frame_out),
|
.pci_frame_out (pci_frame_out),
|
Line 403... |
Line 398... |
assign wtransfer_out = ~pci_trdy_in ;
|
assign wtransfer_out = ~pci_trdy_in ;
|
|
|
// registered transfer status output - calculated from registered target response inputs
|
// registered transfer status output - calculated from registered target response inputs
|
assign rtransfer_out = ~(pci_trdy_reg_in || pci_devsel_reg_in) ;
|
assign rtransfer_out = ~(pci_trdy_reg_in || pci_devsel_reg_in) ;
|
|
|
// current error status - calculated directly from target signals and therefore critical
|
|
assign werror_out = (~pci_stop_in && pci_devsel_in) ;
|
|
|
|
// registered error status - calculated from registered target response inputs
|
// registered error status - calculated from registered target response inputs
|
assign rerror_out = (~pci_stop_reg_in && pci_devsel_reg_in) ;
|
assign rerror_out = (~pci_stop_reg_in && pci_devsel_reg_in) ;
|
|
|
// retry is signalled to backend depending on registered target response or when latency timer expires
|
// retry is signalled to backend depending on registered target response or when latency timer expires
|
assign retry_out = timeout_termination || (~pci_stop_reg_in && ~pci_devsel_reg_in) ;
|
assign retry_out = timeout_termination || (~pci_stop_reg_in && ~pci_devsel_reg_in) ;
|
|
|
// AD output flip flops' clock enable
|
// AD output flip flops' clock enable
|
// new data is loaded to AD outputs whenever state machine is idle, bus was granted and bus is in idle state or
|
// new data is loaded to AD outputs whenever state machine is idle, bus was granted and bus is in idle state or
|
// when address phase is about to be finished
|
// when address phase is about to be finished
|
wire load_force = (sm_idle && u_have_pci_bus) || sm_address ;
|
wire ad_load_slow = sm_address ;
|
|
wire ad_load_on_grant = sm_idle && pci_frame_in && pci_irdy_in ;
|
|
|
// next data loading is allowed when state machine is in transfer state and operation is a write
|
MAS_AD_LOAD_CRIT mas_ad_load_feed
|
wire load_allow = sm_data_phases && do_write ;
|
|
|
|
// actual loading during data phases is done by monitoring critical target response signals - separate module
|
|
MAS_LOAD_NEXT_CRIT ad_iob_ce
|
|
(
|
(
|
.load_next_out (load_next_out),
|
.ad_load_out (ad_load_out),
|
.load_force_in (load_force),
|
.ad_load_in (ad_load_slow),
|
.load_allow_in (load_allow),
|
.ad_load_on_grant_in (ad_load_on_grant),
|
.pci_trdy_in (pci_trdy_in)
|
.pci_gnt_in (pci_gnt_in)
|
) ;
|
) ;
|
|
|
|
// next data loading is allowed when state machine is in transfer state and operation is a write
|
|
assign ad_load_on_transfer_out = sm_data_phases && do_write ;
|
|
|
// request for a bus is issued anytime when backend is requesting a transaction and state machine is in idle state
|
// request for a bus is issued anytime when backend is requesting a transaction and state machine is in idle state
|
assign pci_req_out = ~(req_in && sm_idle) ;
|
assign pci_req_out = ~(req_in && sm_idle) ;
|
|
|
// change state signal is actually clock enable for state register
|
// change state signal is actually clock enable for state register
|
// Non critical path for state change enable:
|
// Non critical path for state change enable:
|
Line 456... |
Line 448... |
.pci_stop_in (pci_stop_in)
|
.pci_stop_in (pci_stop_in)
|
) ;
|
) ;
|
|
|
// ad enable driving
|
// ad enable driving
|
// also divided in several categories - from less critical to most critical in separate module
|
// also divided in several categories - from less critical to most critical in separate module
|
wire ad_en_slowest = do_write && (sm_address || sm_data_phases && ~pci_frame_out_in) ;
|
//wire ad_en_slowest = do_write && (sm_address || sm_data_phases && ~pci_frame_out_in) ;
|
wire ad_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ;
|
//wire ad_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ;
|
wire ad_en_slow = ad_en_on_grant && ~pci_gnt_in || ad_en_slowest ;
|
//wire ad_en_slow = ad_en_on_grant && ~pci_gnt_in || ad_en_slowest ;
|
wire ad_en_keep = sm_data_phases && do_write && (pci_frame_out_in && ~mabort1 && ~mabort2) ;
|
//wire ad_en_keep = sm_data_phases && do_write && (pci_frame_out_in && ~mabort1 && ~mabort2) ;
|
|
|
|
wire ad_en_slow = do_write && ( sm_address || ( sm_data_phases && !( ( pci_frame_out_in && mabort1 ) || mabort2 ) ) ) ;
|
|
wire ad_en_on_grant = ( sm_idle && pci_frame_in && pci_irdy_in ) || sm_turn_arround ;
|
|
|
// critical timing ad enable - calculated from target response inputs
|
// critical timing ad enable - calculated from grant input
|
MAS_AD_EN_CRIT ad_iob_oe_feed
|
MAS_AD_EN_CRIT ad_iob_oe_feed
|
(
|
(
|
.pci_ad_en_out (pci_ad_en_out),
|
.pci_ad_en_out (pci_ad_en_out),
|
.ad_en_slow_in (ad_en_slow),
|
.ad_en_slow_in (ad_en_slow),
|
.ad_en_keep_in (ad_en_keep),
|
.ad_en_on_grant_in (ad_en_on_grant),
|
.pci_stop_in (pci_stop_in),
|
.pci_gnt_in (pci_gnt_in)
|
.pci_trdy_in (pci_trdy_in)
|
|
) ;
|
) ;
|
|
|
// cbe enable driving
|
// cbe enable driving
|
wire cbe_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ;
|
wire cbe_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ;
|
wire cbe_en_slow = cbe_en_on_grant && ~pci_gnt_in || sm_address || sm_data_phases && ~pci_frame_out_in ;
|
wire cbe_en_slow = cbe_en_on_grant && ~pci_gnt_in || sm_address || sm_data_phases && ~pci_frame_out_in ;
|
Line 527... |
Line 521... |
// indicate the state
|
// indicate the state
|
sm_idle = 1'b1 ;
|
sm_idle = 1'b1 ;
|
// assign next state - only possible is address - if state machine is supposed to stay in idle state
|
// assign next state - only possible is address - if state machine is supposed to stay in idle state
|
// outside signals disable the clock
|
// outside signals disable the clock
|
next_state = S_ADDRESS ;
|
next_state = S_ADDRESS ;
|
|
wdata_selector = SEL_DATA_BE ;
|
end
|
end
|
|
|
S_ADDRESS: begin
|
S_ADDRESS: begin
|
// indicate the state
|
// indicate the state
|
sm_address = 1'b1 ;
|
sm_address = 1'b1 ;
|
// select appropriate data/be for outputs
|
// select appropriate data/be for outputs
|
wdata_selector = SEL_DATA_BE ;
|
wdata_selector = SEL_NEXT_DATA_BE ;
|
// only possible next state is transfer state
|
// only possible next state is transfer state
|
next_state = S_TRANSFER ;
|
next_state = S_TRANSFER ;
|
end
|
end
|
|
|
S_TRANSFER: begin
|
S_TRANSFER: begin
|
Line 568... |
Line 563... |
default: next_state = S_IDLE ;
|
default: next_state = S_IDLE ;
|
endcase
|
endcase
|
end
|
end
|
|
|
// ad and cbe lines multiplexer for write data
|
// ad and cbe lines multiplexer for write data
|
always@(wdata_selector or address_in or bc_in or data_in or be_in or next_data_in or next_be_in)
|
reg [1:0] rdata_selector ;
|
|
always@(posedge clk_in or posedge reset_in)
|
begin
|
begin
|
case ( wdata_selector )
|
if ( reset_in )
|
|
rdata_selector <= #`FF_DELAY SEL_ADDR_BC ;
|
|
else
|
|
if ( change_state )
|
|
rdata_selector <= #`FF_DELAY wdata_selector ;
|
|
end
|
|
|
|
always@(rdata_selector or address_in or bc_in or data_in or be_in or next_data_in or next_be_in)
|
|
begin
|
|
case ( rdata_selector )
|
SEL_ADDR_BC: begin
|
SEL_ADDR_BC: begin
|
pci_ad_out = address_in ;
|
pci_ad_out = address_in ;
|
pci_cbe_out = bc_in ;
|
pci_cbe_out = bc_in ;
|
end
|
end
|
|
|
Line 597... |
Line 602... |
data_out = 32'hFFFF_FFFF ;
|
data_out = 32'hFFFF_FFFF ;
|
else
|
else
|
data_out = pci_ad_reg_in ;
|
data_out = pci_ad_reg_in ;
|
end
|
end
|
endmodule
|
endmodule
|
No newline at end of file
|
No newline at end of file
|
|
|
No newline at end of file
|
No newline at end of file
|