`resetall
`timescale 1ns / 1ps
`default_nettype none

// Generates 4 output samples in parallel
// Samples are 16 bit I and 16 bit Q, 32 bits per sample

module gen_sine
(
    input  wire        clk,
    input  wire        reset,
    input  wire        set_phase,
    input  wire        valid,
    input  wire [31:0] phase,
    input  wire [31:0] frequency,

    output wire [127:0] iq_out,
    output wire         iq_out_valid
);

reg        set_phase_q;
reg        valid_q;
reg        valid_q2;
reg [31:0] phase_q;
reg [31:0] frequency_q;
reg [127:0] iq_out_i;

always @ (posedge clk) begin
    set_phase_q <= set_phase;
    phase_q <= phase;
    frequency_q <= frequency;
    valid_q <= valid;
    valid_q2 <= valid_q;
end

genvar i;
generate
    for (i = 0; i < 4; i = i + 1) begin

        reg [31:0] phase_accum;
        
        always @ (posedge clk) begin
            if (reset) begin
                phase_accum <= 0;
            end else if (valid_q) begin
                if (set_phase_q) begin
                    phase_accum <= phase_q + i*frequency_q;
                end else begin
                    phase_accum <= phase_accum + 4*frequency_q;
                end
            end
        end


        wire [39:0] cordic_phase_in = {{8{phase_accum[31]}}, phase_accum};

        wfg_cordic wfg_cordic_i (
            .aclk(clk),
            .s_axis_phase_tvalid(valid_q2),  
            .s_axis_phase_tdata(cordic_phase_in),  
            .m_axis_dout_tvalid(iq_out_valid),
            .m_axis_dout_tdata(iq_out_i[i*32+31:i*32])  
        );
                
    end
endgenerate  

assign iq_out = iq_out_i;

endmodule
`resetall
   