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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_3/] [rtl/] [verilog/] [delayed_sync.v] - Diff between revs 74 and 154

Only display areas with differences | Details | Blame | View Log

Rev 74 Rev 154
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
////  File name "delayed_sync.v"                                  ////
////  File name "delayed_sync.v"                                  ////
////                                                              ////
////                                                              ////
////  This file is part of the "PCI bridge" project               ////
////  This file is part of the "PCI bridge" project               ////
////  http://www.opencores.org/cores/pci/                         ////
////  http://www.opencores.org/cores/pci/                         ////
////                                                              ////
////                                                              ////
////  Author(s):                                                  ////
////  Author(s):                                                  ////
////      - Miha Dolenc (mihad@opencores.org)                     ////
////      - Miha Dolenc (mihad@opencores.org)                     ////
////                                                              ////
////                                                              ////
////  All additional information is avaliable in the README       ////
////  All additional information is avaliable in the README       ////
////  file.                                                       ////
////  file.                                                       ////
////                                                              ////
////                                                              ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org          ////
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org          ////
////                                                              ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
//// later version.                                               ////
////                                                              ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
//// details.                                                     ////
////                                                              ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
// Revision 1.4  2002/03/05 11:53:47  mihad
// Revision 1.4  2002/03/05 11:53:47  mihad
// Added some testcases, removed un-needed fifo signals
// Added some testcases, removed un-needed fifo signals
//
//
// Revision 1.3  2002/02/01 15:25:12  mihad
// Revision 1.3  2002/02/01 15:25:12  mihad
// Repaired a few bugs, updated specification, added test bench files and design document
// Repaired a few bugs, updated specification, added test bench files and design document
//
//
// Revision 1.2  2001/10/05 08:14:28  mihad
// Revision 1.2  2001/10/05 08:14:28  mihad
// Updated all files with inclusion of timescale file for simulation purposes.
// 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 provides synchronization mechanism between requesting and completing side of the bridge
// module provides synchronization mechanism between requesting and completing side of the bridge
`include "pci_constants.v"
`include "pci_constants.v"
`include "bus_commands.v"
`include "bus_commands.v"
 
 
// synopsys translate_off
// synopsys translate_off
`include "timescale.v"
`include "timescale.v"
// synopsys translate_on
// synopsys translate_on
 
 
module DELAYED_SYNC
module DELAYED_SYNC
(
(
    reset_in,
    reset_in,
    req_clk_in,
    req_clk_in,
    comp_clk_in,
    comp_clk_in,
    req_in,
    req_in,
    comp_in,
    comp_in,
    done_in,
    done_in,
    in_progress_in,
    in_progress_in,
    comp_req_pending_out,
    comp_req_pending_out,
    req_req_pending_out,
    req_req_pending_out,
    req_comp_pending_out,
    req_comp_pending_out,
    comp_comp_pending_out,
    comp_comp_pending_out,
    addr_in,
    addr_in,
    be_in,
    be_in,
    addr_out,
    addr_out,
    be_out,
    be_out,
    we_in,
    we_in,
    we_out,
    we_out,
    bc_in,
    bc_in,
    bc_out,
    bc_out,
    status_in,
    status_in,
    status_out,
    status_out,
    comp_flush_out,
    comp_flush_out,
    burst_in,
    burst_in,
    burst_out,
    burst_out,
    retry_expired_in
    retry_expired_in
);
);
 
 
// system inputs
// system inputs
input reset_in,         // reset input
input reset_in,         // reset input
      req_clk_in,       // requesting clock input
      req_clk_in,       // requesting clock input
      comp_clk_in ;     // completing clock input
      comp_clk_in ;     // completing clock input
 
 
// request, completion, done and in progress indication inputs
// request, completion, done and in progress indication inputs
input req_in,           // request qualifier - when 1 it indicates that valid request data is provided on inputs
input req_in,           // request qualifier - when 1 it indicates that valid request data is provided on inputs
      comp_in,          // completion qualifier - when 1, completing side indicates that request has completed
      comp_in,          // completion qualifier - when 1, completing side indicates that request has completed
      done_in,          // done input - when 1 indicates that requesting side of the bridge has completed a transaction on requesting bus
      done_in,          // done input - when 1 indicates that requesting side of the bridge has completed a transaction on requesting bus
      in_progress_in ;  // in progress indicator - indicates that current completion is in progress on requesting side of the bridge
      in_progress_in ;  // in progress indicator - indicates that current completion is in progress on requesting side of the bridge
 
 
// pending indication outputs
// pending indication outputs
output  comp_req_pending_out,   // completion side request output - resynchronized from requesting clock to completing clock
output  comp_req_pending_out,   // completion side request output - resynchronized from requesting clock to completing clock
        req_req_pending_out,    // request pending output for requesting side
        req_req_pending_out,    // request pending output for requesting side
        req_comp_pending_out,   // completion pending output for requesting side of the bridge - it indicates when completion is ready for completing on requesting bus
        req_comp_pending_out,   // completion pending output for requesting side of the bridge - it indicates when completion is ready for completing on requesting bus
        comp_comp_pending_out ; // completion pending output for completing side of the bridge
        comp_comp_pending_out ; // completion pending output for completing side of the bridge
 
 
// additional signals and wires for clock domain passage of signals
// additional signals and wires for clock domain passage of signals
reg     comp_req_pending,
reg     comp_req_pending,
        req_req_pending,
        req_req_pending,
        req_comp_pending,
        req_comp_pending,
        req_comp_pending_sample,
        req_comp_pending_sample,
        comp_comp_pending,
        comp_comp_pending,
        req_done_reg,
        req_done_reg,
        comp_done_reg_main,
        comp_done_reg_main,
        comp_done_reg_clr,
        comp_done_reg_clr,
        req_rty_exp_reg,
        req_rty_exp_reg,
        req_rty_exp_clr,
        req_rty_exp_clr,
        comp_rty_exp_reg,
        comp_rty_exp_reg,
        comp_rty_exp_clr ;
        comp_rty_exp_clr ;
 
 
wire    sync_comp_req_pending,
wire    sync_comp_req_pending,
        sync_req_comp_pending,
        sync_req_comp_pending,
        sync_comp_done,
        sync_comp_done,
        sync_req_rty_exp,
        sync_req_rty_exp,
        sync_comp_rty_exp_clr ;
        sync_comp_rty_exp_clr ;
 
 
// inputs from requesting side - only this side can set address, bus command, byte enables, write enable and burst - outputs are common for both sides
// inputs from requesting side - only this side can set address, bus command, byte enables, write enable and burst - outputs are common for both sides
// all signals that identify requests are stored in this module
// all signals that identify requests are stored in this module
 
 
input [31:0]    addr_in ;   // address bus input
input [31:0]    addr_in ;   // address bus input
input [3:0]     be_in ;     // byte enable input
input [3:0]     be_in ;     // byte enable input
input           we_in ;     // write enable input - read/write request indication 1 = write request / 0 = read request
input           we_in ;     // write enable input - read/write request indication 1 = write request / 0 = read request
input [3:0]     bc_in ;     // bus command input
input [3:0]     bc_in ;     // bus command input
input           burst_in ;  // burst indicator    - qualifies operation as burst/single transfer 1 = burst / 0 = single transfer
input           burst_in ;  // burst indicator    - qualifies operation as burst/single transfer 1 = burst / 0 = single transfer
 
 
// common request outputs used both by completing and requesting sides
// common request outputs used both by completing and requesting sides
// this outputs are not resynchronized, since flags determine the request status
// this outputs are not resynchronized, since flags determine the request status
output [31:0]   addr_out ;
output [31:0]   addr_out ;
output [3:0]    be_out ;
output [3:0]    be_out ;
output          we_out ;
output          we_out ;
output [3:0]    bc_out ;
output [3:0]    bc_out ;
output          burst_out ;
output          burst_out ;
 
 
// completion side signals encoded termination status - 0 = normal completion / 1 = error terminated completion
// completion side signals encoded termination status - 0 = normal completion / 1 = error terminated completion
input          status_in ;
input          status_in ;
output         status_out ;
output         status_out ;
 
 
// input signals that delayed transaction has been retried for max number of times
// input signals that delayed transaction has been retried for max number of times
// on this signal request is ditched, otherwise it would cause a deadlock
// on this signal request is ditched, otherwise it would cause a deadlock
// requestor can issue another request and procedure will be repeated
// requestor can issue another request and procedure will be repeated
input   retry_expired_in ;
input   retry_expired_in ;
 
 
// completion flush output - if in 2^^16 clock cycles transaction is not repeated by requesting agent - flush completion data
// completion flush output - if in 2^^16 clock cycles transaction is not repeated by requesting agent - flush completion data
output  comp_flush_out ;
output  comp_flush_out ;
 
 
// output registers for common signals
// output registers for common signals
reg [31:0]   addr_out ;
reg [31:0]   addr_out ;
reg [3:0]    be_out ;
reg [3:0]    be_out ;
reg          we_out ;
reg          we_out ;
reg [3:0]    bc_out ;
reg [3:0]    bc_out ;
reg          burst_out ;
reg          burst_out ;
 
 
// delayed transaction information is stored only when request is issued and request nor completion are pending
// delayed transaction information is stored only when request is issued and request nor completion are pending
wire new_request = req_in && ~req_comp_pending_out && ~req_req_pending_out ;
wire new_request = req_in && ~req_comp_pending_out && ~req_req_pending_out ;
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if (reset_in)
    if (reset_in)
    begin
    begin
        addr_out  <= #`FF_DELAY 32'h0000_0000 ;
        addr_out  <= #`FF_DELAY 32'h0000_0000 ;
        be_out    <= #`FF_DELAY 4'h0 ;
        be_out    <= #`FF_DELAY 4'h0 ;
        we_out    <= #`FF_DELAY 1'b0 ;
        we_out    <= #`FF_DELAY 1'b0 ;
        bc_out    <= #`FF_DELAY `BC_RESERVED0 ;
        bc_out    <= #`FF_DELAY `BC_RESERVED0 ;
        burst_out <= #`FF_DELAY 1'b0 ;
        burst_out <= #`FF_DELAY 1'b0 ;
    end
    end
    else
    else
        if (new_request)
        if (new_request)
        begin
        begin
            addr_out  <= #`FF_DELAY addr_in ;
            addr_out  <= #`FF_DELAY addr_in ;
            be_out    <= #`FF_DELAY be_in ;
            be_out    <= #`FF_DELAY be_in ;
            we_out    <= #`FF_DELAY we_in ;
            we_out    <= #`FF_DELAY we_in ;
            bc_out    <= #`FF_DELAY bc_in ;
            bc_out    <= #`FF_DELAY bc_in ;
            burst_out <= #`FF_DELAY burst_in ;
            burst_out <= #`FF_DELAY burst_in ;
        end
        end
end
end
 
 
// completion pending cycle counter
// completion pending cycle counter
reg [16:0] comp_cycle_count ;
reg [16:0] comp_cycle_count ;
 
 
/*=================================================================================================================================
/*=================================================================================================================================
Passing of requests between clock domains:
Passing of requests between clock domains:
request originates on requesting side. It's then synchronized with two flip-flops to cross to completing clock domain
request originates on requesting side. It's then synchronized with two flip-flops to cross to completing clock domain
=================================================================================================================================*/
=================================================================================================================================*/
// main request flip-flop triggered on requesting side's clock
// main request flip-flop triggered on requesting side's clock
// request is cleared whenever completion or retry expired is signalled from opposite side of the bridge
// request is cleared whenever completion or retry expired is signalled from opposite side of the bridge
wire req_req_clear = req_comp_pending || (req_rty_exp_reg && ~req_rty_exp_clr) ;
wire req_req_clear = req_comp_pending || (req_rty_exp_reg && ~req_rty_exp_clr) ;
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        req_req_pending <= #`FF_DELAY 1'b0 ;
        req_req_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( req_req_clear )
    if ( req_req_clear )
        req_req_pending <= #`FF_DELAY 1'b0 ;
        req_req_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( req_in )
    if ( req_in )
        req_req_pending <= #`FF_DELAY 1'b1 ;
        req_req_pending <= #`FF_DELAY 1'b1 ;
end
end
 
 
// interemediate stage request synchronization flip - flop - this one is prone to metastability
// interemediate stage request synchronization flip - flop - this one is prone to metastability
// and should have setup and hold times disabled during simulation
// and should have setup and hold times disabled during simulation
synchronizer_flop req_sync
synchronizer_flop req_sync
(
(
    .data_in        (req_req_pending),
    .data_in        (req_req_pending),
    .clk_out        (comp_clk_in),
    .clk_out        (comp_clk_in),
    .sync_data_out  (sync_comp_req_pending),
    .sync_data_out  (sync_comp_req_pending),
    .async_reset    (reset_in)
    .async_reset    (reset_in)
) ;
) ;
 
 
// wire for clearing completion side request flag - whenever completion or retry expired are signalled
// wire for clearing completion side request flag - whenever completion or retry expired are signalled
wire comp_req_pending_clear = comp_req_pending && ( comp_in || retry_expired_in) ;
wire comp_req_pending_clear = comp_req_pending && ( comp_in || retry_expired_in) ;
 
 
// wire for enabling request flip - flop - it is enabled when completion is not active and done is not active
// wire for enabling request flip - flop - it is enabled when completion is not active and done is not active
wire comp_req_pending_ena   = ~comp_comp_pending && ~comp_done_reg_main && ~comp_rty_exp_reg ;
wire comp_req_pending_ena   = ~comp_comp_pending && ~comp_done_reg_main && ~comp_rty_exp_reg ;
 
 
// completion side request flip flop - gets a value from intermediate stage sync flip flop
// completion side request flip flop - gets a value from intermediate stage sync flip flop
always@(posedge comp_clk_in or posedge reset_in)
always@(posedge comp_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        comp_req_pending <= #`FF_DELAY 1'b0 ;
        comp_req_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( comp_req_pending_clear )
    if ( comp_req_pending_clear )
        comp_req_pending <= #`FF_DELAY 1'b0 ;
        comp_req_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( comp_req_pending_ena )
    if ( comp_req_pending_ena )
        comp_req_pending <= #`FF_DELAY sync_comp_req_pending ;
        comp_req_pending <= #`FF_DELAY sync_comp_req_pending ;
end
end
 
 
// completion side request output assignment - when request ff is set and completion ff is not set
// completion side request output assignment - when request ff is set and completion ff is not set
assign comp_req_pending_out = comp_req_pending ;
assign comp_req_pending_out = comp_req_pending ;
 
 
// requesting side request pending output
// requesting side request pending output
assign req_req_pending_out  = req_req_pending ;
assign req_req_pending_out  = req_req_pending ;
/*=================================================================================================================================
/*=================================================================================================================================
Passing of completions between clock domains:
Passing of completions between clock domains:
completion originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain
completion originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain
=================================================================================================================================*/
=================================================================================================================================*/
// main completion Flip - Flop - triggered by completing side's clock
// main completion Flip - Flop - triggered by completing side's clock
// completion side completion pending flag is cleared when done flag propagates through clock domains
// completion side completion pending flag is cleared when done flag propagates through clock domains
wire comp_comp_clear = comp_done_reg_main && ~comp_done_reg_clr ;
wire comp_comp_clear = comp_done_reg_main && ~comp_done_reg_clr ;
always@(posedge comp_clk_in or posedge reset_in)
always@(posedge comp_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        comp_comp_pending <= #`FF_DELAY 1'b0 ;
        comp_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( comp_comp_clear )
    if ( comp_comp_clear )
        comp_comp_pending <= #`FF_DELAY 1'b0 ;
        comp_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( comp_in && comp_req_pending )
    if ( comp_in && comp_req_pending )
        comp_comp_pending <= #`FF_DELAY 1'b1 ;
        comp_comp_pending <= #`FF_DELAY 1'b1 ;
end
end
 
 
assign comp_comp_pending_out = comp_comp_pending ;
assign comp_comp_pending_out = comp_comp_pending ;
 
 
// interemediate stage completion synchronization flip - flop - this one is prone to metastability
// interemediate stage completion synchronization flip - flop - this one is prone to metastability
synchronizer_flop comp_sync
synchronizer_flop comp_sync
(
(
    .data_in        (comp_comp_pending),
    .data_in        (comp_comp_pending),
    .clk_out        (req_clk_in),
    .clk_out        (req_clk_in),
    .sync_data_out  (sync_req_comp_pending),
    .sync_data_out  (sync_req_comp_pending),
    .async_reset    (reset_in)
    .async_reset    (reset_in)
) ;
) ;
 
 
// request side completion pending flip flop is cleared whenever done is signalled or completion counter expires - 2^^16 clock cycles
// request side completion pending flip flop is cleared whenever done is signalled or completion counter expires - 2^^16 clock cycles
wire req_comp_pending_clear = done_in || comp_cycle_count[16];
wire req_comp_pending_clear = done_in || comp_cycle_count[16];
 
 
// request side completion pending flip flop is disabled while done flag is set
// request side completion pending flip flop is disabled while done flag is set
wire req_comp_pending_ena   = ~req_done_reg ;
wire req_comp_pending_ena   = ~req_done_reg ;
 
 
// request side completion flip flop - gets a value from intermediate stage sync flip flop
// request side completion flip flop - gets a value from intermediate stage sync flip flop
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        req_comp_pending <= #`FF_DELAY 1'b0 ;
        req_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( req_comp_pending_clear )
    if ( req_comp_pending_clear )
        req_comp_pending <= #`FF_DELAY 1'b0 ;
        req_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( req_comp_pending_ena )
    if ( req_comp_pending_ena )
        req_comp_pending <= #`FF_DELAY sync_req_comp_pending ;
        req_comp_pending <= #`FF_DELAY sync_req_comp_pending ;
end
end
 
 
// sampling FF - used for sampling incoming completion flag from completing side
// sampling FF - used for sampling incoming completion flag from completing side
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        req_comp_pending_sample <= #`FF_DELAY 1'b0 ;
        req_comp_pending_sample <= #`FF_DELAY 1'b0 ;
    else
    else
        req_comp_pending_sample <= #`FF_DELAY sync_req_comp_pending ;
        req_comp_pending_sample <= #`FF_DELAY sync_req_comp_pending ;
end
end
 
 
// requesting side completion pending output assignment
// requesting side completion pending output assignment
assign req_comp_pending_out = req_comp_pending && ~req_req_pending ;
assign req_comp_pending_out = req_comp_pending && ~req_req_pending ;
 
 
/*==================================================================================================================================
/*==================================================================================================================================
Passing of delayed transaction done signal between clock domains.
Passing of delayed transaction done signal between clock domains.
Done is signalled by requesting side of the bridge and is passed to completing side of the bridge
Done is signalled by requesting side of the bridge and is passed to completing side of the bridge
==================================================================================================================================*/
==================================================================================================================================*/
// main done flip-flop triggered on requesting side's clock
// main done flip-flop triggered on requesting side's clock
// when completing side removes completion flag, done flag is also removed, so requests can proceede
// when completing side removes completion flag, done flag is also removed, so requests can proceede
wire req_done_clear = ~req_comp_pending_sample ;
wire req_done_clear = ~req_comp_pending_sample ;
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        req_done_reg <= #`FF_DELAY 1'b0 ;
        req_done_reg <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( req_done_clear )
    if ( req_done_clear )
        req_done_reg <= #`FF_DELAY 1'b0 ;
        req_done_reg <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( done_in || comp_cycle_count[16] )
    if ( done_in || comp_cycle_count[16] )
        req_done_reg <= #`FF_DELAY 1'b1 ;
        req_done_reg <= #`FF_DELAY 1'b1 ;
end
end
 
 
synchronizer_flop done_sync
synchronizer_flop done_sync
(
(
    .data_in        (req_done_reg),
    .data_in        (req_done_reg),
    .clk_out        (comp_clk_in),
    .clk_out        (comp_clk_in),
    .sync_data_out  (sync_comp_done),
    .sync_data_out  (sync_comp_done),
    .async_reset    (reset_in)
    .async_reset    (reset_in)
) ;
) ;
 
 
always@(posedge comp_clk_in or posedge reset_in)
always@(posedge comp_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        comp_done_reg_main <= #`FF_DELAY 1'b0 ;
        comp_done_reg_main <= #`FF_DELAY 1'b0 ;
    else
    else
        comp_done_reg_main <= #`FF_DELAY sync_comp_done ;
        comp_done_reg_main <= #`FF_DELAY sync_comp_done ;
end
end
 
 
always@(posedge comp_clk_in or posedge reset_in)
always@(posedge comp_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        comp_done_reg_clr <= #`FF_DELAY 1'b0 ;
        comp_done_reg_clr <= #`FF_DELAY 1'b0 ;
    else
    else
        comp_done_reg_clr <= #`FF_DELAY comp_done_reg_main ;
        comp_done_reg_clr <= #`FF_DELAY comp_done_reg_main ;
end
end
 
 
/*=================================================================================================================================
/*=================================================================================================================================
Passing of retry expired signal between clock domains
Passing of retry expired signal between clock domains
Retry expiration originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain
Retry expiration originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain
=================================================================================================================================*/
=================================================================================================================================*/
// main retry expired Flip - Flop - triggered by completing side's clock
// main retry expired Flip - Flop - triggered by completing side's clock
wire comp_rty_exp_clear = comp_rty_exp_clr && comp_rty_exp_reg ;
wire comp_rty_exp_clear = comp_rty_exp_clr && comp_rty_exp_reg ;
 
 
// retry expired is a special case of transaction removal - retry expired propagates from completing
// retry expired is a special case of transaction removal - retry expired propagates from completing
// clock domain to requesting clock domain to remove all pending requests and than propagates back
// clock domain to requesting clock domain to remove all pending requests and than propagates back
// to completing side to qualify valid new requests
// to completing side to qualify valid new requests
 
 
always@(posedge comp_clk_in or posedge reset_in)
always@(posedge comp_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        comp_rty_exp_reg <= #`FF_DELAY 1'b0 ;
        comp_rty_exp_reg <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( comp_rty_exp_clear )
    if ( comp_rty_exp_clear )
        comp_rty_exp_reg <= #`FF_DELAY 1'b0 ;
        comp_rty_exp_reg <= #`FF_DELAY 1'b0 ;
    else
    else
    if ( retry_expired_in && comp_req_pending)
    if ( retry_expired_in && comp_req_pending)
        comp_rty_exp_reg <= #`FF_DELAY 1'b1 ;
        comp_rty_exp_reg <= #`FF_DELAY 1'b1 ;
end
end
 
 
// interemediate stage retry expired synchronization flip - flop - this one is prone to metastability
// interemediate stage retry expired synchronization flip - flop - this one is prone to metastability
synchronizer_flop rty_exp_sync
synchronizer_flop rty_exp_sync
(
(
    .data_in        (comp_rty_exp_reg),
    .data_in        (comp_rty_exp_reg),
    .clk_out        (req_clk_in),
    .clk_out        (req_clk_in),
    .sync_data_out  (sync_req_rty_exp),
    .sync_data_out  (sync_req_rty_exp),
    .async_reset    (reset_in)
    .async_reset    (reset_in)
) ;
) ;
 
 
// request retry expired flip flop - gets a value from intermediate stage sync flip flop
// request retry expired flip flop - gets a value from intermediate stage sync flip flop
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        req_rty_exp_reg <= #`FF_DELAY 1'b0 ;
        req_rty_exp_reg <= #`FF_DELAY 1'b0 ;
    else
    else
        req_rty_exp_reg <= #`FF_DELAY sync_req_rty_exp ;
        req_rty_exp_reg <= #`FF_DELAY sync_req_rty_exp ;
end
end
 
 
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        req_rty_exp_clr <= #`FF_DELAY 1'b0 ;
        req_rty_exp_clr <= #`FF_DELAY 1'b0 ;
    else
    else
        req_rty_exp_clr <= #`FF_DELAY req_rty_exp_reg ;
        req_rty_exp_clr <= #`FF_DELAY req_rty_exp_reg ;
end
end
 
 
synchronizer_flop rty_exp_back_prop_sync
synchronizer_flop rty_exp_back_prop_sync
(
(
    .data_in        (req_rty_exp_reg && req_rty_exp_clr),
    .data_in        (req_rty_exp_reg && req_rty_exp_clr),
    .clk_out        (comp_clk_in),
    .clk_out        (comp_clk_in),
    .sync_data_out  (sync_comp_rty_exp_clr),
    .sync_data_out  (sync_comp_rty_exp_clr),
    .async_reset    (reset_in)
    .async_reset    (reset_in)
) ;
) ;
 
 
always@(posedge comp_clk_in or posedge reset_in)
always@(posedge comp_clk_in or posedge reset_in)
begin
begin
    if ( reset_in )
    if ( reset_in )
        comp_rty_exp_clr <= #`FF_DELAY 1'b0 ;
        comp_rty_exp_clr <= #`FF_DELAY 1'b0 ;
    else
    else
        comp_rty_exp_clr <= #`FF_DELAY sync_comp_rty_exp_clr ;
        comp_rty_exp_clr <= #`FF_DELAY sync_comp_rty_exp_clr ;
end
end
 
 
// completion status flip flop - if 0 when completion is signalled it's finished OK otherwise it means error
// completion status flip flop - if 0 when completion is signalled it's finished OK otherwise it means error
reg status_out ;
reg status_out ;
always@(posedge comp_clk_in or posedge reset_in)
always@(posedge comp_clk_in or posedge reset_in)
begin
begin
    if (reset_in)
    if (reset_in)
        status_out <= #`FF_DELAY 1'b0 ;
        status_out <= #`FF_DELAY 1'b0 ;
    else
    else
    if (comp_in && comp_req_pending)
    if (comp_in && comp_req_pending)
        status_out <= #`FF_DELAY status_in ;
        status_out <= #`FF_DELAY status_in ;
end
end
 
 
// clocks counter - it counts how many clock cycles completion is present without beeing repeated
// clocks counter - it counts how many clock cycles completion is present without beeing repeated
// if it counts to 2^^16 cycles the completion must be ditched
// if it counts to 2^^16 cycles the completion must be ditched
 
 
// wire for clearing this counter
// wire for clearing this counter
wire clear_count = in_progress_in || ~req_comp_pending_out || comp_cycle_count[16] ;
wire clear_count = in_progress_in || ~req_comp_pending_out || comp_cycle_count[16] ;
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if (reset_in)
    if (reset_in)
        comp_cycle_count <= #`FF_DELAY 17'h0_0000 ;
        comp_cycle_count <= #`FF_DELAY 17'h0_0000 ;
    else
    else
    if (clear_count)
    if (clear_count)
        comp_cycle_count <= #`FF_DELAY 17'h0_0000 ;
        comp_cycle_count <= #`FF_DELAY 17'h0_0000 ;
    else
    else
        comp_cycle_count <= #`FF_DELAY comp_cycle_count + 1'b1 ;
        comp_cycle_count <= #`FF_DELAY comp_cycle_count + 1'b1 ;
end
end
 
 
// completion flush output - used for flushing fifos when counter expires
// completion flush output - used for flushing fifos when counter expires
// if counter doesn't expire, fifo flush is up to WISHBONE slave or PCI target state machines
// if counter doesn't expire, fifo flush is up to WISHBONE slave or PCI target state machines
reg comp_flush_out ;
reg comp_flush_out ;
always@(posedge req_clk_in or posedge reset_in)
always@(posedge req_clk_in or posedge reset_in)
begin
begin
    if (reset_in)
    if (reset_in)
        comp_flush_out <= #`FF_DELAY 1'b0 ;
        comp_flush_out <= #`FF_DELAY 1'b0 ;
    else
    else
        comp_flush_out <= #`FF_DELAY comp_cycle_count[16] ;
        comp_flush_out <= #`FF_DELAY comp_cycle_count[16] ;
end
end
 
 
endmodule //delayed_sync
endmodule //delayed_sync
 
 

powered by: WebSVN 2.1.0

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