dakies/OSS_Verilog huggingface dataset:
module spram_18x1024_9x2048 (
    WEN_i,
    REN_i,
    clock0,
    clock1,
    WR_ADDR_i,
    RD_ADDR_i,
    WDATA_i,
    RDATA_o
);

parameter WR_ADDR_WIDTH = 10;
parameter RD_ADDR_WIDTH = 11;
parameter WR_DATA_WIDTH = 18;
parameter RD_DATA_WIDTH = 9;
parameter BE_WIDTH = 2;

input wire WEN_i;
input wire REN_i;
input wire clock0;
input wire clock1;
input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
output wire [RD_DATA_WIDTH-1 :0] RDATA_o;

RAM_18K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
              .WR_DATA_WIDTH(WR_DATA_WIDTH),
              .RD_DATA_WIDTH(RD_DATA_WIDTH),
              .BE_WIDTH(BE_WIDTH)
              ) spram_x18_inst (
              
              .WEN_i(WEN_i),
              .WR_BE_i(2'b11),
              .REN_i(REN_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR_i),
              .RD_ADDR_i(RD_ADDR_i),
              .WDATA_i(WDATA_i),
              .RDATA_o(RDATA_o)
              );
              
endmodule
module mult_16x16 (
    input  wire [15:0] A,
    input  wire [15:0] B,
    output wire [31:0] Z
);

    assign Z = A * B;

endmodule
module mult_20x18 (
    input  wire [19:0] A,
    input  wire [17:0] B,
    output wire [37:0] Z
);

    assign Z = A * B;

endmodule
module mult_8x8 (
    input  wire [ 7:0] A,
    input  wire [ 7:0] B,
    output wire [15:0] Z
);

    assign Z = A * B;

endmodule
module mult_10x9 (
    input  wire [ 9:0] A,
    input  wire [ 8:0] B,
    output wire [18:0] Z
);

    assign Z = A * B;

endmodule
module mult_8x8_s (
    input  wire signed [ 7:0] A,
    input  wire signed [ 7:0] B,
    output wire signed [15:0] Z
);

    assign Z = A * B;

endmodule
module tb();

    // Clock
    reg clk;
    initial clk <= 1'b0;
    always #1 clk <= ~clk;

    // Data Clock
    reg dclk;
    initial dclk <= 1'b0;
    always #2 dclk <= ~dclk;

    // Input data / reference
    reg [9:0] A0;
    reg [9:0] A1;

    reg [8:0] B0;
    reg [8:0] B1;

    reg [18:0] C0;
    reg [18:0] C1;

    always @(negedge dclk) begin
        A0 = $random;
        B0 = $random;

        C0 <= A0 * B0;

        A1 = $random;
        B1 = $random;

        C1 <= A1 * B1;
    end

    // UUT
    wire [18:0] Z0;
    wire [18:0] Z1;

    simd_mult_explicit_ports dsp1 (
        .clk(clk),
        .a0(A0),
        .a1(A1),
        .b0(B0),
        .b1(B1),
        .z0(Z0),
        .z1(Z1)
    );

    reg [18:0] C0_r;
    reg [18:0] C1_r;

    always @(posedge clk) begin
        C0_r = C0;
        C1_r = C1;
    end

    // Error detection
    wire error0 = (Z0 !== C0_r) && (C0_r !== 19'bx);
    wire error1 = (Z1 !== C1_r) && (C0_r !== 19'bx);

    // Error counting
    integer error_count = 0;

    always @(posedge clk) begin
        if (error0) begin
            error_count <= error_count + 1'b1;
            $display("%d: DSP_0: FAIL: mismatch act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
        end else begin
            $display("%d: DSP_0: OK: act=%x exp=%x at A0=%x; B0=%x", $time, Z0, C0_r, A0, B0);
        end
    end

    always @(posedge clk) begin
        if (error1) begin
            error_count <= error_count + 1'b1;
            $display("%d: DSP_1: FAIL: mismatch act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
        end else begin
            $display("%d: DSP_1: OK: act=%x exp=%x at A1=%x; B1=%x", $time, Z1, C1_r, A1, B1);
        end
    end

    // Simulation control / data dump
    initial begin
        $dumpfile(`VCD_FILE);
        $dumpvars;
        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
    end

endmodule
module simd_mult_explicit_ports (
    input  wire         clk,

    input  wire [ 9:0]  a0,
    input  wire [ 8:0]  b0,
    output wire [18:0]  z0,

    input  wire [ 9:0]  a1,
    input  wire [ 8:0]  b1,
    output wire [18:0]  z1
);

    dsp_t1_10x9x32_cfg_ports dsp_0 (
        .a_i                (a0),
        .b_i                (b0),
        .z_o                (z0),

        .clock_i            (clk),

        .feedback_i         (3'd0),
        .load_acc_i         (1'b0),
        .unsigned_a_i       (1'b1),
        .unsigned_b_i       (1'b1),

        .output_select_i    (3'd0),
        .saturate_enable_i  (1'b0),
        .shift_right_i      (6'd0),
        .round_i            (1'b0),
        .subtract_i         (1'b0),
        .register_inputs_i  (1'b1)
    );

    dsp_t1_10x9x32_cfg_ports dsp_1 (
        .a_i                (a1),
        .b_i                (b1),
        .z_o                (z1),

        .clock_i            (clk),

        .feedback_i         (3'd0),
        .load_acc_i         (1'b0),
        .unsigned_a_i       (1'b1),
        .unsigned_b_i       (1'b1),

        .output_select_i    (3'd0),
        .saturate_enable_i  (1'b0),
        .shift_right_i      (6'd0),
        .round_i            (1'b0),
        .subtract_i         (1'b0),
        .register_inputs_i  (1'b1)
    );

endmodule
module dpram_18x1024_x2 (   
    clk_a_0,
    WEN_a_0,
    REN_a_0,
    WR_ADDR_a_0,
    RD_ADDR_a_0,
    WDATA_a_0,
    RDATA_a_0,
    
    clk_b_0,
    WEN_b_0,
    REN_b_0,
    WR_ADDR_b_0,
    RD_ADDR_b_0,
    WDATA_b_0,
    RDATA_b_0,
    
    clk_a_1,
    WEN_a_1,
    REN_a_1,
    WR_ADDR_a_1,
    RD_ADDR_a_1,
    WDATA_a_1,
    RDATA_a_1,
    
    clk_b_1,
    WEN_b_1,
    REN_b_1,
    WR_ADDR_b_1,
    RD_ADDR_b_1,
    WDATA_b_1,
    RDATA_b_1
);

parameter ADDR_WIDTH0 = 10;
parameter DATA_WIDTH0 = 18;
parameter BE1_WIDTH0 = 2;
parameter BE2_WIDTH0 = 2;

parameter ADDR_WIDTH1 = 10;
parameter DATA_WIDTH1 = 18;
parameter BE1_WIDTH1 = 2;
parameter BE2_WIDTH1 = 2;

input wire clk_a_0;
input wire WEN_a_0;
input wire REN_a_0;
input wire [ADDR_WIDTH0-1 :0] WR_ADDR_a_0;
input wire [ADDR_WIDTH0-1 :0] RD_ADDR_a_0;
input wire [DATA_WIDTH0-1 :0] WDATA_a_0;
output wire [DATA_WIDTH0-1 :0] RDATA_a_0;

input wire clk_b_0;
input wire WEN_b_0;
input wire REN_b_0;
input wire [ADDR_WIDTH0-1 :0] WR_ADDR_b_0;
input wire [ADDR_WIDTH0-1 :0] RD_ADDR_b_0;
input wire [DATA_WIDTH0-1 :0] WDATA_b_0;
output wire [DATA_WIDTH0-1 :0] RDATA_b_0;

input wire clk_a_1;
input wire WEN_a_1;
input wire REN_a_1;
input wire [ADDR_WIDTH1-1 :0] WR_ADDR_a_1;
input wire [ADDR_WIDTH1-1 :0] RD_ADDR_a_1;
input wire [DATA_WIDTH1-1 :0] WDATA_a_1;
output wire [DATA_WIDTH1-1 :0] RDATA_a_1;

input wire clk_b_1;
input wire WEN_b_1;
input wire REN_b_1;
input wire [ADDR_WIDTH1-1 :0] WR_ADDR_b_1;
input wire [ADDR_WIDTH1-1 :0] RD_ADDR_b_1;
input wire [DATA_WIDTH1-1 :0] WDATA_b_1;
output wire [DATA_WIDTH1-1 :0] RDATA_b_1;
 
DPRAM_18K_BLK #(
              .ADDR_WIDTH(ADDR_WIDTH0),
              .DATA_WIDTH(DATA_WIDTH0),
              .BE1_WIDTH(BE1_WIDTH0),
              .BE2_WIDTH(BE2_WIDTH0)
              ) dpram_x18_inst0 ( 
              
              .CLK1_i(clk_a_0),
              .WEN1_i(WEN_a_0),
              .REN1_i(REN_a_0),
              .WR1_ADDR_i(WR_ADDR_a_0),
              .RD1_ADDR_i(RD_ADDR_a_0),
              .WDATA1_i(WDATA_a_0),
              .RDATA1_o(RDATA_a_0),
              
              .CLK2_i(clk_b_0),
              .WEN2_i(WEN_b_0),
              .REN2_i(REN_b_0),
              .WR2_ADDR_i(WR_ADDR_b_0),
              .RD2_ADDR_i(RD_ADDR_b_0),
              .WDATA2_i(WDATA_b_0),
              .RDATA2_o(RDATA_b_0)
              );
              
 
DPRAM_18K_BLK #(
              .ADDR_WIDTH(ADDR_WIDTH1),
              .DATA_WIDTH(DATA_WIDTH1),
              .BE1_WIDTH(BE1_WIDTH1),
              .BE2_WIDTH(BE2_WIDTH1)
              ) dpram_x18_inst1 ( 
              
              .CLK1_i(clk_a_1),
              .WEN1_i(WEN_a_1),
              .REN1_i(REN_a_1),
              .WR1_ADDR_i(WR_ADDR_a_1),
              .RD1_ADDR_i(RD_ADDR_a_1),
              .WDATA1_i(WDATA_a_1),
              .RDATA1_o(RDATA_a_1),
              
              .CLK2_i(clk_b_1),
              .WEN2_i(WEN_b_1),
              .REN2_i(REN_b_1),
              .WR2_ADDR_i(WR_ADDR_b_1),
              .RD2_ADDR_i(RD_ADDR_b_1),
              .WDATA2_i(WDATA_b_1),
              .RDATA2_o(RDATA_b_1)
              );
              
endmodule
module dpram_9x2048_x2 (   
    clk_a_0,
    WEN_a_0,
    REN_a_0,
    WR_ADDR_a_0,
    RD_ADDR_a_0,
    WDATA_a_0,
    RDATA_a_0,
    
    clk_b_0,
    WEN_b_0,
    REN_b_0,
    WR_ADDR_b_0,
    RD_ADDR_b_0,
    WDATA_b_0,
    RDATA_b_0,
    
    clk_a_1,
    WEN_a_1,
    REN_a_1,
    WR_ADDR_a_1,
    RD_ADDR_a_1,
    WDATA_a_1,
    RDATA_a_1,
    
    clk_b_1,
    WEN_b_1,
    REN_b_1,
    WR_ADDR_b_1,
    RD_ADDR_b_1,
    WDATA_b_1,
    RDATA_b_1
);

parameter ADDR_WIDTH0 = 11;
parameter DATA_WIDTH0 = 9;
parameter BE1_WIDTH0 = 1;
parameter BE2_WIDTH0 = 1;

parameter ADDR_WIDTH1 = 11;
parameter DATA_WIDTH1 = 9;
parameter BE1_WIDTH1 = 1;
parameter BE2_WIDTH1 = 1;

input wire clk_a_0;
input wire WEN_a_0;
input wire REN_a_0;
input wire [ADDR_WIDTH0-1 :0] WR_ADDR_a_0;
input wire [ADDR_WIDTH0-1 :0] RD_ADDR_a_0;
input wire [DATA_WIDTH0-1 :0] WDATA_a_0;
output wire [DATA_WIDTH0-1 :0] RDATA_a_0;

input wire clk_b_0;
input wire WEN_b_0;
input wire REN_b_0;
input wire [ADDR_WIDTH0-1 :0] WR_ADDR_b_0;
input wire [ADDR_WIDTH0-1 :0] RD_ADDR_b_0;
input wire [DATA_WIDTH0-1 :0] WDATA_b_0;
output wire [DATA_WIDTH0-1 :0] RDATA_b_0;

input wire clk_a_1;
input wire WEN_a_1;
input wire REN_a_1;
input wire [ADDR_WIDTH1-1 :0] WR_ADDR_a_1;
input wire [ADDR_WIDTH1-1 :0] RD_ADDR_a_1;
input wire [DATA_WIDTH1-1 :0] WDATA_a_1;
output wire [DATA_WIDTH1-1 :0] RDATA_a_1;

input wire clk_b_1;
input wire WEN_b_1;
input wire REN_b_1;
input wire [ADDR_WIDTH1-1 :0] WR_ADDR_b_1;
input wire [ADDR_WIDTH1-1 :0] RD_ADDR_b_1;
input wire [DATA_WIDTH1-1 :0] WDATA_b_1;
output wire [DATA_WIDTH1-1 :0] RDATA_b_1;
 
DPRAM_18K_BLK #(
              .ADDR_WIDTH(ADDR_WIDTH0),
              .DATA_WIDTH(DATA_WIDTH0),
              .BE1_WIDTH(BE1_WIDTH0),
              .BE2_WIDTH(BE2_WIDTH0)
              ) dpram_x18_inst0 ( 
              
              .CLK1_i(clk_a_0),
              .WEN1_i(WEN_a_0),
              .REN1_i(REN_a_0),
              .WR1_ADDR_i(WR_ADDR_a_0),
              .RD1_ADDR_i(RD_ADDR_a_0),
              .WDATA1_i(WDATA_a_0),
              .RDATA1_o(RDATA_a_0),
              
              .CLK2_i(clk_b_0),
              .WEN2_i(WEN_b_0),
              .REN2_i(REN_b_0),
              .WR2_ADDR_i(WR_ADDR_b_0),
              .RD2_ADDR_i(RD_ADDR_b_0),
              .WDATA2_i(WDATA_b_0),
              .RDATA2_o(RDATA_b_0)
              );
              
 
DPRAM_18K_BLK #(
              .ADDR_WIDTH(ADDR_WIDTH1),
              .DATA_WIDTH(DATA_WIDTH1),
              .BE1_WIDTH(BE1_WIDTH1),
              .BE2_WIDTH(BE2_WIDTH1)
              ) dpram_x18_inst1 ( 
              
              .CLK1_i(clk_a_1),
              .WEN1_i(WEN_a_1),
              .REN1_i(REN_a_1),
              .WR1_ADDR_i(WR_ADDR_a_1),
              .RD1_ADDR_i(RD_ADDR_a_1),
              .WDATA1_i(WDATA_a_1),
              .RDATA1_o(RDATA_a_1),
              
              .CLK2_i(clk_b_1),
              .WEN2_i(WEN_b_1),
              .REN2_i(REN_b_1),
              .WR2_ADDR_i(WR_ADDR_b_1),
              .RD2_ADDR_i(RD_ADDR_b_1),
              .WDATA2_i(WDATA_b_1),
              .RDATA2_o(RDATA_b_1)
              );
              
endmodule
module dpram_18x1024_9x2048 (   
    clk_a_0,
    WEN_a_0,
    REN_a_0,
    WR_ADDR_a_0,
    RD_ADDR_a_0,
    WDATA_a_0,
    RDATA_a_0,
    
    clk_b_0,
    WEN_b_0,
    REN_b_0,
    WR_ADDR_b_0,
    RD_ADDR_b_0,
    WDATA_b_0,
    RDATA_b_0,
    
    clk_a_1,
    WEN_a_1,
    REN_a_1,
    WR_ADDR_a_1,
    RD_ADDR_a_1,
    WDATA_a_1,
    RDATA_a_1,
    
    clk_b_1,
    WEN_b_1,
    REN_b_1,
    WR_ADDR_b_1,
    RD_ADDR_b_1,
    WDATA_b_1,
    RDATA_b_1
);

parameter ADDR_WIDTH0 = 10;
parameter DATA_WIDTH0 = 18;
parameter BE1_WIDTH0 = 2;
parameter BE2_WIDTH0 = 2;

parameter ADDR_WIDTH1 = 11;
parameter DATA_WIDTH1 = 9;
parameter BE1_WIDTH1 = 1;
parameter BE2_WIDTH1 = 1;

input wire clk_a_0;
input wire WEN_a_0;
input wire REN_a_0;
input wire [ADDR_WIDTH0-1 :0] WR_ADDR_a_0;
input wire [ADDR_WIDTH0-1 :0] RD_ADDR_a_0;
input wire [DATA_WIDTH0-1 :0] WDATA_a_0;
output wire [DATA_WIDTH0-1 :0] RDATA_a_0;

input wire clk_b_0;
input wire WEN_b_0;
input wire REN_b_0;
input wire [ADDR_WIDTH0-1 :0] WR_ADDR_b_0;
input wire [ADDR_WIDTH0-1 :0] RD_ADDR_b_0;
input wire [DATA_WIDTH0-1 :0] WDATA_b_0;
output wire [DATA_WIDTH0-1 :0] RDATA_b_0;

input wire clk_a_1;
input wire WEN_a_1;
input wire REN_a_1;
input wire [ADDR_WIDTH1-1 :0] WR_ADDR_a_1;
input wire [ADDR_WIDTH1-1 :0] RD_ADDR_a_1;
input wire [DATA_WIDTH1-1 :0] WDATA_a_1;
output wire [DATA_WIDTH1-1 :0] RDATA_a_1;

input wire clk_b_1;
input wire WEN_b_1;
input wire REN_b_1;
input wire [ADDR_WIDTH1-1 :0] WR_ADDR_b_1;
input wire [ADDR_WIDTH1-1 :0] RD_ADDR_b_1;
input wire [DATA_WIDTH1-1 :0] WDATA_b_1;
output wire [DATA_WIDTH1-1 :0] RDATA_b_1;
 
DPRAM_18K_BLK #(
              .ADDR_WIDTH(ADDR_WIDTH0),
              .DATA_WIDTH(DATA_WIDTH0),
              .BE1_WIDTH(BE1_WIDTH0),
              .BE2_WIDTH(BE2_WIDTH0)
              ) dpram_x18_inst0 ( 
              
              .CLK1_i(clk_a_0),
              .WEN1_i(WEN_a_0),
              .REN1_i(REN_a_0),
              .WR1_ADDR_i(WR_ADDR_a_0),
              .RD1_ADDR_i(RD_ADDR_a_0),
              .WDATA1_i(WDATA_a_0),
              .RDATA1_o(RDATA_a_0),
              
              .CLK2_i(clk_b_0),
              .WEN2_i(WEN_b_0),
              .REN2_i(REN_b_0),
              .WR2_ADDR_i(WR_ADDR_b_0),
              .RD2_ADDR_i(RD_ADDR_b_0),
              .WDATA2_i(WDATA_b_0),
              .RDATA2_o(RDATA_b_0)
              );
              
 
DPRAM_18K_BLK #(
              .ADDR_WIDTH(ADDR_WIDTH1),
              .DATA_WIDTH(DATA_WIDTH1),
              .BE1_WIDTH(BE1_WIDTH1),
              .BE2_WIDTH(BE2_WIDTH1)
              ) dpram_x18_inst1 ( 
              
              .CLK1_i(clk_a_1),
              .WEN1_i(WEN_a_1),
              .REN1_i(REN_a_1),
              .WR1_ADDR_i(WR_ADDR_a_1),
              .RD1_ADDR_i(RD_ADDR_a_1),
              .WDATA1_i(WDATA_a_1),
              .RDATA1_o(RDATA_a_1),
              
              .CLK2_i(clk_b_1),
              .WEN2_i(WEN_b_1),
              .REN2_i(REN_b_1),
              .WR2_ADDR_i(WR_ADDR_b_1),
              .RD2_ADDR_i(RD_ADDR_b_1),
              .WDATA2_i(WDATA_b_1),
              .RDATA2_o(RDATA_b_1)
              );
              
endmodule
module tb();

    // Clock
    reg clk;
    initial clk <= 1'b0;
    always #0.5 clk <= ~clk;

    // Reset
    reg rst;
    initial begin
            rst <= 1'b0;
        #1  rst <= 1'b1;
        #2  rst <= 1'b0;
    end

    // Input data / reference
    reg signed [19:0] A;
    reg signed [17:0] B;
    reg signed [37:0] C;

    always @(posedge clk) begin
        A = $random;
        B = $random;

        C <= A * B;
    end

    // UUT
    wire signed [37:0] Z;

    dsp_t1_sim_cfg_ports uut (
        .a_i                (A),
        .b_i                (B),
        .unsigned_a_i       (1'h0),
        .unsigned_b_i       (1'h0),
        .feedback_i         (3'h0),
        .register_inputs_i  (1'h0),
        .output_select_i    (3'h0),
        .z_o                (Z)
    );

    // Error detection
    wire error = (Z !== C);

    // Error counting
    integer error_count;
    initial error_count <= 0;
    always @(posedge clk) begin
        if (error) error_count <= error_count + 1;
    end

    // Simulation control / data dump
    initial begin
        $dumpfile(`VCD_FILE);
        $dumpvars(0, tb);
        #10000 $finish_and_return( (error_count == 0) ? 0 : -1 );
    end

endmodule
module spram_18x1024_2x (   
    WEN0_i,
    REN0_i,
    clock0,
    WR_ADDR0_i,
    RD_ADDR0_i,
    WDATA0_i,
    RDATA0_o,
    
    WEN1_i,
    REN1_i,
    clock1,
    WR_ADDR1_i,
    RD_ADDR1_i,
    WDATA1_i,
    RDATA1_o
);

parameter WR_ADDR_WIDTH0 = 10;
parameter RD_ADDR_WIDTH0 = 10;
parameter WR_DATA_WIDTH0 = 18;
parameter RD_DATA_WIDTH0 = 18;
parameter BE_WIDTH0 = 2;

parameter WR_ADDR_WIDTH1 = 10;
parameter RD_ADDR_WIDTH1 = 10;
parameter WR_DATA_WIDTH1 = 18;
parameter RD_DATA_WIDTH1 = 18;
parameter BE_WIDTH1 = 2;

input wire WEN0_i;
input wire REN0_i;
input wire clock0;
input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR0_i;
input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR0_i;
input wire [WR_DATA_WIDTH0-1 :0] WDATA0_i;
output wire [RD_DATA_WIDTH0-1 :0] RDATA0_o;

input wire WEN1_i;
input wire REN1_i;
input wire clock1;
input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR1_i;
input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR1_i;
input wire [WR_DATA_WIDTH0-1 :0] WDATA1_i;
output wire [RD_DATA_WIDTH0-1 :0] RDATA1_o;


RAM_18K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH0),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH0),
              .WR_DATA_WIDTH(WR_DATA_WIDTH0),
              .RD_DATA_WIDTH(RD_DATA_WIDTH0),
              .BE_WIDTH(BE_WIDTH0)
              ) spram_x18_inst1 (
              
              .WEN_i(WEN0_i),
              .WR_BE_i(2'b11),
              .REN_i(REN0_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock0),
              .WR_ADDR_i(WR_ADDR0_i),
              .RD_ADDR_i(RD_ADDR0_i),
              .WDATA_i(WDATA0_i),
              .RDATA_o(RDATA0_o)
              );
              
RAM_18K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH1),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH1),
              .WR_DATA_WIDTH(WR_DATA_WIDTH1),
              .RD_DATA_WIDTH(RD_DATA_WIDTH1),
              .BE_WIDTH(BE_WIDTH1)
              ) spram_x18_inst2 (
              
              .WEN_i(WEN1_i),
              .WR_BE_i(2'b11),
              .REN_i(REN1_i),              
              .WR_CLK_i(clock1),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR1_i),
              .RD_ADDR_i(RD_ADDR1_i),
              .WDATA_i(WDATA1_i),
              .RDATA_o(RDATA1_o)
              );
              
endmodule
module spram_9x2048_x2 (
    WEN0_i,
    REN0_i,
    clock0,
    WR_ADDR0_i,
    RD_ADDR0_i,
    WDATA0_i,
    RDATA0_o,
    
    WEN1_i,
    REN1_i,
    clock1,
    WR_ADDR1_i,
    RD_ADDR1_i,
    WDATA1_i,
    RDATA1_o
);

parameter WR_ADDR_WIDTH0 = 11;
parameter RD_ADDR_WIDTH0 = 11;
parameter WR_DATA_WIDTH0 = 9;
parameter RD_DATA_WIDTH0 = 9;
parameter BE_WIDTH0 = 1;

parameter WR_ADDR_WIDTH1 = 11;
parameter RD_ADDR_WIDTH1 = 11;
parameter WR_DATA_WIDTH1 = 9;
parameter RD_DATA_WIDTH1 = 9;
parameter BE_WIDTH1 = 1;

input wire WEN0_i;
input wire REN0_i;
input wire clock0;
input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR0_i;
input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR0_i;
input wire [WR_DATA_WIDTH0-1 :0] WDATA0_i;
output wire [RD_DATA_WIDTH0-1 :0] RDATA0_o;

input wire WEN1_i;
input wire REN1_i;
input wire clock1;
input wire [WR_ADDR_WIDTH1-1 :0] WR_ADDR1_i;
input wire [RD_ADDR_WIDTH1-1 :0] RD_ADDR1_i;
input wire [WR_DATA_WIDTH1-1 :0] WDATA1_i;
output wire [RD_DATA_WIDTH1-1 :0] RDATA1_o;


RAM_18K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH0),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH0),
              .WR_DATA_WIDTH(WR_DATA_WIDTH0),
              .RD_DATA_WIDTH(RD_DATA_WIDTH0),
              .BE_WIDTH(BE_WIDTH0)
              ) spram_x18_inst1 (
              
              .WEN_i(WEN0_i),
              .WR_BE_i(2'b11),
              .REN_i(REN0_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock0),
              .WR_ADDR_i(WR_ADDR0_i),
              .RD_ADDR_i(RD_ADDR0_i),
              .WDATA_i(WDATA0_i),
              .RDATA_o(RDATA0_o)
              );
              
RAM_18K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH1),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH1),
              .WR_DATA_WIDTH(WR_DATA_WIDTH1),
              .RD_DATA_WIDTH(RD_DATA_WIDTH1),
              .BE_WIDTH(BE_WIDTH1)
              ) spram_x18_inst2 (
              
              .WEN_i(WEN1_i),
              .WR_BE_i(2'b11),
              .REN_i(REN1_i),              
              .WR_CLK_i(clock1),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR1_i),
              .RD_ADDR_i(RD_ADDR1_i),
              .WDATA_i(WDATA1_i),
              .RDATA_o(RDATA1_o)
              );
              
endmodule
module spram_9x2048_18x1024 (
    WEN0_i,
    REN0_i,
    clock0,
    WR_ADDR0_i,
    RD_ADDR0_i,
    WDATA0_i,
    RDATA0_o,
    
    WEN1_i,
    REN1_i,
    clock1,
    WR_ADDR1_i,
    RD_ADDR1_i,
    WDATA1_i,
    RDATA1_o
);

parameter WR_ADDR_WIDTH0 = 11;
parameter RD_ADDR_WIDTH0 = 11;
parameter WR_DATA_WIDTH0 = 9;
parameter RD_DATA_WIDTH0 = 9;
parameter BE_WIDTH0 = 1;

parameter WR_ADDR_WIDTH1 = 10;
parameter RD_ADDR_WIDTH1 = 10;
parameter WR_DATA_WIDTH1 = 18;
parameter RD_DATA_WIDTH1 = 18;
parameter BE_WIDTH1 = 2;

input wire WEN0_i;
input wire REN0_i;
input wire clock0;
input wire [WR_ADDR_WIDTH0-1 :0] WR_ADDR0_i;
input wire [RD_ADDR_WIDTH0-1 :0] RD_ADDR0_i;
input wire [WR_DATA_WIDTH0-1 :0] WDATA0_i;
output wire [RD_DATA_WIDTH0-1 :0] RDATA0_o;

input wire WEN1_i;
input wire REN1_i;
input wire clock1;
input wire [WR_ADDR_WIDTH1-1 :0] WR_ADDR1_i;
input wire [RD_ADDR_WIDTH1-1 :0] RD_ADDR1_i;
input wire [WR_DATA_WIDTH1-1 :0] WDATA1_i;
output wire [RD_DATA_WIDTH1-1 :0] RDATA1_o;


RAM_18K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH0),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH0),
              .WR_DATA_WIDTH(WR_DATA_WIDTH0),
              .RD_DATA_WIDTH(RD_DATA_WIDTH0),
              .BE_WIDTH(BE_WIDTH0)
              ) spram_x18_inst1 (
              
              .WEN_i(WEN0_i),
              .WR_BE_i(1'b1),
              .REN_i(REN0_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock0),
              .WR_ADDR_i(WR_ADDR0_i),
              .RD_ADDR_i(RD_ADDR0_i),
              .WDATA_i(WDATA0_i),
              .RDATA_o(RDATA0_o)
              );
              
RAM_18K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH1),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH1),
              .WR_DATA_WIDTH(WR_DATA_WIDTH1),
              .RD_DATA_WIDTH(RD_DATA_WIDTH1),
              .BE_WIDTH(BE_WIDTH1)
              ) spram_x18_inst2 (
              
              .WEN_i(WEN1_i),
              .WR_BE_i(2'b11),
              .REN_i(REN1_i),              
              .WR_CLK_i(clock1),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR1_i),
              .RD_ADDR_i(RD_ADDR1_i),
              .WDATA_i(WDATA1_i),
              .RDATA_o(RDATA1_o)
              );
              
endmodule
module af1024x18_1024x18 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 18;
parameter RD_DATA_WIDTH = 18;
parameter UPAE_DBITS = 11'd10;
parameter UPAF_DBITS = 11'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;

AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                  )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module af1024x16_1024x16 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 16;
parameter RD_DATA_WIDTH = 16;
parameter UPAE_DBITS = 11'd10;
parameter UPAF_DBITS = 11'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;

AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                  )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module af2048x9_2048x9 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 9;
parameter RD_DATA_WIDTH = 9;
parameter UPAE_DBITS = 11'd10;
parameter UPAF_DBITS = 11'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;

AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                  )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module af2048x8_2048x8 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 8;
parameter RD_DATA_WIDTH = 8;
parameter UPAE_DBITS = 11'd10;
parameter UPAF_DBITS = 11'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;

AFIFO_18K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                  )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module af4096x9_1024x36 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 9;
parameter RD_DATA_WIDTH = 36;
parameter UPAE_DBITS = 12'd10;
parameter UPAF_DBITS = 12'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;


AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                 )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module af2048x18_1024x36 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 18;
parameter RD_DATA_WIDTH = 36;
parameter UPAE_DBITS = 12'd10;
parameter UPAF_DBITS = 12'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;

AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                  )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module af2048x18_4098x9 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 18;
parameter RD_DATA_WIDTH = 9;
parameter UPAE_DBITS = 12'd10;
parameter UPAF_DBITS = 12'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;

AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                  )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module af1024x36_4098x9 (DIN,PUSH,POP,clock0,clock1,Async_Flush,Almost_Full,Almost_Empty,Full,Empty,Full_Watermark,Empty_Watermark,Overrun_Error,Underrun_Error,DOUT);

parameter WR_DATA_WIDTH = 36;
parameter RD_DATA_WIDTH = 9;
parameter UPAE_DBITS = 12'd10;
parameter UPAF_DBITS = 12'd10;

input clock0,clock1;
input PUSH,POP;
input [WR_DATA_WIDTH-1:0] DIN;
input Async_Flush;
output [RD_DATA_WIDTH-1:0] DOUT;
output Almost_Full,Almost_Empty;
output Full, Empty;
output Full_Watermark, Empty_Watermark;
output Overrun_Error, Underrun_Error;

AFIFO_36K_BLK  # (.WR_DATA_WIDTH(WR_DATA_WIDTH),.RD_DATA_WIDTH(RD_DATA_WIDTH),.UPAE_DBITS(UPAE_DBITS),.UPAF_DBITS(UPAF_DBITS)
                  )
  FIFO_INST    (
                .DIN(DIN),
                .PUSH(PUSH),
                .POP(POP),
                .Push_Clk(clock0),
                .Pop_Clk(clock1),
                .Async_Flush(Async_Flush),
                
                .Overrun_Error(Overrun_Error),
                .Full_Watermark(Full_Watermark),
                .Almost_Full(Almost_Full),
                .Full(Full),
                
                .Underrun_Error(Underrun_Error),
                .Empty_Watermark(Empty_Watermark),
                .Almost_Empty(Almost_Empty),
                .Empty(Empty),

                .DOUT(DOUT)
                );
endmodule
module tb();

    // Clock
    reg clk;
    initial clk <= 1'b0;
    always #0.5 clk <= ~clk;

    // Reset
    reg rst;
    initial begin
            rst <= 1'b0;
        #1  rst <= 1'b1;
        #2  rst <= 1'b0;
    end

    // Input data / reference
    reg signed [19:0] A;
    reg signed [17:0] B;
    reg signed [37:0] C;

    // Shift data change half a clock cycle
    // to make registered inputs apparent
    initial begin
        forever begin
            A = $random;
            B = $random;

            C <= A * B;
        #1.5;
        end
    end

    // UUT
    wire signed [37:0] Z;

    dsp_t1_sim_cfg_ports uut (
        .a_i                (A),
        .b_i                (B),
        .unsigned_a_i       (1'h0),
        .unsigned_b_i       (1'h0),
        .feedback_i         (3'h0),
        .register_inputs_i  (1'h1),
        .output_select_i    (3'h0),
        .clock_i            (clk),
        .z_o                (Z)
    );

    // Error detection
    reg [37:0] r_C;
    initial r_C <= 0;
    always @(posedge clk)
        r_C <= C;

    wire error = (Z !== r_C);

    // Error counting
    integer error_count;
    initial error_count <= 0;
    always @(posedge clk) begin
        if (error) error_count <= error_count + 1;
    end

    // Simulation control / data dump
    initial begin
        $dumpfile(`VCD_FILE);
        $dumpvars(0, tb);
        #100 $finish_and_return( (error_count == 0) ? 0 : -1 );
    end

endmodule
module spram_36x1024 (
    WEN_i,
    REN_i,
    clock0,
    clock1,
    WR_ADDR_i,
    RD_ADDR_i,
    WDATA_i,
    RDATA_o
);

parameter WR_ADDR_WIDTH = 10;
parameter RD_ADDR_WIDTH = 10;
parameter WR_DATA_WIDTH = 36;
parameter RD_DATA_WIDTH = 36;
parameter BE_WIDTH = 4;

input wire WEN_i;
input wire REN_i;
input wire clock0;
input wire clock1;
input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
output wire [RD_DATA_WIDTH-1 :0] RDATA_o;

RAM_36K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
              .WR_DATA_WIDTH(WR_DATA_WIDTH),
              .RD_DATA_WIDTH(RD_DATA_WIDTH),
              .BE_WIDTH(BE_WIDTH)
              ) spram_x36_inst (
              
              .WEN_i(WEN_i),
              .WR_BE_i(4'b1111),
              .REN_i(REN_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR_i),
              .RD_ADDR_i(RD_ADDR_i),
              .WDATA_i(WDATA_i),
              .RDATA_o(RDATA_o)
              );
              
endmodule
module spram_32x1024 (
    WEN_i,
    REN_i,
    clock0,
    clock1,
    WR_ADDR_i,
    RD_ADDR_i,
    WDATA_i,
    RDATA_o
);

parameter WR_ADDR_WIDTH = 10;
parameter RD_ADDR_WIDTH = 10;
parameter WR_DATA_WIDTH = 32;
parameter RD_DATA_WIDTH = 32;
parameter BE_WIDTH = 4;

input wire WEN_i;
input wire REN_i;
input wire clock0;
input wire clock1;
input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
output wire [RD_DATA_WIDTH-1 :0] RDATA_o;

RAM_36K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
              .WR_DATA_WIDTH(WR_DATA_WIDTH),
              .RD_DATA_WIDTH(RD_DATA_WIDTH),
              .BE_WIDTH(BE_WIDTH)
              ) spram_x36_inst (
              
              .WEN_i(WEN_i),
              .WR_BE_i(4'b1111),
              .REN_i(REN_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR_i),
              .RD_ADDR_i(RD_ADDR_i),
              .WDATA_i(WDATA_i),
              .RDATA_o(RDATA_o)
              );
              
endmodule
module spram_18x2048 (
    WEN_i,
    REN_i,
    clock0,
    clock1,
    WR_ADDR_i,
    RD_ADDR_i,
    WDATA_i,
    RDATA_o
);

parameter WR_ADDR_WIDTH = 11;
parameter RD_ADDR_WIDTH = 11;
parameter WR_DATA_WIDTH = 18;
parameter RD_DATA_WIDTH = 18;
parameter BE_WIDTH = 2;

input wire WEN_i;
input wire REN_i;
input wire clock0;
input wire clock1;
input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
output wire [RD_DATA_WIDTH-1 :0] RDATA_o;

RAM_36K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
              .WR_DATA_WIDTH(WR_DATA_WIDTH),
              .RD_DATA_WIDTH(RD_DATA_WIDTH),
              .BE_WIDTH(BE_WIDTH)
              ) spram_x36_inst (
              
              .WEN_i(WEN_i),
              .WR_BE_i(2'b11),
              .REN_i(REN_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR_i),
              .RD_ADDR_i(RD_ADDR_i),
              .WDATA_i(WDATA_i),
              .RDATA_o(RDATA_o)
              );
              
endmodule
module spram_16x2048 (
    WEN_i,
    REN_i,
    clock0,
    clock1,
    WR_ADDR_i,
    RD_ADDR_i,
    WDATA_i,
    RDATA_o
);

parameter WR_ADDR_WIDTH = 11;
parameter RD_ADDR_WIDTH = 11;
parameter WR_DATA_WIDTH = 16;
parameter RD_DATA_WIDTH = 16;
parameter BE_WIDTH = 2;

input wire WEN_i;
input wire REN_i;
input wire clock0;
input wire clock1;
input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
output wire [RD_DATA_WIDTH-1 :0] RDATA_o;

RAM_36K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
              .WR_DATA_WIDTH(WR_DATA_WIDTH),
              .RD_DATA_WIDTH(RD_DATA_WIDTH),
              .BE_WIDTH(BE_WIDTH)
              ) spram_x36_inst (
              
              .WEN_i(WEN_i),
              .WR_BE_i(2'b11),
              .REN_i(REN_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR_i),
              .RD_ADDR_i(RD_ADDR_i),
              .WDATA_i(WDATA_i),
              .RDATA_o(RDATA_o)
              );
              
endmodule
module spram_9x4096 (
    WEN_i,
    REN_i,
    clock0,
    clock1,
    WR_ADDR_i,
    RD_ADDR_i,
    WDATA_i,
    RDATA_o
);

parameter WR_ADDR_WIDTH = 12;
parameter RD_ADDR_WIDTH = 12;
parameter WR_DATA_WIDTH = 9;
parameter RD_DATA_WIDTH = 9;
parameter BE_WIDTH = 1;

input wire WEN_i;
input wire REN_i;
input wire clock0;
input wire clock1;
input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
output wire [RD_DATA_WIDTH-1 :0] RDATA_o;

RAM_36K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
              .WR_DATA_WIDTH(WR_DATA_WIDTH),
              .RD_DATA_WIDTH(RD_DATA_WIDTH),
              .BE_WIDTH(BE_WIDTH)
              ) spram_x36_inst (
              
              .WEN_i(WEN_i),
              .WR_BE_i(1'b1),
              .REN_i(REN_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR_i),
              .RD_ADDR_i(RD_ADDR_i),
              .WDATA_i(WDATA_i),
              .RDATA_o(RDATA_o)
              );
              
endmodule
module spram_8x4096 (
    WEN_i,
    REN_i,
    clock0,
    clock1,
    WR_ADDR_i,
    RD_ADDR_i,
    WDATA_i,
    RDATA_o
);

parameter WR_ADDR_WIDTH = 12;
parameter RD_ADDR_WIDTH = 12;
parameter WR_DATA_WIDTH = 8;
parameter RD_DATA_WIDTH = 8;
parameter BE_WIDTH = 1;

input wire WEN_i;
input wire REN_i;
input wire clock0;
input wire clock1;
input wire [WR_ADDR_WIDTH-1 :0] WR_ADDR_i;
input wire [RD_ADDR_WIDTH-1 :0] RD_ADDR_i;
input wire [WR_DATA_WIDTH-1 :0] WDATA_i;
output wire [RD_DATA_WIDTH-1 :0] RDATA_o;

RAM_36K_BLK #(
              .WR_ADDR_WIDTH(WR_ADDR_WIDTH),
              .RD_ADDR_WIDTH(RD_ADDR_WIDTH),
              .WR_DATA_WIDTH(WR_DATA_WIDTH),
              .RD_DATA_WIDTH(RD_DATA_WIDTH),
              .BE_WIDTH(BE_WIDTH)
              ) spram_x36_inst (
              
              .WEN_i(WEN_i),
              .WR_BE_i(1'b1),
              .REN_i(REN_i),              
              .WR_CLK_i(clock0),
              .RD_CLK_i(clock1),
              .WR_ADDR_i(WR_ADDR_i),
              .RD_ADDR_i(RD_ADDR_i),
              .WDATA_i(WDATA_i),
              .RDATA_o(RDATA_o)
              );
              
endmodule
module BRAM_TDP_SPLIT #(parameter AWIDTH = 9,
parameter DWIDTH = 32)(
	clk_a,
	rce_a,
	ra_a,
	rq_a,
	wce_a,
	wa_a,
	wd_a,

	clk_b,
	rce_b,
	ra_b,
	rq_b,
	wce_b,
	wa_b,
	wd_b
);

	input			clk_a;
	input                   rce_a;
	input      [AWIDTH-1:0] ra_a;
	output reg [DWIDTH-1:0] rq_a;
	input                   wce_a;
	input      [AWIDTH-1:0] wa_a;
	input      [DWIDTH-1:0] wd_a;

	input			clk_b;
	input                   rce_b;
	input      [AWIDTH-1:0] ra_b;
	output reg [DWIDTH-1:0] rq_b;
	input                   wce_b;
	input      [AWIDTH-1:0] wa_b;
	input      [DWIDTH-1:0] wd_b;

	reg        [DWIDTH-1:0] memory[0:(1<<AWIDTH)-1];

	always @(posedge clk_a) begin
		if (rce_a)
			rq_a <= memory[ra_a];

		if (wce_a)
			memory[wa_a] <= wd_a;
	end

	always @(posedge clk_b) begin
		if (rce_b)
			rq_b <= memory[ra_b];

		if (wce_b)
			memory[wa_b] <= wd_b;
	end

	integer i;
	initial
	begin
		for(i = 0; i < (1<<AWIDTH)-1; i = i + 1)
			memory[i] = 0;
	end

endmodule
module BRAM_TDP_SPLIT_2x18K #(parameter AWIDTH = 10, parameter DWIDTH = 18)(
	clk_a_0,
	rce_a_0,
	ra_a_0,
	rq_a_0,
	wce_a_0,
	wa_a_0,
	wd_a_0,

	clk_a_1,
	rce_a_1,
	ra_a_1,
	rq_a_1,
	wce_a_1,
	wa_a_1,
	wd_a_1,

	clk_b_0,
	rce_b_0,
	ra_b_0,
	rq_b_0,
	wce_b_0,
	wa_b_0,
	wd_b_0,

	clk_b_1,
	rce_b_1,
	ra_b_1,
	rq_b_1,
	wce_b_1,
	wa_b_1,
	wd_b_1
);

	input			clk_a_0;
	input                   rce_a_0;
	input      [AWIDTH-1:0] ra_a_0;
	output     [DWIDTH-1:0] rq_a_0;
	input                   wce_a_0;
	input      [AWIDTH-1:0] wa_a_0;
	input      [DWIDTH-1:0] wd_a_0;
	input			clk_b_0;
	input                   rce_b_0;
	input      [AWIDTH-1:0] ra_b_0;
	output     [DWIDTH-1:0] rq_b_0;
	input                   wce_b_0;
	input      [AWIDTH-1:0] wa_b_0;
	input      [DWIDTH-1:0] wd_b_0;

	input			clk_a_1;
	input                   rce_a_1;
	input      [AWIDTH-1:0] ra_a_1;
	output     [DWIDTH-1:0] rq_a_1;
	input                   wce_a_1;
	input      [AWIDTH-1:0] wa_a_1;
	input      [DWIDTH-1:0] wd_a_1;
	input			clk_b_1;
	input                   rce_b_1;
	input      [AWIDTH-1:0] ra_b_1;
	output     [DWIDTH-1:0] rq_b_1;
	input                   wce_b_1;
	input      [AWIDTH-1:0] wa_b_1;
	input      [DWIDTH-1:0] wd_b_1;

BRAM_TDP_SPLIT #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
	BRAM_TDP_SPLIT_0 (.clk_a(clk_a_0),
		 .rce_a(rce_a_0),
		 .ra_a(ra_a_0),
		 .rq_a(rq_a_0),
		 .wce_a(wce_a_0),
		 .wa_a(wa_a_0),
		 .wd_a(wd_a_0),
		 .clk_b(clk_b_0),
		 .rce_b(rce_b_0),
		 .ra_b(ra_b_0),
		 .rq_b(rq_b_0),
		 .wce_b(wce_b_0),
		 .wa_b(wa_b_0),
		 .wd_b(wd_b_0));

BRAM_TDP_SPLIT #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
	BRAM_TDP_SPLIT_1 (.clk_a(clk_a_1),
		 .rce_a(rce_a_1),
		 .ra_a(ra_a_1),
		 .rq_a(rq_a_1),
		 .wce_a(wce_a_1),
		 .wa_a(wa_a_1),
		 .wd_a(wd_a_1),
		 .clk_b(clk_b_1),
		 .rce_b(rce_b_1),
		 .ra_b(ra_b_1),
		 .rq_b(rq_b_1),
		 .wce_b(wce_b_1),
		 .wa_b(wa_b_1),
		 .wd_b(wd_b_1));
endmodule
module BRAM_TDP_SPLIT_2x18x1024 (
	clk_a_0,
	rce_a_0,
	ra_a_0,
	rq_a_0,
	wce_a_0,
	wa_a_0,
	wd_a_0,

	clk_a_1,
	rce_a_1,
	ra_a_1,
	rq_a_1,
	wce_a_1,
	wa_a_1,
	wd_a_1,

	clk_b_0,
	rce_b_0,
	ra_b_0,
	rq_b_0,
	wce_b_0,
	wa_b_0,
	wd_b_0,

	clk_b_1,
	rce_b_1,
	ra_b_1,
	rq_b_1,
	wce_b_1,
	wa_b_1,
	wd_b_1
);

parameter AWIDTH = 10;
parameter DWIDTH = 18;

	input			clk_a_0;
	input                   rce_a_0;
	input      [AWIDTH-1:0] ra_a_0;
	output     [DWIDTH-1:0] rq_a_0;
	input                   wce_a_0;
	input      [AWIDTH-1:0] wa_a_0;
	input      [DWIDTH-1:0] wd_a_0;
	input			clk_b_0;
	input                   rce_b_0;
	input      [AWIDTH-1:0] ra_b_0;
	output     [DWIDTH-1:0] rq_b_0;
	input                   wce_b_0;
	input      [AWIDTH-1:0] wa_b_0;
	input      [DWIDTH-1:0] wd_b_0;

	input			clk_a_1;
	input                   rce_a_1;
	input      [AWIDTH-1:0] ra_a_1;
	output     [DWIDTH-1:0] rq_a_1;
	input                   wce_a_1;
	input      [AWIDTH-1:0] wa_a_1;
	input      [DWIDTH-1:0] wd_a_1;
	input			clk_b_1;
	input                   rce_b_1;
	input      [AWIDTH-1:0] ra_b_1;
	output     [DWIDTH-1:0] rq_b_1;
	input                   wce_b_1;
	input      [AWIDTH-1:0] wa_b_1;
	input      [DWIDTH-1:0] wd_b_1;

BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
	BRAM_TDP_SPLIT_2x18x1024 (
		 .clk_a_0(clk_a_0),
		 .rce_a_0(rce_a_0),
		 .ra_a_0(ra_a_0),
		 .rq_a_0(rq_a_0),
		 .wce_a_0(wce_a_0),
		 .wa_a_0(wa_a_0),
		 .wd_a_0(wd_a_0),
		 .clk_b_0(clk_b_0),
		 .rce_b_0(rce_b_0),
		 .ra_b_0(ra_b_0),
		 .rq_b_0(rq_b_0),
		 .wce_b_0(wce_b_0),
		 .wa_b_0(wa_b_0),
		 .wd_b_0(wd_b_0),
		 .clk_a_1(clk_a_1),
		 .rce_a_1(rce_a_1),
		 .ra_a_1(ra_a_1),
		 .rq_a_1(rq_a_1),
		 .wce_a_1(wce_a_1),
		 .wa_a_1(wa_a_1),
		 .wd_a_1(wd_a_1),
		 .clk_b_1(clk_b_1),
		 .rce_b_1(rce_b_1),
		 .ra_b_1(ra_b_1),
		 .rq_b_1(rq_b_1),
		 .wce_b_1(wce_b_1),
		 .wa_b_1(wa_b_1),
		 .wd_b_1(wd_b_1));
endmodule
module BRAM_TDP_SPLIT_2x16x1024 (
	clk_a_0,
	rce_a_0,
	ra_a_0,
	rq_a_0,
	wce_a_0,
	wa_a_0,
	wd_a_0,

	clk_a_1,
	rce_a_1,
	ra_a_1,
	rq_a_1,
	wce_a_1,
	wa_a_1,
	wd_a_1,

	clk_b_0,
	rce_b_0,
	ra_b_0,
	rq_b_0,
	wce_b_0,
	wa_b_0,
	wd_b_0,

	clk_b_1,
	rce_b_1,
	ra_b_1,
	rq_b_1,
	wce_b_1,
	wa_b_1,
	wd_b_1
);

parameter AWIDTH = 10;
parameter DWIDTH = 16;

	input			clk_a_0;
	input                   rce_a_0;
	input      [AWIDTH-1:0] ra_a_0;
	output     [DWIDTH-1:0] rq_a_0;
	input                   wce_a_0;
	input      [AWIDTH-1:0] wa_a_0;
	input      [DWIDTH-1:0] wd_a_0;
	input			clk_b_0;
	input                   rce_b_0;
	input      [AWIDTH-1:0] ra_b_0;
	output     [DWIDTH-1:0] rq_b_0;
	input                   wce_b_0;
	input      [AWIDTH-1:0] wa_b_0;
	input      [DWIDTH-1:0] wd_b_0;

	input			clk_a_1;
	input                   rce_a_1;
	input      [AWIDTH-1:0] ra_a_1;
	output     [DWIDTH-1:0] rq_a_1;
	input                   wce_a_1;
	input      [AWIDTH-1:0] wa_a_1;
	input      [DWIDTH-1:0] wd_a_1;
	input			clk_b_1;
	input                   rce_b_1;
	input      [AWIDTH-1:0] ra_b_1;
	output     [DWIDTH-1:0] rq_b_1;
	input                   wce_b_1;
	input      [AWIDTH-1:0] wa_b_1;
	input      [DWIDTH-1:0] wd_b_1;

BRAM_TDP_SPLIT_2x18K #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
	BRAM_TDP_SPLIT_2x16x1024 (
		 .clk_a_0(clk_a_0),
		 .rce_a_0(rce_a_0),
		 .ra_a_0(ra_a_0),
		 .rq_a_0(rq_a_0),
		 .wce_a_0(wce_a_0),
		 .wa_a_0(wa_a_0),
		 .wd_a_0(wd_a_0),
		 .clk_b_0(clk_b_0),
		 .rce_b_0(rce_b_0),
		 .ra_b_0(ra_b_0),
		 .rq_b_0(rq_b_0),
		 .wce_b_0(wce_b_0),
		 .wa_b_0(wa_b_0),
		 .wd_b_0(wd_b_0),
		 .clk_a_1(clk_a_1),
		 .rce_a_1(rce_a_1),
		 .ra_a_1(ra_a_1),
		 .rq_a_1(rq_a_1),
		 .wce_a_1(wce_a_1),
		 .wa_a_1(wa_a_1),
		 .wd_a_1(wd_a_1),
		 .clk_b_1(clk_b_1),
		 .rce_b_1(rce_b_1),
		 .ra_b_1(ra_b_1),
		 .rq_b_1(rq_b_1),
		 .wce_b_1(wce_b_1),
		 .wa_b_1(wa_b_1),
		 .wd_b_1(wd_b_1));
endmodule