dakies/OSS_Verilog huggingface dataset:
module test_bench(clk, rst);
  input  clk;
  input  rst;
  wire   [31:0] wire_39069600;
  wire   wire_39069600_stb;
  wire   wire_39069600_ack;
  wire   [31:0] wire_39795168;
  wire   wire_39795168_stb;
  wire   wire_39795168_ack;
  file_reader_a file_reader_a_39796104(
    .clk(clk),
    .rst(rst),
    .output_z(wire_39069600),
    .output_z_stb(wire_39069600_stb),
    .output_z_ack(wire_39069600_ack));
  file_writer file_writer_39028208(
    .clk(clk),
    .rst(rst),
    .input_a(wire_39795168),
    .input_a_stb(wire_39795168_stb),
    .input_a_ack(wire_39795168_ack));
  int_to_float int_to_float_39759952(
    .clk(clk),
    .rst(rst),
    .input_a(wire_39069600),
    .input_a_stb(wire_39069600_stb),
    .input_a_ack(wire_39069600_ack),
    .output_z(wire_39795168),
    .output_z_stb(wire_39795168_stb),
    .output_z_ack(wire_39795168_ack));
endmodule
module test_bench(clk, rst);
  input  clk;
  input  rst;
  wire   [63:0] wire_39069600;
  wire   wire_39069600_stb;
  wire   wire_39069600_ack;
  wire   [63:0] wire_39795024;
  wire   wire_39795024_stb;
  wire   wire_39795024_ack;
  wire   [63:0] wire_39795168;
  wire   wire_39795168_stb;
  wire   wire_39795168_ack;
  file_reader_a file_reader_a_39796104(
    .clk(clk),
    .rst(rst),
    .output_z(wire_39069600),
    .output_z_stb(wire_39069600_stb),
    .output_z_ack(wire_39069600_ack));
  file_reader_b file_reader_b_39759816(
    .clk(clk),
    .rst(rst),
    .output_z(wire_39795024),
    .output_z_stb(wire_39795024_stb),
    .output_z_ack(wire_39795024_ack));
  file_writer file_writer_39028208(
    .clk(clk),
    .rst(rst),
    .input_a(wire_39795168),
    .input_a_stb(wire_39795168_stb),
    .input_a_ack(wire_39795168_ack));
  double_multiplier multiplier_39759952(
    .clk(clk),
    .rst(rst),
    .input_a(wire_39069600),
    .input_a_stb(wire_39069600_stb),
    .input_a_ack(wire_39069600_ack),
    .input_b(wire_39795024),
    .input_b_stb(wire_39795024_stb),
    .input_b_ack(wire_39795024_ack),
    .output_z(wire_39795168),
    .output_z_stb(wire_39795168_stb),
    .output_z_ack(wire_39795168_ack));
endmodule
module blinky (
    input  wire clk_p,
    input  wire clk_n,
    output wire led
    );

    wire clk_ibufg;
    wire clk;

    IBUFDS ibuf_inst (.I(clk_p), .IB(clk_n), .O(clk_ibufg));
    BUFG   bufg_inst (.I(clk_ibufg), .O(clk));

    reg [24:0] r_count = 0;

    always @(posedge(clk)) r_count <= r_count + 1;

    assign led = r_count[24];
endmodule
module blinky (
    input  wire clk,
    output wire led
    );

    reg [24:0] r_count = 0;

    always @(posedge(clk)) r_count <= r_count + 1;

    assign led = r_count[24];
endmodule
module uart #
(
    parameter DATA_WIDTH = 8
)
(
    input  wire                   clk,
    input  wire                   rst,

    /*
     * AXI input
     */
    input  wire [DATA_WIDTH-1:0]  s_axis_tdata,
    input  wire                   s_axis_tvalid,
    output wire                   s_axis_tready,

    /*
     * AXI output
     */
    output wire [DATA_WIDTH-1:0]  m_axis_tdata,
    output wire                   m_axis_tvalid,
    input  wire                   m_axis_tready,

    /*
     * UART interface
     */
    input  wire                   rxd,
    output wire                   txd,

    /*
     * Status
     */
    output wire                   tx_busy,
    output wire                   rx_busy,
    output wire                   rx_overrun_error,
    output wire                   rx_frame_error,

    /*
     * Configuration
     */
    input  wire [15:0]            prescale

);

uart_tx #(
    .DATA_WIDTH(DATA_WIDTH)
)
uart_tx_inst (
    .clk(clk),
    .rst(rst),
    // axi input
    .s_axis_tdata(s_axis_tdata),
    .s_axis_tvalid(s_axis_tvalid),
    .s_axis_tready(s_axis_tready),
    // output
    .txd(txd),
    // status
    .busy(tx_busy),
    // configuration
    .prescale(prescale)
);

uart_rx #(
    .DATA_WIDTH(DATA_WIDTH)
)
uart_rx_inst (
    .clk(clk),
    .rst(rst),
    // axi output
    .m_axis_tdata(m_axis_tdata),
    .m_axis_tvalid(m_axis_tvalid),
    .m_axis_tready(m_axis_tready),
    // input
    .rxd(rxd),
    // status
    .busy(rx_busy),
    .overrun_error(rx_overrun_error),
    .frame_error(rx_frame_error),
    // configuration
    .prescale(prescale)
);

endmodule
module uart_rx #
(
    parameter DATA_WIDTH = 8
)
(
    input  wire                   clk,
    input  wire                   rst,

    /*
     * AXI output
     */
    output wire [DATA_WIDTH-1:0]  m_axis_tdata,
    output wire                   m_axis_tvalid,
    input  wire                   m_axis_tready,

    /*
     * UART interface
     */
    input  wire                   rxd,

    /*
     * Status
     */
    output wire                   busy,
    output wire                   overrun_error,
    output wire                   frame_error,

    /*
     * Configuration
     */
    input  wire [15:0]            prescale

);

reg [DATA_WIDTH-1:0] m_axis_tdata_reg = 0;
reg m_axis_tvalid_reg = 0;

reg rxd_reg = 1;

reg busy_reg = 0;
reg overrun_error_reg = 0;
reg frame_error_reg = 0;

reg [DATA_WIDTH-1:0] data_reg = 0;
reg [18:0] prescale_reg = 0;
reg [3:0] bit_cnt = 0;

assign m_axis_tdata = m_axis_tdata_reg;
assign m_axis_tvalid = m_axis_tvalid_reg;

assign busy = busy_reg;
assign overrun_error = overrun_error_reg;
assign frame_error = frame_error_reg;

always @(posedge clk) begin
    if (rst) begin
        m_axis_tdata_reg <= 0;
        m_axis_tvalid_reg <= 0;
        rxd_reg <= 1;
        prescale_reg <= 0;
        bit_cnt <= 0;
        busy_reg <= 0;
        overrun_error_reg <= 0;
        frame_error_reg <= 0;
    end else begin
        rxd_reg <= rxd;
        overrun_error_reg <= 0;
        frame_error_reg <= 0;

        if (m_axis_tvalid && m_axis_tready) begin
            m_axis_tvalid_reg <= 0;
        end

        if (prescale_reg > 0) begin
            prescale_reg <= prescale_reg - 1;
        end else if (bit_cnt > 0) begin
            if (bit_cnt > DATA_WIDTH+1) begin
                if (!rxd_reg) begin
                    bit_cnt <= bit_cnt - 1;
                    prescale_reg <= (prescale << 3)-1;
                end else begin
                    bit_cnt <= 0;
                    prescale_reg <= 0;
                end
            end else if (bit_cnt > 1) begin
                bit_cnt <= bit_cnt - 1;
                prescale_reg <= (prescale << 3)-1;
                data_reg <= {rxd_reg, data_reg[DATA_WIDTH-1:1]};
            end else if (bit_cnt == 1) begin
                bit_cnt <= bit_cnt - 1;
                if (rxd_reg) begin
                    m_axis_tdata_reg <= data_reg;
                    m_axis_tvalid_reg <= 1;
                    overrun_error_reg <= m_axis_tvalid_reg;
                end else begin
                    frame_error_reg <= 1;
                end
            end
        end else begin
            busy_reg <= 0;
            if (!rxd_reg) begin
                prescale_reg <= (prescale << 2)-2;
                bit_cnt <= DATA_WIDTH+2;
                data_reg <= 0;
                busy_reg <= 1;
            end
        end
    end
end

endmodule
module clk_wiz_0 
 (
  // Clock out ports
  output        clk_out1,
  output        clk_out2,
  output        clk_out3,
  output        clk_out4,
  // Status and control signals
  input         reset,
  output        locked,
 // Clock in ports
  input         clk_in1
 );

  clk_wiz_0_clk_wiz inst
  (
  // Clock out ports  
  .clk_out1(clk_out1),
  .clk_out2(clk_out2),
  .clk_out3(clk_out3),
  .clk_out4(clk_out4),
  // Status and control signals               
  .reset(reset), 
  .locked(locked),
 // Clock in ports
  .clk_in1(clk_in1)
  );

endmodule
module uart_tx #
(
    parameter DATA_WIDTH = 8
)
(
    input  wire                   clk,
    input  wire                   rst,

    /*
     * AXI input
     */
    input  wire [DATA_WIDTH-1:0]  s_axis_tdata,
    input  wire                   s_axis_tvalid,
    output wire                   s_axis_tready,

    /*
     * UART interface
     */
    output wire                   txd,

    /*
     * Status
     */
    output wire                   busy,

    /*
     * Configuration
     */
    input  wire [15:0]            prescale
);

reg s_axis_tready_reg = 0;

reg txd_reg = 1;

reg busy_reg = 0;

reg [DATA_WIDTH:0] data_reg = 0;
reg [18:0] prescale_reg = 0;
reg [3:0] bit_cnt = 0;

assign s_axis_tready = s_axis_tready_reg;
assign txd = txd_reg;

assign busy = busy_reg;

always @(posedge clk) begin
    if (rst) begin
        s_axis_tready_reg <= 0;
        txd_reg <= 1;
        prescale_reg <= 0;
        bit_cnt <= 0;
        busy_reg <= 0;
    end else begin
        if (prescale_reg > 0) begin
            s_axis_tready_reg <= 0;
            prescale_reg <= prescale_reg - 1;
        end else if (bit_cnt == 0) begin
            s_axis_tready_reg <= 1;
            busy_reg <= 0;

            if (s_axis_tvalid) begin
                s_axis_tready_reg <= !s_axis_tready_reg;
                prescale_reg <= (prescale << 3)-1;
                bit_cnt <= DATA_WIDTH+1;
                data_reg <= {1'b1, s_axis_tdata};
                txd_reg <= 0;
                busy_reg <= 1;
            end
        end else begin
            if (bit_cnt > 1) begin
                bit_cnt <= bit_cnt - 1;
                prescale_reg <= (prescale << 3)-1;
                {data_reg, txd_reg} <= {1'b0, data_reg};
            end else if (bit_cnt == 1) begin
                bit_cnt <= bit_cnt - 1;
                prescale_reg <= (prescale << 3);
                txd_reg <= 1;
            end
        end
    end
end

endmodule
module blinky (
    input  wire clk_p,
    input  wire clk_n,
    output wire led,
    input  wire button,
    output reg button_led,
    output wire diff_led_p,
    output wire diff_led_n
    );

    wire clk_ibufg;
    wire clk;

    IBUFDS ibuf_inst (.I(clk_p), .IB(clk_n), .O(clk_ibufg));
    BUFG   bufg_inst (.I(clk_ibufg), .O(clk));

    reg [26:0] r_count = 0;

    always @(posedge(clk)) begin
        r_count <= r_count + 1;
        button_led <= button;
    end

    assign led = r_count[26];

    OBUFDS obuf_inst (.I(led), .O(diff_led_p), .OB(diff_led_n));
endmodule
module Ram_1w_1rs #(
        parameter integer wordCount = 0,
        parameter integer wordWidth = 0,
        parameter clockCrossing = 1'b0,
        parameter technology = "auto",
        parameter readUnderWrite = "dontCare",
        parameter integer wrAddressWidth = 0,
        parameter integer wrDataWidth = 0,
        parameter integer wrMaskWidth = 0,
        parameter wrMaskEnable = 1'b0,
        parameter integer rdAddressWidth = 0,
        parameter integer rdDataWidth  = 0
    )(
        input wr_clk,
        input wr_en,
        input [wrMaskWidth-1:0] wr_mask,
        input [wrAddressWidth-1:0] wr_addr,
        input [wrDataWidth-1:0] wr_data,
        input rd_clk,
        input rd_en,
        input [rdAddressWidth-1:0] rd_addr,
        output [rdDataWidth-1:0] rd_data
    );

    generate
    genvar i;

    for (i=0;i<wrMaskWidth;i=i+1) begin
        reg [8-1:0] ram_block [(2**wrAddressWidth)-1:0];
        always @ (posedge wr_clk) begin
            if(wr_en && wr_mask[i]) begin
                ram_block[wr_addr] <= wr_data[i*8 +:8];
            end
        end

        reg [8-1:0] ram_rd_data;
        always @ (posedge rd_clk) begin
            if(rd_en) begin
                ram_rd_data <= ram_block[rd_addr];
            end
        end
        assign rd_data[i*8 +:8] = ram_rd_data;
    end
    endgenerate

endmodule
module toplevel(
    input   io_J3,
    input   io_H16,
    input   io_G15,
    output  io_G16,
    input   io_F15,
    output  io_B12,
    input   io_B10,
    output [7:0] io_led
  );
  
  wire [31:0] io_gpioA_read;
  wire [31:0] io_gpioA_write;
  wire [31:0] io_gpioA_writeEnable;
  wire io_mainClk;
  wire io_jtag_tck;

  SB_GB mainClkBuffer (
    .USER_SIGNAL_TO_GLOBAL_BUFFER (io_J3),
    .GLOBAL_BUFFER_OUTPUT ( io_mainClk)
  );

  SB_GB jtagClkBuffer (
    .USER_SIGNAL_TO_GLOBAL_BUFFER (io_H16),
    .GLOBAL_BUFFER_OUTPUT ( io_jtag_tck)
  );

  assign io_led = io_gpioA_write[7 : 0];

  Murax murax ( 
    .io_asyncReset(0),
    .io_mainClk (io_mainClk ),
    .io_jtag_tck(io_jtag_tck),
    .io_jtag_tdi(io_G15),
    .io_jtag_tdo(io_G16),
    .io_jtag_tms(io_F15),
    .io_gpioA_read       (io_gpioA_read),
    .io_gpioA_write      (io_gpioA_write),
    .io_gpioA_writeEnable(io_gpioA_writeEnable),
    .io_uart_txd(io_B12),
    .io_uart_rxd(io_B10)
  );		
endmodule
module toplevel_pll(REFERENCECLK,
                    PLLOUTCORE,
                    PLLOUTGLOBAL,
                    RESET);

input REFERENCECLK;
input RESET;    /* To initialize the simulation properly, the RESET signal (Active Low) must be asserted at the beginning of the simulation */ 
output PLLOUTCORE;
output PLLOUTGLOBAL;

SB_PLL40_CORE toplevel_pll_inst(.REFERENCECLK(REFERENCECLK),
                                .PLLOUTCORE(PLLOUTCORE),
                                .PLLOUTGLOBAL(PLLOUTGLOBAL),
                                .EXTFEEDBACK(),
                                .DYNAMICDELAY(),
                                .RESETB(RESET),
                                .BYPASS(1'b0),
                                .LATCHINPUTVALUE(),
                                .LOCK(),
                                .SDI(),
                                .SDO(),
                                .SCLK());

//\\ Fin=100, Fout=12;
defparam toplevel_pll_inst.DIVR = 4'b0010;
defparam toplevel_pll_inst.DIVF = 7'b0010110;
defparam toplevel_pll_inst.DIVQ = 3'b110;
defparam toplevel_pll_inst.FILTER_RANGE = 3'b011;
defparam toplevel_pll_inst.FEEDBACK_PATH = "SIMPLE";
defparam toplevel_pll_inst.DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
defparam toplevel_pll_inst.FDA_FEEDBACK = 4'b0000;
defparam toplevel_pll_inst.DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
defparam toplevel_pll_inst.FDA_RELATIVE = 4'b0000;
defparam toplevel_pll_inst.SHIFTREG_DIV_MODE = 2'b00;
defparam toplevel_pll_inst.PLLOUT_SELECT = "GENCLK";
defparam toplevel_pll_inst.ENABLE_ICEGATE = 1'b0;

endmodule
module toplevel(
    input  wire clk100,
    input  wire cpu_reset,//active low

    input  wire tck,
    input  wire tms,
    input  wire tdi,
    input  wire trst,//ignored
    output reg  tdo,

    input  wire serial_rx,
    output wire serial_tx,

    input  wire user_sw0,
    input  wire user_sw1,
    input  wire user_sw2,
    input  wire user_sw3,

    input  wire user_btn0,
    input  wire user_btn1,
    input  wire user_btn2,
    input  wire user_btn3,

    output wire user_led0,
    output wire user_led1,
    output wire user_led2,
    output wire user_led3
  );

  wire [31:0] io_gpioA_read;
  wire [31:0] io_gpioA_write;
  wire [31:0] io_gpioA_writeEnable;

  wire io_asyncReset = ~cpu_reset;

  assign {user_led3,user_led2,user_led1,user_led0} = io_gpioA_write[3 : 0];
  assign io_gpioA_read[3:0] = {user_sw3,user_sw2,user_sw1,user_sw0};
  assign io_gpioA_read[7:4] = {user_btn3,user_btn2,user_btn1,user_btn0};
  assign io_gpioA_read[11:8] = {tck,tms,tdi,trst};

  reg  tesic_tck,tesic_tms,tesic_tdi;
  wire tesic_tdo;
  reg  soc_tck,soc_tms,soc_tdi;
  wire soc_tdo;

  always @(*) begin
      {soc_tck,  soc_tms,  soc_tdi  } = {tck,tms,tdi};
      tdo = soc_tdo;
  end

  Murax core (
    .io_asyncReset(io_asyncReset),
    .io_mainClk (clk100 ),
    .io_jtag_tck(soc_tck),
    .io_jtag_tdi(soc_tdi),
    .io_jtag_tdo(soc_tdo),
    .io_jtag_tms(soc_tms),
    .io_gpioA_read       (io_gpioA_read),
    .io_gpioA_write      (io_gpioA_write),
    .io_gpioA_writeEnable(io_gpioA_writeEnable),
    .io_uart_txd(serial_tx),
    .io_uart_rxd(serial_rx)
  );
endmodule
module SdramCtrlTester_tb
(
  input   io_bus_cmd_valid,
  output  io_bus_cmd_ready,
  input  [23:0] io_bus_cmd_payload_address,
  input   io_bus_cmd_payload_write,
  input  [15:0] io_bus_cmd_payload_data,
  input  [1:0] io_bus_cmd_payload_mask,
  input  [7:0] io_bus_cmd_payload_context,
  output  io_bus_rsp_valid,
  input   io_bus_rsp_ready,
  output [15:0] io_bus_rsp_payload_data,
  output [7:0] io_bus_rsp_payload_context,
  input   clk,
  input   reset
);

  wire [12:0] io_sdram_ADDR;
  wire [1:0] io_sdram_BA;
  wire [15:0] io_sdram_DQ;
  wire [15:0] io_sdram_DQ_read;
  wire [15:0] io_sdram_DQ_write;
  wire  io_sdram_DQ_writeEnable;
  wire [1:0] io_sdram_DQM;
  wire  io_sdram_CASn;
  wire  io_sdram_CKE;
  wire  io_sdram_CSn;
  wire  io_sdram_RASn;
  wire  io_sdram_WEn;

  assign io_sdram_DQ_read = io_sdram_DQ;
  assign io_sdram_DQ = io_sdram_DQ_writeEnable ? io_sdram_DQ_write : 16'bZZZZZZZZZZZZZZZZ;

  mt48lc16m16a2 sdram(
    .Dq(io_sdram_DQ),
    .Addr(io_sdram_ADDR),
    .Ba(io_sdram_BA),
    .Clk(clk),
    .Cke(io_sdram_CKE),
    .Cs_n(io_sdram_CSn),
    .Ras_n(io_sdram_RASn),
    .Cas_n(io_sdram_CASn),
    .We_n(io_sdram_WEn),
    .Dqm(io_sdram_DQM)
  );


  SdramCtrlTester uut (
    .io_sdram_ADDR(io_sdram_ADDR),
    .io_sdram_BA(io_sdram_BA),
    .io_sdram_DQ_read(io_sdram_DQ_read),
    .io_sdram_DQ_write(io_sdram_DQ_write),
    .io_sdram_DQ_writeEnable(io_sdram_DQ_writeEnable),
    .io_sdram_DQM(io_sdram_DQM),
    .io_sdram_CASn(io_sdram_CASn),
    .io_sdram_CKE(io_sdram_CKE),
    .io_sdram_CSn(io_sdram_CSn),
    .io_sdram_RASn(io_sdram_RASn),
    .io_sdram_WEn(io_sdram_WEn),
    .io_bus_cmd_valid(io_bus_cmd_valid),
    .io_bus_cmd_ready(io_bus_cmd_ready),
    .io_bus_cmd_payload_address(io_bus_cmd_payload_address),
    .io_bus_cmd_payload_write(io_bus_cmd_payload_write),
    .io_bus_cmd_payload_data(io_bus_cmd_payload_data),
    .io_bus_cmd_payload_mask(io_bus_cmd_payload_mask),
    .io_bus_cmd_payload_context(io_bus_cmd_payload_context),
    .io_bus_rsp_valid(io_bus_rsp_valid),
    .io_bus_rsp_ready(io_bus_rsp_ready),
    .io_bus_rsp_payload_data(io_bus_rsp_payload_data),
    .io_bus_rsp_payload_context(io_bus_rsp_payload_context),
    .clk(clk),
    .reset(reset)
  );

 // initial begin
  //  $dumpfile("wave.vcd");
  //  $dumpvars(0, SdramCtrlTester_tb);
 // end
endmodule
module Dummy();
  initial begin
    $dumpfile("wave.vcd");
    $dumpvars(1, Dummy);
  end
endmodule
module BlackBoxToTest
#(parameter aWidth=0, parameter bWidth=0)
(
  input [aWidth-1:0] io_inA,
  input [bWidth-1:0] io_inB,
  output reg [aWidth-1:0] io_outA,
  output reg [bWidth-1:0] io_outB,
  input  io_clockPin,
  input  io_resetPin
);


  always @ (posedge io_clockPin or posedge io_resetPin)
  begin
    if (io_resetPin) begin
      io_outA <= 0;
      io_outB <= 0;
    end else begin
      io_outA <= io_outA + io_inA;
      io_outB <= io_outB + io_inB;
    end
  end
endmodule
module BlackBoxed
(
  output[7:0]  bus3_cmd_read ,
  input [7:0] bus3_cmd_write ,
  input  bus3_cmd_writeenable ,
  inout [7:0] bus3_gpio
);


  assign bus3_gpio = bus3_cmd_writeenable ? bus3_cmd_write : 8'bZZZZZZZZ;
  assign bus3_cmd_read = bus3_gpio;
endmodule
module BlackBoxed
(
  output  bus3_cmd_read ,
  input  bus3_cmd_write ,
  input  bus3_cmd_writeenable ,
  inout  bus3_gpio
);


  assign bus3_gpio = bus3_cmd_writeenable ? bus3_cmd_write : 1'bZ;
  assign bus3_cmd_read = bus3_gpio;
endmodule
module PLL
(
  input  clk_in,
  output  clk_out = 0
);


  always @ (posedge clk_in)
  begin
      clk_out <= ! clk_out;
  end
endmodule
module OSERDESE2 (
  OFB,
  OQ,
  SHIFTOUT1,
  SHIFTOUT2,
  TBYTEOUT,
  TFB,
  TQ,

  CLK,
  CLKDIV,
  D1,
  D2,
  D3,
  D4,
  D5,
  D6,
  D7,
  D8,
  OCE,
  RST,
  SHIFTIN1,
  SHIFTIN2,
  T1,
  T2,
  T3,
  T4,
  TBYTEIN,
  TCE
);

  parameter DATA_RATE_OQ = "DDR";
  parameter DATA_RATE_TQ = "DDR";
  parameter integer DATA_WIDTH = 4;
  parameter [0:0] INIT_OQ = 1'b0;
  parameter [0:0] INIT_TQ = 1'b0;
  parameter [0:0] IS_CLKDIV_INVERTED = 1'b0;
  parameter [0:0] IS_CLK_INVERTED = 1'b0;
  parameter [0:0] IS_D1_INVERTED = 1'b0;
  parameter [0:0] IS_D2_INVERTED = 1'b0;
  parameter [0:0] IS_D3_INVERTED = 1'b0;
  parameter [0:0] IS_D4_INVERTED = 1'b0;
  parameter [0:0] IS_D5_INVERTED = 1'b0;
  parameter [0:0] IS_D6_INVERTED = 1'b0;
  parameter [0:0] IS_D7_INVERTED = 1'b0;
  parameter [0:0] IS_D8_INVERTED = 1'b0;
  parameter [0:0] IS_T1_INVERTED = 1'b0;
  parameter [0:0] IS_T2_INVERTED = 1'b0;
  parameter [0:0] IS_T3_INVERTED = 1'b0;
  parameter [0:0] IS_T4_INVERTED = 1'b0;


  `ifdef XIL_TIMING //Simprim
  parameter LOC = "UNPLACED";
  `endif
  parameter SERDES_MODE = "MASTER";
  parameter [0:0] SRVAL_OQ = 1'b0;
  parameter [0:0] SRVAL_TQ = 1'b0;
  parameter TBYTE_CTL = "FALSE";
  parameter TBYTE_SRC = "FALSE";
  parameter integer TRISTATE_WIDTH = 4;
  
  localparam in_delay = 0;
  localparam out_delay = 0;
  localparam INCLK_DELAY = 0;
  localparam OUTCLK_DELAY = 0;

  output OFB;
  output OQ;
  output SHIFTOUT1;
  output SHIFTOUT2;
  output TBYTEOUT;
  output TFB;
  output TQ;

  input CLK;
  input CLKDIV;
  input D1;
  input D2;
  input D3;
  input D4;
  input D5;
  input D6;
  input D7;
  input D8;
  input OCE;
  input RST;
  input SHIFTIN1;
  input SHIFTIN2;
  input T1;
  input T2;
  input T3;
  input T4;
  input TBYTEIN;
  input TCE;

  reg [1:0] counter;
  reg [7:0] dataA, dataB;
  reg [3:0] tA, tB;

  always @ (posedge CLKDIV or posedge RST) begin
    if (RST) begin
    end else begin
      dataA[0] <= D1;
      dataA[1] <= D2;
      dataA[2] <= D3;
      dataA[3] <= D4;
      dataA[4] <= D5;
      dataA[5] <= D6;
      dataA[6] <= D7;
      dataA[7] <= D8;

      tA[0] <= T1;
      tA[1] <= T2;
      tA[2] <= T3;
      tA[3] <= T4;
    end
  end

  always @ (posedge CLK or posedge RST) begin
    if (RST) begin
      counter <= 3;
    end else begin
      counter <= counter + 1;
      if(counter == DATA_WIDTH/2-1) begin
        counter <= 0;
        dataB <= dataA;
        tB <= tA;
      end;
    end
  end

  assign TQ = tB[0];
  assign OQ = dataB[counter*2 + 1 - CLK];


endmodule
module ISERDESE2 (
  O,
  Q1,
  Q2,
  Q3,
  Q4,
  Q5,
  Q6,
  Q7,
  Q8,
  SHIFTOUT1,
  SHIFTOUT2,

  BITSLIP,
  CE1,
  CE2,
  CLK,
  CLKB,
  CLKDIV,
  CLKDIVP,
  D,
  DDLY,
  DYNCLKDIVSEL,
  DYNCLKSEL,
  OCLK,
  OCLKB,
  OFB,
  RST,
  SHIFTIN1,
  SHIFTIN2
);

  parameter DATA_RATE = "DDR";
  parameter integer DATA_WIDTH = 4;
  parameter DYN_CLKDIV_INV_EN = "FALSE";
  parameter DYN_CLK_INV_EN = "FALSE";
  parameter [0:0] INIT_Q1 = 1'b0;
  parameter [0:0] INIT_Q2 = 1'b0;
  parameter [0:0] INIT_Q3 = 1'b0;
  parameter [0:0] INIT_Q4 = 1'b0;
  parameter INTERFACE_TYPE = "MEMORY";
  parameter IOBDELAY = "NONE";
  parameter [0:0] IS_CLKB_INVERTED = 1'b0;
  parameter [0:0] IS_CLKDIVP_INVERTED = 1'b0;
  parameter [0:0] IS_CLKDIV_INVERTED = 1'b0;
  parameter [0:0] IS_CLK_INVERTED = 1'b0;
  parameter [0:0] IS_D_INVERTED = 1'b0;
  parameter [0:0] IS_OCLKB_INVERTED = 1'b0;
  parameter [0:0] IS_OCLK_INVERTED = 1'b0;

  `ifdef XIL_TIMING //Simprim
  parameter LOC = "UNPLACED";
  `endif
  parameter integer NUM_CE = 2;
  parameter OFB_USED = "FALSE";
  parameter SERDES_MODE = "MASTER";
  parameter [0:0] SRVAL_Q1 = 1'b0;
  parameter [0:0] SRVAL_Q2 = 1'b0;
  parameter [0:0] SRVAL_Q3 = 1'b0;
  parameter [0:0] SRVAL_Q4 = 1'b0;

  localparam in_delay = 0;
  localparam out_delay = 0;
  localparam INCLK_DELAY = 0;
  localparam OUTCLK_DELAY = 0;

  output O;
  output Q1;
  output Q2;
  output Q3;
  output Q4;
  output Q5;
  output Q6;
  output Q7;
  output Q8;
  output SHIFTOUT1;
  output SHIFTOUT2;

  input BITSLIP;
  input CE1;
  input CE2;
  input CLK;
  input CLKB;
  input CLKDIV;
  input CLKDIVP;
  input D;
  input DDLY;
  input DYNCLKDIVSEL;
  input DYNCLKSEL;
  input OCLK;
  input OCLKB;
  input OFB;
  input RST;
  input SHIFTIN1;
  input SHIFTIN2;

endmodule
module OSERDESE2 (
  OFB,
  OQ,
  SHIFTOUT1,
  SHIFTOUT2,
  TBYTEOUT,
  TFB,
  TQ,

  CLK,
  CLKDIV,
  D1,
  D2,
  D3,
  D4,
  D5,
  D6,
  D7,
  D8,
  OCE,
  RST,
  SHIFTIN1,
  SHIFTIN2,
  T1,
  T2,
  T3,
  T4,
  TBYTEIN,
  TCE
);

  parameter DATA_RATE_OQ = "DDR";
  parameter DATA_RATE_TQ = "DDR";
  parameter integer DATA_WIDTH = 4;
  parameter [0:0] INIT_OQ = 1'b0;
  parameter [0:0] INIT_TQ = 1'b0;
  parameter [0:0] IS_CLKDIV_INVERTED = 1'b0;
  parameter [0:0] IS_CLK_INVERTED = 1'b0;
  parameter [0:0] IS_D1_INVERTED = 1'b0;
  parameter [0:0] IS_D2_INVERTED = 1'b0;
  parameter [0:0] IS_D3_INVERTED = 1'b0;
  parameter [0:0] IS_D4_INVERTED = 1'b0;
  parameter [0:0] IS_D5_INVERTED = 1'b0;
  parameter [0:0] IS_D6_INVERTED = 1'b0;
  parameter [0:0] IS_D7_INVERTED = 1'b0;
  parameter [0:0] IS_D8_INVERTED = 1'b0;
  parameter [0:0] IS_T1_INVERTED = 1'b0;
  parameter [0:0] IS_T2_INVERTED = 1'b0;
  parameter [0:0] IS_T3_INVERTED = 1'b0;
  parameter [0:0] IS_T4_INVERTED = 1'b0;


  `ifdef XIL_TIMING //Simprim
  parameter LOC = "UNPLACED";
  `endif
  parameter SERDES_MODE = "MASTER";
  parameter [0:0] SRVAL_OQ = 1'b0;
  parameter [0:0] SRVAL_TQ = 1'b0;
  parameter TBYTE_CTL = "FALSE";
  parameter TBYTE_SRC = "FALSE";
  parameter integer TRISTATE_WIDTH = 4;

  localparam in_delay = 0;
  localparam out_delay = 0;
  localparam INCLK_DELAY = 0;
  localparam OUTCLK_DELAY = 0;

  output OFB;
  output OQ;
  output SHIFTOUT1;
  output SHIFTOUT2;
  output TBYTEOUT;
  output TFB;
  output TQ;

  input CLK;
  input CLKDIV;
  input D1;
  input D2;
  input D3;
  input D4;
  input D5;
  input D6;
  input D7;
  input D8;
  input OCE;
  input RST;
  input SHIFTIN1;
  input SHIFTIN2;
  input T1;
  input T2;
  input T3;
  input T4;
  input TBYTEIN;
  input TCE;

endmodule
module PinsecTester_tb
(
);

  wire [12:0] io_sdram_ADDR;
  wire [1:0] io_sdram_BA;
  wire [15:0] io_sdram_DQ;
  wire [15:0] io_sdram_DQ_read;
  wire [15:0] io_sdram_DQ_write;
  wire  io_sdram_DQ_writeEnable;
  wire [1:0] io_sdram_DQM;
  wire  io_sdram_CASn;
  wire  io_sdram_CKE;
  wire  io_sdram_CSn;
  wire  io_sdram_RASn;
  wire  io_sdram_WEn;

  reg   io_asyncReset;
  reg   io_axiClk;
  reg   io_vgaClk;

  reg  loader_valid;
  reg  [15 : 0]loader_data;
  reg  [1 : 0]loader_bank;
  reg  [31 : 0]loader_address;

  assign io_sdram_DQ_read = io_sdram_DQ;
  assign io_sdram_DQ = io_sdram_DQ_writeEnable ? io_sdram_DQ_write : 16'bZZZZZZZZZZZZZZZZ;

  mt48lc16m16a2 sdram(
    .Dq(io_sdram_DQ),
    .Addr(io_sdram_ADDR),
    .Ba(io_sdram_BA),
    .Clk(io_axiClk),
    .Cke(io_sdram_CKE),
    .Cs_n(io_sdram_CSn),
    .Ras_n(io_sdram_RASn),
    .Cas_n(io_sdram_CASn),
    .We_n(io_sdram_WEn),
    .Dqm(io_sdram_DQM),
    .loader_valid(loader_valid),
    .loader_data(loader_data),
    .loader_bank(loader_bank),
    .loader_address(loader_address)
  );


  Pinsec uut (
    .io_sdram_ADDR(io_sdram_ADDR),
    .io_sdram_BA(io_sdram_BA),
    .io_sdram_DQ_read(io_sdram_DQ_read),
    .io_sdram_DQ_write(io_sdram_DQ_write),
    .io_sdram_DQ_writeEnable(io_sdram_DQ_writeEnable),
    .io_sdram_DQM(io_sdram_DQM),
    .io_sdram_CASn(io_sdram_CASn),
    .io_sdram_CKE(io_sdram_CKE),
    .io_sdram_CSn(io_sdram_CSn),
    .io_sdram_RASn(io_sdram_RASn),
    .io_sdram_WEn(io_sdram_WEn),
    .io_asyncReset(io_asyncReset),
    .io_axiClk(io_axiClk),
    .io_vgaClk(io_vgaClk)
  );

 initial begin
   // $dumpfile("E:/waves/wave.vcd");
   // $dumpvars(0, uut);
   // $dumpvars(0, uut.axi_vgaCtrl);
   // $dumpvars(0, uut.axi_core);
   //  $dumpvars(0, sdram);
    //$dumpvars(0, uut.axi_sdramCtrl);
   // $dumpvars(0, uut.axi_core.core.execute0_inInst_payload_pc);
 end
endmodule
module adder(nibble1, nibble2, sum, carry_out);  
input  [3:0] nibble1;  
input  [3:0] nibble2;  
output [3:0] sum;  
output carry_out;  
wire [4:0] temp; 
  
  assign temp = nibble1 + nibble2;  
  assign sum = temp [3:0];  
  assign carry_out  = temp [4];  
endmodule
module counter(count, reset, enable, clk);
output [3:0] count;
input reset, enable, clk;
reg [3:0] count_temp = 4'h0;
assign count = count_temp;

always @ (posedge clk)
  begin
     if (reset)
       count_temp <= 4'h0;
     else if (enable)
       count_temp <= count_temp + 4'h01;
    $display("Counter++");
  end
endmodule
module TestMemVerilator (
  input      [9:0]    io_addr,
  input      [10:0]    io_wvalue,
  input               io_wenable,
  output     [10:0]    io_rvalue,
  input               clk,
  input               reset 
);
  reg        [10:0]    _zz_2_;
  wire                _zz_3_;
  wire       [10:0]    _zz_1_;
  reg [10:0] mem [0:1023] /* verilator public */;

  assign _zz_3_ = 1'b1;
  always @ (posedge clk) begin
    if(_zz_3_) begin
      _zz_2_ <= mem[io_addr];
    end
  end

  always @ (posedge clk) begin
    if(_zz_3_ && io_wenable ) begin
      mem[io_addr] <= _zz_1_;
    end
  end

  assign _zz_1_ = io_wvalue;
  assign io_rvalue = _zz_2_;

endmodule
module TestMemVerilatorW (
  input      [9:0]    io_addr,
  input      [127:0]    io_wvalue,
  input               io_wenable,
  output     [127:0]    io_rvalue,
  input               clk,
  input               reset 
);
  reg        [127:0]    _zz_2_;
  wire                _zz_3_;
  wire       [127:0]    _zz_1_;
  reg [127:0] mem [0:1023] /* verilator public */;

  assign _zz_3_ = 1'b1;
  always @ (posedge clk) begin
    if(_zz_3_) begin
      _zz_2_ <= mem[io_addr];
    end
  end

  always @ (posedge clk) begin
    if(_zz_3_ && io_wenable ) begin
      mem[io_addr] <= _zz_1_;
    end
  end

  assign _zz_1_ = io_wvalue;
  assign io_rvalue = _zz_2_;

endmodule
module TestMemIVerilog (
  input      [9:0]    io_addr,
  input      [10:0]    io_wvalue,
  input               io_wenable,
  output     [10:0]    io_rvalue,
  input               clk,
  input               reset 
);
  reg        [10:0]    _zz_2_;
  wire                _zz_3_;
  wire       [10:0]    _zz_1_;
  reg [10:0] mem [0:1023] /* verilator public */;

  assign _zz_3_ = 1'b1;
  always @ (posedge clk) begin
    if(_zz_3_) begin
      _zz_2_ <= mem[io_addr];
    end
  end

  always @ (posedge clk) begin
    if(_zz_3_ && io_wenable ) begin
      mem[io_addr] <= _zz_1_;
    end
  end

  assign _zz_1_ = io_wvalue;
  assign io_rvalue = _zz_2_;

endmodule
module rand_gen
(
    input clock,
    input enable,
    input reset,

    output reg [7:0] rnd
);

localparam LFSR_LEN = 128;

reg [LFSR_LEN-1:0] random;
wire feedback = random[127] ^ random[125] ^ random[100] ^ random[98];
reg [2:0] bit_idx;

always @(posedge clock) begin
    if (reset) begin
        random <= {LFSR_LEN{4'b0101}};
        bit_idx <= 0;
        rnd <= 0;
    end else if (enable) begin
        random <= {random[LFSR_LEN-2:0], feedback};
        rnd[bit_idx] <= feedback;
        bit_idx <= bit_idx + 1;
    end
end

endmodule
module phy_len_calculation
(
    input clock,
    input reset,
    input enable,

    input [4:0]   state,
    input [4:0]   old_state,
    input [19:0]  num_bits_to_decode,
    input [7:0]   pkt_rate,//bit [7] 1 means ht; 0 means non-ht
    
    output reg [14:0] n_ofdm_sym,//max 20166 = (22+65535*8)/26
    output reg [19:0] n_bit_in_last_sym,//max ht ndbps 260
    output reg        phy_len_valid
);

reg start_calculation;
reg   end_calculation;

reg [8:0] n_dbps;

// lookup table for N_DBPS (Number of data bits per OFDM symbol)
always @( pkt_rate[7],pkt_rate[3:0] )
begin
    case ({pkt_rate[7],pkt_rate[3:0]})
        5'b01011 : begin //non-ht 6Mbps
            n_dbps = 24;
            end
        5'b01111 : begin //non-ht 9Mbps
            n_dbps = 36;
            end
        5'b01010 : begin //non-ht 12Mbps
            n_dbps = 48;
            end
        5'b01110 : begin //non-ht 18Mbps
            n_dbps = 72;
            end
        5'b01001 :  begin //non-ht 24Mbps
            n_dbps = 96;
            end
        5'b01101 : begin //non-ht 36Mbps
            n_dbps = 144;
            end
        5'b01000  : begin //non-ht 48Mbps
            n_dbps = 192;
            end
        5'b01100 : begin //non-ht 54Mbps
            n_dbps = 216;
            end
        5'b10000 : begin //ht mcs 0
            n_dbps = 26;
            end
        5'b10001 : begin //ht mcs 1
            n_dbps = 52;
            end
        5'b10010 : begin //ht mcs 2
            n_dbps = 78;
            end
        5'b10011 : begin //ht mcs 3
            n_dbps = 104;
            end
        5'b10100 :  begin //ht mcs 4
            n_dbps = 156;
            end
        5'b10101 : begin //ht mcs 5
            n_dbps = 208;
            end
        5'b10110  : begin //ht mcs 6
            n_dbps = 234;
            end
        5'b10111 : begin //ht mcs 7
            n_dbps = 260;
            end
        default: begin
            n_dbps = 0;
            end
    endcase
end

`include "common_params.v"
always @(posedge clock) begin
if (reset) begin
    n_ofdm_sym <= 1;
    n_bit_in_last_sym <= 130; // half of max num bits to have a rough mid-point estimation in case no calculation happen
    phy_len_valid <= 0;
    start_calculation <= 0;
    end_calculation <= 0;
end else begin
    if ( (state != S_HT_SIG_ERROR && old_state == S_CHECK_HT_SIG) || ((state == S_DECODE_DATA && (old_state == S_CHECK_SIGNAL || old_state == S_DETECT_HT))) ) begin
        n_bit_in_last_sym <= num_bits_to_decode;
        if (num_bits_to_decode <= n_dbps) begin
            phy_len_valid <= 1;
            end_calculation <= 1;
        end else begin
            start_calculation <= 1;
        end
    end

    if (start_calculation == 1 && end_calculation != 1) begin
        if (n_bit_in_last_sym <= n_dbps) begin
            phy_len_valid <= 1;
            end_calculation <= 1;
        end else begin
            n_bit_in_last_sym <= n_bit_in_last_sym - n_dbps;
            n_ofdm_sym = n_ofdm_sym + 1;
        end
    end
end
end

endmodule
module fifo_sample_delay #
(
    parameter integer DATA_WIDTH	= 8,
    parameter integer LOG2_FIFO_DEPTH	= 7
)
(
      input wire clk,
      input wire rst,

      input wire [(LOG2_FIFO_DEPTH-1):0] delay_ctl,

      input wire [(DATA_WIDTH-1):0] data_in,
      input wire data_in_valid,
      output wire [(DATA_WIDTH-1):0] data_out,
      output wire data_out_valid
);

wire [LOG2_FIFO_DEPTH:0] rd_data_count;
wire [LOG2_FIFO_DEPTH:0] wr_data_count;
wire full;
wire empty;

reg rd_en_start;
wire rd_en;

reg  [LOG2_FIFO_DEPTH:0]  wr_data_count_reg;
wire wr_complete_pulse;

assign wr_complete_pulse = (wr_data_count > wr_data_count_reg);
assign rd_en = (rd_en_start&wr_complete_pulse);
assign data_out_valid = (rd_en_start&data_in_valid);

xpm_fifo_sync #(
  .DOUT_RESET_VALUE("0"),    // String
  .ECC_MODE("no_ecc"),       // String
  .FIFO_MEMORY_TYPE("auto"), // String
  .FIFO_READ_LATENCY(0),     // DECIMAL
  .FIFO_WRITE_DEPTH(1<<LOG2_FIFO_DEPTH),   // DECIMAL
  .FULL_RESET_VALUE(0),      // DECIMAL
  .PROG_EMPTY_THRESH(10),    // DECIMAL
  .PROG_FULL_THRESH(10),     // DECIMAL
  .RD_DATA_COUNT_WIDTH(LOG2_FIFO_DEPTH+1),   // DECIMAL
  .READ_DATA_WIDTH(DATA_WIDTH),      // DECIMAL
  .READ_MODE("fwft"),         // String
  .USE_ADV_FEATURES("0404"), // only enable rd_data_count and wr_data_count
  .WAKEUP_TIME(0),           // DECIMAL
  .WRITE_DATA_WIDTH(DATA_WIDTH),     // DECIMAL
  .WR_DATA_COUNT_WIDTH(LOG2_FIFO_DEPTH+1)    // DECIMAL
) fifo_1clk_i (
  .almost_empty(),
  .almost_full(),
  .data_valid(),
  .dbiterr(),
  .dout(data_out),
  .empty(empty),
  .full(full),
  .overflow(),
  .prog_empty(),
  .prog_full(),
  .rd_data_count(rd_data_count),
  .rd_rst_busy(),
  .sbiterr(),
  .underflow(),
  .wr_ack(),
  .wr_data_count(wr_data_count),
  .wr_rst_busy(),
  .din(data_in),
  .injectdbiterr(),
  .injectsbiterr(),
  .rd_en(rd_en),
  .rst(rst),
  .sleep(),
  .wr_clk(clk),
  .wr_en(data_in_valid)
);

always @(posedge clk) begin
  if (rst) begin
    wr_data_count_reg <= 0;
    rd_en_start <= 0;
  end else begin                                                                   
    wr_data_count_reg <= wr_data_count;
    rd_en_start <= ((wr_data_count == delay_ctl)?1:rd_en_start);
  end
end

endmodule
module rate_to_idx
(
    input clock,
    input enable,
    input reset,

    input [7:0] rate,
    input input_strobe,

    output reg [7:0] idx,
    output reg output_strobe
);

always @(posedge clock) begin
    if (reset) begin
        idx <= 0;
        output_strobe <= 0;
    end else if (enable & input_strobe) begin
        case ({rate[7], rate[2:0]})
            4'b0011: begin
                // 6 mbps
                idx <= 0;
            end
            4'b0111: begin
                // 9 mbps
                idx <= 1;
            end
            4'b0010: begin
                // 12 mbps
                idx <= 2;
            end
            4'b0110: begin
                // 18 mbps
                idx <= 3;
            end
            4'b0001: begin
                // 24 mbps
                idx <= 4;
            end
            4'b0101: begin
                // 36 mbps
                idx <= 5;
            end
            4'b0000: begin
                // 48 mbps
                idx <= 6;
            end
            4'b0100: begin
                // 54 mbps
                idx <= 7;
            end
            default: begin
                // mcs
                idx <= {5'b0, rate[2:0]};
            end
        endcase
        output_strobe <= 1;
    end else begin
        output_strobe <= 0;
    end
end

endmodule
module last_sym_indicator
(
    input clock,
    input reset,
    input enable,

    input ofdm_sym_valid,
    input [7:0] pkt_rate,//bit [7] 1 means ht; 0 means non-ht
    input [15:0] pkt_len,
    input ht_correction,

    output reg last_sym_flag
);

localparam S_WAIT_FOR_ALL_SYM = 0;
localparam S_ALL_SYM_RECEIVED = 1;

reg state;
reg ofdm_sym_valid_reg;

reg [8:0] n_dbps;
reg [7:0] n_ofdm_sym;
wire [16:0] n_bit;
wire [16:0] n_bit_target;

assign n_bit = n_dbps*(n_ofdm_sym+ht_correction);
assign n_bit_target = (({1'b0,pkt_len}<<3) + 16 + 6);

// lookup table for N_DBPS (Number of data bits per OFDM symbol)
always @( pkt_rate[7],pkt_rate[3:0] )
begin
    case ({pkt_rate[7],pkt_rate[3:0]})
        5'b01011 : begin //non-ht 6Mbps
            n_dbps = 24;
            end
        5'b01111 : begin //non-ht 9Mbps
            n_dbps = 36;
            end
        5'b01010 : begin //non-ht 12Mbps
            n_dbps = 48;
            end
        5'b01110 : begin //non-ht 18Mbps
            n_dbps = 72;
            end
        5'b01001 :  begin //non-ht 24Mbps
            n_dbps = 96;
            end
        5'b01101 : begin //non-ht 36Mbps
            n_dbps = 144;
            end
        5'b01000  : begin //non-ht 48Mbps
            n_dbps = 192;
            end
        5'b01100 : begin //non-ht 54Mbps
            n_dbps = 216;
            end
        5'b10000 : begin //ht mcs 0
            n_dbps = 26;
            end
        5'b10001 : begin //ht mcs 1
            n_dbps = 52;
            end
        5'b10010 : begin //ht mcs 2
            n_dbps = 78;
            end
        5'b10011 : begin //ht mcs 3
            n_dbps = 104;
            end
        5'b10100 :  begin //ht mcs 4
            n_dbps = 156;
            end
        5'b10101 : begin //ht mcs 5
            n_dbps = 208;
            end
        5'b10110  : begin //ht mcs 6
            n_dbps = 234;
            end
        5'b10111 : begin //ht mcs 7
            n_dbps = 260;
            end
        default: begin
            n_dbps = 0;
            end
    endcase
end

always @(posedge clock) begin
    if (reset) begin
        ofdm_sym_valid_reg <= 0;
    end else begin
        ofdm_sym_valid_reg <= ofdm_sym_valid;
    end
end

always @(posedge clock) begin
    if (reset) begin
        n_ofdm_sym <= 0;
        last_sym_flag <= 0;
        state <= S_WAIT_FOR_ALL_SYM;
    end else if (ofdm_sym_valid==0 && ofdm_sym_valid_reg==1) begin //falling edge means that current deinterleaving is finished, then we can start flush to speedup finishing work.
        n_ofdm_sym <= n_ofdm_sym + 1;
        if (enable) begin
            case(state)
                S_WAIT_FOR_ALL_SYM: begin
                    if ( (n_bit_target-n_bit)<=n_dbps ) begin
                        last_sym_flag <= 0;
                        state <= S_ALL_SYM_RECEIVED;
                    end
                end

                S_ALL_SYM_RECEIVED: begin
                    last_sym_flag <= 1;
                    state <= S_ALL_SYM_RECEIVED;
                end
                default: begin
                end
            endcase
        end
    end
end

endmodule
module delay_sample
#(
    parameter DATA_WIDTH = 16,
    parameter DELAY_SHIFT = 4
)
(
    input clock, 
    input enable,
    input reset,

    input [(DATA_WIDTH-1):0] data_in,
    input input_strobe,

    output [(DATA_WIDTH-1):0] data_out,
    output reg output_strobe
);

localparam DELAY_SIZE = 1<<DELAY_SHIFT;

reg [DELAY_SHIFT-1:0] 	  addr;
reg full;

ram_2port  #(.DWIDTH(DATA_WIDTH), .AWIDTH(DELAY_SHIFT)) delay_line (
    .clka(clock),
    .ena(1),
    .wea(input_strobe),
    .addra(addr),
    .dia(data_in),
    .doa(),
    .clkb(clock),
    .enb(input_strobe),
    .web(1'b0),
    .addrb(addr),
    .dib(32'hFFFF),
    .dob(data_out)
);

always @(posedge clock) begin
    if (reset) begin
        addr <= 0;
        full <= 0;
    end else if (enable) begin
        if (input_strobe) begin
            addr <= addr + 1;
            if (addr == DELAY_SIZE-1) begin
                full <= 1;
            end
            output_strobe <= full;
        end else begin
            output_strobe <= 0;
        end
    end else begin
        output_strobe <= 0;
    end
end

endmodule
module complex_to_mag_sq (
    input clock,
    input enable,
    input reset,

    input signed [15:0] i,
    input signed [15:0] q,
    input input_strobe,

    output [31:0] mag_sq,
    output mag_sq_strobe
);

reg valid_in;
reg [15:0] input_i;
reg [15:0] input_q;
reg [15:0] input_q_neg;

complex_mult mult_inst (
    .clock(clock),
    .reset(reset),
    .enable(enable),
    
    .a_i(input_i),
    .a_q(input_q),
    .b_i(input_i),
    .b_q(input_q_neg),
    .input_strobe(valid_in),

    .p_i(mag_sq),
    .output_strobe(mag_sq_strobe)
);

always @(posedge clock) begin
    if (reset) begin
        input_i <= 0;
        input_q <= 0;
        input_q_neg <= 0;
        valid_in <= 0;
    end else if (enable) begin
        valid_in <= input_strobe;
        input_i <= i;
        input_q <= q;
        input_q_neg <= ~q+1;
    end
end
endmodule
module calc_mean
(
    input clock,
    input enable,
    input reset,

    input signed [15:0] a,
    input signed [15:0] b,
    input sign,
    input input_strobe,

    output reg signed [15:0] c,
    output reg output_strobe
);

reg signed [15:0] aa;
reg signed [15:0] bb;
reg signed [15:0] cc;

reg [1:0] delay;
reg [1:0] sign_stage;

always @(posedge clock) begin
    if (reset) begin
        aa <= 0;
        bb <= 0;
        cc <= 0;
        c <= 0;
        output_strobe <= 0;
        delay <= 0;
    end else if (enable) begin
        delay[0] <= input_strobe;
        delay[1] <= delay[0];
        output_strobe <= delay[1];
        sign_stage[1] <= sign_stage[0];
        sign_stage[0] <= sign;

        aa <= a>>>1;
        bb <= b>>>1;
        cc <= aa + bb;
        c <= sign_stage[1]? ~cc+1: cc;
    end
end

endmodule
module moving_avg
#(
    parameter DATA_WIDTH = 32,
    parameter WINDOW_SHIFT = 4,
    parameter SIGNED = 0
)
(
    input clock,
    input enable,
    input reset,

    input signed [DATA_WIDTH-1:0] data_in,
    input input_strobe,

    output reg signed [DATA_WIDTH-1:0] data_out,
    output reg output_strobe
);

localparam WINDOW_SIZE = 1<<WINDOW_SHIFT;
localparam SUM_WIDTH = DATA_WIDTH + WINDOW_SHIFT;

reg signed [(SUM_WIDTH-1):0] running_sum;

wire signed [DATA_WIDTH-1:0] old_data;
wire signed [DATA_WIDTH-1:0] new_data = data_in;

wire signed [SUM_WIDTH-1:0] ext_old_data = {{WINDOW_SHIFT{old_data[DATA_WIDTH-1]}}, old_data};
wire signed [SUM_WIDTH-1:0] ext_new_data = {{WINDOW_SHIFT{new_data[DATA_WIDTH-1]}}, new_data};


reg [WINDOW_SHIFT-1:0] addr;
reg full;

ram_2port  #(.DWIDTH(DATA_WIDTH), .AWIDTH(WINDOW_SHIFT)) delay_line (
    .clka(clock),
    .ena(1),
    .wea(input_strobe),
    .addra(addr),
    .dia(data_in),
    .doa(),
    .clkb(clock),
    .enb(input_strobe),
    .web(0),
    .addrb(addr),
    .dib(32'hFFFF),
    .dob(old_data)
);

integer i;
always @(posedge clock) begin
    if (reset) begin
        addr <= 0;
        running_sum <= 0;
        full <= 0;
        data_out <= 0;
    end else if (enable) begin
        if (input_strobe) begin
            addr <= addr + 1;
            data_out <= running_sum[SUM_WIDTH-1:WINDOW_SHIFT];

            if (addr == WINDOW_SIZE-1) begin
                full <= 1;
            end

            if (full) begin
                running_sum <= running_sum + ext_new_data- ext_old_data;
            end else begin
                running_sum <= running_sum + ext_new_data;
            end

            output_strobe <= full;
        end else begin
            output_strobe <= 0;
        end
    end else begin
        output_strobe <= 0;
    end
end
endmodule
module delayT
#(
    parameter DATA_WIDTH = 32,
    parameter DELAY = 1
)
(
    input clock,
    input reset,

    input [DATA_WIDTH-1:0] data_in,
    output [DATA_WIDTH-1:0] data_out
);

reg [DATA_WIDTH-1:0] ram[DELAY-1:0];
integer i;

assign data_out = ram[DELAY-1];

always @(posedge clock) begin
    if (reset) begin
        for (i = 0; i < DELAY; i = i+1) begin
            ram[i] <= 0;
        end
    end else begin
        ram[0] <= data_in;
        for (i = 1; i < DELAY; i= i+1) begin
            ram[i] <= ram[i-1];
        end
    end
end

endmodule
module divider (
    input clock,
    input reset,
    input enable,

    input signed [31:0] dividend,
    input signed [23:0] divisor,
    input input_strobe,

    output signed [31:0] quotient,
    output output_strobe
);

div_gen div_inst (
    .clk(clock),
    .dividend(dividend),
    .divisor(divisor),
    .input_strobe(input_strobe),
    .output_strobe(output_strobe),
    .quotient(quotient)
);

// // --------old one---------------
// div_gen_v3_0 div_inst (
//     .clk(clock),
//     .dividend(dividend),
//     .divisor(divisor),
//     .quotient(quotient)
// );

// delayT #(.DATA_WIDTH(1), .DELAY(36)) out_inst (
//     .clock(clock),
//     .reset(reset),
//     .data_in(input_strobe),
//     .data_out(output_strobe)
// );

endmodule
module rand_gen_tb;

reg clock;
reg reset;
reg enable;

wire [7:0] rnd;

integer fd;

rand_gen inst (
    .clock(clock),
    .enable(enable),
    .reset(reset),

    .rnd(rnd)
);


initial begin
    clock = 0;
    reset = 1;
    enable = 0;

    fd = $fopen("./sim_out/rand_gen.txt", "w");

    # 10 reset = 0;
    enable = 1;

    # 10000000 $finish;
end


always begin
    #1 clock <= ~clock;
end

always @(posedge clock) begin
    if (enable) begin
        $fwrite(fd, "%d\n", rnd);
    end
end

endmodule