dakies/OSS_Verilog huggingface dataset:
module RAM64M
#(
    parameter  [63:0] INIT_A           = 64'h0,
    parameter  [63:0] INIT_B           = 64'h0,
    parameter  [63:0] INIT_C           = 64'h0,
    parameter  [63:0] INIT_D           = 64'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Port A
    input  wire [5:0] ADDRA,
    input  wire       DIA,
    output wire       DOA,
    // Port B
    input  wire [5:0] ADDRB,
    input  wire       DIB,
    output wire       DOB,
    // Port C
    input  wire [5:0] ADDRC,
    input  wire       DIC,
    output wire       DOC,
    // Port D
    input  wire [5:0] ADDRD,
    input  wire       DID,
    output wire       DOD
);
    // 64 x 4-bit Select RAM
    reg  [63:0] _r_mem_a;
    reg  [63:0] _r_mem_b;
    reg  [63:0] _r_mem_c;
    reg  [63:0] _r_mem_d;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem_a = INIT_A;
        _r_mem_b = INIT_B;
        _r_mem_c = INIT_C;
        _r_mem_d = INIT_D;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem_a[ADDRD] <= DIA;
                    _r_mem_b[ADDRD] <= DIB;
                    _r_mem_c[ADDRD] <= DIC;
                    _r_mem_d[ADDRD] <= DID;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem_a[ADDRD] <= DIA;
                    _r_mem_b[ADDRD] <= DIB;
                    _r_mem_c[ADDRD] <= DIC;
                    _r_mem_d[ADDRD] <= DID;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign DOA = _r_mem_a[ADDRA];
    assign DOB = _r_mem_b[ADDRB];
    assign DOC = _r_mem_c[ADDRC];
    assign DOD = _r_mem_d[ADDRD];

endmodule
module LUT1
#(
    parameter [1:0] INIT = 2'b00
)
(
    input  wire I0,
    output wire O
);
    assign O = INIT[I0];

endmodule
module RAM32X1D
#(
    parameter  [31:0] INIT = 32'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire       A0,
    input  wire       A1,
    input  wire       A2,
    input  wire       A3,
    input  wire       A4,
    // Read address
    input  wire       DPRA0,
    input  wire       DPRA1,
    input  wire       DPRA2,
    input  wire       DPRA3,
    input  wire       DPRA4,
    // Data in
    input  wire       D,
    // Data out
    output wire       SPO,
    output wire       DPO
);
    // Read / Write address
    wire  [4:0] _w_A    = { A4, A3, A2, A1, A0 };
    // Read address
    wire  [4:0] _w_DPRA = { DPRA4, DPRA3, DPRA2, DPRA1, DPRA0 };
    // 32 x 1-bit Select RAM
    reg  [31:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign SPO = _r_mem[_w_A];
    assign DPO = _r_mem[_w_DPRA];

endmodule
module BUFG
(
    input  I,
    output O /* verilator clocker */
);

    assign O = I;

endmodule
module RAM128X1D
#(
    parameter [127:0] INIT = 128'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire [6:0] A,
    // Read address
    input  wire [6:0] DPRA,
    // Data in
    input  wire       D,
    // Data out
    output wire       SPO,
    output wire       DPO
);
    // 128 x 1-bit Select RAM
    reg  [127:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign SPO = _r_mem[A];
    assign DPO = _r_mem[DPRA];

endmodule
module LUT4
#(
    parameter [15:0] INIT = 16'h0000
)
(
    input  wire I0, I1, I2, I3,
    output wire O
);
    wire [3:0] _w_idx = { I3, I2, I1, I0 };
    
    assign O = INIT[_w_idx];

endmodule
module LUT6
#(
    parameter [63:0] INIT = 64'h0000000000000000
)
(
    input  wire I0, I1, I2, I3, I4, I5,
    output wire O
);
    wire [5:0] _w_idx = { I5, I4, I3, I2, I1, I0 };
    
    assign O = INIT[_w_idx];

endmodule
module MUXF9
(
    input  wire I0, I1,
    input  wire S,
    output wire O
);

    assign O = (S) ? I1 : I0;

endmodule
module RAM512X1S
#(
    parameter [511:0] INIT = 512'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire [8:0] A,
    // Data in
    input  wire       D,
    // Data out
    output wire       O
);
    // 512 x 1-bit Select RAM
    reg  [511:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign O = _r_mem[A];

endmodule
module LUT6_2
#(
    parameter [63:0] INIT = 64'h0000000000000000
)
(
    input  wire I0, I1, I2, I3, I4, I5,
    output wire O5,
    output wire O6
);
    wire [5:0] _w_idx_5 = { 1'b0, I4, I3, I2, I1, I0 };
    wire [5:0] _w_idx_6 = {   I5, I4, I3, I2, I1, I0 };
    
    assign O5 = INIT[_w_idx_5];
    assign O6 = INIT[_w_idx_6];

endmodule
module RAM64X1S
#(
    parameter  [63:0] INIT = 64'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire       A0,
    input  wire       A1,
    input  wire       A2,
    input  wire       A3,
    input  wire       A4,
    input  wire       A5,
    // Data in
    input  wire       D,
    // Data out
    output wire       O
);
    // Read / Write address
    wire  [5:0] _w_A = { A5, A4, A3, A2, A1, A0 };
    // 64 x 1-bit Select RAM
    reg  [63:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign O = _r_mem[_w_A];

endmodule
module RAM256X1S
#(
    parameter [255:0] INIT = 256'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire [7:0] A,
    // Data in
    input  wire       D,
    // Data out
    output wire       O
);
    // 256 x 1-bit Select RAM
    reg  [255:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign O = _r_mem[A];

endmodule
module GND
(
    output wire G
);

    assign G = 1'b0;

endmodule
module MUXF8_L
(
    input  wire I0, I1,
    input  wire S,
    output wire LO
);

    assign LO = (S) ? I1 : I0;

endmodule
module RAM64X1D
#(
    parameter  [63:0] INIT = 64'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire       A0,
    input  wire       A1,
    input  wire       A2,
    input  wire       A3,
    input  wire       A4,
    input  wire       A5,
    // Read address
    input  wire       DPRA0,
    input  wire       DPRA1,
    input  wire       DPRA2,
    input  wire       DPRA3,
    input  wire       DPRA4,
    input  wire       DPRA5,
    // Data in
    input  wire       D,
    // Data out
    output wire       SPO,
    output wire       DPO
);
    // Read / Write address
    wire  [5:0] _w_A    = { A5, A4, A3, A2, A1, A0 };
    // Read address
    wire  [5:0] _w_DPRA = { DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0 };
    // 64 x 1-bit Select RAM
    reg  [63:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign SPO = _r_mem[_w_A];
    assign DPO = _r_mem[_w_DPRA];

endmodule
module ODDRE1
#(
    parameter [0:0] IS_C_INVERTED  = 1'b0,
    parameter [0:0] IS_D1_INVERTED = 1'b0,
    parameter [0:0] IS_D2_INVERTED = 1'b0,
    parameter       SIM_DEVICE     = "ULTRASCALE",
    parameter [0:0] SRVAL          = 1'b0
)
(
    input  C,
    input  D1,
    input  D2,
    input  SR,
    output Q
);
  
    wire       w_CLK = C  ^ IS_C_INVERTED;
    wire       w_D1  = D1 ^ IS_D1_INVERTED;
    wire       w_D2  = D2 ^ IS_D2_INVERTED;
    wire       w_SR;
    
    reg  [2:0] r_SR_cdc;
    
    reg        r_Q_p;
    reg        r_D2_p;
    reg        r_Q_n;

generate
    /* verilator lint_off WIDTH */
    if ((SIM_DEVICE == "EVEREST") || (SIM_DEVICE == "EVEREST_ES1") || (SIM_DEVICE == "EVEREST_ES2")) begin
    /* verilator lint_on WIDTH */
    
        assign w_SR = SR;
        
    end
    else begin

        always @(posedge w_CLK) begin
        
            r_SR_cdc <= { r_SR_cdc[1:0], SR };
        end
    
        assign w_SR = |{ SR, r_SR_cdc };
        
    end
endgenerate

    always @(posedge w_CLK) begin
    
        if (w_SR) begin
            r_Q_p  <= SRVAL ^ r_Q_n;
            r_D2_p <= SRVAL;
        end
        else begin
            r_Q_p  <= w_D1 ^ r_Q_n;
            r_D2_p <= w_D2;
        end
    end
    
    always @(negedge w_CLK) begin
    
        if (w_SR) begin
            r_Q_n <= SRVAL ^ r_Q_p;
        end
        else begin
            r_Q_n <= r_D2_p ^ r_Q_p;
        end
    end
    
    assign Q = r_Q_p ^ r_Q_n;
 
endmodule
module LUT5_L
#(
    parameter [31:0] INIT = 32'h00000000
)
(
    input  wire I0, I1, I2, I3, I4,
    output wire LO
);
    wire [4:0] _w_idx = { I4, I3, I2, I1, I0 };
    
    assign LO = INIT[_w_idx];

endmodule
module LDCE
#(
    parameter INIT = 1'b0
)
(
    // Asynchronous clear
    input  wire CLR,
    // Latch
    input  wire G,
    // Latch enable
    input  wire GE,
    // Data in
    input  wire D,
    // Data out
    output wire Q
);
    reg _r_Q;

    initial begin : INIT_STATE
        _r_Q = INIT[0];
    end
    
    always @(CLR or G or GE or D) begin : LATCH
    
        if (CLR) begin
            _r_Q = 1'b0;
        end
        else if (G & GE) begin
            _r_Q = D;
        end
    end
    
    assign Q = _r_Q;

endmodule
module RAM32M
#(
    parameter  [63:0] INIT_A           = 64'h0,
    parameter  [63:0] INIT_B           = 64'h0,
    parameter  [63:0] INIT_C           = 64'h0,
    parameter  [63:0] INIT_D           = 64'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Port A
    input  wire [4:0] ADDRA,
    input  wire [1:0] DIA,
    output wire [1:0] DOA,
    // Port B
    input  wire [4:0] ADDRB,
    input  wire [1:0] DIB,
    output wire [1:0] DOB,
    // Port C
    input  wire [4:0] ADDRC,
    input  wire [1:0] DIC,
    output wire [1:0] DOC,
    // Port D
    input  wire [4:0] ADDRD,
    input  wire [1:0] DID,
    output wire [1:0] DOD
);
    // 64 x 4-bit Select RAM
    reg [63:0] _r_mem_a;
    reg [63:0] _r_mem_b;
    reg [63:0] _r_mem_c;
    reg [63:0] _r_mem_d;

    // Power-up value
    initial begin : INIT_STATE
        _r_mem_a = INIT_A;
        _r_mem_b = INIT_B;
        _r_mem_c = INIT_C;
        _r_mem_d = INIT_D;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem_a[{ ADDRD, 1'b0 } +: 2] <= DIA;
                    _r_mem_b[{ ADDRD, 1'b0 } +: 2] <= DIB;
                    _r_mem_c[{ ADDRD, 1'b0 } +: 2] <= DIC;
                    _r_mem_d[{ ADDRD, 1'b0 } +: 2] <= DID;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem_a[{ ADDRD, 1'b0 } +: 2] <= DIA;
                    _r_mem_b[{ ADDRD, 1'b0 } +: 2] <= DIB;
                    _r_mem_c[{ ADDRD, 1'b0 } +: 2] <= DIC;
                    _r_mem_d[{ ADDRD, 1'b0 } +: 2] <= DID;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign DOA = _r_mem_a[{ ADDRA, 1'b0 } +: 2];
    assign DOB = _r_mem_b[{ ADDRB, 1'b0 } +: 2];
    assign DOC = _r_mem_c[{ ADDRC, 1'b0 } +: 2];
    assign DOD = _r_mem_d[{ ADDRD, 1'b0 } +: 2];
    
endmodule
module RAM256X1D
#(
    parameter [255:0] INIT = 256'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire [7:0] A,
    // Read address
    input  wire [7:0] DPRA,
    // Data in
    input  wire       D,
    // Data out
    output wire       SPO,
    output wire       DPO
);
    // 256 x 1-bit Select RAM
    reg  [255:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign SPO = _r_mem[A];
    assign DPO = _r_mem[DPRA];

endmodule
module LDPE
#(
    parameter INIT = 1'b0
)
(
    // Asynchronous preset
    input   wire PRE,
    // Latch
    input   wire G,
    // Latch enable
    input   wire GE,
    // Data in
    input   wire D,
    // Data out
    output  wire Q
);
    reg _r_Q;

    initial begin : INIT_STATE
        _r_Q = INIT[0];
    end
    
    always @(PRE or G or GE or D) begin : LATCH
    
        if (PRE) begin
            _r_Q = 1'b1;
        end
        else if (G & GE) begin
            _r_Q = D;
        end
    end
    
    assign Q = _r_Q;

endmodule
module BUFGCE_DIV
#(
    parameter integer BUFGCE_DIVIDE   = 1,
    parameter         CE_TYPE         = "SYNC",
    parameter         HARDSYNC_CLR    = "FALSE",
    parameter   [0:0] IS_CE_INVERTED  = 1'b0,
    parameter   [0:0] IS_CLR_INVERTED = 1'b0,
    parameter   [0:0] IS_I_INVERTED   = 1'b0
)
(
    input      I,
    input      CE,
    input      CLR,
    output reg O /* verilator clocker */
);

    wire       w_CLK = I ^ IS_I_INVERTED;
    wire       w_CE;
    wire       w_CLR;
    wire [2:0] w_DIV = BUFGCE_DIVIDE[2:0] - 3'd1;

    reg  [2:0] r_CE_cdc;
    reg  [2:0] r_CLR_cdc;
    reg  [2:0] r_clk_div;
  
    initial begin
        r_CE_cdc  = 3'b000;
        r_CLR_cdc = 3'b000;
        r_clk_div = 3'd0;
    end

    always @(negedge w_CLK) begin
    
        if (HARDSYNC_CLR == "FALSE") begin
            r_CLR_cdc <= 3'b0;
        end
        else begin
            r_CLR_cdc <= {r_CLR_cdc[1:0], CLR ^ IS_CLR_INVERTED };
        end
    end

    assign w_CLR = (HARDSYNC_CLR == "FALSE") ? CLR ^ IS_CLR_INVERTED
                 : (HARDSYNC_CLR == "TRUE") ? r_CLR_cdc[2]
                 : 1'b0;

    always @(posedge w_CLR or negedge w_CLK) begin
    
        if (w_CLR) begin
            r_CE_cdc <= 3'b000;
        end
        else begin
            r_CE_cdc <= { r_CE_cdc[1:0], CE ^ IS_CE_INVERTED };
        end
    end

    assign w_CE = (CE_TYPE == "SYNC") ? r_CE_cdc[0]
                : (CE_TYPE == "HARDSYNC") ? r_CE_cdc[2]
                : 1'b0;

    always @(posedge I) begin
    
        if (w_CLR) begin
            r_clk_div <= (w_DIV[2:1] == 2'b10) ? 3'd1 : 3'd0;
        end
        else if (w_CE | O) begin
            if (w_DIV[2:1] == 2'b10) begin
                r_clk_div <= (r_clk_div == (w_DIV + 3'd1)) ? 3'd1 : r_clk_div + 3'd1;
            end
            else begin
                r_clk_div <= (r_clk_div == w_DIV) ? 3'd0 : r_clk_div + 3'd1;
            end
        end
    end
    
    always @(*) begin
    
        casez (w_DIV)
            3'b000 : O = I & w_CE;
            3'b001 : O = r_clk_div[0];
            3'b01? : O = r_clk_div[1];
            3'b1?? : O = r_clk_div[2];
        endcase
    end

endmodule
module MUXF7_D
(
    input  wire I0, I1,
    input  wire S,
    output wire LO,
    output wire O
);

    assign LO = (S) ? I1 : I0;
    assign O  = (S) ? I1 : I0;

endmodule
module IBUFDS_GTE3
#(
    parameter [0:0] REFCLK_EN_TX_PATH  = 1'b0,
    parameter [1:0] REFCLK_HROW_CK_SEL = 2'b00,
    parameter [1:0] REFCLK_ICNTL_RX    = 2'b00
)
(
    // Clock input
    input      I,
    input      IB,
    // Clock enable
    input      CEB,
    // Clock outputs
    output     O /* verilator clocker */,
    output reg ODIV2 /* verilator clocker */
);

    reg r_IDIV2;
    
    initial begin
        r_IDIV2 = 1'b0;
    end
    
    always @ (posedge I) begin
        r_IDIV2 <= (CEB) ? 1'b0 : ~r_IDIV2;
    end
    
    always @(*) begin
        case (REFCLK_HROW_CK_SEL)
            2'b00   : ODIV2 = (REFCLK_EN_TX_PATH | CEB) ? 1'b0 : I;
            2'b01   : ODIV2 = r_IDIV2;
            default : ODIV2 = 1'b0;
        endcase
    end
    
    assign O = (REFCLK_EN_TX_PATH | CEB) ? 1'b0 : I;

endmodule
module RAM128X1S
#(
    parameter [127:0] INIT = 128'h0,
    parameter   [0:0] IS_WCLK_INVERTED = 1'b0
)
(
    // Write clock
    input  wire       WCLK,
    // Write enable
    input  wire       WE,
    // Read / Write address
    input  wire       A0,
    input  wire       A1,
    input  wire       A2,
    input  wire       A3,
    input  wire       A4,
    input  wire       A5,
    input  wire       A6,
    // Data in
    input  wire       D,
    // Data out
    output wire       O
);
    // Read / Write address
    wire   [6:0] _w_A = { A6, A5, A4, A3, A2, A1, A0 };
    // 128 x 1-bit Select RAM
    reg  [127:0] _r_mem;
    
    // Power-up value
    initial begin : INIT_STATE
        _r_mem = INIT;
    end
    
    // Synchronous memory write
    generate
        if (IS_WCLK_INVERTED) begin : GEN_WCLK_NEG
            always @(negedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
        else begin : GEN_WCLK_POS
            always @(posedge WCLK) begin : MEM_WRITE
            
                if (WE) begin
                    _r_mem[_w_A] <= D;
                end
            end
        end
    endgenerate
    
    // Asynchronous memory read
    assign O = _r_mem[_w_A];

endmodule
module SRLC32E
#(
    parameter [31:0] INIT = 32'h0,
    parameter  [0:0] IS_CLK_INVERTED = 1'b0
)
(
    // Clock
    input  wire       CLK,
    // Clock enable
    input  wire       CE,
    // Bit output position
    input  wire [4:0] A,
    // Data in
    input  wire       D,
    // Data out
    output wire       Q,
    // Cascading data out
    output wire       Q31
);
    
    // 32-bit shift register
    reg  [31:0] _r_srl;
    
    // Power-up value
    initial begin
        _r_srl = INIT;
    end
    
    // Shifter logic
    generate
        if (IS_CLK_INVERTED) begin : GEN_CLK_NEG
            always @(negedge CLK) begin : SHIFTER_32B
            
                if (CE) begin
                    _r_srl <= { _r_srl[30:0], D };
                end
            end
        end
        else begin : GEN_CLK_POS
            always @(posedge CLK) begin : SHIFTER_32B
            
                if (CE) begin
                    _r_srl <= { _r_srl[30:0], D };
                end
            end
        end
    endgenerate
    
    // Data out
    assign Q   = _r_srl[A];
    
    // Cascading data out
    assign Q31 = _r_srl[31];

endmodule
module VCC
(
    output wire P
);

    assign P = 1'b1;

endmodule
module SRL32E
#(
    parameter [31:0] INIT = 32'h0,
    parameter  [0:0] IS_CLK_INVERTED = 1'b0
)
(
    // Clock
    input  wire       CLK,
    // Clock enable
    input  wire       CE,
    // Bit output position
    input  wire [4:0] A,
    // Data in
    input  wire       D,
    // Data out
    output wire       Q
);

    // 32-bit shift register
    reg [31:0] _r_srl;
    
    // Power-up value
    initial begin
        _r_srl = INIT;
    end
    
    // Shifter logic
    generate
        if (IS_CLK_INVERTED) begin : GEN_CLK_NEG
            always @(negedge CLK) begin : SHIFTER_32B
                if (CE) begin
                    _r_srl <= { _r_srl[30:0], D };
                end
            end
        end
        else begin : GEN_CLK_POS
            always @(posedge CLK) begin : SHIFTER_32B
                if (CE) begin
                    _r_srl <= { _r_srl[30:0], D };
                end
            end
        end
    endgenerate
    
    // Data out
    assign Q   = _r_srl[A];
    
endmodule
module CFGLUT5
#(
    parameter [31:0] INIT            = 32'h00000000,
    parameter  [0:0] IS_CLK_INVERTED = 1'b0
)
(
    // Clock
    input  wire CLK,
    // Clock enable
    input  wire CE,
    // LUT inputs
    input  wire I0, I1, I2, I3, I4,
    // LUT configuration data input
    input  wire CDI,
    // LUT configuration data output
    output wire CDO,
    // LUT4 output
    output wire O5,
    // LUT5 output
    output wire O6
  
);
    reg [31:0] _r_sreg;

    initial begin : INIT_STATE
        _r_sreg = INIT;
    end

    generate
        if (IS_CLK_INVERTED) begin : GEN_CLK_NEG
            always @(negedge CLK) begin
            
                if (CE) begin
                    _r_sreg <= { _r_sreg[30:0], CDI };
                end
            end
        end
        else begin : GEN_CLK_POS
            always @(posedge CLK) begin
            
                if (CE) begin
                    _r_sreg <= { _r_sreg[30:0], CDI };
                end
            end
        end
    endgenerate

    assign O6  = _r_sreg[{   I4, I3, I2, I1, I0 }];
    assign O5  = _r_sreg[{ 1'b0, I3, I2, I1, I0 }];
    assign CDO = _r_sreg[31];

endmodule
module MUXF8
(
    input  wire I0, I1,
    input  wire S,
    output wire O
);

    assign O = (S) ? I1 : I0;

endmodule
module FDSE
#(
    parameter [0:0] IS_C_INVERTED = 1'b0,
    parameter [0:0] IS_D_INVERTED = 1'b0,
    parameter [0:0] IS_S_INVERTED = 1'b0,
    parameter [0:0] INIT          = 1'b1
)
(
    // Clock
    input  wire C,
    // Clock enable
    input  wire CE,
    // Synchronous set
    input  wire S,
    // Data in
    input  wire D,
    // Data out
    output wire Q
);
    reg _r_Q;

    wire _w_D = D ^ IS_D_INVERTED;
    wire _w_S = S ^ IS_S_INVERTED;
    
    initial begin : INIT_STATE
        _r_Q = INIT[0];
    end

    generate
        if (IS_C_INVERTED) begin : GEN_CLK_NEG
            always @(negedge C) begin
            
                if (_w_S) begin
                    _r_Q <= 1'b1;
                end
                else if (CE) begin
                    _r_Q <= _w_D;
                end
            end
        end
        else begin : GEN_CLK_POS
            always @(posedge C) begin
            
                if (_w_S) begin
                    _r_Q <= 1'b1;
                end
                else if (CE) begin
                    _r_Q <= _w_D;
                end
            end
        end
    endgenerate
    
    assign Q = _r_Q;
    
endmodule
module MUXF8_D
(
    input  wire I0, I1,
    input  wire S,
    output wire LO,
    output wire O
);

    assign LO = (S) ? I1 : I0;
    assign O  = (S) ? I1 : I0;

endmodule
module LUT3
#(
    parameter [7:0] INIT = 8'b00000000
)
(
    input  wire I0, I1, I2,
    output wire O
);
    wire [2:0] _w_idx = { I2, I1, I0 };

    assign O = INIT[_w_idx];

endmodule
module LUT6_L
#(
    parameter [63:0] INIT = 64'h0000000000000000
)
(
    input  wire I0, I1, I2, I3, I4, I5,
    output wire LO
);
    wire [5:0] _w_idx = { I5, I4, I3, I2, I1, I0 };
    
    assign LO = INIT[_w_idx];

endmodule
module LUT5
#(
    parameter [31:0] INIT = 32'h00000000
)
(
    input  wire I0, I1, I2, I3, I4,
    output wire O
);
    wire [4:0] _w_idx = { I4, I3, I2, I1, I0 };
    
    assign O = INIT[_w_idx];

endmodule
module BUFG_GT
(
    input       I,
    input [2:0] DIV,
    input       CE,
    input       CEMASK,
    input       CLR,
    input       CLRMASK,
    
    output      O /* verilator clocker */
);

    reg  [1:0] r_CE_cdc;
    wire       w_CE_msk;
    reg        r_CE_msk;
    
    reg  [1:0] r_CLR_cdc;
    wire       w_CLR_msk;
    
    reg  [2:0] r_clk_div;
    
    /* verilator lint_off MULTIDRIVEN */
    reg        r_O;
    /* verilator lint_on MULTIDRIVEN */
   
    initial begin
        r_CE_cdc  = 2'b00;
        r_CE_msk  = 1'b0;
        r_CLR_cdc = 2'b00;
        r_clk_div = 3'd0;
    end
    
    always @(posedge I) begin
    
        r_CE_cdc <= { r_CE_cdc[0], CE };
    end

    assign w_CE_msk = r_CE_cdc[1] | CEMASK;

    always @(negedge I) begin
    
        if (w_CLR_msk) begin
            r_CE_msk <= 1'b0;
        end
        else begin
            r_CE_msk <= w_CE_msk;
        end
    end

    always @(posedge CLR or posedge I) begin
    
        if (CLR) begin
            r_CLR_cdc <= 2'b11;
        end
        else begin
            r_CLR_cdc <= { r_CLR_cdc[0], 1'b0 };
        end
    end
    
    assign w_CLR_msk = r_CLR_cdc[1] & ~CLRMASK;

    always @(posedge I) begin
    
        if (w_CLR_msk) begin
            r_clk_div <= (DIV[2:1] == 2'b10) ? 3'd1 : 3'd0;
        end
        else if (r_CE_msk | O) begin
            if (DIV[2:1] == 2'b10) begin
                r_clk_div <= (r_clk_div == (DIV + 3'd1)) ? 3'd1 : r_clk_div + 3'd1;
            end
            else begin
                r_clk_div <= (r_clk_div == DIV) ? 3'd0 : r_clk_div + 3'd1;
            end
        end
    end
    
    always @(posedge I) begin
    
        casez (DIV)
            3'b000 : r_O <= r_CE_msk;
            3'b001 : r_O <= r_clk_div[0];
            3'b01? : r_O <= r_clk_div[1];
            3'b1?? : r_O <= r_clk_div[2];
        endcase
    end

    always @(negedge I) begin
    
        if (DIV == 3'b000) begin
            r_O <= 1'b0;
        end
    end
    
    assign O = r_O;

endmodule
module IBUFDS
#(
    parameter CAPACITANCE      = "DONT_CARE",
    parameter DIFF_TERM        = "FALSE",
    parameter DQS_BIAS         = "FALSE",
    parameter IBUF_DELAY_VALUE = "0",
    parameter IBUF_LOW_PWR     = "TRUE",
    parameter IFD_DELAY_VALUE  = "AUTO",
    parameter IOSTANDARD       = "DEFAULT"
)
(
    // Clock input
    input  I,
    input  IB,
    // Clock outputs
    output O /* verilator clocker */
);

    assign O = I;
    
endmodule
module CARRY8
#(
    parameter CARRY_TYPE = "SINGLE_CY8" // "SINGLE_CY8", "DUAL_CY4"
)
(
    // Carry cascade input
    input  wire       CI,
    // Second carry input (in DUAL_CY4 mode)
    input  wire       CI_TOP,
    // Carry MUX data input
    input  wire [7:0] DI,
    // Carry MUX select line
    input  wire [7:0] S,
    // Carry out of each stage of the chain
    output wire [7:0] CO,
    // Carry chain XOR general data out
    output wire [7:0] O
);
    wire _w_CO0 = (S[0]) ?     CI : DI[0];
    wire _w_CO1 = (S[1]) ? _w_CO0 : DI[1];
    wire _w_CO2 = (S[2]) ? _w_CO1 : DI[2];
    wire _w_CO3 = (S[3]) ? _w_CO2 : DI[3];
    wire _w_CI  = (CARRY_TYPE == "DUAL_CY4") ? CI_TOP : _w_CO3;
    wire _w_CO4 = (S[4]) ?  _w_CI : DI[4];
    wire _w_CO5 = (S[5]) ? _w_CO4 : DI[5];
    wire _w_CO6 = (S[6]) ? _w_CO5 : DI[6];
    wire _w_CO7 = (S[7]) ? _w_CO6 : DI[7];

    assign CO   = { _w_CO7, _w_CO6, _w_CO5, _w_CO4, _w_CO3, _w_CO2, _w_CO1, _w_CO0 };
    
    assign O    =  S ^ { _w_CO6, _w_CO5, _w_CO4, _w_CI, _w_CO2, _w_CO1, _w_CO0, CI };

endmodule
module FDRE
#(
    parameter [0:0] IS_C_INVERTED = 1'b0,
    parameter [0:0] IS_D_INVERTED = 1'b0,
    parameter [0:0] IS_R_INVERTED = 1'b0,
    parameter [0:0] INIT          = 1'b0
)
(
    // Clock
    input  wire C,
    // Clock enable
    input  wire CE,
    // Synchronous reset
    input  wire R,
    // Data in
    input  wire D,
    // Data out
    output wire Q
);
    reg _r_Q;

    wire _w_D = D ^ IS_D_INVERTED;
    wire _w_R = R ^ IS_R_INVERTED;
    
    initial begin : INIT_STATE
        _r_Q = INIT[0];
    end

    generate
        if (IS_C_INVERTED) begin : GEN_CLK_NEG
            always @(negedge C) begin
            
                if (_w_R) begin
                    _r_Q <= 1'b0;
                end
                else if (CE) begin
                    _r_Q <= _w_D;
                end
            end
        end
        else begin : GEN_CLK_POS
            always @(posedge C) begin
            
                if (_w_R) begin
                    _r_Q <= 1'b0;
                end
                else if (CE) begin
                    _r_Q <= _w_D;
                end
            end
        end
    endgenerate
    
    assign Q = _r_Q;

endmodule
module FDPE
#(
    parameter [0:0] IS_C_INVERTED   = 1'b0,
    parameter [0:0] IS_D_INVERTED   = 1'b0,
    parameter [0:0] IS_PRE_INVERTED = 1'b0,
    parameter [0:0] INIT            = 1'b0
)
(
    // Clock
    input  wire C,
    // Clock enable
    input  wire CE,
    // Asynchronous preset
    input  wire PRE,
    // Data in
    input  wire D,
    // Data out
    output wire Q
);
    reg    _r_Q;
    
    wire   _w_PRE = PRE ^ IS_PRE_INVERTED;
    wire   _w_D   = D   ^ IS_D_INVERTED;
    
    initial begin : INIT_STATE
        _r_Q = INIT[0];
    end

    generate
        if (IS_C_INVERTED) begin : GEN_CLK_NEG
            always @(negedge C or posedge _w_PRE) begin
            
                if (_w_PRE) begin
                    _r_Q <= 1'b1;
                end
                else if (CE) begin
                    _r_Q <= _w_D;
                end
            end
        end
        else begin : GEN_CLK_POS
            always @(posedge C or posedge _w_PRE) begin
            
                if (_w_PRE) begin
                    _r_Q <= 1'b1;
                end
                else if (CE) begin
                    _r_Q <= _w_D;
                end
            end
        end
    endgenerate
    
    assign Q = _r_Q;

endmodule
module SRL16E
#(
    parameter [15:0] INIT = 16'h0,
    parameter  [0:0] IS_CLK_INVERTED = 1'b0
)
(
    // Clock
    input  wire CLK,
    // Clock enable
    input  wire CE,
    // Bit output position
    input  wire A0, A1, A2, A3,
    // Data in
    input  wire D,
    // Data out
    output wire Q
);
    
    wire  [3:0] _w_addr = { A3, A2, A1, A0 };
    
    // 16-bit shift register
    reg  [15:0] _r_srl;
    
    // Power-up value
    initial begin
        _r_srl = INIT;
    end
    
    // Shifter logic
    generate
        if (IS_CLK_INVERTED) begin : GEN_CLK_NEG
            always @(negedge CLK) begin : SHIFTER_16B
            
                if (CE) begin
                    _r_srl <= { _r_srl[14:0], D };
                end
            end
        end
        else begin : GEN_CLK_POS
            always @(posedge CLK) begin : SHIFTER_16B
            
                if (CE) begin
                    _r_srl <= { _r_srl[14:0], D };
                end
            end
        end
    endgenerate
    
    // Data out
    assign Q = _r_srl[_w_addr];

endmodule
module LUT5_D
#(
    parameter [31:0] INIT = 32'h00000000
)
(
    input  wire I0, I1, I2, I3, I4,
    output wire LO,
    output wire O
);
    
    wire [4:0] _w_idx = { I4, I3, I2, I1, I0 };
    
    assign LO = INIT[_w_idx];
    assign O  = INIT[_w_idx];

endmodule
module CARRY4
(
    // Carry cascade input
    input  wire       CI,
    // 
    input  wire       CYINIT,
    // Carry MUX data input
    input  wire [3:0] DI,
    // Carry MUX select line
    input  wire [3:0] S,
    // Carry out of each stage of the chain
    output wire [3:0] CO,
    // Carry chain XOR general data out
    output wire [3:0] O
);
    wire _w_CO0 = S[0] ? CI | CYINIT : DI[0];
    wire _w_CO1 = S[1] ?      _w_CO0 : DI[1];
    wire _w_CO2 = S[2] ?      _w_CO1 : DI[2];
    wire _w_CO3 = S[3] ?      _w_CO2 : DI[3];

    assign CO   = { _w_CO3, _w_CO2, _w_CO1, _w_CO0 };

    assign O    =  S ^ { _w_CO2, _w_CO1, _w_CO0, CI | CYINIT };

endmodule
module mult_pipe2 #(
	parameter SIZE = 16,
	parameter LVL = 2
)
( a, b, clk, pdt) ;
/*
* parameter 'SIZE' is the width of multiplier/multiplicand;.Application Notes 10-5
* parameter '' is the intended number of stages of the
* pipelined multiplier;
* which is typically the smallest integer greater than or equal
* to base 2 logarithm of 'SIZE'
*/
	input [SIZE-1 : 0] a;
	input [SIZE-1 : 0] b;
	input clk;
	output wire [2*SIZE-1 : 0] pdt;
	reg [SIZE-1 : 0] a_int, b_int;
	reg [2*SIZE-1 : 0] pdt_int [LVL-1 : 0];
	integer i;

	assign pdt = pdt_int [LVL-1];

	always @ (posedge clk)
	begin
	// registering input of the multiplier
		a_int <= a;
		b_int <= b;
		for(i=1; i <LVL ; i = i + 1)
			pdt_int[i] <= pdt_int [i-1];
		pdt_int[0] <= a_int * b_int;
	end // always @ (posedge clk)
endmodule // pipelined_multiplier
module psum_spad(clk, addr, we, data_port);
	// 24 * 16bit
	input clk;
	input [4:0] addr;
	input we; // write enable signal, 0: Read; 1: Write
	inout [15:0] data_port;
	reg [15:0] data_out;
	reg [15:0] mem [23:0]; // 24 * 16bit

	assign data_port = !we ? data_out : 16'bz;

	always @ (posedge clk)	
	begin
		if (we)
			mem[addr] <= data_port;
		else
		begin
			data_out <= mem[addr];
		end

	end
endmodule
module dual_clock_fifo #(
	parameter ADDR_WIDTH = 3,
	parameter DATA_WIDTH = 16
)
(
	input wire 			wr_rst_i,
	input wire 			wr_clk_i,
	input wire 			wr_en_i,
	input wire [DATA_WIDTH-1:0]	wr_data_i,

	input wire 			rd_rst_i,
	input wire 			rd_clk_i,
	input wire 			rd_en_i,
	output reg [DATA_WIDTH-1:0]	rd_data_o,

	output reg 			full_o,
	output reg 			empty_o
);

reg [ADDR_WIDTH-1:0]	wr_addr;
reg [ADDR_WIDTH-1:0]	wr_addr_gray;
reg [ADDR_WIDTH-1:0]	wr_addr_gray_rd;
reg [ADDR_WIDTH-1:0]	wr_addr_gray_rd_r;
reg [ADDR_WIDTH-1:0]	rd_addr;
reg [ADDR_WIDTH-1:0]	rd_addr_gray;
reg [ADDR_WIDTH-1:0]	rd_addr_gray_wr;
reg [ADDR_WIDTH-1:0]	rd_addr_gray_wr_r;

function [ADDR_WIDTH-1:0] gray_conv;
input [ADDR_WIDTH-1:0] in;
begin
	gray_conv = {in[ADDR_WIDTH-1],
		     in[ADDR_WIDTH-2:0] ^ in[ADDR_WIDTH-1:1]};
end
endfunction

always @(posedge wr_clk_i) begin
	if (wr_rst_i) begin
		wr_addr <= 0;
		wr_addr_gray <= 0;
	end else if (wr_en_i) begin
		wr_addr <= wr_addr + 1'b1;
		wr_addr_gray <= gray_conv(wr_addr + 1'b1);
	end
end

// synchronize read address to write clock domain
always @(posedge wr_clk_i) begin
	rd_addr_gray_wr <= rd_addr_gray;
	rd_addr_gray_wr_r <= rd_addr_gray_wr;
end

always @(posedge wr_clk_i)
	if (wr_rst_i)
		full_o <= 0;
	else if (wr_en_i)
		full_o <= gray_conv(wr_addr + 2) == rd_addr_gray_wr_r;
	else
		full_o <= full_o & (gray_conv(wr_addr + 1'b1) == rd_addr_gray_wr_r);

always @(posedge rd_clk_i) begin
	if (rd_rst_i) begin
		rd_addr <= 0;
		rd_addr_gray <= 0;
	end else if (rd_en_i) begin
		rd_addr <= rd_addr + 1'b1;
		rd_addr_gray <= gray_conv(rd_addr + 1'b1);
	end
end

// synchronize write address to read clock domain
always @(posedge rd_clk_i) begin
	wr_addr_gray_rd <= wr_addr_gray;
	wr_addr_gray_rd_r <= wr_addr_gray_rd;
end

always @(posedge rd_clk_i)
	if (rd_rst_i)
		empty_o <= 1'b1;
	else if (rd_en_i)
		empty_o <= gray_conv(rd_addr + 1) == wr_addr_gray_rd_r;
	else
		empty_o <= empty_o & (gray_conv(rd_addr) == wr_addr_gray_rd_r);

// generate dual clocked memory
reg [DATA_WIDTH-1:0] mem[(1<<ADDR_WIDTH)-1:0];

always @(posedge rd_clk_i)
	if (rd_en_i)
		rd_data_o <= mem[rd_addr];

always @(posedge wr_clk_i)
	if (wr_en_i)
		mem[wr_addr] <= wr_data_i;
endmodule
module clacc_mem (ipf_valid, ipf_data, ipf_addr, clk);

	input	ipf_valid;
	input	[13:0] ipf_addr;
	input	[7:0]  ipf_data;
	input	clk;

	reg [7:0] ipf_M [0:16383];
	integer i;

	initial begin
		for (i=0; i<=16383; i=i+1) ipf_M[i] = 0;
	end

	always@(negedge clk) 
		if (ipf_valid) ipf_M[ ipf_addr ] <= ipf_data;

endmodule
module counter_5to3(x, y);
	input [4:0] x;
	output [2:0] y;
	assign y[2:0] = (x[4:0] == 5'b00000) ? 3'b000 :
				( x[4:0] == 5'b00001) ? 3'b001 :
				( x[4:0] == 5'b00010) ? 3'b001 :
				( x[4:0] == 5'b00100) ? 3'b001 :
				( x[4:0] == 5'b01000) ? 3'b001 :
				( x[4:0] == 5'b10000) ? 3'b001 :
				( x[4:0] == 5'b00011) ? 3'b010 :
				( x[4:0] == 5'b00110) ? 3'b010 :
				( x[4:0] == 5'b01100) ? 3'b010 :
				( x[4:0] == 5'b11000) ? 3'b010 :
				( x[4:0] == 5'b00101) ? 3'b010 :
				( x[4:0] == 5'b01010) ? 3'b010 :
				( x[4:0] == 5'b10100) ? 3'b010 :
				( x[4:0] == 5'b01001) ? 3'b010 :
				( x[4:0] == 5'b10010) ? 3'b010 :
				( x[4:0] == 5'b10001) ? 3'b010 :
				( x[4:0] == 5'b11100) ? 3'b011 :
				( x[4:0] == 5'b11001) ? 3'b011 :
				( x[4:0] == 5'b10011) ? 3'b011 :
				( x[4:0] == 5'b00111) ? 3'b011 :
				( x[4:0] == 5'b11010) ? 3'b011 :
				( x[4:0] == 5'b10101) ? 3'b011 :
				( x[4:0] == 5'b01011) ? 3'b011 :
				( x[4:0] == 5'b10110) ? 3'b011 :
				( x[4:0] == 5'b01101) ? 3'b011 :
				( x[4:0] == 5'b01110) ? 3'b011 :
				( x[4:0] == 5'b01111) ? 3'b100 :
				( x[4:0] == 5'b10111) ? 3'b100 :
				( x[4:0] == 5'b11011) ? 3'b100 :
				( x[4:0] == 5'b11101) ? 3'b100 :
				( x[4:0] == 5'b11110) ? 3'b100 :
				( x[4:0] == 5'b11111) ? 3'b101 : 3'b111;
endmodule
module bs_mult_slice(clk, xy, pin, cin, rin, x, y, pout, cout, rout, lastbit);
	input clk;
	input xy, pin, cin, rin, x, y, lastbit;
	output pout, cout, rout;
	wire [2:0] cout_int;
	reg cout;
	reg rout;
	wire a, b;
	reg pin_delay;
	reg x_delay;
	reg y_delay;
	reg cout1_delay;
	assign a = x_delay & y;
	assign b = x & y_delay;
	assign pout = (rin == 1'b1) ? xy : cout_int[0];
	counter_5to3 I0(.x({a, b, pin_delay, cin, cout1_delay}), .y(cout_int));	

	always @ (posedge clk)
	begin
		if(lastbit)
		begin 
			x_delay <= 1'b0;
			y_delay <= 1'b0;
			pin_delay <= 1'b0;
			cout1_delay <= 1'b0;
			cout <= 1'b0;
			rout <= 1'b0;
		end
		else
		begin
			if(rin)
			begin
				x_delay <= x;
				y_delay <= y;
			end
			pin_delay <= pin;
			cout1_delay <= cout_int[1];
			cout <= cout_int[2];
			rout <= rin;
		end


	end
endmodule
module filter_spad(clk, addr, we, data_port);
	// 224 * 16bit
	input clk;
	input [7:0] addr;
	input we; // write enable signal, 0: Read; 1: Write
	inout [15:0] data_port;
	reg [15:0] data_out;
	reg [15:0] mem [223:0]; // 12 * 16bit

	assign data_port = !we ? data_out : 16'bz;

	always @ (posedge clk)	
	begin
		if (we)
			mem[addr] <= data_port;
		else
		begin
			data_out <= mem[addr];
		end

	end
endmodule
module ifmap_spad(clk, addr, we, data_port);
	// 12 * 16bit
	input clk;
	input [3:0] addr;
	input we; // write enable signal, 0: Read; 1: Write
	inout [15:0] data_port;
	reg [15:0] data_out;
	reg [15:0] mem [11:0]; // 12 * 16bit

	assign data_port = !we ? data_out : 16'bz;

	always @ (posedge clk)	
	begin
		if (we)
			mem[addr] <= data_port;
		else
		begin
			data_out <= mem[addr];
		end

	end
endmodule
module bs_adder(x, y, clk, z, rst);
	input x, y, clk, rst;
	output reg z;
	reg cin_int;	
	wire sum_int;
	
	fa I0(.x(x), .y(y), .cin(cin_int), .cout(cout_int), .sum(sum_int));
	always @ (posedge clk)	
	begin
		if(rst)
		begin
			cin_int <= 1'b0;
			z <= 1'b0;
		end
		else
		begin
			cin_int <= cout_int;
			z <= sum_int;
		end
	end
endmodule
module ha(x, y, cout, sum);
	input x, y;
	output cout, sum;

	assign sum = x ^ y;
	assign cout = x & y;

endmodule
module fa(x, y, cin, cout, sum);
	input x, y, cin;
	output cout, sum;
	wire cout_int, cout_int2;
	wire sum_int;
	ha I0(.x(x), .y(y), .cout(cout_int), .sum(sum_int));
	ha I1(.x(sum_int), .y(cin), .cout(cout_int2), .sum(sum));
	assign cout = cout_int | cout_int2;
endmodule
module exponential (
		input 	wire 			           	Clock,
		input 	wire           				Reset,
        input   wire                        Str,
		input	wire    [`DATALENGTH-1:0] 	Datain,
        output reg                          Ack,
		output reg      [`DATALENGTH-1:0]	DataOut
	
);
wire [`DATALENGTH-1:0] one, oversix, half;
//reg [`DATALENGTH-1:0]	T0R,T1R,T2R,TsR,TdR,TcR, DoR;
reg [`DATALENGTH-1:0] Count;
reg [`DATALENGTH-1:0]	T0;
wire [`DATALENGTH-1:0] T1,T2,Ts,Td,Tc,To,Tsh;
wire wa_add_1,wb_add_1,wz_add_1;
wire wa_add_2,wb_add_2,wz_add_2;
wire wa_add_3,wb_add_3,wz_add_3;
wire wa_mul_1,wb_mul_1,wz_mul_1;
wire wa_mul_2,wb_mul_2,wz_mul_2;
wire wa_sh_1,wb_sh_1,wz_sh_1;
wire wa_div_1,wb_div_1,wz_div_1;

assign one = 32'h3f800000;
assign oversix = 32'h3e2aaaab ;
assign half = 32'h3f000000;

adder A1 (        
        one,
        T0,
        Str,
        Str,
        Str,
        Clock,
        Reset,
        T1,
        wz_add_1,
        wa_add_1,
        wb_add_1);
multiplier Ms (        
        T0,
        T0,
        wa_add_1,
        wb_add_1,
        wz_add_1,
        Clock,
        Reset,
        Ts,
        wz_mul_1,
        wa_mul_1,
        wb_mul_1);
multiplier Msh (
        half,
        Ts,
        wa_mul_1,
        wb_mul_1,
        wz_mul_1,
        Clock,
        Reset,
        Tsh,
        wz_sh_1,
        wa_sh_1,
        wb_sh_1);
adder A2 (        
        T1,
        Tsh,
        wa_sh_1,
        wb_sh_1,
        wz_sh_1,
        Clock,
        Reset,
        T2,
        wz_add_2,
        wa_add_2,
        wb_add_2);

multiplier Mc (        
        Ts,
        Ts,
        wa_add_2,
        wb_add_2,
        wz_add_2,
        Clock,
        Reset,
        Tc,
        wz_mul_2,
        wa_mul_2,
        wb_mul_2);

multiplier Dm (
        Tc,
        oversix,
        wa_mul_2,
        wb_mul_2,
        wz_mul_2,
        Clock,
        Reset,
        Td,
        wz_div_1,
        wa_div_1,
        wb_div_1
        );

adder A3 (        
        Td,
        T2,
        wa_div_1,
        wb_div_1,
        wz_div_1,
        Clock,
        Reset,
        To,
        wz_add_3,
        wa_add_3,
        wb_add_3);
integer i;
always @(posedge Clock or negedge Reset) begin 
	if(Reset) begin
                T0 <= 0;
                DataOut <= 0;
                Ack <= 0;
                Count <= 0;
//                T1 <= 0;
//                T2 <= 0;
//                Ts <= 0;
//                Tc <= 0;
//                Td <= 0;
	end else begin
        if (Str) begin
    		T0 <= Datain;
            DataOut <= To;
            if (Count == 140)
                Ack <= 1;
            Count <= Count +1;
        end
        else 
            T0 <= 32'hz;

		// T1R <= T1;
		// TsR <= Ts;
		// T2R <= T2;
		// TcR <= Tc;
		// T1 <= T0 + 1 ;
		// Ts <= T0 * T0;
		// T2 <= T1 + (Ts >> 2);
		// Tc <= Ts* T0; 
		// DataOut <= T2 + (Tc /6);

	end
end

endmodule
module adder_tb();

reg            clk;
reg            rst;
reg    [31:0]   input_a;
reg    [31:0]   input_b;
reg             input_a_stb;
reg             input_b_stb;
reg            output_z_ack;
wire            input_a_ack;
wire            input_b_ack;
wire            output_z_stb;
wire   [31:0]  output_z;
initial begin 
  clk = 1;
  rst = 1;
  input_a_stb = 0;  
  input_b_stb = 0;
  output_z_ack = 0;
  #10
  rst = 0;
////////////////////////////  
  input_a_stb = 1;  
  input_b_stb = 1;
  output_z_ack = 1;
//  #5
  input_a = 32'h3f800000;
  input_b = 32'h3f800000;
  #32
  // input_a_stb = 0;  
  // input_b_stb = 0;
  // output_z_ack = 0;
  // #10
////////////////////////////  
//     input_a_stb = 0;  
//   input_b_stb = 0;
//   output_z_ack = 0;
// ////////////////////////////  
//   #10
  //   input_a_stb = 1;  
  // input_b_stb = 1;
  // output_z_ack = 1;
  // #5
  input_a = 32'h3f000000;
  input_b = 32'h3f000000;
  #32
  input_a = 32'h3f000000;
  input_b = 32'hbf000000;
    
  
end

adder DUT (        
        input_a,
        input_b,
        input_a_stb,
        input_b_stb,
        output_z_ack,
        clk,
        rst,
        output_z,
        output_z_stb,
        input_a_ack,
        input_b_ack);

always 
#1 clk = ~clk;

endmodule // adder_tb
module exponential_tb ();

reg 						Clock;
reg 						Reset;
reg 						Str;
reg  [`DATALENGTH-1:0] 	Datain;
wire [`DATALENGTH-1:0]	DataOut;
wire					Ack;


exponential DUT (Clock, Reset,Str, Datain ,Ack, DataOut);
	
initial begin
	Clock = 0;
	Reset = 1;
	Str   = 0;
	#10
	Reset = 0;
	Str	  = 1;
	Datain = 32'h3f800000;
	#50 
	$finish;
end

always 
#1 Clock = ~Clock;

endmodule
module softmax_tb(
		);
reg 						Clock;
reg 						Reset;
reg 						Start;
reg [`DATALENGTH-1:0] 	Datain;
reg	[`INPUTMAX-1:0]		N;
wire [`DATALENGTH-1:0] Dataout;



	softmax DUT (Clock, Reset, Start, Datain,N, Dataout);
	
initial begin
	Clock = 1;
	Reset = 1;
	N   = 3;
	#10
	Start = 1;
	Reset = 0;
	Datain = 32'h3f800000;
	#2
	Datain = 32'h3f800000;
    #2
    Datain = 32'h3f800000;            
    #2
    Datain = 32'h3f800000;          
	
	Start = 0;
	#2000 
	$finish;
end

always 
#1 Clock = ~Clock;

endmodule