OpenCores
URL https://opencores.org/ocsvn/pci/pci/trunk

Subversion Repositories pci

[/] [pci/] [trunk/] [rtl/] [verilog/] [pci_master32_sm.v] - Diff between revs 6 and 21

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 6 Rev 21
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.