module RAMDP_20X16_GL_M1_E2 (CLK_R, CLK_W, RE, WE
 , RADR_4, RADR_3, RADR_2, RADR_1, RADR_0
    , WADR_4, WADR_3, WADR_2, WADR_1, WADR_0
 , WD_15, WD_14, WD_13, WD_12, WD_11, WD_10, WD_9, WD_8, WD_7, WD_6, WD_5, WD_4, WD_3, WD_2, WD_1, WD_0
 , RD_15, RD_14, RD_13, RD_12, RD_11, RD_10, RD_9, RD_8, RD_7, RD_6, RD_5, RD_4, RD_3, RD_2, RD_1, RD_0
    , IDDQ
 , SVOP_1, SVOP_0
    , SLEEP_EN_7, SLEEP_EN_6, SLEEP_EN_5, SLEEP_EN_4, SLEEP_EN_3, SLEEP_EN_2, SLEEP_EN_1, SLEEP_EN_0, RET_EN
);
// nvProps NoBus SLEEP_EN_
`ifndef RAM_INTERFACE
`ifndef EMULATION
`ifndef SYNTHESIS
// Physical ram size defined as localparam
localparam phy_rows = 20;
localparam phy_cols = 16;
localparam phy_rcols_pos = 16'b0;
`endif //ndef SYNTHESIS
`endif //EMULATION
`endif //ndef RAM_INTERFACE
input CLK_R, CLK_W, RE, WE
 , RADR_4, RADR_3, RADR_2, RADR_1, RADR_0
    , WADR_4, WADR_3, WADR_2, WADR_1, WADR_0
 , WD_15, WD_14, WD_13, WD_12, WD_11, WD_10, WD_9, WD_8, WD_7, WD_6, WD_5, WD_4, WD_3, WD_2, WD_1, WD_0
    , SLEEP_EN_7, SLEEP_EN_6, SLEEP_EN_5, SLEEP_EN_4, SLEEP_EN_3, SLEEP_EN_2, SLEEP_EN_1, SLEEP_EN_0, RET_EN
    , IDDQ
 , SVOP_1, SVOP_0;
output RD_15, RD_14, RD_13, RD_12, RD_11, RD_10, RD_9, RD_8, RD_7, RD_6, RD_5, RD_4, RD_3, RD_2, RD_1, RD_0;
`ifndef RAM_INTERFACE
//assemble & rename wires
 wire [4:0] RA = {RADR_4, RADR_3, RADR_2, RADR_1, RADR_0};
 wire [4:0] WA = {WADR_4, WADR_3, WADR_2, WADR_1, WADR_0};
 wire [15:0] WD = {WD_15, WD_14, WD_13, WD_12, WD_11, WD_10, WD_9, WD_8, WD_7, WD_6, WD_5, WD_4, WD_3, WD_2, WD_1, WD_0};
 wire [15:0] RD;
 assign {RD_15, RD_14, RD_13, RD_12, RD_11, RD_10, RD_9, RD_8, RD_7, RD_6, RD_5, RD_4, RD_3, RD_2, RD_1, RD_0} = RD;
 wire [1:0] SVOP = {SVOP_1, SVOP_0};
    wire [7:0] SLEEP_EN = {SLEEP_EN_7, SLEEP_EN_6, SLEEP_EN_5, SLEEP_EN_4, SLEEP_EN_3, SLEEP_EN_2, SLEEP_EN_1, SLEEP_EN_0};
`ifndef EMULATION
`ifndef SYNTHESIS
//State point clobering signals:
    wire check_x = (SVOP_0 ^ SVOP_1);
    wire clobber_x;
    assign clobber_x = ((check_x === 1'bx) || (check_x === 1'bz)) ? 1'b1 : 1'b0;
    wire clobber_array = ((|SLEEP_EN) & ~RET_EN) | clobber_x;
    wire clobber_flops = (|SLEEP_EN) | clobber_x;
    integer i;
    always @(clobber_array) begin
      if (clobber_array) begin
      for (i=0; i<20; i=i+1) begin
          ITOP.io.array[i] <= 16'bx;
      end
      end
    end
//VCS coverage off
    always @(clobber_flops) begin
        if (clobber_flops) begin
        ITOP.we_lat <= 1'bx;
        ITOP.wa_lat <= 5'bx;
        ITOP.wd_lat <= 16'bx;
        ITOP.re_lat <= 1'bx;
        ITOP.ra_lat <= 5'bx;
        ITOP.io.r0_dout_tmp <= 16'b0;
        end
    end
//VCS coverage on
//VCS coverage off
`ifdef NV_RAM_ASSERT
//first reset signal for nv_assert_module:
    reg sim_reset;
    initial begin: init_sim_reset
        sim_reset = 0;
        #6 sim_reset = 1;
    end
    reg rst_clk;
    initial begin: init_rst_clk
        rst_clk = 0;
        #2 rst_clk = 1;
        #4 rst_clk = 0;
    end
//internal weclk|reclk gating signal:
    wire weclk_gating = ITOP.we_lat & ~IDDQ;
    wire reclk_gating = ITOP.re_lat & ~IDDQ;
//Logic-S1: write address out of range
    wire illegal_logic_assertion_wadr_out_of_range = (ITOP.wa_lat>=5'd20) & weclk_gating;
    wire disable_logic_assertion_wadr_out_of_range = $test$plusargs("disable_logic_assertions_globally") | $test$plusargs("disable_logic_assertion_wadr_out_of_range");
    nv_assert_never #(0,0, "Logic-S1:write address out of range") disable_logic_assertion_wadr_out_of_range_x (CLK_W ^ rst_clk, ~disable_logic_assertion_wadr_out_of_range & sim_reset, illegal_logic_assertion_wadr_out_of_range);
//Logic-S2: read address out of range
    wire illegal_logic_assertion_radr_out_of_range = (ITOP.ra_lat>=5'd20) & reclk_gating;
    wire disable_logic_assertion_radr_out_of_range = $test$plusargs("disable_logic_assertions_globally") | $test$plusargs("disable_logic_assertion_radr_out_of_range");
    nv_assert_never #(0,0, "Logic-S2:read address out of range") disable_logic_assertion_radr_out_of_range_x (CLK_R ^ rst_clk, ~disable_logic_assertion_radr_out_of_range & sim_reset, illegal_logic_assertion_radr_out_of_range);
//Assertion checks for power sequence of G-option RAMDP:
//weclk_gating after 2 clk
    reg weclk_gating_1p, weclk_gating_2p;
    always @(posedge CLK_W) begin
        weclk_gating_1p <= weclk_gating;
        weclk_gating_2p <= weclk_gating_1p;
    end
//reclk_gating after 2 clk
    reg reclk_gating_1p, reclk_gating_2p;
    always @(posedge CLK_R) begin
        reclk_gating_1p <= reclk_gating;
        reclk_gating_2p <= reclk_gating_1p;
    end
//RET_EN off after 2 CLK_W
    reg ret_en_w_1p, ret_en_w_2p;
    always @(posedge CLK_W or posedge RET_EN) begin
        if(RET_EN)
            begin
                ret_en_w_1p <= 1'b1;
                ret_en_w_2p <= 1'b1;
            end
        else
            begin
                ret_en_w_1p <= RET_EN;
                ret_en_w_2p <= ret_en_w_1p;
            end
    end
//RET_EN off after 2 CLK_R
    reg ret_en_r_1p, ret_en_r_2p;
    always @(posedge CLK_R or posedge RET_EN) begin
        if(RET_EN)
            begin
                ret_en_r_1p <= 1'b1;
                ret_en_r_2p <= 1'b1;
            end
        else
            begin
                ret_en_r_1p <= RET_EN;
                ret_en_r_2p <= ret_en_r_1p;
            end
    end
    wire sleep_en_or = (|SLEEP_EN) ;
//SLEEP_EN off after 2 CLK_W
    reg sleep_en_off_w_1p, sleep_en_off_w_2p;
    always @(posedge CLK_W or posedge sleep_en_or) begin
        if(sleep_en_or)
            begin
                sleep_en_off_w_1p <= 1'b1;
                sleep_en_off_w_2p <= 1'b1;
            end
        else
            begin
                sleep_en_off_w_1p <= sleep_en_or;
                sleep_en_off_w_2p <= sleep_en_off_w_1p;
            end
    end
//SLEEP_EN off after 2 CLK_R
    reg sleep_en_off_r_1p, sleep_en_off_r_2p;
    always @(posedge CLK_R or posedge sleep_en_or) begin
        if(sleep_en_or)
            begin
                sleep_en_off_r_1p <= 1'b1;
                sleep_en_off_r_2p <= 1'b1;
            end
        else
            begin
                sleep_en_off_r_1p <= |sleep_en_or;
                sleep_en_off_r_2p <= sleep_en_off_r_1p;
            end
    end
//#1 From function mode to retention mode:
//Power-S1.1:illegal assert RET_EN after asserting SLEEP_EN
    wire disable_power_assertion_S1P1 = $test$plusargs("disable_power_assertions_globally") | $test$plusargs("disable_power_assertion_assert_RET_EN_after_SLEEP_EN_on_when_function2retention");
    nv_assert_never #(0,0, "Power-S1.1:illegal assert RET_EN after asserting SLEEP_EN") inst_S1P1 (RET_EN ^ rst_clk, ~disable_power_assertion_S1P1 & sim_reset, (|SLEEP_EN));
//Power-S1.2:illegal assert RET_EN without 2 nop-CLK
    wire disable_power_assertion_S1P2 = $test$plusargs("disable_power_assertions_globally") | $test$plusargs("disable_power_assertion_assert_RET_EN_without_2_nop_CLK");
    nv_assert_never #(0,0, "Power-S1.2:illegal assert RET_EN without 2 nop-CLK") inst_S1P2 (RET_EN ^ rst_clk, ~disable_power_assertion_S1P2 & sim_reset, weclk_gating | weclk_gating_1p | weclk_gating_2p | reclk_gating | reclk_gating_1p | reclk_gating_2p);
//#2 From retention mode to function mode:
//Power-S2.1:illegal write without 2 nop-CLK after de-asserting RET_EN
    wire disable_power_assertion_S2P1 = $test$plusargs("disable_power_assertions_globally") | $test$plusargs("disable_power_assertion_write_without_2_nop_CLK_after_retention2function");
    nv_assert_never #(0,0, "Power-S2.1:illegal write without 2 nop-CLK after de-asserting RET_EN") inst_S2P1 (CLK_W ^ rst_clk, ~disable_power_assertion_S2P1 & sim_reset, ~RET_EN & ret_en_w_2p & weclk_gating);
//Power-S2.2:illegal read without 2 nop-CLK after de-asserting RET_EN
    wire disable_power_assertion_S2P2 = $test$plusargs("disable_power_assertions_globally") | $test$plusargs("disable_power_assertion_read_without_2_nop_CLK_after_retention2function");
    nv_assert_never #(0,0, "Power-S2.2:illegal read without 2 nop-CLK after de-asserting RET_EN") inst_S2P2 (CLK_R ^ rst_clk, ~disable_power_assertion_S2P2 & sim_reset, ~RET_EN & ret_en_r_2p & reclk_gating);
//#3 From function mode to sleep mode:
//Power-S3.2:illegal assert SLEEP_EN without 2 nop-CLK
    wire disable_power_assertion_S3P2 = $test$plusargs("disable_power_assertions_globally") | $test$plusargs("disable_power_assertion_assert_SLEEP_EN_without_2_nop_CLK");
    nv_assert_never #(0,0, "Power-S3.2:illegal assert SLEEP_EN without 2 nop-CLK") inst_S3P2 ((|SLEEP_EN) ^ rst_clk, ~disable_power_assertion_S3P2 & sim_reset, weclk_gating | weclk_gating_1p | weclk_gating_2p | reclk_gating | reclk_gating_1p | reclk_gating_2p);
//#4 From sleep mode to function mode:
//Power-S4.1:illegal write without 2 nop-CLK after switching from sleep mode to function mode
    wire disable_power_assertion_S4P1 = $test$plusargs("disable_power_assertions_globally") | $test$plusargs("disable_power_assertion_write_without_2_nop_CLK_after_sleep2function");
    nv_assert_never #(0,0, "Power-S4.1:illegal write without 2 nop-CLK after switching from sleep mode to function mode") inst_S4P1 (CLK_W ^ rst_clk, ~disable_power_assertion_S4P1 & sim_reset, ~(|SLEEP_EN) & sleep_en_off_w_2p & weclk_gating);
//Power-S4.2:illegal read without 2 nop-CLK after switching from sleep mode to function mode
    wire disable_power_assertion_S4P2 = $test$plusargs("disable_power_assertions_globally") | $test$plusargs("disable_power_assertion_read_without_2_nop_after_sleep2function");
    nv_assert_never #(0,0, "Power-S4.2:illegal read without 2 nop-CLK after switching from sleep mode to function mode") inst_S4P2 (CLK_R ^ rst_clk, ~disable_power_assertion_S4P2 & sim_reset, ~(|SLEEP_EN) & sleep_en_off_r_2p & reclk_gating);
`endif //NV_RAM_ASSERT
//VCS coverage on
`ifdef NV_RAM_EXPAND_ARRAY
  wire [16-1:0] Q_19 = ITOP.io.array[19];
  wire [16-1:0] Q_18 = ITOP.io.array[18];
  wire [16-1:0] Q_17 = ITOP.io.array[17];
  wire [16-1:0] Q_16 = ITOP.io.array[16];
  wire [16-1:0] Q_15 = ITOP.io.array[15];
  wire [16-1:0] Q_14 = ITOP.io.array[14];
  wire [16-1:0] Q_13 = ITOP.io.array[13];
  wire [16-1:0] Q_12 = ITOP.io.array[12];
  wire [16-1:0] Q_11 = ITOP.io.array[11];
  wire [16-1:0] Q_10 = ITOP.io.array[10];
  wire [16-1:0] Q_9 = ITOP.io.array[9];
  wire [16-1:0] Q_8 = ITOP.io.array[8];
  wire [16-1:0] Q_7 = ITOP.io.array[7];
  wire [16-1:0] Q_6 = ITOP.io.array[6];
  wire [16-1:0] Q_5 = ITOP.io.array[5];
  wire [16-1:0] Q_4 = ITOP.io.array[4];
  wire [16-1:0] Q_3 = ITOP.io.array[3];
  wire [16-1:0] Q_2 = ITOP.io.array[2];
  wire [16-1:0] Q_1 = ITOP.io.array[1];
  wire [16-1:0] Q_0 = ITOP.io.array[0];
`endif //def NV_RAM_EXPAND_ARRAY
//VCS coverage off
`ifdef MONITOR
task monitor_on;
    begin
        ITOP.io.monitor_on = 1'b1;
    end
endtask
task monitor_off;
    begin
        ITOP.io.monitor_on = 1'b0;
        ITOP.io.dump_monitor_result = 1'b1;
    end
endtask
`endif//def MONITOR
//VCS coverage on
//VCS coverage off
task mem_fill_value;
input fill_bit;
integer i;
begin
    for (i=0; i<20; i=i+1) begin
     ITOP.io.array[i] = {16{fill_bit}};
    end
end
endtask
task mem_fill_random;
integer i;
integer j;
reg [15:0] val;
begin
    for (j=0; j<20; j=j+1) begin
        for (i=0; i<16; i=i+1) begin
            val[i] = {$random};
        end
     ITOP.io.array[j] = val;
    end
end
endtask
task mem_write;
  input [4:0] addr;
  input [15:0] data;
  begin
     ITOP.io.mem_wr_raw(addr,data);
  end
endtask
function [15:0] mem_read;
  input [4:0] addr;
  begin
 mem_read = ITOP.io.mem_read_raw(addr);
  end
endfunction
task force_rd;
  input [4:0] addr;
  begin
 ITOP.io.r0_dout_tmp = ITOP.io.array[addr];
  end
endtask
`ifdef MEM_PHYS_INFO
task mem_phys_write;
  input [4:0] addr;
  input [15:0] data;
  begin
     ITOP.io.mem_wr_raw(addr,data);
  end
endtask
function [15:0] mem_phys_read_padr;
  input [4:0] addr;
  begin
 mem_phys_read_padr = ITOP.io.mem_read_raw(addr);
  end
endfunction
function [4:0] mem_log_to_phys_adr;
    input [4:0] addr;
    begin
    mem_log_to_phys_adr = addr;
    end
endfunction
function [15:0] mem_phys_read_pmasked;
  input [4:0] addr;
  begin
 mem_phys_read_pmasked = ITOP.io.mem_read_raw(addr);
  end
endfunction
function [15:0] mem_phys_read_ladr;
  input [4:0] addr;
  begin
 mem_phys_read_ladr = mem_phys_read_padr(mem_log_to_phys_adr(addr));
  end
endfunction
`endif //def MEM_PHYS_INFO
`ifdef FAULT_INJECTION
task mem_fault_no_write;
  input [15:0] fault_mask;
   begin
    ITOP.io.mem_fault_no_write(fault_mask);
  end
endtask
task mem_fault_stuck_0;
  input [15:0] fault_mask;
  integer i;
   begin
    ITOP.io.mem_fault_stuck_0(fault_mask);
   end
endtask
task mem_fault_stuck_1;
  input [15:0] fault_mask;
  integer i;
   begin
    ITOP.io.mem_fault_stuck_1(fault_mask);
  end
endtask
task set_bit_fault_stuck_0;
  input r;
  input c;
  integer r;
  integer c;
    ITOP.io.set_bit_fault_stuck_0(r,c);
endtask
task set_bit_fault_stuck_1;
  input r;
  input c;
  integer r;
  integer c;
    ITOP.io.set_bit_fault_stuck_1(r,c);
endtask
task clear_bit_fault_stuck_0;
  input r;
  input c;
  integer r;
  integer c;
    ITOP.io.clear_bit_fault_stuck_0(r,c);
endtask
task clear_bit_fault_stuck_1;
  input r;
  input c;
  integer r;
  integer c;
    ITOP.io.clear_bit_fault_stuck_1(r,c);
endtask
//VCS coverage on
`endif //def FAULT_INJECTION
`else //def SYNTHESIS
    wire clobber_x;
    assign clobber_x = 1'b0;
    wire clobber_array = 1'b0;
    wire clobber_flops = 1'b0;
`endif //ndef SYNTHESIS
//instantiate memory bank
 RAM_BANK_RAMDP_20X16_GL_M1_E2 ITOP (
  .RE(RE),
  .WE(WE),
  .RA(RA),
  .WA(WA),
  .CLK_R(CLK_R),
  .CLK_W(CLK_W),
  .IDDQ(IDDQ),
  .SVOP(SVOP),
  .WD(WD),
  .RD(RD),
  .SLEEP_EN(SLEEP_EN),
        .RET_EN(RET_EN),
        .clobber_flops(clobber_flops),
        .clobber_array(clobber_array),
        .clobber_x(clobber_x)
 );
//VCS coverage off
`else //def EMULATION
// Simple emulation model without MBIST, SCAN or REDUNDANCY
//common part for write
     reg we_ff;
        reg [4:0] wa_ff;
        reg [15:0] wd_ff;
     always @(posedge CLK_W) begin // spyglass disable W391
                we_ff <= WE;
                wa_ff <= WA;
                wd_ff <= WD;
     end
//common part for read
     reg re_lat;
        always @(*) begin
      if (!CLK_R) begin
                re_lat <= RE; // spyglass disable W18
      end
     end
     wire reclk = CLK_R & re_lat;
     reg [4:0] ra_ff;
     always @(posedge CLK_R) begin // spyglass disable W391
       ra_ff <= RA;
     end
        reg [15:0] dout;
        assign RD = dout;
//memory array
     reg [15:0] array[0:19];
     always @(negedge CLK_W ) begin
            if (we_ff) begin
       array[wa_ff] <= wd_ff; // spyglass disable SYNTH_5130
            end
     end
     always @(*) begin
      if (reclk) begin
       dout <= array[ra_ff]; // spyglass disable SYNTH_5130, W18
      end
     end
// End of the simple emulation model
`endif //def EMULATION
//VCS coverage on
`endif //ndef RAM_INTERFACE
endmodule