`timescale 1ns / 1ps

import axi_vip_pkg::*;
import axi_vip_0_pkg::*;

module testbench();


reg clk;
reg reset;
reg resetn;

assign resetn = ~reset;

localparam T = 4;
always #(T/2) clk=~clk;

axi4l_intf # (
  .AXI_ADDR_WIDTH(32), 
  .AXI_DATA_WIDTH(32)
) 
ctrl_if (
  .clk(clk),
  .resetn(resetn)
);

axi_vip_0_mst_t  vip_mst;
xil_axi_resp_t     resp;

axi_vip_0 axi_vip_inst (
  .aclk(clk),                   
  .aresetn(resetn),             
  .m_axi_awaddr( ctrl_if.awaddr ),
  .m_axi_awprot( ctrl_if.awprot ),
  .m_axi_awvalid( ctrl_if.awvalid ),
  .m_axi_awready( ctrl_if.awready ),
  .m_axi_wdata( ctrl_if.wdata ),
  .m_axi_wstrb( ctrl_if.wstrb ),
  .m_axi_wvalid( ctrl_if.wvalid ),
  .m_axi_wready( ctrl_if.wready ),
  .m_axi_bresp( ctrl_if.bresp ),
  .m_axi_bvalid( ctrl_if.bvalid ),
  .m_axi_bready( ctrl_if.bready ),
  .m_axi_araddr( ctrl_if.araddr ),
  .m_axi_arprot( ctrl_if.arprot ),
  .m_axi_arvalid( ctrl_if.arvalid ),
  .m_axi_arready( ctrl_if.arready ),
  .m_axi_rdata( ctrl_if.rdata ),
  .m_axi_rresp( ctrl_if.rresp ),
  .m_axi_rvalid( ctrl_if.rvalid ),
  .m_axi_rready( ctrl_if.rready )  

);

initial begin
    vip_mst = new("vip_mst", axi_vip_inst.inst.IF);
    vip_mst.start_master();
end

wire [127:0] iq_out;
wire iq_out_valid;
reg start_pulse;

gen_ofdm dut (
  .clk(clk),    
  .reset(reset),

  .ctrl_if(ctrl_if),
  .start_pulse(start_pulse),
  .iq_out(iq_out),
  .iq_out_valid(iq_out_valid)
);

int fid_out;

reg [15:0] n_samp_per_chip;
reg [15:0] n_chip_per_pulse;
reg [15:0] n_total_chips;
reg [15:0] n_pulses;

initial begin
    reset = 1'b1;
    clk = 1'b0;
    start_pulse = 1'b0;
    $display($time, " << Starting the Simulation >>");

    // Open Output File
    fid_out = $fopen("/home/bkiedinger/projects/castelion/radar_alinx_kintex/python/waveform_generator/sim_out.bin", "wb");

    // Release Reset
    repeat(25) @(posedge clk);
    reset = 1'b0;
    repeat(25) @(posedge clk);

    n_samp_per_chip = 64;
    n_chip_per_pulse = 8;
    n_total_chips = 16;
    n_pulses = 4;
    

    // Set Control Regs
        vip_mst.AXI4LITE_WRITE_BURST(16'h0004, 0, 4177526784, resp);      // Start Freq
    vip_mst.AXI4LITE_WRITE_BURST(16'h0008, 0, n_total_chips, resp);             
    vip_mst.AXI4LITE_WRITE_BURST(16'h000C, 0, (n_chip_per_pulse << 16) | n_samp_per_chip, resp);
    vip_mst.AXI4LITE_WRITE_BURST(16'h0010, 0, 33554432, resp);        // Delta Freq

    // Load Sequence
    vip_mst.AXI4LITE_WRITE_BURST(16'h0018, 0, 0, resp);  // Set Start Address
    for (int i = 0; i < 8; i = i + 1) begin
      vip_mst.AXI4LITE_WRITE_BURST(16'h001C, 0, i, resp);  // Load Chirp Sequence
    end
    for (int i = 0; i < 8; i = i + 1) begin
      vip_mst.AXI4LITE_WRITE_BURST(16'h001C, 0, i, resp);  // Load Chirp Sequence
    end

    // Load Start Phases
    // vip_mst.AXI4LITE_WRITE_BURST(16'h0020, 0, 0, resp);  // Set Start Address
    // for (int i = 0; i < 8; i = i + 1) begin
    //   vip_mst.AXI4LITE_WRITE_BURST(16'h0024, 0, i, resp);  // Load Chirp Sequence
    // end    

    for (int i = 0; i < n_pulses; i = i + 1) begin

      repeat(1000) @(posedge clk);
      start_pulse = 1'b1;
      @(posedge clk);
      start_pulse = 1'b0;

      repeat(n_samp_per_chip * n_chip_per_pulse) @(posedge clk);
    end


    repeat(10000) @(posedge clk);
    $fclose(fid_out);
    $display($time, " << Ending the Simulation >>");
    $stop; 

end

// Write output data to file
always @ (posedge clk) begin
    if ( iq_out_valid == 1'b1 ) begin
        $fwrite(fid_out, "%d\n", iq_out[15:0] );
        $fwrite(fid_out, "%d\n", iq_out[31:16]);
        $fwrite(fid_out, "%d\n", iq_out[47:32]);
        $fwrite(fid_out, "%d\n", iq_out[63:48]);
        $fwrite(fid_out, "%d\n", iq_out[79:64]);
        $fwrite(fid_out, "%d\n", iq_out[95:80]);
        $fwrite(fid_out, "%d\n", iq_out[111:96]);
        $fwrite(fid_out, "%d\n", iq_out[127:112]);
    end
end
    
endmodule
`resetall
