//////////////////////////////////////////////////////////////////////////////// // // This confidential and proprietary software may be used only // as authorized by a licensing agreement from Synopsys Inc. // In the event of publication, the following notice is applicable: // // (C) COPYRIGHT 2005 - 2018 SYNOPSYS INC. // ALL RIGHTS RESERVED // // The entire notice above must be reproduced on all authorized // copies. // // AUTHOR: Doug Lee 12/7/05 // // VERSION: Simulation Architecture // // DesignWare_version: b7a01861 // DesignWare_release: O-2018.06-DWBB_201806.1 // //////////////////////////////////////////////////////////////////////////////// // // ABSTRACT: Reset Sequence Synchronizer Simulation Model // // // This synchronizer coordinates reset to the source and destination domains which initiated by // either domain. // // Parameters: Valid Values // ========== ============ // f_sync_type default: 2 // Forward Synchronized Type (Source to Destination Domains) // 0 = single clock design, no synchronizing stages implemented, // 1 = 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing, // 2 = 2-stage synchronization w/ both stages pos-edge capturing, // 3 = 3-stage synchronization w/ all stages pos-edge capturing // 4 = 4-stage synchronization w/ all stages pos-edge capturing // r_sync_type default: 2 // Reverse Synchronization Type (Destination to Source Domains) // 0 = single clock design, no synchronizing stages implemented, // 1 = 2-stage synchronization w/ 1st stage neg-edge & 2nd stage pos-edge capturing, // 2 = 2-stage synchronization w/ both stages pos-edge capturing, // 3 = 3-stage synchronization w/ all stages pos-edge capturing // 4 = 4-stage synchronization w/ all stages pos-edge capturing // clk_d_faster default: 1 // clk_d faster than clk_s by difference ratio // 0 = Either clr_s or clr_d active with the other tied low at input // 1 to 15 = ratio of clk_d to clk_s plus 1 // reg_in_prog default: 1 // Register the 'clr_in_prog_s' and 'clr_in_prog_d' Outputs // 0 = unregistered // 1 = registered // tst_mode default: 0 // Test Mode Setting // 0 = no hold latch inserted, // 1 = insert hold 'latch' using a neg-edge triggered register // 2 = insert hold latch using active low latch // verif_en default: 1 // Verification Enable (simulation only) // 0 = no sampling errors inserted, // 1 = sampling errors are randomly inserted with 0 or up to 1 destination clock cycle delays // 2 = sampling errors are randomly inserted with 0, 0.5, 1, or 1.5 destination clock cycle delays // 3 = sampling errors are randomly inserted with 0, 1, 2, or 3 destination clock cycle delays // 4 = sampling errors are randomly inserted with 0 or up to 0.5 destination clock cycle delays // // Input Ports: Size Description // =========== ==== =========== // clk_s 1 bit Source Domain Input Clock // rst_s_n 1 bit Source Domain Active Low Async. Reset // init_s_n 1 bit Source Domain Active Low Sync. Reset // clr_s 1 bit Source Domain Clear Initiated // clk_d 1 bit Destination Domain Input Clock // rst_d_n 1 bit Destination Domain Active Low Async. Reset // init_d_n 1 bit Destination Domain Active Low Sync. Reset // clr_d 1 bit Destination Domain Clear Initiated // test 1 bit Test input // // Output Ports Size Description // ============ ==== =========== // clr_sync_s 1 bit Source Domain Clear // clr_in_prog_s 1 bit Source Domain Clear in Progress // clr_cmplt_s 1 bit Source Domain Clear Complete (pulse) // clr_in_prog_d 1 bit Destination Domain Clear in Progress // clr_sync_d 1 bit Destination Domain Clear (pulse) // clr_cmplt_d 1 bit Destination Domain Clear Complete (pulse) // // MODIFIED: // DLL 5-7-15 (1) Restricted the amount of missampling allowed for DW_pulse_sync // U_PS_DEST_INIT to make delay more realistic. // (2) Changed 'reg_event' from '1' to '0' for instance U_PS_DEST_INIT // to allow 'clr_in_prog_s' to occur one cycle earlier that // helps prevent a race condition on signals syncrhonized back // to the source domain. // Addresses fix for STAR#9000896107 (filed against DW_fifoctl_2c_df but // is really a DW_reset_sync issue). // // DLL 7-22-11 Add inherent delay to the feedback path in the destination // domain and clr_in_prog_d. This effectively extends the // destination domain acive clearing state. // Also, added 'tst_mode = 2' capability. // // DLL 12-2-10 Removed assertions since only ones left were not // relevant any more. This fix is by-product of investigating // STAR#9000435571. // // DLL 9-5-08 Accommodate sustained "clr_s" and "clr_d" assertion behavior. // Satisfies STAR#9000261751. // // DLL 8-11-08 Filter long pulses of "clr_s" and "clr_d" to one // clock cycle pulses. // // DLL 10-31-06 Added SystemVerilog assertions // // DLL 8-21-06 Added parameters 'r_sync_type', 'clk_d_faster', 'reg_in_prog'. // Added Destination outputs 'clr_in_prog_d' and 'clr_cmplt_d' // and changed Source output 'lO1O1011' to 'clr_cmplt_s'. // // DLL 6-14-06 Removed unnecessary To_X01 processing some input signals // // DLL 11-7-06 Modified functionality to support f_sync_type = 4 and // r_sync_type = 4 // module DW_reset_sync ( clk_s, rst_s_n, init_s_n, clr_s, clr_sync_s, clr_in_prog_s, clr_cmplt_s, clk_d, rst_d_n, init_d_n, clr_d, clr_in_prog_d, clr_sync_d, clr_cmplt_d, test ); parameter integer f_sync_type = 2; // RANGE 0 to 4 parameter integer r_sync_type = 2; // RANGE 0 to 4 parameter integer clk_d_faster = 1; // RANGE 0 to 15 parameter integer reg_in_prog = 1; // RANGE 0 to 1 parameter integer tst_mode = 0; // RANGE 0 to 2 parameter integer verif_en = 1; // RANGE 0 to 4 `define DW_IIOOl10O 2 localparam O0llO1Ol = ((verif_en==2)?4:((verif_en==3)?1:verif_en)); input clk_s; // clock input from source domain input rst_s_n; // active low asynchronous reset from source domain input init_s_n; // active low synchronous reset from source domain input clr_s; // active high clear from source domain output clr_sync_s; // clear to source domain sequential devices output clr_in_prog_s; // clear in progress status to source domain output clr_cmplt_s; // clear sequence complete (pulse) input clk_d; // clock input from destination domain input rst_d_n; // active low asynchronous reset from destination domain input init_d_n; // active low synchronous reset from destination domain input clr_d; // active high clear from destination domain output clr_in_prog_d; // clear in progress status to source domain output clr_sync_d; // clear to destination domain sequential devices (pulse) output clr_cmplt_d; // clear sequence complete (pulse) input test; // test input // synopsys translate_off //------------------------------------------------------------------------- // Parameter legality check //------------------------------------------------------------------------- initial begin : parameter_check integer param_err_flg; param_err_flg = 0; if ( ((f_sync_type & 7) < 0) || ((f_sync_type & 7) > 4) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter (f_sync_type & 7) (legal range: 0 to 4)", (f_sync_type & 7) ); end if ( ((r_sync_type & 7) < 0) || ((r_sync_type & 7) > 4) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter (r_sync_type & 7) (legal range: 0 to 4)", (r_sync_type & 7) ); end if ( (reg_in_prog < 0) || (reg_in_prog > 1) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter reg_in_prog (legal range: 0 to 1)", reg_in_prog ); end if ( (tst_mode < 0) || (tst_mode > 2) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter tst_mode (legal range: 0 to 2)", tst_mode ); end if ( (verif_en < 0) || (verif_en > 4) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter verif_en (legal range: 0 to 4)", verif_en ); end if ( param_err_flg == 1) begin $display( "%m :\n Simulation aborted due to invalid parameter value(s)"); $finish; end end // parameter_check wire lOl0I0l1; wire Il0110O1; wire O010111l; integer I01O0111; integer l1010110; reg O1111O0O; wire OOlIO1OO; reg lll0OO11; wire I0I0O1l1; wire lO1O1011; reg l011lO0l; wire l00O0lO1; wire l11Ol01I; wire OI01IO11; wire l0Ol100I; reg l10Ol00O; wire IOIOOIlO; wire OOI1001O; reg O100OIlI; wire l0IlI00O; reg IIOOI0Ol; reg Il1O110I; reg O1OOO1O0; wire O0OIl111; integer OOOOIlO1; integer OI1IO11l; reg OlOOO000; wire IllIlOl0; wire I0OO1l01; wire lI1IO1O0; reg OO001I10; wire O0III10l; reg IO00llI0; wire OOlOO11O; reg OIO10I11; integer O0IOO0OO; assign IllIlOl0 = (reg_in_prog == 0) ? ((IOIOOIlO && !OlOOO000) || (((OI1IO11l == 1) && (OOOOIlO1 == 0)) && IOIOOIlO)) : // (!clr_in_prog_d && IOIOOIlO); (OI1IO11l == 1) && (OOOOIlO1 == 0); assign I0OO1l01 = (OI1IO11l == 0) && (OOOOIlO1 == 1); assign lI1IO1O0 = (IllIlOl0 && !I0OO1l01) ? 1'b1 : (I0OO1l01) ? 1'b0 : OO001I10; initial begin if ((f_sync_type > 0)&&(f_sync_type < 8)) $display("Information: *** Instance %m is the DW_reset_sync Clock Domain Crossing Module ***"); end DW_pulse_sync #(1, (f_sync_type + 8), tst_mode, verif_en, 1) U_PS_SRC_INIT ( .clk_s(clk_s), .rst_s_n(rst_s_n), .init_s_n(init_s_n), .event_s(clr_s), .clk_d(clk_d), .rst_d_n(rst_d_n), .init_d_n(init_d_n), .test(test), .event_d(lOl0I0l1) ); generate if (((f_sync_type&7)>1)&&(tst_mode==2)) begin : GEN_LATCH_frwd_hold_latch_PROC reg [1-1:0] OIO10I11; always @ (clk_s or clr_s) begin : LATCH_frwd_hold_latch_PROC_PROC if (clk_s == 1'b0) OIO10I11 = clr_s; end // LATCH_frwd_hold_latch_PROC_PROC assign OOlOO11O = (test==1'b1)? OIO10I11 : clr_s; end else begin : GEN_DIRECT_frwd_hold_latch_PROC assign OOlOO11O = clr_s; end endgenerate DW_sync #(1, f_sync_type+8, tst_mode, verif_en) U_SYNC_CLR_S( .clk_d(clk_d), .rst_d_n(rst_d_n), .init_d_n(init_d_n), .data_s(OOlOO11O), .test(test), .data_d(Il0110O1) ); assign O010111l = lOl0I0l1 || Il0110O1; DW_pulse_sync #(0, (r_sync_type + 8), tst_mode, O0llO1Ol, 0) U_PS_DEST_INIT ( .clk_s(clk_d), .rst_s_n(rst_d_n), .init_s_n(init_d_n), .event_s(OOI1001O), .clk_d(clk_s), .rst_d_n(rst_s_n), .init_d_n(init_s_n), .test(test), .event_d(OI01IO11) ); DW_pulse_sync #(0, (f_sync_type + 8), tst_mode, verif_en, 0) U_PS_FB_DEST ( .clk_s(clk_s), .rst_s_n(rst_s_n), .init_s_n(init_s_n), .event_s(l10Ol00O), .clk_d(clk_d), .rst_d_n(rst_d_n), .init_d_n(init_d_n), .test(test), .event_d(l11Ol01I) ); assign O0III10l = (l11Ol01I && IOIOOIlO) ? 1'b1 : (!l11Ol01I && !IOIOOIlO && IO00llI0) ? 1'b0 : IO00llI0; assign l00O0lO1 = (l11Ol01I && !IOIOOIlO && !IO00llI0) || (!l11Ol01I && !IOIOOIlO && IO00llI0); DW_pulse_sync #(0, (r_sync_type + 8), tst_mode, verif_en, 0) U_PS_ACK ( .clk_s(clk_d), .rst_s_n(rst_d_n), .init_s_n(init_d_n), .event_s(l011lO0l), .clk_d(clk_s), .rst_d_n(rst_s_n), .init_d_n(init_s_n), .test(test), .event_d(lO1O1011) ); always @(OI01IO11 or lO1O1011 or I01O0111) begin : a1000_PROC if (OI01IO11 && ~lO1O1011) begin if (I01O0111 === `DW_IIOOl10O) l1010110 = I01O0111; else l1010110 = I01O0111 + 1; end else if (~OI01IO11 && lO1O1011) begin if (I01O0111 === 0) l1010110 = I01O0111; else l1010110 = I01O0111 - 1; end else begin l1010110 = I01O0111; end end assign OOlIO1OO = (l1010110 > 0); assign I0I0O1l1 = lO1O1011 && ((I01O0111 === 1) && (l1010110 === 0)); assign IOIOOIlO = O010111l || clr_d; assign OOI1001O = IOIOOIlO && !OO001I10; assign l0IlI00O = (OI1IO11l > 0); assign l0Ol100I = l00O0lO1 & ~OOI1001O; always @(OOI1001O or l011lO0l or OOOOIlO1) begin : a1001_PROC if (OOI1001O && ~l011lO0l) begin if (OOOOIlO1 === `DW_IIOOl10O) OI1IO11l = OOOOIlO1; else OI1IO11l = OOOOIlO1 + 1; end else if (~OOI1001O && l011lO0l) begin if (OOOOIlO1 === 0) OI1IO11l = OOOOIlO1; else OI1IO11l = OOOOIlO1 - 1; end else begin OI1IO11l = OOOOIlO1; end end assign O0OIl111 = ~O100OIlI && IIOOI0Ol; always @(posedge clk_s or negedge rst_s_n) begin : a1002_PROC if (rst_s_n === 1'b0) begin I01O0111 <= 0; l10Ol00O <= 1'b0; O1111O0O <= 1'b0; lll0OO11 <= 1'b0; end else if (rst_s_n === 1'b1) begin if (init_s_n === 1'b0) begin I01O0111 <= 0; l10Ol00O <= 1'b0; O1111O0O <= 1'b0; lll0OO11 <= 1'b0; end else if (init_s_n === 1'b1) begin I01O0111 <= l1010110; l10Ol00O <= OI01IO11; O1111O0O <= OOlIO1OO; lll0OO11 <= I0I0O1l1; end else begin I01O0111 <= -1; l10Ol00O <= 1'bX; O1111O0O <= 1'bX; lll0OO11 <= 1'bX; end end else begin I01O0111 <= -1; l10Ol00O <= 1'bX; O1111O0O <= 1'bX; lll0OO11 <= 1'bX; end end always @(posedge clk_d or negedge rst_d_n) begin : a1003_PROC if (rst_d_n === 1'b0) begin OlOOO000 <= 1'b0; OO001I10 <= 1'b0; OOOOIlO1 <= 0; O100OIlI <= 1'b0; IIOOI0Ol <= 1'b0; l011lO0l <= 1'b0; Il1O110I <= 1'b0; O1OOO1O0 <= 1'b0; IO00llI0 <= 1'b0; end else if (rst_d_n === 1'b1) begin if (init_d_n === 1'b0) begin OlOOO000 <= 1'b0; OO001I10 <= 1'b0; OOOOIlO1 <= 0; O100OIlI <= 1'b0; IIOOI0Ol <= 1'b0; l011lO0l <= 1'b0; Il1O110I <= 1'b0; O1OOO1O0 <= 1'b0; IO00llI0 <= 1'b0; end else if (init_d_n === 1'b1) begin OlOOO000 <= IOIOOIlO; OO001I10 <= lI1IO1O0; OOOOIlO1 <= OI1IO11l; O100OIlI <= l0IlI00O; IIOOI0Ol <= O100OIlI; l011lO0l <= l00O0lO1; Il1O110I <= l0Ol100I; O1OOO1O0 <= O0OIl111; IO00llI0 <= O0III10l; end else begin OlOOO000 <= 1'bX; OO001I10 <= 1'bX; OOOOIlO1 <= -1; O100OIlI <= 1'bX; IIOOI0Ol <= 1'bX; l011lO0l <= 1'bX; Il1O110I <= 1'bX; O1OOO1O0 <= 1'bX; IO00llI0 <= 1'bX; end end else begin OlOOO000 <= 1'bX; OO001I10 <= 1'bX; OOOOIlO1 <= -1; O100OIlI <= 1'bX; IIOOI0Ol <= 1'bX; l011lO0l <= 1'bX; Il1O110I <= 1'bX; O1OOO1O0 <= 1'bX; IO00llI0 <= 1'bX; end end assign clr_sync_s = OI01IO11; assign clr_cmplt_s = lll0OO11; assign clr_in_prog_s = (reg_in_prog == 0) ? OOlIO1OO : O1111O0O; assign clr_in_prog_d = (reg_in_prog == 0) ? O100OIlI : IIOOI0Ol; assign clr_sync_d = Il1O110I; assign clr_cmplt_d = O1OOO1O0; always @ (clk_s) begin : monitor_clk_s if ( (clk_s !== 1'b0) && (clk_s !== 1'b1) && ($time > 0) ) $display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_s input.", $time, clk_s ); end // monitor_clk_s always @ (clk_d) begin : monitor_clk_d if ( (clk_d !== 1'b0) && (clk_d !== 1'b1) && ($time > 0) ) $display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk_d input.", $time, clk_d ); end // monitor_clk_d // synopsys translate_on `undef DW_IIOOl10O endmodule /* vcs gen_ip dbg_ip off */ /* */