module TB();

initial
begin
     $fsdbDumpfile("TB.fsdb");
     $fsdbDumpvars(0, TB);
end

reg             clk;
reg             rstn;
reg     [15:0]  din_im; 

reg     [36:0]  a;
reg     [36:0]  b;
reg     [20:0]  c;
reg     [20:0]  d;

reg     [47:0]  fcw;

reg     [21:0]  cnt;
reg     [15:0]  din_imp;
reg     [15:0]  din_rect;
reg     [15:0]  din_cos;
reg     [15:0]  diff_in;
reg             en;

wire    [1 :0]  source_mode;
wire    [15 :0] iir_in;
wire    [15:0]  cos;
wire    [15:0]  sin;
wire    [15:0]  dout_p0;

initial 
begin
                #0;
                rstn    =         1'b0;
                clk     =         1'b0;

                din_im  =        16'd0;

                a       =        37'd1757225200;
                b       =        37'd0;
                c       =       -21'd1042856;
                d       =        21'd0;

                fcw     =       48'h0840_0000_0000;

                din_imp   =      16'd0; 
                din_rect  =      16'd0; 
                din_cos   =      16'd0; 

                #3600;
                en        =      1'b1; 
                #3800;
                rstn      =      1'b1;
                din_imp   =      16'd32767; 
                din_rect  =      16'd30000;
                #400;
                din_imp   =      16'd0; 
                #12000;
                din_rect  =      16'd0; 

end

always #200 clk = ~clk;

always@(posedge clk or negedge rstn)
                if(!rstn)
                        cnt     <=      22'd0;
                else
                        cnt     <=      cnt + 22'd1;

initial 
begin
        wait(cnt[16]==1'b1)
                        $finish(0);
end


always@(posedge clk or negedge rstn)
                if(!rstn)
                        begin
                                din_cos   <=    16'd0;
                                diff_in   <=    16'd0;
                        end
                else
                        din_cos   <=    cos;

assign source_mode = 2'b01;

always @(*)

        case(source_mode)
                2'b00 :   diff_in = din_imp;
                2'b01 :   diff_in = din_rect;
                2'b10 :   diff_in = din_cos;
        endcase


NCO     inst_nco_0(
                                .clk                            (clk            ),
                                .rstn                           (rstn           ),
                                .phase_manual_clr               (1'b0           ),
                                .phase_auto_clr                 (1'b0           ),
                                .fcw                            (fcw            ),
                                .pha                            (16'd0          ),
                                .cos                            (cos            ),
                                .sin                            (sin            )
                        );

diff    inst_diff
               (
                        .clk                    (clk                    ),
                        .en                     (en                     ),
                        .rstn                   (rstn                   ),
                        .din                    (diff_in                ),
                        .dout                   (iir_in                 )
                );

IIR_Filter      inst1_IIR_Filter
               (
                        .clk                    (clk                    ),
                        .rstn                   (rstn                   ),
                        .en                     (en                     ),
                        .din_re                 (iir_in                 ),
                        .din_im                 (din_im                 ),
                        .a_re                   (a                      ),   
                        .a_im                   (b                      ),               
                        .b_re                   (c                      ),               
                        .b_im                   (d                      ),                           
                        .dout                   (dout_p0                )
                );

integer signed In_fid;
integer signed Out_fid;

initial begin
        #0;
        In_fid  =       $fopen("./in");
        Out_fid =       $fopen("./out");
end

always@(posedge clk)

                $fwrite(In_fid,"%d\n",{{~{iir_in[15]}},iir_in[14:0]});

always@(posedge clk)

                $fwrite(Out_fid,"%d\n",{{~{dout_p0[15]}},dout_p0[14:0]});

endmodule                                                                               
                                                                                        
                                                                                        

