//////////////////////////////////////////////////////////////////////////////// // // 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 2002 - 2018 SYNOPSYS INC. // ALL RIGHTS RESERVED // // The entire notice above must be reproduced on all authorized // copies. // // AUTHOR: Rajeev Huralikoppi Feb 15, 2002 // // VERSION: Verilog Simulation Architecture // // DesignWare_version: 4e25d03d // DesignWare_release: O-2018.06-DWBB_201806.3 // //////////////////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- // ABSTRACT: An n stage pipelined multipler simulation model // // Parameters Valid Values Description // ========== ========= =========== // a_width >= 1 default: none // Word length of a // // b_width >= 1 default: none // Word length of b // // num_stages >= 2 default: 2 // Number of pipelined stages // // stall_mode 0 or 1 default: 1 // Stall mode // 0 => non-stallable // 1 => stallable // // rst_mode 0 to 2 default: 1 // Reset mode // 0 => no reset // 1 => asynchronous reset // 2 => synchronous reset // // op_iso_mode 0 to 4 default: 0 // Type of operand isolation // If 'stall_mode' is '0', this parameter is ignored and no isolation is applied // 0 => Follow intent defined by Power Compiler user setting // 1 => no operand isolation // 2 => 'and' gate operand isolaton // 3 => 'or' gate operand isolation // 4 => preferred isolation style: 'and' // // // Input Ports Size Description // =========== ==== ============ // clk 1 Clock // rst_n 1 Reset, active low // en 1 Register enable, active high // tc 1 2's complement control // a a_width Multiplier // b b_width Multiplicand // // product a_width+b_width Product (a*b) // // MODIFIED: // RJK 05/14/15 Updated model to work with less propagated 'X's // so as to be more friendly with VCS-NLP // // RJK 05/28/13 Updated documentation in comments to properly // describe the "en" input (STAR 9000627580) // // DLL 02/01/08 Enhanced abstract and added "op_iso_mode" parameter // and related code. // // DLL 11/14/05 Changed legality checking of 'num_stages' // parameter along with its abstract "Valid Values" // // //----------------------------------------------------------------------------- module DW_mult_pipe (clk,rst_n,en,tc,a,b,product); parameter integer a_width = 2; parameter integer b_width = 2; parameter integer num_stages = 2; parameter integer stall_mode = 1; parameter integer rst_mode = 1; parameter integer op_iso_mode = 0; input clk; input rst_n; input [a_width-1 : 0] a; input [b_width-1 : 0] b; input tc; input en; output [a_width+b_width-1: 0] product; reg [a_width-1 : 0] a_reg [0 : num_stages-2]; reg [b_width-1 : 0] b_reg [0 : num_stages-2]; reg tc_reg [0 : num_stages-2]; // synopsys translate_off //--------------------------------------------------------------------------- // Behavioral model //--------------------------------------------------------------------------- generate if (rst_mode == 0) begin : GEN_RSM_EQ_0 if (stall_mode == 0) begin : GEN_RM0_SM0 always @(posedge clk) begin: rm0_sm0_pipe_reg_PROC integer i; for(i= 0; i < num_stages-1; i=i+1) begin if (i == 0) begin a_reg[0] <= a; b_reg[0] <= b; tc_reg[0] <= tc; end else begin a_reg[i] <= a_reg[i-1]; b_reg[i] <= b_reg[i-1]; tc_reg[i] <= tc_reg[i-1]; end end // for (i= 0; i < num_stages-1; i++) end // block: rm0_pipe_reg_PROC end else begin : GEN_RM0_SM1 always @(posedge clk) begin: rm0_sm1_pipe_reg_PROC integer i; for(i= 0; i < num_stages-1; i=i+1) begin if (i == 0) begin a_reg[0] <= (en == 1'b0)? a_reg[0] : ((en == 1'b1)? a : {a_width{1'bx}}); b_reg[0] <= (en == 1'b0)? b_reg[0] : ((en == 1'b1)? b : {b_width{1'bx}}); tc_reg[0] <= (en == 1'b0)? tc_reg[0]: ((en == 1'b1)? tc: 1'bx); end else begin a_reg[i] <= (en == 1'b0)? a_reg[i] : ((en == 1'b1)? a_reg[i-1] : {a_width{1'bx}}); b_reg[i] <= (en == 1'b0)? b_reg[i] : ((en == 1'b1)? b_reg[i-1] : {b_width{1'bx}}); tc_reg[i] <= (en == 1'b0)? tc_reg[i]: ((en == 1'b1)? tc_reg[i-1]: 1'bx); end end end end end else if (rst_mode == 1) begin : GEN_RM_EQ_1 if (stall_mode == 0) begin : GEN_RM1_SM0 always @(posedge clk or negedge rst_n) begin: rm1_pipe_reg_PROC integer i; if (rst_n == 1'b0) begin for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'b0}}; b_reg[i] <= {b_width{1'b0}}; tc_reg[i] <= 1'b0; end // for (i= 0; i < num_stages-1; i++) end else if (rst_n == 1'b1) begin for(i= 0; i < num_stages-1; i=i+1) begin if (i == 0) begin a_reg[0] <= a; b_reg[0] <= b; tc_reg[0] <= tc; end else begin a_reg[i] <= a_reg[i-1]; b_reg[i] <= b_reg[i-1]; tc_reg[i] <= tc_reg[i-1]; end end // for (i= 0; i < num_stages-1; i++) end else begin // rst_n not 1'b0 and not 1'b1 for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'bx}}; b_reg[i] <= {b_width{1'bx}}; tc_reg[i] <= 1'bx; end // for (i= 0; i < num_stages-1; i++) end end // block: rm1_pipe_reg_PROC end else begin : GEN_RM1_SM1 always @(posedge clk or negedge rst_n) begin: rm1_pipe_reg_PROC integer i; if (rst_n == 1'b0) begin for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'b0}}; b_reg[i] <= {b_width{1'b0}}; tc_reg[i] <= 1'b0; end // for (i= 0; i < num_stages-1; i++) end else if (rst_n == 1'b1) begin for(i= 0; i < num_stages-1; i=i+1) begin if (i == 0) begin a_reg[0] <= (en == 1'b0)? a_reg[0] : ((en == 1'b1)? a : {a_width{1'bx}}); b_reg[0] <= (en == 1'b0)? b_reg[0] : ((en == 1'b1)? b : {b_width{1'bx}}); tc_reg[0] <= (en == 1'b0)? tc_reg[0]: ((en == 1'b1)? tc: 1'bx); end else begin a_reg[i] <= (en == 1'b0)? a_reg[i] : ((en == 1'b1)? a_reg[i-1] : {a_width{1'bx}}); b_reg[i] <= (en == 1'b0)? b_reg[i] : ((en == 1'b1)? b_reg[i-1] : {b_width{1'bx}}); tc_reg[i] <= (en == 1'b0)? tc_reg[i]: ((en == 1'b1)? tc_reg[i-1]: 1'bx); end end // for (i= 0; i < num_stages-1; i++) end else begin // rst_n not 1'b0 and not 1'b1 for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'bx}}; b_reg[i] <= {b_width{1'bx}}; tc_reg[i] <= 1'bx; end // for (i= 0; i < num_stages-1; i++) end end // block: rm1_pipe_reg_PROC end end else begin : GEN_RM_GT_1 if (stall_mode == 0) begin : GEN_RM2_SM0 always @(posedge clk) begin: rm2_pipe_reg_PROC integer i; if (rst_n == 1'b0) begin for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'b0}}; b_reg[i] <= {b_width{1'b0}}; tc_reg[i] <= 1'b0; end // for (i= 0; i < num_stages-1; i++) end else if (rst_n == 1'b1) begin for(i= 0; i < num_stages-1; i=i+1) begin if (i == 0) begin a_reg[0] <= a; b_reg[0] <= b; tc_reg[0] <= tc; end else begin a_reg[i] <= a_reg[i-1]; b_reg[i] <= b_reg[i-1]; tc_reg[i] <= tc_reg[i-1]; end end // for (i= 0; i < num_stages-1; i++) end else begin // rst_n not 1'b0 and not 1'b1 for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'bx}}; b_reg[i] <= {b_width{1'bx}}; tc_reg[i] <= 1'bx; end // for (i= 0; i < num_stages-1; i++) end end // block: rm2_pipe_reg_PROC end else begin : GEN_RM2_SM1 always @(posedge clk) begin: rm2_pipe_reg_PROC integer i; if (rst_n == 1'b0) begin for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'b0}}; b_reg[i] <= {b_width{1'b0}}; tc_reg[i] <= 1'b0; end // for (i= 0; i < num_stages-1; i++) end else if (rst_n == 1'b1) begin for(i= 0; i < num_stages-1; i=i+1) begin if (i == 0) begin a_reg[0] <= (en == 1'b0)? a_reg[0] : ((en == 1'b1)? a : {a_width{1'bx}}); b_reg[0] <= (en == 1'b0)? b_reg[0] : ((en == 1'b1)? b : {b_width{1'bx}}); tc_reg[0] <= (en == 1'b0)? tc_reg[0]: ((en == 1'b1)? tc: 1'bx); end else begin a_reg[i] <= (en == 1'b0)? a_reg[i] : ((en == 1'b1)? a_reg[i-1] : {a_width{1'bx}}); b_reg[i] <= (en == 1'b0)? b_reg[i] : ((en == 1'b1)? b_reg[i-1] : {b_width{1'bx}}); tc_reg[i] <= (en == 1'b0)? tc_reg[i]: ((en == 1'b1)? tc_reg[i-1]: 1'bx); end end // for (i= 0; i < num_stages-1; i++) end else begin // rst_n not 1'b0 and not 1'b1 for (i= 0; i < num_stages-1; i=i+1) begin a_reg[i] <= {a_width{1'bx}}; b_reg[i] <= {b_width{1'bx}}; tc_reg[i] <= 1'bx; end // for (i= 0; i < num_stages-1; i++) end end // block: rm2_pipe_reg_PROC end end endgenerate DW02_mult #(a_width, b_width) U1 (.A(a_reg[num_stages-2]), .B(b_reg[num_stages-2]), .TC(tc_reg[num_stages-2]), .PRODUCT(product)); //--------------------------------------------------------------------------- // Parameter legality check and initializations //--------------------------------------------------------------------------- initial begin : parameter_check integer param_err_flg; param_err_flg = 0; if (a_width < 1) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter a_width (lower bound: 1)", a_width ); end if (b_width < 1) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter b_width (lower bound: 1)", b_width ); end if (num_stages < 2) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter num_stages (lower bound: 2)", num_stages ); end if ( (stall_mode < 0) || (stall_mode > 1) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter stall_mode (legal range: 0 to 1)", stall_mode ); end if ( (rst_mode < 0) || (rst_mode > 2) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter rst_mode (legal range: 0 to 2)", rst_mode ); end if ( (op_iso_mode < 0) || (op_iso_mode > 4) ) begin param_err_flg = 1; $display( "ERROR: %m :\n Invalid value (%d) for parameter op_iso_mode (legal range: 0 to 4)", op_iso_mode ); end if ( param_err_flg == 1) begin $display( "%m :\n Simulation aborted due to invalid parameter value(s)"); $finish; end end // parameter_check //--------------------------------------------------------------------------- // Report unknown clock inputs //--------------------------------------------------------------------------- always @ (clk) begin : clk_monitor if ( (clk !== 1'b0) && (clk !== 1'b1) && ($time > 0) ) $display( "WARNING: %m :\n at time = %t, detected unknown value, %b, on clk input.", $time, clk ); end // clk_monitor // synopsys translate_on endmodule //