【SDR】costas_loop

SDR的一部分,2018-2019年设计的,未继续

早期希望使用120-125MSPS的ADC,考虑到成本,按照64.8MSPS设计。LTC2248或ZGAD65S14C。



CIC抽取倍率为27倍,输出为2.4MSPS。
CIC补偿滤波器为480阶FIR,抽取倍率为5倍,输出为480KSPS。
相位检测使用cordic计算arctan。
环路滤波为二阶锁频三阶锁相,相位差作为频率差,使用移位简化计算。
数字本振为IQ双路DDS加8阶cordic流水线修正。

 

 

/*

                      dsp48a1 x2                    dsp48a1 x2
    滤波器阶数                        4                   480n
    抽取倍数                            27x                 5x
    采样率       64.8M                   2.4M                         480k
    带宽                               200k                         200k/可变
                   +-->mul----->+ +--->+    +------+           +---------------------------------------->+--------------
                   |    |       | |    |    |      |           |                                         |
        adc------->+    +<--+   cic   ddc_fifo    fir_comp_dec_iq                                        |
                   |        |   | |    |    |      |           |                                         |
                   +-->mul-- -->+ +--->+    +------+           +----------------------------------------- -->+----------
                        |   |                                                                            |   |
                        |   |                     phase_increase                                         |   |
                        |   +<--+      +<----+    +<---phase_add<---loop_filter<------------+<---+    +--+   |
                        |       |      |     |    |        |             |                  |    |    |      |
                        |      cordic_dds    dds_iq        |             +<---phase_diff<---+    arctan      |
                        |       |      |     |    |        |                                     |    |      |
                        +<------+      +<----+    |        |                                     |    +<-----+
                                                  |        |

*/
/*
        +---+
    din--+->|mul|------------------------------->+
         |  +---+                                |
         |    |                                  |
         |    c1                                 |
         |                                       |
         |  +---+    +---+                     +---+
         +->|mul|--->|add|-->integral------+-->|add|-->dout
            +---+    +---+                 |   +---+
              |        |                   |
              c2       +<--integral_last<--+
*/

/*
                          +---+
    phase_diff-->+--->|mul|----------------------------------------------------------->+
                 |    +---+                                                            |
                 |      |                                                              |
                 |   freq_c1                                                           |
                 |                                                                     |
                 |    +---+                                                            |
                 +--->|mul|------>+                                                    |
                      +---+       |                                                    |
                        |         |                                                    |
                     freq_c2      |                     +<---integral_0_last<---+      |                                            +<---integral_1_last<---+
                                  |                     |                       |      |                                            |                       |
                      +---+     +---+                 +---+                     |    +---+                +---+                   +---+                     |   sum_1_k1   +---+
    phase----+------->|mul|---->|add|--->sum_c2_k3--->|add|--->integral_0------>+--->|add|--->sum_0_c1--->|add|--->sum_0_c1_k2--->|add|--->integral_1------>+------------->|add|--->dout--->
             |        +---+     +---+                 +---+                          +---+                +---+                   +---+                                    +---+
             |          |                                                                                   |                                                                |
             |       phase_k3                                                                               |                                                                |
             |                                                                                              |                                                                |
             |        +---+                                                                                 |                                                                |
             +------->|mul|-------------------------------------------------------------------------------->+                                                                |
             |        +---+                                                                                                                                                  |
             |          |                                                                                                                                                    |
             |       phase_k2                                                                                                                                                |
             |                                                                                                                                                               |
             |        +---+                                                                                                                                                  |
             +------->|mul|--------------------------------------------------------------------------------------------------------------------------------------------------+
                      +---+
                        |
                     phase_k1
*/

module loop_filter
#(
    parameter ANGLE_WIDTH=36
)
(
    input                        rst,
    input                        clk,
    input        signed    [ANGLE_WIDTH - 1:0]    phase,
    input        signed    [ANGLE_WIDTH - 1:0]    phase_diff,
    input                        din_latch,
    output    reg    signed    [31:0]            dout,
    output    reg                    dout_latch
);
    ////////////////////////////////////////////////////////////////
    localparam     shift_freq_c1    = 13;
    localparam    shift_freq_c2    = 19;
    localparam    shift_phase_k1    = 12;
    localparam    shift_phase_k2    = 17;
    localparam    shift_phase_k3    = 26;
    localparam    INTEGRAL_WIDTH    = ANGLE_WIDTH + shift_phase_k3;

    reg    [INTEGRAL_WIDTH - 1:0]    integral_0    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    integral_0_last    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    integral_1    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    integral_1_last    = 0;

    reg                din_latch_last        = 0;
    reg                din_latch_0        = 0;
    reg                din_latch_0_last    = 0;
    reg                din_latch_1        = 0;
    reg                din_latch_1_last    = 0;

    reg    signed    [INTEGRAL_WIDTH - 1:0]    sum_c2_k3 = 0;
    reg    signed    [INTEGRAL_WIDTH - 1:0]    sum_0_c1 = 0;
    reg    signed    [INTEGRAL_WIDTH - 1:0]    sum_0_c1_k2 = 0;
    wire    signed    [INTEGRAL_WIDTH - 1:0]    sum_1_k1;

    reg                    rst_last = 0;

    wire    [INTEGRAL_WIDTH - 1:0]    mul_freq_c1    = {{shift_freq_c1{phase_diff[ANGLE_WIDTH - 1]}},phase_diff,    {(INTEGRAL_WIDTH - shift_freq_c1 - ANGLE_WIDTH){1'b0}}};
    wire    [INTEGRAL_WIDTH - 1:0]    mul_freq_c2    = {{shift_freq_c2{phase_diff[ANGLE_WIDTH - 1]}},phase_diff,    {(INTEGRAL_WIDTH - shift_freq_c2 - ANGLE_WIDTH){1'b0}}};
    wire    [INTEGRAL_WIDTH - 1:0]    mul_phase_k1    = {{shift_phase_k1{phase[ANGLE_WIDTH - 1]}},    phase,        {(INTEGRAL_WIDTH - shift_phase_k1 - ANGLE_WIDTH){1'b0}}};
    wire    [INTEGRAL_WIDTH - 1:0]    mul_phase_k2    = {{shift_phase_k2{phase[ANGLE_WIDTH - 1]}},    phase,        {(INTEGRAL_WIDTH - shift_phase_k2 - ANGLE_WIDTH){1'b0}}};
    wire    [INTEGRAL_WIDTH - 1:0]    mul_phase_k3    = {{shift_phase_k3{phase[ANGLE_WIDTH - 1]}},    phase,        {(INTEGRAL_WIDTH - shift_phase_k3 - ANGLE_WIDTH){1'b0}}};
    /////////////////////////////////////
    always @(posedge clk)
    begin
        if(din_latch)
            sum_c2_k3    <= mul_freq_c2 - mul_phase_k3;

        din_latch_last    <= din_latch;
    end

    always @(negedge clk)
    begin
        if(rst)
        begin
            integral_0    <= 0;
        end
        else
        begin
            if(din_latch_last)
            begin
                integral_0    <= integral_0_last + sum_c2_k3;
            end
        end
        din_latch_0    <= din_latch_last;
    end

    always @(posedge clk)
    begin
        integral_0_last    <= integral_0;
    end

    always @(posedge clk)
    begin
        if(din_latch_0)
            sum_0_c1    <= integral_0 + mul_freq_c1;
        din_latch_0_last    <= din_latch;
    end
    always @(negedge clk)
    begin
        if(din_latch_0_last)
            sum_0_c1_k2    <= sum_0_c1 - mul_phase_k2;
        din_latch_1    <= din_latch_0_last;

        rst_last    <= rst;
    end
    //////////////////////////////////////////////////////////////
    always @(posedge clk)
    begin
        if(rst_last)
        begin
            integral_1    <= 0;
        end
        else
        begin
            if(din_latch_1)
            begin
                integral_1    <= integral_1_last + sum_0_c1_k2;
            end
        end
        din_latch_1_last    <= din_latch_1;
    end

    always @(negedge clk)
    begin
        integral_1_last    <= integral_1;
    end

    assign sum_1_k1    = integral_1 - mul_phase_k1;

    always @(negedge clk)
    begin
        if(rst)
        begin
            dout        <= 0;
        end
        else
        begin
            if(din_latch_1_last)
                dout        <= sum_1_k1[(INTEGRAL_WIDTH - 1)-:32];
        end
        dout_latch    <= din_latch_1_last;
    end

endmodule
/*
module loop_filter__freq
#(
    parameter ANGLE_WIDTH=36
)
(
    input                        rst,
    input                        costas_en,
    input                        clk,
    input        signed    [ANGLE_WIDTH - 1:0]    din,
    input                        din_latch,
    output    reg    signed    [31:0]            dout,
    output    reg                    dout_latch
);
    ////////////////////////////////////////////////////////////////
    localparam     shift_c1    = 13;
    localparam    shift_c2    = 19;
    localparam    shift_c3    = 24;
    localparam    INTEGRAL_WIDTH    = ANGLE_WIDTH + shift_c3;

    reg    [INTEGRAL_WIDTH - 1:0]    integral_0    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    integral_0_last    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    integral_1    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    integral_1_last    = 0;
    reg                din_latch_last    = 0;
    reg                costas_en_last    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    sum_0;
    wire    [INTEGRAL_WIDTH - 1:0]    sum_1;

    wire    [INTEGRAL_WIDTH - 1:0]    mul_c1    = {{shift_c1{din[ANGLE_WIDTH - 1]}},din,{(INTEGRAL_WIDTH - shift_c1 - ANGLE_WIDTH){1'b0}}};
    wire    [INTEGRAL_WIDTH - 1:0]    mul_c2    = {{shift_c2{din[ANGLE_WIDTH - 1]}},din,{(INTEGRAL_WIDTH - shift_c2 - ANGLE_WIDTH){1'b0}}};
    wire    [INTEGRAL_WIDTH - 1:0]    mul_c3    = {{shift_c3{din[ANGLE_WIDTH - 1]}},din,{(INTEGRAL_WIDTH - shift_c3 - ANGLE_WIDTH){1'b0}}};
    /////////////////////////////////////
    always @(posedge clk)
    begin
        din_latch_last    <= din_latch;
        costas_en_last    <= costas_en;
    end

    always @(posedge clk)
    begin
        if(din_latch)
        begin
            integral_0    <= integral_0_last + mul_c2;
        end
    end

    always @(negedge clk)
    begin
        if(rst || !costas_en_last)
            integral_0_last    <= 0;
        else
            integral_0_last    <= integral_0;
    end

    always @(negedge clk)
    begin
        sum_0    <= integral_0 + mul_c1;
    end
    //////////////////////////////////////////////////////////////
    always @(posedge clk)
    begin
        if(din_latch)
        begin
            integral_1    <= integral_1_last + sum_0;
        end
    end
    always @(negedge clk)
    begin
        if(rst || !costas_en_last)
            integral_1_last    <= 0;
        else
            integral_1_last    <= integral_1;
    end
    assign sum_1    = integral_1 + mul_c3;

    always @(negedge clk)
    begin
        dout        <= sum_1[(INTEGRAL_WIDTH - 1)-:32];
        dout_latch    <= din_latch_last;
    end

endmodule

module loop_filter__phase
#(
    parameter ANGLE_WIDTH=36
)
(
    input                        rst,
    input                        costas_en,
    input                        clk,
    input        signed    [ANGLE_WIDTH - 1:0]    din,
    input                        din_latch,
    output    reg    signed    [31:0]            dout,
    output    reg                    dout_latch
);
    ////////////////////////////////////////////////////////////////
    localparam     shift_c1    = 8;
    localparam    shift_c2    = 13;
    localparam    INTEGRAL_WIDTH    = ANGLE_WIDTH + shift_c2;

    reg    [INTEGRAL_WIDTH - 1:0]    integral_0    = 0;
    reg    [INTEGRAL_WIDTH - 1:0]    integral_0_last    = 0;
    reg                din_latch_last    = 0;
    reg                costas_en_last    = 0;
    wire    [INTEGRAL_WIDTH - 1:0]    sum_0;

    wire    [INTEGRAL_WIDTH - 1:0]    mul_c1    = {{shift_c1{din[ANGLE_WIDTH - 1]}},din,{(INTEGRAL_WIDTH - shift_c1 - ANGLE_WIDTH){1'b0}}};
    wire    [INTEGRAL_WIDTH - 1:0]    mul_c2    = {{shift_c2{din[ANGLE_WIDTH - 1]}},din,{(INTEGRAL_WIDTH - shift_c2 - ANGLE_WIDTH){1'b0}}};

    reg    rst_last = 0;
    /////////////////////////////////////
    always @(posedge clk)
    begin
        din_latch_last    <= din_latch;
        costas_en_last    <= costas_en;
    end

    always @(posedge clk)
    begin
        if(rst_last)
        begin
            integral_0    <= 0;
        end
        else
        begin
            if(din_latch)
            begin
                integral_0    <= integral_0_last + mul_c2;
            end
        end
    end

    always @(negedge clk)
    begin
        if(rst || !costas_en_last)
            integral_0_last    <= 0;
        else
            integral_0_last    <= integral_0;
        rst_last    <= rst;
    end
    assign    sum_0    = integral_0 + mul_c1;
    always @(negedge clk)
    begin
        if(rst)
        begin
            dout        <= 0;
            dout_latch    <= 1'b0;
        end
        else
        begin
            if(din_latch_last)
            begin
                dout        <= sum_0[(INTEGRAL_WIDTH - 1)-:32];
            end
            dout_latch    <= din_latch_last;
        end
    end

endmodule
*/
module phase_diff
(
    input                clk,
    input                en,

    input        signed    [35:0]    phase_in,
    input                latch_in,

    output    reg    signed    [35:0]    diff_out,
    output    reg            latch_out
);
    reg    signed    [35:0]    phase_0 = 0;
    reg    signed    [35:0]    phase_0_last = 0;
    reg    signed    [35:0]    phase_1 = 0;

    always @(posedge clk)
    begin
        if(latch_in)
            phase_0    <= phase_in;
    end
    always @(negedge clk)
    begin
        phase_0_last <= phase_0;
    end
    always @(posedge clk)
    begin
        if(latch_in)
            phase_1    <= phase_0_last;
    end
    always @(negedge clk)
    begin
        diff_out    <= phase_1 - phase_0;

        if(en)
            latch_out    <= latch_in;
        else
            latch_out    <= 1'b0;
    end
endmodule

module phase_detect_start_delay
#(
    localparam DELAY = 12
)
(
    input            rst,
    input            clk,
    input            din_latch,
    output    reg        dout_latch,
    output    reg        diff_en
);
    reg    [3:0]    count        = 0;
    reg    [3:0]    count_next    = 0;
    reg        condition_next    = 0;
    reg        din_latch_last    = 0;
    reg        diff_en_0    = 0;
    reg        diff_en_0_last    = 0;

    always @(posedge clk)
    begin
        if(rst)
        begin
            count        <= 0;
            condition_next    <= 1'b1;
        end
        else
        begin
            if(din_latch)
            begin
                count        <= count_next;
                condition_next    <= count_next < DELAY;
            end
        end
        din_latch_last    <= din_latch;
    end
    always @(negedge clk)
    begin
        if(condition_next)
        begin
            count_next    <= count + 1'b1;
        end

        if(condition_next)
            dout_latch    <= 1'b0;
        else
            dout_latch    <= din_latch_last;
    end

    always @(posedge clk)
    begin
        if(rst)
        begin
            diff_en_0        <= 1'b0;
        end
        else
        begin
            if(din_latch)
                diff_en_0    <= !condition_next;
        end
    end
    always @(negedge clk)
    begin
        diff_en_0_last    <= diff_en_0;
    end
    always @(posedge clk)
    begin
        if(din_latch)
            diff_en        <= diff_en_0_last;
    end
endmodule
module lock_detect
#(
    parameter    HYSTERESIS_UP    = 20,
    parameter    HYSTERESIS_DOWN    = 20,
    parameter    DIFF_ABS    = 2**24 - 1,
    parameter    HYSTERESIS_WIDTH    = 8
)
(
    input                rst,
    input                clk,
    input        signed    [35:0]    din,
    input                din_latch,
    input                phase_update,
    output    reg            lockon,
    output    reg            latch_out
);
    ////////////////////////////////////////////////////////////////
    reg    [HYSTERESIS_WIDTH - 1:0]    count_add = 0;
    reg    [HYSTERESIS_WIDTH - 1:0]    count_sub = 0;
    reg    [HYSTERESIS_WIDTH - 1:0]    count_add_next = 0;
    reg    [HYSTERESIS_WIDTH - 1:0]    count_sub_next = 0;
    reg                    in_range = 0;
    reg                    din_latch_last = 0;
    reg                    latch_0 = 0;
    reg                    condition_next_add = 0;
    reg                    condition_next_sub = 0;
    ////////////////////////////////////////////////////////////////
    always @(posedge clk)
    begin
        if(rst || phase_update)
        begin
            in_range    <= 1'b0;
        end
        else
        begin
            if(din_latch)
            begin
                if(din[35])
                    in_range    <= (din > (0 - DIFF_ABS));
                else
                    in_range    <= (din < DIFF_ABS);
            end
        end
        din_latch_last    <= din_latch;
    end

    always @(negedge clk)
    begin
        if(in_range)
        begin
            if(condition_next_add)
                count_add_next    <= count_add + 1'b1;
            else
                count_sub_next    <= HYSTERESIS_DOWN;
        end
        else
        begin
            if(condition_next_sub)
                count_sub_next    <= count_sub - 1'b1;
            else
                count_add_next    <= 0;
        end
        latch_0        <= din_latch_last;
        ///////////////////////////////////////////
        if(!condition_next_sub)    // count_next_sub==0,fully unlock
        begin
            latch_out    <= din_latch_last;
        end
        else
        begin
            if(in_range)    // locked,and in_range
            begin
                latch_out    <= din_latch_last;
            end
        end
    end

    always @(posedge clk)
    begin
        if(rst || phase_update)
        begin
            count_add        <= 0;
            count_sub        <= 0;

            condition_next_add    <= 1'b1;
            condition_next_sub    <= 1'b0;
        end
        else
        begin
            if(latch_0)
            begin
                count_add        <= count_add_next;
                count_sub        <= count_sub_next;

                condition_next_add    <= (count_add_next < HYSTERESIS_UP);
                condition_next_sub    <= (count_sub_next > 0);
            end
        end
    end
    always @(negedge clk)
    begin
        lockon    <= condition_next_sub;
    end
    ////////////////////////////////////////
endmodule
/*
module costas_adjust
(
    input                rst,
    input                clk,
    input                freq_lockon,
    input                phase_lockon,
    input                phase_update,

    input        signed    [35:0]    phase_in,
    input        signed    [35:0]    phase_diff_in,
    input                latch_in,

    output    reg    signed    [35:0]    phase_out,
    output    reg    signed    [35:0]    phase_diff_out,
    output    reg            latch_out
);
    ////////////////////////////////////////////////////////////////
    reg            freq_lockon_last    = 0;
    reg            freq_lockon_0        = 0;

    //reg            freq_unlocked        = 0;
    reg            freq_relocked        = 0;
    ////////////////////////////////////////////////////////////////
    reg            phase_lockon_last    = 0;
    reg            phase_lockon_0        = 0;

    reg            phase_unlocked        = 0;
    //reg            phase_relocked        = 0;
    ////////////////////////////////////////////////////////////////
    reg            use_pll            = 0;
    reg            phase_update_last    = 0;
    reg            latch_in_last        = 0;
    ////////////////////////////////////////////////////////////////
    always @(posedge clk)
    begin
        freq_lockon_last    <= freq_lockon;
    end
    always @(negedge clk)
    begin
        freq_lockon_0        <= freq_lockon_last;
    end
    always @(posedge clk)
    begin
        //freq_unlocked        <= ({freq_lockon_0,freq_lockon} == 2'b10);
        freq_relocked        <= ({freq_lockon_0,freq_lockon} == 2'b01);
    end
    ////////////////////////////////////////////////////////////////
    always @(posedge clk)
    begin
        phase_lockon_last    <= phase_lockon;
    end
    always @(negedge clk)
    begin
        phase_lockon_0        <= phase_lockon_last;
    end
    always @(posedge clk)
    begin
        phase_unlocked        <= ({phase_lockon_0,phase_lockon} == 2'b10);
        //phase_relocked        <= ({phase_lockon_0,phase_lockon} == 2'b01);
    end
    /////////////////////////////////////////////////////////////////
    always @(posedge clk)
    begin
        phase_update_last    <= phase_update;
    end
    always @(negedge clk)
    begin
        if(rst || phase_update_last)// || phase_unlocked)
        begin
            use_pll    <= 1'b0;
        end
        else
        begin
            if(freq_relocked)
                use_pll    <= 1'b1;
        end
    end
    always @(posedge clk)
    begin
        if(use_pll)
        begin
            phase_out    <= phase_in;
            phase_diff_out    <= 0;
        end
        else
        begin
            phase_out    <= 0;
            phase_diff_out    <= phase_diff_in;
        end
        latch_in_last    <= latch_in;
    end
    always @(negedge clk)
    begin
        latch_out    <= latch_in_last;
    end

endmodule
*/
module costas_loop
#(
    parameter    RAM_ADDR_WIDTH = 8
)
(
    input                        rst,
    input                        costas_en,

    input                        adc_clk,
    input        signed    [17:0]            adc_d,

    input            [31:0]            phase_increase_base,
    input                        phase_update,

    input                        proc_clk,
    output            [5:0]            error,

    input                        coef_in_clk,
    input                        coef_in_we,
    input            [RAM_ADDR_WIDTH - 1:0]    coef_in_addr,
    input        signed    [17:0]            coef_in_d,

    output        signed    [17:0]            ddc_out_i,
    output        signed    [17:0]            ddc_out_q,
    output                        ddc_out_latch,

    output        signed    [35:0]            dout_angle,
    output            [17:0]            magnitude,

    output                        lockon,
    output    reg        [31:0]            phase_increase
);
    //////////////////////////////////////////////////////////////

    wire    signed    [35:0]    phase_detect_out;
    wire            phase_detect_out_latch;
    wire    signed    [35:0]    phase_diff_out;
    wire            phase_diff_out_latch;

    wire    signed    [31:0]    loop_filter_out;
    wire            loop_filter_out_latch;

    wire        [4:0]    error_ddc;
    wire            error__arctan__conflict;
    assign error = {error__arctan__conflict,error_ddc};

    wire            phase_detect_start;
    wire            diff_en;
    wire            freq_lockon;
    wire            freq_lockon_latch;
    wire            phase_lockon;
    wire            phase_lockon_latch;

    assign dout_angle    = phase_detect_out;
    assign lockon        = phase_lockon;

    reg    signed    [31:0]    loop_filter_out_last = 0;

    wire    signed    [35:0]    adjust_phase_out;
    wire    signed    [35:0]    adjust_phase_diff_out;
    wire            adjust_latch_out;

    ddc
    #(
        .RAM_ADDR_WIDTH    (RAM_ADDR_WIDTH)
    )
    ddc_ins
    (
        .rst        (rst),

        .adc_clk    (adc_clk),
        .adc_d        (adc_d),

        .phase_increase    (phase_increase),
        .phase_offset    (32'd0),

        .proc_clk    (proc_clk),
        .error        (error_ddc),

        .coef_in_clk        (coef_in_clk),
        .coef_in_we        (coef_in_we),
        .coef_in_addr        (coef_in_addr),
        .coef_in_d        (coef_in_d),

        .dout_i        (ddc_out_i),
        .dout_q        (ddc_out_q),
        .dout_latch    (ddc_out_latch)
    );

    phase_detect_start_delay start_delay
    (
        .rst        (rst),
        .clk        (proc_clk),
        .din_latch    (ddc_out_latch),
        .dout_latch    (phase_detect_start),
        .diff_en    (diff_en)
    );
/*
    cordic_arctan phase_detect
    (
        .rst        (rst),
        .clk        (proc_clk),
        .calc_begin    (phase_detect_start),
        .error_conflict    (error__arctan__conflict),

        .din_x        (ddc_out_q),
        .din_y        (ddc_out_i),

        .dout_angle    (phase_detect_out),
        .dout_latch    (phase_detect_out_latch)
    );
*/
    cordic_arctan_and_magnitude phase_detect
    (
        .rst        (rst),
        .clk        (proc_clk),
        .calc_begin    (phase_detect_start),
        .error_conflict    (error__arctan__conflict),

        .din_x        (ddc_out_q),
        .din_y        (ddc_out_i),

        .dout_angle    (phase_detect_out),
        .magnitude    (magnitude),
        .dout_latch    (phase_detect_out_latch)
    );

    phase_diff phase_diff_ins
    (
        .clk        (proc_clk),
        .en        (diff_en),

        .phase_in    (phase_detect_out),
        .latch_in    (phase_detect_out_latch),

        .diff_out    (phase_diff_out),
        .latch_out    (phase_diff_out_latch)
    );

    lock_detect
    #(
        .HYSTERESIS_UP        (20),
        .HYSTERESIS_DOWN    (20),
        .DIFF_ABS        (2**24 - 1),
        .HYSTERESIS_WIDTH    (6)
    )
    freq_lock_detect
    (
        .rst            (rst),
        .clk            (proc_clk),
        .din            (phase_diff_out),
        .din_latch        (phase_diff_out_latch),
        .phase_update        (phase_update),
        .lockon            (freq_lockon),
        .latch_out        (freq_lockon_latch)
    );

    lock_detect
    #(
        .HYSTERESIS_UP        (50),
        .HYSTERESIS_DOWN    (50),
        .DIFF_ABS        (2**27 - 1),
        .HYSTERESIS_WIDTH    (6)
    )
    phase_lock_detect
    (
        .rst            (rst),
        .clk            (proc_clk),
        .din            (phase_detect_out),
        .din_latch        (phase_detect_out_latch),
        .phase_update        (phase_update),
        .lockon            (phase_lockon),
        .latch_out        (phase_lockon_latch)
    );
/*
    costas_adjust adjust
    (
        .rst            (rst),
        .clk            (proc_clk),
        .freq_lockon        (freq_lockon),
        .phase_lockon        (phase_lockon),
        .phase_update        (phase_update),

        .phase_in        (phase_detect_out),
        .phase_diff_in        (phase_diff_out),
        .latch_in        (freq_lockon_latch),

        .phase_out        (adjust_phase_out),
        .phase_diff_out        (adjust_phase_diff_out),
        .latch_out        (adjust_latch_out)
    );
*/
    loop_filter loop_filter_ins
    (
        .rst            (rst),
        .clk            (proc_clk),

        .phase            (phase_detect_out),    //(adjust_phase_out),
        .phase_diff        (phase_diff_out),    //(adjust_phase_diff_out),
        .din_latch        (phase_diff_out_latch),    //(adjust_latch_out),

        .dout            (loop_filter_out),
        .dout_latch        (loop_filter_out_latch)
    );

    /*
    costas_unlock_detect unlock_detect
    (
        .rst            (rst),
        .clk            (proc_clk),
        .locked            (locked),
        .phase_update        (phase_update),
        .adjust            (adjust),
        .adjust_out        (adjust_final)
    );
    */
    always @(posedge proc_clk)
    begin
        if(loop_filter_out_latch)
            loop_filter_out_last    <= loop_filter_out;
    end
    always @(negedge proc_clk)
    begin
        if(costas_en)
            phase_increase        <= phase_increase_base + loop_filter_out_last;
        else
            phase_increase        <= phase_increase_base;
    end

endmodule
costas_loop.v

 

 

/*


                                                 |    |               |      |                                |     |
                                                 |    |               |      |                                |     |
                            24M         24M      |    | 24M           | 480K |              480K              | 48K |
            +-->mul----->+ +--->+      +--->+    +---- --->+          +------ -->+          +----+----+       +----- --->+            +-->mul----->+
       120M |    |       | |    |      |    |    |    |    |          |      |   |          |    |    |       |     |    |            |    |       |
    adc---->+    +<--+   cic    cic_comp   ddc_fifo   |   fir_ddc_dec_iq     |  fir_ddc_lpf_iq   |   down_sample    |   fir_ddc_audio_iq   +<--+   add/sub---->ssb_out
            |        |   | |    |      |    |    |    |    |    50x   |      |   |    1x    |    |    |  10x  |     |    |     1x     |        |   |
            +-->mul-- -->+ +--->+      +--->+    +--->+--->+          +------+-->+          +---- ----+       +-----+--->+            +-->mul-- -->+
                 |   |   5x                                                                 |    |                                         |   |
                 |   |                                                                      |    |                                         |   |
                 |   |                     phase_increase                                   |    |                                         |   |
                 |   +<--+      +<----+    +<---phase_add<---loop_filter<----+----+    +<---+    |                                         |   +<--+
                 |       |      |     |    |        |                        |    |    |         |                                         |       |
                 |      cordic_dds    dds_iq        |                        |    arctan         |                                         |     dds_iq
                 |       |      |     |    |        |                        |    |    |         |                                         |       |
                 +<------+      +<----+    |        |                        |    |    +<--------+                                         +<------+
                                           |        |                        |



*/

/*
                                                                                                      +------->+
                                                                                                      |        |
                                                                                                      |       arctan
                                                                                                      |        |
                                                                                                      |   +--->+
                                                                                                      |   |
                                                                                                      |   |
                                                                                     37.5k/12.5k/1.5k |   |
                                                                                        480k/96k      |   |
                                                                                        500n/2000n    |   |
                                                                                        dsp48a1 x2    |   |
                                                                     +------->mul------>+      +----->+--- ----->mul----->+
                                                                     |         |        |      |          |       |       |
                                                                     |      dds_iq     fir_lpf_iq         |    dds_iq   add/sub--->
                                                                     |         |        |      |          |       |       |
                                                                     |   +--->mul------>+      +--------->+----->mul----->+
                                                                     |   |
                                                                     |   |
                                                                     |   |
                     dsp48a1 x2           dsp48a1 x2                 |   |           DSP48A1 x2
                                            480n                     |   |           500n/2000n
                                   2.4M             480k             |   |                       480K/96K
                                                    200k/25k         |   |           1.5k~1.75k
                   +-->mul----->+ +--->+           +---->+       +-->+--- --------->+          +-->+------->mul----->+
            64.8M  |    |       | |    |           |     |       |       |          |          |   |         |       |
        adc------->+    +<--+   cic   fir_comp_dec_iq   down_sample      |         fir_ddc_lpf_iq  |      dds_iq   add/sub--->
                   |        |   | |    |    5x     |     |  1/5x |       |          |    1x    |   |         |       |
                   +-->mul-- -->+ +--->+           +---->+       +------>+--------->+          +--- -->+--->mul----->+
                        |   |   27x                                                                |   |
                        |   |                                                                      |   |
                        |   |                                                                      |   |
                        |   +<--+      +<----+                                              +<-----+   |
                        |       |      |     |                                              |          |
                        |      cordic_dds    dds_iq                                     arctan         |
                        |       |      |     |                                              |          |
                        +<------+      +<----+                                              +<---------+

*/





/*
    115.2M/48=2.4M                57.6M        115.2M        172.8
                            WFM        AM_120M
                ---------------------------------------------------------------------------
                        403.2M        460.8M
                            UHF
                ######################################################################
    124.8M/52=2.4M        0.5M        62.4M        124.8M        187.2M        249.6
                SW    HF                VHF
                ---------------------------------------------------------------------------
                374.4        436.8        499.2



    57.6M/24=2.4M                28.8M        57.6M        86.4M        115.2M        144M        172.8M
                            HF_50-54            WFM_88-108    AM_AIR_120M
                -----------------------------------------------------------------------------------------
                403.2M        432M        460.8M        488.8M        518.4M
                    CB_409M
                ##########################################################################################
    64.8M/27=2.4M        0.5M        32.4M        64.8M        97.2M        129.6M        162M    194.4M    259.2    324
                    SW_1.6-30                            VHF_143M
                ----------------------------------------------------------------------------------------------
                388.8M        421.2M        453.6M        486M        518.4M
                            UHF_438M
                ###############################################################################################
*/

/*
WFM
    120M        2.4M        480K                480k
        CIC_4        fir_480n    down        fir_500n
        50X        5X        1x        1X
        200K        200K                200K
-100db        2.27M        223.8K                204.7K

NFM
    120M        2.4M        480K                96k
        CIC_4        fir_480n    down        fir_500n
        50X        5X        5x        1X
        200K        25K                25K
-100db        2.27M        49.6K                25.9K

                20K                20K
                44.7K                20.9K

                12.5K                12.5K
                37.5K                13.4K

AM
    120M        2.4M        480K        96k        96k
                fir_480n    down_s        fir_500n
                5x        5x        1x
                10k                10k
                34.7k                11k

                20K
                44.7K

SSB
            2.4M        480k        96K        96k        12K        12k
                fir_480n    down_s        fir_500n    down        fir_500n
                5X        5x        1x        8X        1x
                3.5K                3.5K                3.5k
                29.7K                4.5k                3.6k

                20K
                44.7K


CW
            2.4M        480k        96K        96k        2K        2k
                fir_480n    down_s        fir_500n    down        fir_500n
                5X        5x        1x        48X        1x
                0.1K                0.1K                0.1k
                19.3K                0.75k                0.112k

                20K
                44.7K

*/

module ddc_fifo_cross_clk
(
    input            rst,

    input            din_clk,
    input            din_latch,
    input        [17:0]    din_i,
    input        [17:0]    din_q,

    input            dout_clk,
    output    reg        dout_latch,
    output        [17:0]    dout_i,
    output        [17:0]    dout_q,

    output    reg        error_conflicted
);
    wire            full;
    wire            empty;
    wire        [35:0]    fifo_dout;
    assign dout_i    = fifo_dout[18+:18];
    assign dout_q    = fifo_dout[0+:18];

    fifo
    #(
        .DATA_WIDTH    (36),
        .ADDR_WIDTH    (3)
    )
    fifo_ins
    (
        .rst        (rst),
        .wr_clk        (din_clk),
        .wr_en        (din_latch),
        .full        (full),
        .din        ({din_i,din_q}),
        .rd_clk        (dout_clk),
        .rd_en        (!empty),
        .empty        (empty),
        .dout        (fifo_dout)
    );
    always @(negedge dout_clk)
    begin
        dout_latch    <= !empty;
    end
    always @(posedge din_clk)
    begin
        if(rst)
            error_conflicted    <= 1'b0;
        else
        begin
            if(full)
                error_conflicted    <= 1'b1;
        end
    end

endmodule

module mul_ddc
(
    input                clk,
    input        signed    [17:0]    a,
    input        signed    [17:0]    b,
    output        signed    [35:0]    m
);
    // see ug389 Figure 1-3

    wire [7:0] opmode=
    {
        1'd0,//0=post-add,1=post-sub
        1'd0,//0=pre-add,1=pre-sub
        1'd0,//Force a value on carry-in to the post-adder,not usefull here
        1'd0,//Use the pre-adder
        2'd2,//Z input to the post-add==Use the POUT port
        2'd1//X input to the post-add== Use the multiplier product
    };
    DSP48A1 #(
        .A0REG(1),                  // First stage A input pipeline register (0/1)
        .A1REG(1),                  // Second stage A input pipeline register (0/1)
        .B0REG(1),                  // First stage B input pipeline register (0/1)
        .B1REG(1),                  // Second stage B input pipeline register (0/1)
        .CARRYINREG(1),            // CARRYIN input pipeline register (0/1)
        .CARRYINSEL("OPMODE5"), // Specify carry-in source, "CARRYIN" or "OPMODE5"
        .CARRYOUTREG(1),          // CARRYOUT output pipeline register (0/1)
        .CREG(1),                    // C input pipeline register (0/1)
        .DREG(1),                    // D pre-adder input pipeline register (0/1)
        .MREG(1),                    // M pipeline register (0/1)
        .OPMODEREG(0),             // Enable=1/disable=0 OPMODE input pipeline registers
        .PREG(1),                    // P output pipeline register (0/1)
        .RSTTYPE("SYNC")          // Specify reset type, "SYNC" or "ASYNC"
    )
    DSP48A1_inst (
        // Cascade Ports: 18-bit (each) output: Ports to cascade from one DSP48 to another
        .BCOUT(),              // 18-bit output: B port cascade output
        .PCOUT(),              // 48-bit output"OPMODE5" : P cascade output (if used, connect to PCIN of another DSP48A1)
        // Data Ports: 1-bit (each) output: Data input and output ports
        .CARRYOUT(),      // 1-bit output: carry output (if used, connect to CARRYIN pin of another
                                         // DSP48A1)

        .CARRYOUTF(),    // 1-bit output: fabric carry output
        .M(m),                         // 36-bit output: fabric multiplier data output
        .P(),                         // 48-bit output: data output
        // Cascade Ports: 48-bit (each) input: Ports to cascade from one DSP48 to another
        .PCIN(48'd0),                 // 48-bit input: P cascade input (if used, connect to PCOUT of another DSP48A1)
        // Control Input Ports: 1-bit (each) input: Clocking and operation mode
        .CLK(clk),                    // 1-bit input: clock input
        .OPMODE(opmode),            // 8-bit input: operation mode input
        // Data Ports: 18-bit (each) input: Data input and output ports
        .A(b),                         // 18-bit input: A data input
        .B(a),                         // 18-bit input: B data input (connected to fabric or BCOUT of adjacent DSP48A1)
        .C(48'd0),                         // 48-bit input: C data input
        .CARRYIN(1'b0),         // 1-bit input: carry input signal (if used, connect to CARRYOUT pin of another
                                         // DSP48A1)

        .D(),                         // 18-bit input: B pre-adder data input
        // Reset/Clock Enable Input Ports: 1-bit (each) input: Reset and enable input ports
        .CEA(1'b1),                    // 1-bit input: active high clock enable input for A registers
        .CEB(1'b1),                    // 1-bit input: active high clock enable input for B registers
        .CEC(1'b1),                    // 1-bit input: active high clock enable input for C registers
        .CECARRYIN(1'b1),    // 1-bit input: active high clock enable input for CARRYIN registers
        .CED(1'b1),                    // 1-bit input: active high clock enable input for D registers
        .CEM(1'b1),                    // 1-bit input: active high clock enable input for multiplier registers
        .CEOPMODE(1'b1),      // 1-bit input: active high clock enable input for OPMODE registers
        .CEP(1'b1),                    // 1-bit input: active high clock enable input for P registers
        .RSTA(1'b0),                 // 1-bit input: reset input for A pipeline registers
        .RSTB(1'b0),                 // 1-bit input: reset input for B pipeline registers
        .RSTC(1'b0),                 // 1-bit input: reset input for C pipeline registers
        .RSTCARRYIN(1'b0), // 1-bit input: reset input for CARRYIN pipeline registers
        .RSTD(1'b0),                 // 1-bit input: reset input for D pipeline registers
        .RSTM(1'b0),                 // 1-bit input: reset input for M pipeline registers
        .RSTOPMODE(1'b0),    // 1-bit input: reset input for OPMODE pipeline registers
        .RSTP(1'b0)                  // 1-bit input: reset input for P pipeline registers
    );
endmodule
/*
module down_sample
#(
    parameter    DOWN_RATIO    = 10,
    parameter    COUNT_WIDTH    = 4
)
(
    input                rst,
    input                clk,

    input        signed    [17:0]    din_i,
    input        signed    [17:0]    din_q,
    input                din_latch,

    output    reg    signed    [17:0]    dout_i,
    output    reg    signed    [17:0]    dout_q,
    output    reg            dout_latch
);
    reg    [COUNT_WIDTH - 1:0]    count        = 0;
    reg    [COUNT_WIDTH - 1:0]    count_next    = 0;

    reg    signed    [17:0]    din_i_last    = 0;
    reg    signed    [17:0]    din_q_last    = 0;

    reg            din_latch_last    = 0;
    reg            condition_rst    = 0;

    always @(posedge clk)
    begin
        if(rst)
        begin
            din_i_last    <= 0;
            din_q_last    <= 0;
        end
        else
        begin
            if(din_latch)
            begin
                din_i_last    <= din_i;
                din_q_last    <= din_q;
            end
        end

        if(rst)
        begin
            count        <= 0;
            condition_rst    <= 1'b1;
        end
        else
        begin
            if(din_latch)
            begin
                count        <= count_next;
                condition_rst    <= (count_next == DOWN_RATIO);
            end
        end
        din_latch_last    <= din_latch;
    end
    always @(negedge clk)
    begin
        if(condition_rst)
            count_next    <= 0;
        else
            count_next    <= count + 1'b1;

        dout_latch    <= (din_latch_last && condition_rst);

        if(din_latch_last && condition_rst)
        begin
            dout_i    <= din_i_last;
            dout_q    <= din_q_last;
        end
    end
endmodule

module down_sample2
#(
    parameter    DOWN_RATIO    = 10,
    parameter    COUNT_WIDTH    = 4
)
(
    input                rst,
    input                clk,

    input        signed    [17:0]    din_i,
    input        signed    [17:0]    din_q,
    input                din_latch,

    input                bypass,

    output    reg    signed    [17:0]    dout_i,
    output    reg    signed    [17:0]    dout_q,
    output    reg            dout_latch
);
    reg    [COUNT_WIDTH - 1:0]    count        = 0;
    reg    [COUNT_WIDTH - 1:0]    count_next    = 0;

    reg    signed    [17:0]    din_i_last    = 0;
    reg    signed    [17:0]    din_q_last    = 0;

    reg            din_latch_last    = 0;
    reg            condition_rst    = 0;

    reg            rst_last    = 0;
    reg            rst_0        = 0;

    always @(posedge clk)
    begin
        if(bypass)
            rst_last    <= 1'b1;
        else
            rst_last    <= rst;
    end
    always @(negedge clk)
    begin
        rst_0    <= rst_last;
    end

    always @(posedge clk)
    begin
        if(din_latch)
        begin
            din_i_last    <= din_i;
            din_q_last    <= din_q;
        end

        if(rst_0)
        begin
            count        <= 0;
            condition_rst    <= 1'b1;
        end
        else
        begin
            if(din_latch)
            begin
                count        <= count_next;
                condition_rst    <= (count_next == DOWN_RATIO);
            end
        end
        din_latch_last    <= din_latch;
    end
    always @(negedge clk)
    begin
        if(condition_rst)
            count_next    <= 0;
        else
            count_next    <= count + 1'b1;

        dout_latch    <= (din_latch_last && condition_rst);

        if(din_latch_last && condition_rst)
        begin
            dout_i    <= din_i_last;
            dout_q    <= din_q_last;
        end
    end
endmodule
*/

module ddc
#(
    parameter RAM_ADDR_WIDTH=8
)
(
    input            rst,
    input            adc_clk,
    input    signed    [17:0]    adc_d,
    input        [31:0]    phase_increase,
    input    signed    [31:0]    phase_offset,

    input            proc_clk,
    output        [2:0]    error,

    input                        coef_in_clk,
    input                        coef_in_we,
    input            [RAM_ADDR_WIDTH - 1:0]    coef_in_addr,
    input        signed    [17:0]            coef_in_d,

    output    signed    [17:0]    dout_i,
    output    signed    [17:0]    dout_q,
    output            dout_latch
);
    reg    signed    [17:0]    adc_d_last    = 0;

    wire    signed    [17:0]    dds_out_sin;
    wire    signed    [17:0]    dds_out_cos;
    wire        [31:0]    dds_phase_out;

    wire    signed    [17:0]    cordic_dds_out_sin;
    wire    signed    [17:0]    cordic_dds_out_cos;

    wire    signed    [35:0]    mul_out_i;
    wire    signed    [35:0]    mul_out_q;

    wire    signed    [17:0]    cic_out_i;
    wire    signed    [17:0]    cic_out_q;
    wire            cic_out_latch;

    wire    signed    [17:0]    fifo_out_i;
    wire    signed    [17:0]    fifo_out_q;
    wire            fifo_out_latch;
    wire            cic_comp_dec__error_conflicted;
    wire            cic_comp_dec__error_overflow;

    wire            fifo__error_conflicted;

    ////////////////////////////////////////////////////////////////
    assign error =
    {
        cic_comp_dec__error_conflicted,
        cic_comp_dec__error_overflow,

        fifo__error_conflicted
    };

    dds_iq dds_iq_ins
    (
        .rst            (rst),
        .clk            (adc_clk),
        .phase_increase        (phase_increase),
        .phase_offset        (phase_offset),
        .phase_out        (dds_phase_out),
        .dout_sin        (dds_out_sin),
        .dout_cos        (dds_out_cos)
    );
    cordic_dds cordic_dds_ins
    (
        .clk            (adc_clk),
        .din_sin        (dds_out_sin),
        .din_cos        (dds_out_cos),
        .phase_in        (dds_phase_out),
        .dout_sin        (cordic_dds_out_sin),
        .dout_cos        (cordic_dds_out_cos)
    );

    mul_ddc mul_ddc_i
    (
        .clk            (adc_clk),     // input clk
        .a            (adc_d),    // input [17 : 0] a
        .b            (cordic_dds_out_sin),    // input [17 : 0] b
        .m            (mul_out_i)        // output [35 : 0] p
    );
    mul_ddc mul_ddc_q
    (
        .clk            (adc_clk),    // input clk
        .a            (adc_d),    // input [17 : 0] a
        .b            (cordic_dds_out_cos),    // input [17 : 0] b
        .m            (mul_out_q)        // output [35 : 0] p
    );
    cic_iq cic_iq_ins
    (
        .ratio_sel        (2'd1),
        .rst            (rst),
        .clk            (adc_clk),
        .din_i            (mul_out_i[34-:18]),
        .din_q            (mul_out_q[34-:18]),
        .dout_i            (cic_out_i),
        .dout_q            (cic_out_q),
        .dout_latch        (cic_out_latch)
    );
    ddc_fifo_cross_clk ddc_fifo_ins
    (
        .rst            (rst),

        .din_clk        (adc_clk),
        .din_i            (cic_out_i),
        .din_q            (cic_out_q),
        .din_latch        (cic_out_latch),

        .dout_clk        (proc_clk),
        .dout_i            (fifo_out_i),
        .dout_q            (fifo_out_q),
        .dout_latch        (fifo_out_latch),

        .error_conflicted    (fifo__error_conflicted)
    );
    cic_comp_dec_iq
    #(
        .RAM_ADDR_WIDTH        (RAM_ADDR_WIDTH)
    )
    cic_comp_dec_iq_ins
    (
        .rst            (rst),
        .clk            (proc_clk),

        .coef_in_clk        (coef_in_clk),
        .coef_in_we        (coef_in_we),
        .coef_in_addr        (coef_in_addr),
        .coef_in_d        (coef_in_d),

        .din_i            (fifo_out_i),
        .din_q            (fifo_out_q),
        .din_latch        (fifo_out_latch),

        .dout_i            (dout_i),
        .dout_q            (dout_q),
        .dout_latch        (dout_latch),

        .error_conflicted    (cic_comp_dec__error_conflicted),
        .error_overflow        (cic_comp_dec__error_overflow)
    );
endmodule
ddc.v

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:    14:37:16 01/18/2019
// Design Name:
// Module Name:    dds_iq
// Project Name:
// Target Devices:
// Tool versions:

`define ROM_ADDR_WIDTH 12
`define ROM_DATA_WIDTH 18

`define PHASE_OUT 1
`define PHASE_WIDTH 32
module dds_iq_addr
(
    input                        clk,
    input                        rst,
    input            [`PHASE_WIDTH - 1:0]    phase_increase,
    input        signed    [`PHASE_WIDTH - 1:0]    phase_offset,
`ifdef    PHASE_OUT
    output    reg        [`PHASE_WIDTH - 1:0]    phase_out,
`endif
    output    reg        [`ROM_ADDR_WIDTH - 1:0]    ram_addr_sin,
    output    reg        [`ROM_ADDR_WIDTH - 1:0]    ram_addr_cos
);
    reg    [`PHASE_WIDTH - 1:0]    phase_0_next = 0;
    reg    [`PHASE_WIDTH - 1:0]    phase_0 = 0;
`ifdef    PHASE_OUT
    reg    [`PHASE_WIDTH - 1:0]    phase_out_next = 0;
`endif
    reg    [`ROM_ADDR_WIDTH - 1:0]    phase = 0;

    wire    [`PHASE_WIDTH - 1:0]    phase_next;
    wire    [1:0]            addr_cos_top2bit;

    always @(negedge clk)
    begin
        if(rst)
            phase_0    <= 0;
        else
            phase_0    <= phase_0_next;
    end

    always @(posedge clk)
    begin
        phase_0_next    <= phase_0 + phase_increase;
    end

    assign phase_next = phase_0 + phase_offset;
    always @(posedge clk)
    begin
        phase        <= phase_next[`PHASE_WIDTH - 1:`PHASE_WIDTH - `ROM_ADDR_WIDTH];
`ifdef    PHASE_OUT
        phase_out_next    <= phase_next;
`endif
    end

    assign addr_cos_top2bit = phase[`ROM_ADDR_WIDTH - 1: `ROM_ADDR_WIDTH - 2] + 1'b1;

    always @(negedge clk)
    begin
`ifdef    PHASE_OUT
        phase_out    <= phase_out_next;
`endif
        ram_addr_sin    <= phase;
        ram_addr_cos    <= {addr_cos_top2bit,phase[`ROM_ADDR_WIDTH - 3:0]};
    end

endmodule

module dds_iq
(
    input                            rst,
    input                            clk,
    input            [`PHASE_WIDTH - 1:0]        phase_increase,
    input        signed    [`PHASE_WIDTH - 1:0]        phase_offset,
`ifdef PHASE_OUT
    output            [`PHASE_WIDTH - 1:0]        phase_out,
`endif
    output    reg    signed    [`ROM_DATA_WIDTH - 1:0]        dout_sin,
    output    reg    signed    [`ROM_DATA_WIDTH - 1:0]        dout_cos
);
    wire        [`ROM_ADDR_WIDTH - 1:0]        ram_addr_sin;
    wire        [`ROM_ADDR_WIDTH - 1:0]        ram_addr_cos;

    wire    signed    [`ROM_DATA_WIDTH - 1:0]        ram_out_sin;
    wire    signed    [`ROM_DATA_WIDTH - 1:0]        ram_out_cos;

    dds_iq_addr
    addr_ctrl
    (
        .clk        (clk),
        .rst        (rst),
        .phase_increase    (phase_increase),
        .phase_offset    (phase_offset),
`ifdef PHASE_OUT
        .phase_out    (phase_out),
`endif
        .ram_addr_sin    (ram_addr_sin),
        .ram_addr_cos    (ram_addr_cos)
    );

    rom_dds rom_ins
    (
        .clka        (clk),
        .addra        (ram_addr_sin),
        .douta        (ram_out_sin),
        .clkb        (clk),
        .addrb        (ram_addr_cos),
        .doutb        (ram_out_cos)
    );

    always @(negedge clk)
    begin
        dout_sin    <= ram_out_sin;
        dout_cos    <= ram_out_cos;
    end

endmodule
dds_iq.v
module rom_dds                                                
(                                                    
    input                clka,                    
    input            [11:0]    addra,                    
    output    reg    signed    [17:0]    douta,                    
    input                clkb,                    
    input            [11:0]    addrb,                    
    output    reg    signed    [17:0]    doutb                    
);                                                    
    (* RAM_STYLE="BLOCK" *)                                    
    reg    signed    [17:0]    rom    [4095:0];    
    initial                                                
    begin                                                
        rom[0]    = 0;
        rom[1]    = 127;
        rom[2]    = 255;
        rom[3]    = 383;
        rom[4]    = 510;
        rom[5]    = 638;
        rom[6]    = 766;
        rom[7]    = 893;
        rom[8]    = 1021;
        rom[9]    = 1149;
        rom[10]    = 1276;
        rom[11]    = 1404;
        rom[12]    = 1532;
        rom[13]    = 1659;
        rom[14]    = 1787;
        rom[15]    = 1915;
        rom[16]    = 2042;
        rom[17]    = 2170;
        rom[18]    = 2298;
        rom[19]    = 2425;
        rom[20]    = 2553;
        rom[21]    = 2681;
        rom[22]    = 2808;
        rom[23]    = 2936;
        rom[24]    = 3063;
        rom[25]    = 3191;
        rom[26]    = 3319;
        rom[27]    = 3446;
        rom[28]    = 3574;
        rom[29]    = 3701;
        rom[30]    = 3829;
        rom[31]    = 3957;
        rom[32]    = 4084;
        rom[33]    = 4212;
        rom[34]    = 4339;
        rom[35]    = 4467;
        rom[36]    = 4594;
        rom[37]    = 4722;
        rom[38]    = 4849;
        rom[39]    = 4977;
        rom[40]    = 5104;
        rom[41]    = 5231;
        rom[42]    = 5359;
        rom[43]    = 5486;
        rom[44]    = 5614;
        rom[45]    = 5741;
        rom[46]    = 5869;
        rom[47]    = 5996;
        rom[48]    = 6123;
        rom[49]    = 6251;
        rom[50]    = 6378;
        rom[51]    = 6505;
        rom[52]    = 6633;
        rom[53]    = 6760;
        rom[54]    = 6887;
        rom[55]    = 7014;
        rom[56]    = 7142;
        rom[57]    = 7269;
        rom[58]    = 7396;
        rom[59]    = 7523;
        rom[60]    = 7650;
        rom[61]    = 7777;
        rom[62]    = 7905;
        rom[63]    = 8032;
        rom[64]    = 8159;
        rom[65]    = 8286;
        rom[66]    = 8413;
        rom[67]    = 8540;
        rom[68]    = 8667;
        rom[69]    = 8794;
        rom[70]    = 8921;
        rom[71]    = 9048;
        rom[72]    = 9175;
        rom[73]    = 9302;
        rom[74]    = 9429;
        rom[75]    = 9555;
        rom[76]    = 9682;
        rom[77]    = 9809;
        rom[78]    = 9936;
        rom[79]    = 10063;
        rom[80]    = 10189;
        rom[81]    = 10316;
        rom[82]    = 10443;
        rom[83]    = 10569;
        rom[84]    = 10696;
        rom[85]    = 10823;
        rom[86]    = 10949;
        rom[87]    = 11076;
        rom[88]    = 11202;
        rom[89]    = 11329;
        rom[90]    = 11455;
        rom[91]    = 11582;
        rom[92]    = 11708;
        rom[93]    = 11835;
        rom[94]    = 11961;
        rom[95]    = 12087;
        rom[96]    = 12214;
        rom[97]    = 12340;
        rom[98]    = 12466;
        rom[99]    = 12593;
        rom[100]    = 12719;
        rom[101]    = 12845;
        rom[102]    = 12971;
        rom[103]    = 13097;
        rom[104]    = 13223;
        rom[105]    = 13349;
        rom[106]    = 13475;
        rom[107]    = 13601;
        rom[108]    = 13727;
        rom[109]    = 13853;
        rom[110]    = 13979;
        rom[111]    = 14105;
        rom[112]    = 14231;
        rom[113]    = 14357;
        rom[114]    = 14482;
        rom[115]    = 14608;
        rom[116]    = 14734;
        rom[117]    = 14860;
        rom[118]    = 14985;
        rom[119]    = 15111;
        rom[120]    = 15236;
        rom[121]    = 15362;
        rom[122]    = 15487;
        rom[123]    = 15613;
        rom[124]    = 15738;
        rom[125]    = 15864;
        rom[126]    = 15989;
        rom[127]    = 16114;
        rom[128]    = 16239;
        rom[129]    = 16365;
        rom[130]    = 16490;
        rom[131]    = 16615;
        rom[132]    = 16740;
        rom[133]    = 16865;
        rom[134]    = 16990;
        rom[135]    = 17115;
        rom[136]    = 17240;
        rom[137]    = 17365;
        rom[138]    = 17490;
        rom[139]    = 17615;
        rom[140]    = 17739;
        rom[141]    = 17864;
        rom[142]    = 17989;
        rom[143]    = 18114;
        rom[144]    = 18238;
        rom[145]    = 18363;
        rom[146]    = 18487;
        rom[147]    = 18612;
        rom[148]    = 18736;
        rom[149]    = 18861;
        rom[150]    = 18985;
        rom[151]    = 19109;
        rom[152]    = 19234;
        rom[153]    = 19358;
        rom[154]    = 19482;
        rom[155]    = 19606;
        rom[156]    = 19730;
        rom[157]    = 19854;
        rom[158]    = 19978;
        rom[159]    = 20102;
        rom[160]    = 20226;
        rom[161]    = 20350;
        rom[162]    = 20474;
        rom[163]    = 20597;
        rom[164]    = 20721;
        rom[165]    = 20845;
        rom[166]    = 20968;
        rom[167]    = 21092;
        rom[168]    = 21215;
        rom[169]    = 21339;
        rom[170]    = 21462;
        rom[171]    = 21586;
        rom[172]    = 21709;
        rom[173]    = 21832;
        rom[174]    = 21955;
        rom[175]    = 22078;
        rom[176]    = 22202;
        rom[177]    = 22325;
        rom[178]    = 22448;
        rom[179]    = 22570;
        rom[180]    = 22693;
        rom[181]    = 22816;
        rom[182]    = 22939;
        rom[183]    = 23062;
        rom[184]    = 23184;
        rom[185]    = 23307;
        rom[186]    = 23430;
        rom[187]    = 23552;
        rom[188]    = 23674;
        rom[189]    = 23797;
        rom[190]    = 23919;
        rom[191]    = 24041;
        rom[192]    = 24164;
        rom[193]    = 24286;
        rom[194]    = 24408;
        rom[195]    = 24530;
        rom[196]    = 24652;
        rom[197]    = 24774;
        rom[198]    = 24896;
        rom[199]    = 25018;
        rom[200]    = 25139;
        rom[201]    = 25261;
        rom[202]    = 25383;
        rom[203]    = 25504;
        rom[204]    = 25626;
        rom[205]    = 25747;
        rom[206]    = 25869;
        rom[207]    = 25990;
        rom[208]    = 26111;
        rom[209]    = 26233;
        rom[210]    = 26354;
        rom[211]    = 26475;
        rom[212]    = 26596;
        rom[213]    = 26717;
        rom[214]    = 26838;
        rom[215]    = 26959;
        rom[216]    = 27079;
        rom[217]    = 27200;
        rom[218]    = 27321;
        rom[219]    = 27441;
        rom[220]    = 27562;
        rom[221]    = 27682;
        rom[222]    = 27803;
        rom[223]    = 27923;
        rom[224]    = 28043;
        rom[225]    = 28163;
        rom[226]    = 28284;
        rom[227]    = 28404;
        rom[228]    = 28524;
        rom[229]    = 28644;
        rom[230]    = 28763;
        rom[231]    = 28883;
        rom[232]    = 29003;
        rom[233]    = 29123;
        rom[234]    = 29242;
        rom[235]    = 29362;
        rom[236]    = 29481;
        rom[237]    = 29601;
        rom[238]    = 29720;
        rom[239]    = 29839;
        rom[240]    = 29958;
        rom[241]    = 30077;
        rom[242]    = 30196;
        rom[243]    = 30315;
        rom[244]    = 30434;
        rom[245]    = 30553;
        rom[246]    = 30672;
        rom[247]    = 30791;
        rom[248]    = 30909;
        rom[249]    = 31028;
        rom[250]    = 31146;
        rom[251]    = 31264;
        rom[252]    = 31383;
        rom[253]    = 31501;
        rom[254]    = 31619;
        rom[255]    = 31737;
        rom[256]    = 31855;
        rom[257]    = 31973;
        rom[258]    = 32091;
        rom[259]    = 32209;
        rom[260]    = 32327;
        rom[261]    = 32444;
        rom[262]    = 32562;
        rom[263]    = 32679;
        rom[264]    = 32797;
        rom[265]    = 32914;
        rom[266]    = 33031;
        rom[267]    = 33148;
        rom[268]    = 33265;
        rom[269]    = 33383;
        rom[270]    = 33499;
        rom[271]    = 33616;
        rom[272]    = 33733;
        rom[273]    = 33850;
        rom[274]    = 33966;
        rom[275]    = 34083;
        rom[276]    = 34199;
        rom[277]    = 34316;
        rom[278]    = 34432;
        rom[279]    = 34548;
        rom[280]    = 34664;
        rom[281]    = 34780;
        rom[282]    = 34896;
        rom[283]    = 35012;
        rom[284]    = 35128;
        rom[285]    = 35244;
        rom[286]    = 35360;
        rom[287]    = 35475;
        rom[288]    = 35591;
        rom[289]    = 35706;
        rom[290]    = 35821;
        rom[291]    = 35936;
        rom[292]    = 36052;
        rom[293]    = 36167;
        rom[294]    = 36282;
        rom[295]    = 36397;
        rom[296]    = 36511;
        rom[297]    = 36626;
        rom[298]    = 36741;
        rom[299]    = 36855;
        rom[300]    = 36970;
        rom[301]    = 37084;
        rom[302]    = 37198;
        rom[303]    = 37312;
        rom[304]    = 37427;
        rom[305]    = 37541;
        rom[306]    = 37655;
        rom[307]    = 37768;
        rom[308]    = 37882;
        rom[309]    = 37996;
        rom[310]    = 38109;
        rom[311]    = 38223;
        rom[312]    = 38336;
        rom[313]    = 38450;
        rom[314]    = 38563;
        rom[315]    = 38676;
        rom[316]    = 38789;
        rom[317]    = 38902;
        rom[318]    = 39015;
        rom[319]    = 39127;
        rom[320]    = 39240;
        rom[321]    = 39353;
        rom[322]    = 39465;
        rom[323]    = 39577;
        rom[324]    = 39690;
        rom[325]    = 39802;
        rom[326]    = 39914;
        rom[327]    = 40026;
        rom[328]    = 40138;
        rom[329]    = 40250;
        rom[330]    = 40362;
        rom[331]    = 40473;
        rom[332]    = 40585;
        rom[333]    = 40696;
        rom[334]    = 40808;
        rom[335]    = 40919;
        rom[336]    = 41030;
        rom[337]    = 41141;
        rom[338]    = 41252;
        rom[339]    = 41363;
        rom[340]    = 41474;
        rom[341]    = 41584;
        rom[342]    = 41695;
        rom[343]    = 41805;
        rom[344]    = 41916;
        rom[345]    = 42026;
        rom[346]    = 42136;
        rom[347]    = 42246;
        rom[348]    = 42356;
        rom[349]    = 42466;
        rom[350]    = 42576;
        rom[351]    = 42685;
        rom[352]    = 42795;
        rom[353]    = 42905;
        rom[354]    = 43014;
        rom[355]    = 43123;
        rom[356]    = 43232;
        rom[357]    = 43341;
        rom[358]    = 43450;
        rom[359]    = 43559;
        rom[360]    = 43668;
        rom[361]    = 43777;
        rom[362]    = 43885;
        rom[363]    = 43994;
        rom[364]    = 44102;
        rom[365]    = 44210;
        rom[366]    = 44318;
        rom[367]    = 44426;
        rom[368]    = 44534;
        rom[369]    = 44642;
        rom[370]    = 44750;
        rom[371]    = 44858;
        rom[372]    = 44965;
        rom[373]    = 45073;
        rom[374]    = 45180;
        rom[375]    = 45287;
        rom[376]    = 45394;
        rom[377]    = 45501;
        rom[378]    = 45608;
        rom[379]    = 45715;
        rom[380]    = 45821;
        rom[381]    = 45928;
        rom[382]    = 46034;
        rom[383]    = 46141;
        rom[384]    = 46247;
        rom[385]    = 46353;
        rom[386]    = 46459;
        rom[387]    = 46565;
        rom[388]    = 46671;
        rom[389]    = 46776;
        rom[390]    = 46882;
        rom[391]    = 46987;
        rom[392]    = 47093;
        rom[393]    = 47198;
        rom[394]    = 47303;
        rom[395]    = 47408;
        rom[396]    = 47513;
        rom[397]    = 47618;
        rom[398]    = 47723;
        rom[399]    = 47827;
        rom[400]    = 47932;
        rom[401]    = 48036;
        rom[402]    = 48140;
        rom[403]    = 48244;
        rom[404]    = 48348;
        rom[405]    = 48452;
        rom[406]    = 48556;
        rom[407]    = 48660;
        rom[408]    = 48763;
        rom[409]    = 48867;
        rom[410]    = 48970;
        rom[411]    = 49073;
        rom[412]    = 49176;
        rom[413]    = 49279;
        rom[414]    = 49382;
        rom[415]    = 49485;
        rom[416]    = 49587;
        rom[417]    = 49690;
        rom[418]    = 49792;
        rom[419]    = 49895;
        rom[420]    = 49997;
        rom[421]    = 50099;
        rom[422]    = 50201;
        rom[423]    = 50302;
        rom[424]    = 50404;
        rom[425]    = 50506;
        rom[426]    = 50607;
        rom[427]    = 50709;
        rom[428]    = 50810;
        rom[429]    = 50911;
        rom[430]    = 51012;
        rom[431]    = 51113;
        rom[432]    = 51213;
        rom[433]    = 51314;
        rom[434]    = 51414;
        rom[435]    = 51515;
        rom[436]    = 51615;
        rom[437]    = 51715;
        rom[438]    = 51815;
        rom[439]    = 51915;
        rom[440]    = 52015;
        rom[441]    = 52114;
        rom[442]    = 52214;
        rom[443]    = 52313;
        rom[444]    = 52413;
        rom[445]    = 52512;
        rom[446]    = 52611;
        rom[447]    = 52710;
        rom[448]    = 52808;
        rom[449]    = 52907;
        rom[450]    = 53006;
        rom[451]    = 53104;
        rom[452]    = 53202;
        rom[453]    = 53300;
        rom[454]    = 53398;
        rom[455]    = 53496;
        rom[456]    = 53594;
        rom[457]    = 53692;
        rom[458]    = 53789;
        rom[459]    = 53887;
        rom[460]    = 53984;
        rom[461]    = 54081;
        rom[462]    = 54178;
        rom[463]    = 54275;
        rom[464]    = 54372;
        rom[465]    = 54468;
        rom[466]    = 54565;
        rom[467]    = 54661;
        rom[468]    = 54757;
        rom[469]    = 54854;
        rom[470]    = 54950;
        rom[471]    = 55045;
        rom[472]    = 55141;
        rom[473]    = 55237;
        rom[474]    = 55332;
        rom[475]    = 55427;
        rom[476]    = 55523;
        rom[477]    = 55618;
        rom[478]    = 55713;
        rom[479]    = 55808;
        rom[480]    = 55902;
        rom[481]    = 55997;
        rom[482]    = 56091;
        rom[483]    = 56185;
        rom[484]    = 56280;
        rom[485]    = 56374;
        rom[486]    = 56468;
        rom[487]    = 56561;
        rom[488]    = 56655;
        rom[489]    = 56748;
        rom[490]    = 56842;
        rom[491]    = 56935;
        rom[492]    = 57028;
        rom[493]    = 57121;
        rom[494]    = 57214;
        rom[495]    = 57307;
        rom[496]    = 57399;
        rom[497]    = 57491;
        rom[498]    = 57584;
        rom[499]    = 57676;
        rom[500]    = 57768;
        rom[501]    = 57860;
        rom[502]    = 57952;
        rom[503]    = 58043;
        rom[504]    = 58135;
        rom[505]    = 58226;
        rom[506]    = 58317;
        rom[507]    = 58408;
        rom[508]    = 58499;
        rom[509]    = 58590;
        rom[510]    = 58680;
        rom[511]    = 58771;
        rom[512]    = 58861;
        rom[513]    = 58952;
        rom[514]    = 59042;
        rom[515]    = 59132;
        rom[516]    = 59221;
        rom[517]    = 59311;
        rom[518]    = 59401;
        rom[519]    = 59490;
        rom[520]    = 59579;
        rom[521]    = 59668;
        rom[522]    = 59757;
        rom[523]    = 59846;
        rom[524]    = 59935;
        rom[525]    = 60023;
        rom[526]    = 60112;
        rom[527]    = 60200;
        rom[528]    = 60288;
        rom[529]    = 60376;
        rom[530]    = 60464;
        rom[531]    = 60552;
        rom[532]    = 60639;
        rom[533]    = 60727;
        rom[534]    = 60814;
        rom[535]    = 60901;
        rom[536]    = 60988;
        rom[537]    = 61075;
        rom[538]    = 61162;
        rom[539]    = 61248;
        rom[540]    = 61334;
        rom[541]    = 61421;
        rom[542]    = 61507;
        rom[543]    = 61593;
        rom[544]    = 61679;
        rom[545]    = 61764;
        rom[546]    = 61850;
        rom[547]    = 61935;
        rom[548]    = 62020;
        rom[549]    = 62106;
        rom[550]    = 62191;
        rom[551]    = 62275;
        rom[552]    = 62360;
        rom[553]    = 62445;
        rom[554]    = 62529;
        rom[555]    = 62613;
        rom[556]    = 62697;
        rom[557]    = 62781;
        rom[558]    = 62865;
        rom[559]    = 62949;
        rom[560]    = 63032;
        rom[561]    = 63115;
        rom[562]    = 63198;
        rom[563]    = 63282;
        rom[564]    = 63364;
        rom[565]    = 63447;
        rom[566]    = 63530;
        rom[567]    = 63612;
        rom[568]    = 63694;
        rom[569]    = 63777;
        rom[570]    = 63859;
        rom[571]    = 63940;
        rom[572]    = 64022;
        rom[573]    = 64104;
        rom[574]    = 64185;
        rom[575]    = 64266;
        rom[576]    = 64347;
        rom[577]    = 64428;
        rom[578]    = 64509;
        rom[579]    = 64590;
        rom[580]    = 64670;
        rom[581]    = 64751;
        rom[582]    = 64831;
        rom[583]    = 64911;
        rom[584]    = 64991;
        rom[585]    = 65070;
        rom[586]    = 65150;
        rom[587]    = 65229;
        rom[588]    = 65308;
        rom[589]    = 65388;
        rom[590]    = 65467;
        rom[591]    = 65545;
        rom[592]    = 65624;
        rom[593]    = 65702;
        rom[594]    = 65781;
        rom[595]    = 65859;
        rom[596]    = 65937;
        rom[597]    = 66015;
        rom[598]    = 66093;
        rom[599]    = 66170;
        rom[600]    = 66248;
        rom[601]    = 66325;
        rom[602]    = 66402;
        rom[603]    = 66479;
        rom[604]    = 66556;
        rom[605]    = 66632;
        rom[606]    = 66709;
        rom[607]    = 66785;
        rom[608]    = 66861;
        rom[609]    = 66937;
        rom[610]    = 67013;
        rom[611]    = 67089;
        rom[612]    = 67164;
        rom[613]    = 67239;
        rom[614]    = 67315;
        rom[615]    = 67390;
        rom[616]    = 67465;
        rom[617]    = 67539;
        rom[618]    = 67614;
        rom[619]    = 67688;
        rom[620]    = 67762;
        rom[621]    = 67837;
        rom[622]    = 67910;
        rom[623]    = 67984;
        rom[624]    = 68058;
        rom[625]    = 68131;
        rom[626]    = 68205;
        rom[627]    = 68278;
        rom[628]    = 68351;
        rom[629]    = 68423;
        rom[630]    = 68496;
        rom[631]    = 68569;
        rom[632]    = 68641;
        rom[633]    = 68713;
        rom[634]    = 68785;
        rom[635]    = 68857;
        rom[636]    = 68929;
        rom[637]    = 69000;
        rom[638]    = 69071;
        rom[639]    = 69143;
        rom[640]    = 69214;
        rom[641]    = 69285;
        rom[642]    = 69355;
        rom[643]    = 69426;
        rom[644]    = 69496;
        rom[645]    = 69566;
        rom[646]    = 69636;
        rom[647]    = 69706;
        rom[648]    = 69776;
        rom[649]    = 69846;
        rom[650]    = 69915;
        rom[651]    = 69984;
        rom[652]    = 70053;
        rom[653]    = 70122;
        rom[654]    = 70191;
        rom[655]    = 70259;
        rom[656]    = 70328;
        rom[657]    = 70396;
        rom[658]    = 70464;
        rom[659]    = 70532;
        rom[660]    = 70600;
        rom[661]    = 70667;
        rom[662]    = 70735;
        rom[663]    = 70802;
        rom[664]    = 70869;
        rom[665]    = 70936;
        rom[666]    = 71003;
        rom[667]    = 71069;
        rom[668]    = 71136;
        rom[669]    = 71202;
        rom[670]    = 71268;
        rom[671]    = 71334;
        rom[672]    = 71400;
        rom[673]    = 71465;
        rom[674]    = 71531;
        rom[675]    = 71596;
        rom[676]    = 71661;
        rom[677]    = 71726;
        rom[678]    = 71790;
        rom[679]    = 71855;
        rom[680]    = 71919;
        rom[681]    = 71984;
        rom[682]    = 72048;
        rom[683]    = 72111;
        rom[684]    = 72175;
        rom[685]    = 72239;
        rom[686]    = 72302;
        rom[687]    = 72365;
        rom[688]    = 72428;
        rom[689]    = 72491;
        rom[690]    = 72554;
        rom[691]    = 72616;
        rom[692]    = 72679;
        rom[693]    = 72741;
        rom[694]    = 72803;
        rom[695]    = 72865;
        rom[696]    = 72926;
        rom[697]    = 72988;
        rom[698]    = 73049;
        rom[699]    = 73110;
        rom[700]    = 73171;
        rom[701]    = 73232;
        rom[702]    = 73293;
        rom[703]    = 73353;
        rom[704]    = 73413;
        rom[705]    = 73474;
        rom[706]    = 73533;
        rom[707]    = 73593;
        rom[708]    = 73653;
        rom[709]    = 73712;
        rom[710]    = 73771;
        rom[711]    = 73831;
        rom[712]    = 73889;
        rom[713]    = 73948;
        rom[714]    = 74007;
        rom[715]    = 74065;
        rom[716]    = 74123;
        rom[717]    = 74181;
        rom[718]    = 74239;
        rom[719]    = 74297;
        rom[720]    = 74354;
        rom[721]    = 74412;
        rom[722]    = 74469;
        rom[723]    = 74526;
        rom[724]    = 74583;
        rom[725]    = 74639;
        rom[726]    = 74696;
        rom[727]    = 74752;
        rom[728]    = 74808;
        rom[729]    = 74864;
        rom[730]    = 74920;
        rom[731]    = 74975;
        rom[732]    = 75031;
        rom[733]    = 75086;
        rom[734]    = 75141;
        rom[735]    = 75196;
        rom[736]    = 75250;
        rom[737]    = 75305;
        rom[738]    = 75359;
        rom[739]    = 75413;
        rom[740]    = 75467;
        rom[741]    = 75521;
        rom[742]    = 75575;
        rom[743]    = 75628;
        rom[744]    = 75682;
        rom[745]    = 75735;
        rom[746]    = 75788;
        rom[747]    = 75840;
        rom[748]    = 75893;
        rom[749]    = 75945;
        rom[750]    = 75997;
        rom[751]    = 76049;
        rom[752]    = 76101;
        rom[753]    = 76153;
        rom[754]    = 76204;
        rom[755]    = 76256;
        rom[756]    = 76307;
        rom[757]    = 76358;
        rom[758]    = 76408;
        rom[759]    = 76459;
        rom[760]    = 76509;
        rom[761]    = 76560;
        rom[762]    = 76610;
        rom[763]    = 76660;
        rom[764]    = 76709;
        rom[765]    = 76759;
        rom[766]    = 76808;
        rom[767]    = 76857;
        rom[768]    = 76906;
        rom[769]    = 76955;
        rom[770]    = 77004;
        rom[771]    = 77052;
        rom[772]    = 77100;
        rom[773]    = 77148;
        rom[774]    = 77196;
        rom[775]    = 77244;
        rom[776]    = 77291;
        rom[777]    = 77339;
        rom[778]    = 77386;
        rom[779]    = 77433;
        rom[780]    = 77480;
        rom[781]    = 77526;
        rom[782]    = 77573;
        rom[783]    = 77619;
        rom[784]    = 77665;
        rom[785]    = 77711;
        rom[786]    = 77756;
        rom[787]    = 77802;
        rom[788]    = 77847;
        rom[789]    = 77892;
        rom[790]    = 77937;
        rom[791]    = 77982;
        rom[792]    = 78027;
        rom[793]    = 78071;
        rom[794]    = 78115;
        rom[795]    = 78159;
        rom[796]    = 78203;
        rom[797]    = 78247;
        rom[798]    = 78290;
        rom[799]    = 78334;
        rom[800]    = 78377;
        rom[801]    = 78420;
        rom[802]    = 78462;
        rom[803]    = 78505;
        rom[804]    = 78547;
        rom[805]    = 78589;
        rom[806]    = 78631;
        rom[807]    = 78673;
        rom[808]    = 78715;
        rom[809]    = 78756;
        rom[810]    = 78798;
        rom[811]    = 78839;
        rom[812]    = 78880;
        rom[813]    = 78920;
        rom[814]    = 78961;
        rom[815]    = 79001;
        rom[816]    = 79041;
        rom[817]    = 79081;
        rom[818]    = 79121;
        rom[819]    = 79161;
        rom[820]    = 79200;
        rom[821]    = 79239;
        rom[822]    = 79278;
        rom[823]    = 79317;
        rom[824]    = 79356;
        rom[825]    = 79394;
        rom[826]    = 79432;
        rom[827]    = 79471;
        rom[828]    = 79508;
        rom[829]    = 79546;
        rom[830]    = 79584;
        rom[831]    = 79621;
        rom[832]    = 79658;
        rom[833]    = 79695;
        rom[834]    = 79732;
        rom[835]    = 79769;
        rom[836]    = 79805;
        rom[837]    = 79841;
        rom[838]    = 79877;
        rom[839]    = 79913;
        rom[840]    = 79949;
        rom[841]    = 79984;
        rom[842]    = 80020;
        rom[843]    = 80055;
        rom[844]    = 80090;
        rom[845]    = 80124;
        rom[846]    = 80159;
        rom[847]    = 80193;
        rom[848]    = 80227;
        rom[849]    = 80261;
        rom[850]    = 80295;
        rom[851]    = 80329;
        rom[852]    = 80362;
        rom[853]    = 80395;
        rom[854]    = 80428;
        rom[855]    = 80461;
        rom[856]    = 80494;
        rom[857]    = 80526;
        rom[858]    = 80558;
        rom[859]    = 80590;
        rom[860]    = 80622;
        rom[861]    = 80654;
        rom[862]    = 80686;
        rom[863]    = 80717;
        rom[864]    = 80748;
        rom[865]    = 80779;
        rom[866]    = 80810;
        rom[867]    = 80840;
        rom[868]    = 80871;
        rom[869]    = 80901;
        rom[870]    = 80931;
        rom[871]    = 80961;
        rom[872]    = 80990;
        rom[873]    = 81020;
        rom[874]    = 81049;
        rom[875]    = 81078;
        rom[876]    = 81107;
        rom[877]    = 81135;
        rom[878]    = 81164;
        rom[879]    = 81192;
        rom[880]    = 81220;
        rom[881]    = 81248;
        rom[882]    = 81276;
        rom[883]    = 81303;
        rom[884]    = 81330;
        rom[885]    = 81358;
        rom[886]    = 81384;
        rom[887]    = 81411;
        rom[888]    = 81438;
        rom[889]    = 81464;
        rom[890]    = 81490;
        rom[891]    = 81516;
        rom[892]    = 81542;
        rom[893]    = 81568;
        rom[894]    = 81593;
        rom[895]    = 81618;
        rom[896]    = 81643;
        rom[897]    = 81668;
        rom[898]    = 81693;
        rom[899]    = 81717;
        rom[900]    = 81741;
        rom[901]    = 81765;
        rom[902]    = 81789;
        rom[903]    = 81813;
        rom[904]    = 81836;
        rom[905]    = 81860;
        rom[906]    = 81883;
        rom[907]    = 81906;
        rom[908]    = 81928;
        rom[909]    = 81951;
        rom[910]    = 81973;
        rom[911]    = 81995;
        rom[912]    = 82017;
        rom[913]    = 82039;
        rom[914]    = 82060;
        rom[915]    = 82082;
        rom[916]    = 82103;
        rom[917]    = 82124;
        rom[918]    = 82145;
        rom[919]    = 82165;
        rom[920]    = 82186;
        rom[921]    = 82206;
        rom[922]    = 82226;
        rom[923]    = 82246;
        rom[924]    = 82265;
        rom[925]    = 82285;
        rom[926]    = 82304;
        rom[927]    = 82323;
        rom[928]    = 82342;
        rom[929]    = 82360;
        rom[930]    = 82379;
        rom[931]    = 82397;
        rom[932]    = 82415;
        rom[933]    = 82433;
        rom[934]    = 82451;
        rom[935]    = 82468;
        rom[936]    = 82485;
        rom[937]    = 82502;
        rom[938]    = 82519;
        rom[939]    = 82536;
        rom[940]    = 82553;
        rom[941]    = 82569;
        rom[942]    = 82585;
        rom[943]    = 82601;
        rom[944]    = 82617;
        rom[945]    = 82632;
        rom[946]    = 82648;
        rom[947]    = 82663;
        rom[948]    = 82678;
        rom[949]    = 82692;
        rom[950]    = 82707;
        rom[951]    = 82721;
        rom[952]    = 82735;
        rom[953]    = 82749;
        rom[954]    = 82763;
        rom[955]    = 82777;
        rom[956]    = 82790;
        rom[957]    = 82803;
        rom[958]    = 82816;
        rom[959]    = 82829;
        rom[960]    = 82842;
        rom[961]    = 82854;
        rom[962]    = 82866;
        rom[963]    = 82879;
        rom[964]    = 82890;
        rom[965]    = 82902;
        rom[966]    = 82913;
        rom[967]    = 82925;
        rom[968]    = 82936;
        rom[969]    = 82947;
        rom[970]    = 82957;
        rom[971]    = 82968;
        rom[972]    = 82978;
        rom[973]    = 82988;
        rom[974]    = 82998;
        rom[975]    = 83008;
        rom[976]    = 83017;
        rom[977]    = 83026;
        rom[978]    = 83036;
        rom[979]    = 83044;
        rom[980]    = 83053;
        rom[981]    = 83062;
        rom[982]    = 83070;
        rom[983]    = 83078;
        rom[984]    = 83086;
        rom[985]    = 83094;
        rom[986]    = 83101;
        rom[987]    = 83109;
        rom[988]    = 83116;
        rom[989]    = 83123;
        rom[990]    = 83129;
        rom[991]    = 83136;
        rom[992]    = 83142;
        rom[993]    = 83149;
        rom[994]    = 83155;
        rom[995]    = 83160;
        rom[996]    = 83166;
        rom[997]    = 83171;
        rom[998]    = 83176;
        rom[999]    = 83181;
        rom[1000]    = 83186;
        rom[1001]    = 83191;
        rom[1002]    = 83195;
        rom[1003]    = 83200;
        rom[1004]    = 83204;
        rom[1005]    = 83207;
        rom[1006]    = 83211;
        rom[1007]    = 83214;
        rom[1008]    = 83218;
        rom[1009]    = 83221;
        rom[1010]    = 83223;
        rom[1011]    = 83226;
        rom[1012]    = 83229;
        rom[1013]    = 83231;
        rom[1014]    = 83233;
        rom[1015]    = 83235;
        rom[1016]    = 83236;
        rom[1017]    = 83238;
        rom[1018]    = 83239;
        rom[1019]    = 83240;
        rom[1020]    = 83241;
        rom[1021]    = 83242;
        rom[1022]    = 83242;
        rom[1023]    = 83243;
        rom[1024]    = 83243;
        rom[1025]    = 83243;
        rom[1026]    = 83242;
        rom[1027]    = 83242;
        rom[1028]    = 83241;
        rom[1029]    = 83240;
        rom[1030]    = 83239;
        rom[1031]    = 83238;
        rom[1032]    = 83236;
        rom[1033]    = 83235;
        rom[1034]    = 83233;
        rom[1035]    = 83231;
        rom[1036]    = 83229;
        rom[1037]    = 83226;
        rom[1038]    = 83223;
        rom[1039]    = 83221;
        rom[1040]    = 83218;
        rom[1041]    = 83214;
        rom[1042]    = 83211;
        rom[1043]    = 83207;
        rom[1044]    = 83204;
        rom[1045]    = 83200;
        rom[1046]    = 83195;
        rom[1047]    = 83191;
        rom[1048]    = 83186;
        rom[1049]    = 83181;
        rom[1050]    = 83176;
        rom[1051]    = 83171;
        rom[1052]    = 83166;
        rom[1053]    = 83160;
        rom[1054]    = 83155;
        rom[1055]    = 83149;
        rom[1056]    = 83142;
        rom[1057]    = 83136;
        rom[1058]    = 83129;
        rom[1059]    = 83123;
        rom[1060]    = 83116;
        rom[1061]    = 83109;
        rom[1062]    = 83101;
        rom[1063]    = 83094;
        rom[1064]    = 83086;
        rom[1065]    = 83078;
        rom[1066]    = 83070;
        rom[1067]    = 83062;
        rom[1068]    = 83053;
        rom[1069]    = 83044;
        rom[1070]    = 83036;
        rom[1071]    = 83026;
        rom[1072]    = 83017;
        rom[1073]    = 83008;
        rom[1074]    = 82998;
        rom[1075]    = 82988;
        rom[1076]    = 82978;
        rom[1077]    = 82968;
        rom[1078]    = 82957;
        rom[1079]    = 82947;
        rom[1080]    = 82936;
        rom[1081]    = 82925;
        rom[1082]    = 82913;
        rom[1083]    = 82902;
        rom[1084]    = 82890;
        rom[1085]    = 82879;
        rom[1086]    = 82866;
        rom[1087]    = 82854;
        rom[1088]    = 82842;
        rom[1089]    = 82829;
        rom[1090]    = 82816;
        rom[1091]    = 82803;
        rom[1092]    = 82790;
        rom[1093]    = 82777;
        rom[1094]    = 82763;
        rom[1095]    = 82749;
        rom[1096]    = 82735;
        rom[1097]    = 82721;
        rom[1098]    = 82707;
        rom[1099]    = 82692;
        rom[1100]    = 82678;
        rom[1101]    = 82663;
        rom[1102]    = 82648;
        rom[1103]    = 82632;
        rom[1104]    = 82617;
        rom[1105]    = 82601;
        rom[1106]    = 82585;
        rom[1107]    = 82569;
        rom[1108]    = 82553;
        rom[1109]    = 82536;
        rom[1110]    = 82519;
        rom[1111]    = 82502;
        rom[1112]    = 82485;
        rom[1113]    = 82468;
        rom[1114]    = 82451;
        rom[1115]    = 82433;
        rom[1116]    = 82415;
        rom[1117]    = 82397;
        rom[1118]    = 82379;
        rom[1119]    = 82360;
        rom[1120]    = 82342;
        rom[1121]    = 82323;
        rom[1122]    = 82304;
        rom[1123]    = 82285;
        rom[1124]    = 82265;
        rom[1125]    = 82246;
        rom[1126]    = 82226;
        rom[1127]    = 82206;
        rom[1128]    = 82186;
        rom[1129]    = 82165;
        rom[1130]    = 82145;
        rom[1131]    = 82124;
        rom[1132]    = 82103;
        rom[1133]    = 82082;
        rom[1134]    = 82060;
        rom[1135]    = 82039;
        rom[1136]    = 82017;
        rom[1137]    = 81995;
        rom[1138]    = 81973;
        rom[1139]    = 81951;
        rom[1140]    = 81928;
        rom[1141]    = 81906;
        rom[1142]    = 81883;
        rom[1143]    = 81860;
        rom[1144]    = 81836;
        rom[1145]    = 81813;
        rom[1146]    = 81789;
        rom[1147]    = 81765;
        rom[1148]    = 81741;
        rom[1149]    = 81717;
        rom[1150]    = 81693;
        rom[1151]    = 81668;
        rom[1152]    = 81643;
        rom[1153]    = 81618;
        rom[1154]    = 81593;
        rom[1155]    = 81568;
        rom[1156]    = 81542;
        rom[1157]    = 81516;
        rom[1158]    = 81490;
        rom[1159]    = 81464;
        rom[1160]    = 81438;
        rom[1161]    = 81411;
        rom[1162]    = 81384;
        rom[1163]    = 81358;
        rom[1164]    = 81330;
        rom[1165]    = 81303;
        rom[1166]    = 81276;
        rom[1167]    = 81248;
        rom[1168]    = 81220;
        rom[1169]    = 81192;
        rom[1170]    = 81164;
        rom[1171]    = 81135;
        rom[1172]    = 81107;
        rom[1173]    = 81078;
        rom[1174]    = 81049;
        rom[1175]    = 81020;
        rom[1176]    = 80990;
        rom[1177]    = 80961;
        rom[1178]    = 80931;
        rom[1179]    = 80901;
        rom[1180]    = 80871;
        rom[1181]    = 80840;
        rom[1182]    = 80810;
        rom[1183]    = 80779;
        rom[1184]    = 80748;
        rom[1185]    = 80717;
        rom[1186]    = 80686;
        rom[1187]    = 80654;
        rom[1188]    = 80622;
        rom[1189]    = 80590;
        rom[1190]    = 80558;
        rom[1191]    = 80526;
        rom[1192]    = 80494;
        rom[1193]    = 80461;
        rom[1194]    = 80428;
        rom[1195]    = 80395;
        rom[1196]    = 80362;
        rom[1197]    = 80329;
        rom[1198]    = 80295;
        rom[1199]    = 80261;
        rom[1200]    = 80227;
        rom[1201]    = 80193;
        rom[1202]    = 80159;
        rom[1203]    = 80124;
        rom[1204]    = 80090;
        rom[1205]    = 80055;
        rom[1206]    = 80020;
        rom[1207]    = 79984;
        rom[1208]    = 79949;
        rom[1209]    = 79913;
        rom[1210]    = 79877;
        rom[1211]    = 79841;
        rom[1212]    = 79805;
        rom[1213]    = 79769;
        rom[1214]    = 79732;
        rom[1215]    = 79695;
        rom[1216]    = 79658;
        rom[1217]    = 79621;
        rom[1218]    = 79584;
        rom[1219]    = 79546;
        rom[1220]    = 79508;
        rom[1221]    = 79471;
        rom[1222]    = 79432;
        rom[1223]    = 79394;
        rom[1224]    = 79356;
        rom[1225]    = 79317;
        rom[1226]    = 79278;
        rom[1227]    = 79239;
        rom[1228]    = 79200;
        rom[1229]    = 79161;
        rom[1230]    = 79121;
        rom[1231]    = 79081;
        rom[1232]    = 79041;
        rom[1233]    = 79001;
        rom[1234]    = 78961;
        rom[1235]    = 78920;
        rom[1236]    = 78880;
        rom[1237]    = 78839;
        rom[1238]    = 78798;
        rom[1239]    = 78756;
        rom[1240]    = 78715;
        rom[1241]    = 78673;
        rom[1242]    = 78631;
        rom[1243]    = 78589;
        rom[1244]    = 78547;
        rom[1245]    = 78505;
        rom[1246]    = 78462;
        rom[1247]    = 78420;
        rom[1248]    = 78377;
        rom[1249]    = 78334;
        rom[1250]    = 78290;
        rom[1251]    = 78247;
        rom[1252]    = 78203;
        rom[1253]    = 78159;
        rom[1254]    = 78115;
        rom[1255]    = 78071;
        rom[1256]    = 78027;
        rom[1257]    = 77982;
        rom[1258]    = 77937;
        rom[1259]    = 77892;
        rom[1260]    = 77847;
        rom[1261]    = 77802;
        rom[1262]    = 77756;
        rom[1263]    = 77711;
        rom[1264]    = 77665;
        rom[1265]    = 77619;
        rom[1266]    = 77573;
        rom[1267]    = 77526;
        rom[1268]    = 77480;
        rom[1269]    = 77433;
        rom[1270]    = 77386;
        rom[1271]    = 77339;
        rom[1272]    = 77291;
        rom[1273]    = 77244;
        rom[1274]    = 77196;
        rom[1275]    = 77148;
        rom[1276]    = 77100;
        rom[1277]    = 77052;
        rom[1278]    = 77004;
        rom[1279]    = 76955;
        rom[1280]    = 76906;
        rom[1281]    = 76857;
        rom[1282]    = 76808;
        rom[1283]    = 76759;
        rom[1284]    = 76709;
        rom[1285]    = 76660;
        rom[1286]    = 76610;
        rom[1287]    = 76560;
        rom[1288]    = 76509;
        rom[1289]    = 76459;
        rom[1290]    = 76408;
        rom[1291]    = 76358;
        rom[1292]    = 76307;
        rom[1293]    = 76256;
        rom[1294]    = 76204;
        rom[1295]    = 76153;
        rom[1296]    = 76101;
        rom[1297]    = 76049;
        rom[1298]    = 75997;
        rom[1299]    = 75945;
        rom[1300]    = 75893;
        rom[1301]    = 75840;
        rom[1302]    = 75788;
        rom[1303]    = 75735;
        rom[1304]    = 75682;
        rom[1305]    = 75628;
        rom[1306]    = 75575;
        rom[1307]    = 75521;
        rom[1308]    = 75467;
        rom[1309]    = 75413;
        rom[1310]    = 75359;
        rom[1311]    = 75305;
        rom[1312]    = 75250;
        rom[1313]    = 75196;
        rom[1314]    = 75141;
        rom[1315]    = 75086;
        rom[1316]    = 75031;
        rom[1317]    = 74975;
        rom[1318]    = 74920;
        rom[1319]    = 74864;
        rom[1320]    = 74808;
        rom[1321]    = 74752;
        rom[1322]    = 74696;
        rom[1323]    = 74639;
        rom[1324]    = 74583;
        rom[1325]    = 74526;
        rom[1326]    = 74469;
        rom[1327]    = 74412;
        rom[1328]    = 74354;
        rom[1329]    = 74297;
        rom[1330]    = 74239;
        rom[1331]    = 74181;
        rom[1332]    = 74123;
        rom[1333]    = 74065;
        rom[1334]    = 74007;
        rom[1335]    = 73948;
        rom[1336]    = 73889;
        rom[1337]    = 73831;
        rom[1338]    = 73771;
        rom[1339]    = 73712;
        rom[1340]    = 73653;
        rom[1341]    = 73593;
        rom[1342]    = 73533;
        rom[1343]    = 73474;
        rom[1344]    = 73413;
        rom[1345]    = 73353;
        rom[1346]    = 73293;
        rom[1347]    = 73232;
        rom[1348]    = 73171;
        rom[1349]    = 73110;
        rom[1350]    = 73049;
        rom[1351]    = 72988;
        rom[1352]    = 72926;
        rom[1353]    = 72865;
        rom[1354]    = 72803;
        rom[1355]    = 72741;
        rom[1356]    = 72679;
        rom[1357]    = 72616;
        rom[1358]    = 72554;
        rom[1359]    = 72491;
        rom[1360]    = 72428;
        rom[1361]    = 72365;
        rom[1362]    = 72302;
        rom[1363]    = 72239;
        rom[1364]    = 72175;
        rom[1365]    = 72111;
        rom[1366]    = 72048;
        rom[1367]    = 71984;
        rom[1368]    = 71919;
        rom[1369]    = 71855;
        rom[1370]    = 71790;
        rom[1371]    = 71726;
        rom[1372]    = 71661;
        rom[1373]    = 71596;
        rom[1374]    = 71531;
        rom[1375]    = 71465;
        rom[1376]    = 71400;
        rom[1377]    = 71334;
        rom[1378]    = 71268;
        rom[1379]    = 71202;
        rom[1380]    = 71136;
        rom[1381]    = 71069;
        rom[1382]    = 71003;
        rom[1383]    = 70936;
        rom[1384]    = 70869;
        rom[1385]    = 70802;
        rom[1386]    = 70735;
        rom[1387]    = 70667;
        rom[1388]    = 70600;
        rom[1389]    = 70532;
        rom[1390]    = 70464;
        rom[1391]    = 70396;
        rom[1392]    = 70328;
        rom[1393]    = 70259;
        rom[1394]    = 70191;
        rom[1395]    = 70122;
        rom[1396]    = 70053;
        rom[1397]    = 69984;
        rom[1398]    = 69915;
        rom[1399]    = 69846;
        rom[1400]    = 69776;
        rom[1401]    = 69706;
        rom[1402]    = 69636;
        rom[1403]    = 69566;
        rom[1404]    = 69496;
        rom[1405]    = 69426;
        rom[1406]    = 69355;
        rom[1407]    = 69285;
        rom[1408]    = 69214;
        rom[1409]    = 69143;
        rom[1410]    = 69071;
        rom[1411]    = 69000;
        rom[1412]    = 68929;
        rom[1413]    = 68857;
        rom[1414]    = 68785;
        rom[1415]    = 68713;
        rom[1416]    = 68641;
        rom[1417]    = 68569;
        rom[1418]    = 68496;
        rom[1419]    = 68423;
        rom[1420]    = 68351;
        rom[1421]    = 68278;
        rom[1422]    = 68205;
        rom[1423]    = 68131;
        rom[1424]    = 68058;
        rom[1425]    = 67984;
        rom[1426]    = 67910;
        rom[1427]    = 67837;
        rom[1428]    = 67762;
        rom[1429]    = 67688;
        rom[1430]    = 67614;
        rom[1431]    = 67539;
        rom[1432]    = 67465;
        rom[1433]    = 67390;
        rom[1434]    = 67315;
        rom[1435]    = 67239;
        rom[1436]    = 67164;
        rom[1437]    = 67089;
        rom[1438]    = 67013;
        rom[1439]    = 66937;
        rom[1440]    = 66861;
        rom[1441]    = 66785;
        rom[1442]    = 66709;
        rom[1443]    = 66632;
        rom[1444]    = 66556;
        rom[1445]    = 66479;
        rom[1446]    = 66402;
        rom[1447]    = 66325;
        rom[1448]    = 66248;
        rom[1449]    = 66170;
        rom[1450]    = 66093;
        rom[1451]    = 66015;
        rom[1452]    = 65937;
        rom[1453]    = 65859;
        rom[1454]    = 65781;
        rom[1455]    = 65702;
        rom[1456]    = 65624;
        rom[1457]    = 65545;
        rom[1458]    = 65467;
        rom[1459]    = 65388;
        rom[1460]    = 65308;
        rom[1461]    = 65229;
        rom[1462]    = 65150;
        rom[1463]    = 65070;
        rom[1464]    = 64991;
        rom[1465]    = 64911;
        rom[1466]    = 64831;
        rom[1467]    = 64751;
        rom[1468]    = 64670;
        rom[1469]    = 64590;
        rom[1470]    = 64509;
        rom[1471]    = 64428;
        rom[1472]    = 64347;
        rom[1473]    = 64266;
        rom[1474]    = 64185;
        rom[1475]    = 64104;
        rom[1476]    = 64022;
        rom[1477]    = 63940;
        rom[1478]    = 63859;
        rom[1479]    = 63777;
        rom[1480]    = 63694;
        rom[1481]    = 63612;
        rom[1482]    = 63530;
        rom[1483]    = 63447;
        rom[1484]    = 63364;
        rom[1485]    = 63282;
        rom[1486]    = 63198;
        rom[1487]    = 63115;
        rom[1488]    = 63032;
        rom[1489]    = 62949;
        rom[1490]    = 62865;
        rom[1491]    = 62781;
        rom[1492]    = 62697;
        rom[1493]    = 62613;
        rom[1494]    = 62529;
        rom[1495]    = 62445;
        rom[1496]    = 62360;
        rom[1497]    = 62275;
        rom[1498]    = 62191;
        rom[1499]    = 62106;
        rom[1500]    = 62020;
        rom[1501]    = 61935;
        rom[1502]    = 61850;
        rom[1503]    = 61764;
        rom[1504]    = 61679;
        rom[1505]    = 61593;
        rom[1506]    = 61507;
        rom[1507]    = 61421;
        rom[1508]    = 61334;
        rom[1509]    = 61248;
        rom[1510]    = 61162;
        rom[1511]    = 61075;
        rom[1512]    = 60988;
        rom[1513]    = 60901;
        rom[1514]    = 60814;
        rom[1515]    = 60727;
        rom[1516]    = 60639;
        rom[1517]    = 60552;
        rom[1518]    = 60464;
        rom[1519]    = 60376;
        rom[1520]    = 60288;
        rom[1521]    = 60200;
        rom[1522]    = 60112;
        rom[1523]    = 60023;
        rom[1524]    = 59935;
        rom[1525]    = 59846;
        rom[1526]    = 59757;
        rom[1527]    = 59668;
        rom[1528]    = 59579;
        rom[1529]    = 59490;
        rom[1530]    = 59401;
        rom[1531]    = 59311;
        rom[1532]    = 59221;
        rom[1533]    = 59132;
        rom[1534]    = 59042;
        rom[1535]    = 58952;
        rom[1536]    = 58861;
        rom[1537]    = 58771;
        rom[1538]    = 58680;
        rom[1539]    = 58590;
        rom[1540]    = 58499;
        rom[1541]    = 58408;
        rom[1542]    = 58317;
        rom[1543]    = 58226;
        rom[1544]    = 58135;
        rom[1545]    = 58043;
        rom[1546]    = 57952;
        rom[1547]    = 57860;
        rom[1548]    = 57768;
        rom[1549]    = 57676;
        rom[1550]    = 57584;
        rom[1551]    = 57491;
        rom[1552]    = 57399;
        rom[1553]    = 57307;
        rom[1554]    = 57214;
        rom[1555]    = 57121;
        rom[1556]    = 57028;
        rom[1557]    = 56935;
        rom[1558]    = 56842;
        rom[1559]    = 56748;
        rom[1560]    = 56655;
        rom[1561]    = 56561;
        rom[1562]    = 56468;
        rom[1563]    = 56374;
        rom[1564]    = 56280;
        rom[1565]    = 56185;
        rom[1566]    = 56091;
        rom[1567]    = 55997;
        rom[1568]    = 55902;
        rom[1569]    = 55808;
        rom[1570]    = 55713;
        rom[1571]    = 55618;
        rom[1572]    = 55523;
        rom[1573]    = 55427;
        rom[1574]    = 55332;
        rom[1575]    = 55237;
        rom[1576]    = 55141;
        rom[1577]    = 55045;
        rom[1578]    = 54950;
        rom[1579]    = 54854;
        rom[1580]    = 54757;
        rom[1581]    = 54661;
        rom[1582]    = 54565;
        rom[1583]    = 54468;
        rom[1584]    = 54372;
        rom[1585]    = 54275;
        rom[1586]    = 54178;
        rom[1587]    = 54081;
        rom[1588]    = 53984;
        rom[1589]    = 53887;
        rom[1590]    = 53789;
        rom[1591]    = 53692;
        rom[1592]    = 53594;
        rom[1593]    = 53496;
        rom[1594]    = 53398;
        rom[1595]    = 53300;
        rom[1596]    = 53202;
        rom[1597]    = 53104;
        rom[1598]    = 53006;
        rom[1599]    = 52907;
        rom[1600]    = 52808;
        rom[1601]    = 52710;
        rom[1602]    = 52611;
        rom[1603]    = 52512;
        rom[1604]    = 52413;
        rom[1605]    = 52313;
        rom[1606]    = 52214;
        rom[1607]    = 52114;
        rom[1608]    = 52015;
        rom[1609]    = 51915;
        rom[1610]    = 51815;
        rom[1611]    = 51715;
        rom[1612]    = 51615;
        rom[1613]    = 51515;
        rom[1614]    = 51414;
        rom[1615]    = 51314;
        rom[1616]    = 51213;
        rom[1617]    = 51113;
        rom[1618]    = 51012;
        rom[1619]    = 50911;
        rom[1620]    = 50810;
        rom[1621]    = 50709;
        rom[1622]    = 50607;
        rom[1623]    = 50506;
        rom[1624]    = 50404;
        rom[1625]    = 50302;
        rom[1626]    = 50201;
        rom[1627]    = 50099;
        rom[1628]    = 49997;
        rom[1629]    = 49895;
        rom[1630]    = 49792;
        rom[1631]    = 49690;
        rom[1632]    = 49587;
        rom[1633]    = 49485;
        rom[1634]    = 49382;
        rom[1635]    = 49279;
        rom[1636]    = 49176;
        rom[1637]    = 49073;
        rom[1638]    = 48970;
        rom[1639]    = 48867;
        rom[1640]    = 48763;
        rom[1641]    = 48660;
        rom[1642]    = 48556;
        rom[1643]    = 48452;
        rom[1644]    = 48348;
        rom[1645]    = 48244;
        rom[1646]    = 48140;
        rom[1647]    = 48036;
        rom[1648]    = 47932;
        rom[1649]    = 47827;
        rom[1650]    = 47723;
        rom[1651]    = 47618;
        rom[1652]    = 47513;
        rom[1653]    = 47408;
        rom[1654]    = 47303;
        rom[1655]    = 47198;
        rom[1656]    = 47093;
        rom[1657]    = 46987;
        rom[1658]    = 46882;
        rom[1659]    = 46776;
        rom[1660]    = 46671;
        rom[1661]    = 46565;
        rom[1662]    = 46459;
        rom[1663]    = 46353;
        rom[1664]    = 46247;
        rom[1665]    = 46141;
        rom[1666]    = 46034;
        rom[1667]    = 45928;
        rom[1668]    = 45821;
        rom[1669]    = 45715;
        rom[1670]    = 45608;
        rom[1671]    = 45501;
        rom[1672]    = 45394;
        rom[1673]    = 45287;
        rom[1674]    = 45180;
        rom[1675]    = 45073;
        rom[1676]    = 44965;
        rom[1677]    = 44858;
        rom[1678]    = 44750;
        rom[1679]    = 44642;
        rom[1680]    = 44534;
        rom[1681]    = 44426;
        rom[1682]    = 44318;
        rom[1683]    = 44210;
        rom[1684]    = 44102;
        rom[1685]    = 43994;
        rom[1686]    = 43885;
        rom[1687]    = 43777;
        rom[1688]    = 43668;
        rom[1689]    = 43559;
        rom[1690]    = 43450;
        rom[1691]    = 43341;
        rom[1692]    = 43232;
        rom[1693]    = 43123;
        rom[1694]    = 43014;
        rom[1695]    = 42905;
        rom[1696]    = 42795;
        rom[1697]    = 42685;
        rom[1698]    = 42576;
        rom[1699]    = 42466;
        rom[1700]    = 42356;
        rom[1701]    = 42246;
        rom[1702]    = 42136;
        rom[1703]    = 42026;
        rom[1704]    = 41916;
        rom[1705]    = 41805;
        rom[1706]    = 41695;
        rom[1707]    = 41584;
        rom[1708]    = 41474;
        rom[1709]    = 41363;
        rom[1710]    = 41252;
        rom[1711]    = 41141;
        rom[1712]    = 41030;
        rom[1713]    = 40919;
        rom[1714]    = 40808;
        rom[1715]    = 40696;
        rom[1716]    = 40585;
        rom[1717]    = 40473;
        rom[1718]    = 40362;
        rom[1719]    = 40250;
        rom[1720]    = 40138;
        rom[1721]    = 40026;
        rom[1722]    = 39914;
        rom[1723]    = 39802;
        rom[1724]    = 39690;
        rom[1725]    = 39577;
        rom[1726]    = 39465;
        rom[1727]    = 39353;
        rom[1728]    = 39240;
        rom[1729]    = 39127;
        rom[1730]    = 39015;
        rom[1731]    = 38902;
        rom[1732]    = 38789;
        rom[1733]    = 38676;
        rom[1734]    = 38563;
        rom[1735]    = 38450;
        rom[1736]    = 38336;
        rom[1737]    = 38223;
        rom[1738]    = 38109;
        rom[1739]    = 37996;
        rom[1740]    = 37882;
        rom[1741]    = 37768;
        rom[1742]    = 37655;
        rom[1743]    = 37541;
        rom[1744]    = 37427;
        rom[1745]    = 37312;
        rom[1746]    = 37198;
        rom[1747]    = 37084;
        rom[1748]    = 36970;
        rom[1749]    = 36855;
        rom[1750]    = 36741;
        rom[1751]    = 36626;
        rom[1752]    = 36511;
        rom[1753]    = 36397;
        rom[1754]    = 36282;
        rom[1755]    = 36167;
        rom[1756]    = 36052;
        rom[1757]    = 35936;
        rom[1758]    = 35821;
        rom[1759]    = 35706;
        rom[1760]    = 35591;
        rom[1761]    = 35475;
        rom[1762]    = 35360;
        rom[1763]    = 35244;
        rom[1764]    = 35128;
        rom[1765]    = 35012;
        rom[1766]    = 34896;
        rom[1767]    = 34780;
        rom[1768]    = 34664;
        rom[1769]    = 34548;
        rom[1770]    = 34432;
        rom[1771]    = 34316;
        rom[1772]    = 34199;
        rom[1773]    = 34083;
        rom[1774]    = 33966;
        rom[1775]    = 33850;
        rom[1776]    = 33733;
        rom[1777]    = 33616;
        rom[1778]    = 33499;
        rom[1779]    = 33383;
        rom[1780]    = 33265;
        rom[1781]    = 33148;
        rom[1782]    = 33031;
        rom[1783]    = 32914;
        rom[1784]    = 32797;
        rom[1785]    = 32679;
        rom[1786]    = 32562;
        rom[1787]    = 32444;
        rom[1788]    = 32327;
        rom[1789]    = 32209;
        rom[1790]    = 32091;
        rom[1791]    = 31973;
        rom[1792]    = 31855;
        rom[1793]    = 31737;
        rom[1794]    = 31619;
        rom[1795]    = 31501;
        rom[1796]    = 31383;
        rom[1797]    = 31264;
        rom[1798]    = 31146;
        rom[1799]    = 31028;
        rom[1800]    = 30909;
        rom[1801]    = 30791;
        rom[1802]    = 30672;
        rom[1803]    = 30553;
        rom[1804]    = 30434;
        rom[1805]    = 30315;
        rom[1806]    = 30196;
        rom[1807]    = 30077;
        rom[1808]    = 29958;
        rom[1809]    = 29839;
        rom[1810]    = 29720;
        rom[1811]    = 29601;
        rom[1812]    = 29481;
        rom[1813]    = 29362;
        rom[1814]    = 29242;
        rom[1815]    = 29123;
        rom[1816]    = 29003;
        rom[1817]    = 28883;
        rom[1818]    = 28763;
        rom[1819]    = 28644;
        rom[1820]    = 28524;
        rom[1821]    = 28404;
        rom[1822]    = 28284;
        rom[1823]    = 28163;
        rom[1824]    = 28043;
        rom[1825]    = 27923;
        rom[1826]    = 27803;
        rom[1827]    = 27682;
        rom[1828]    = 27562;
        rom[1829]    = 27441;
        rom[1830]    = 27321;
        rom[1831]    = 27200;
        rom[1832]    = 27079;
        rom[1833]    = 26959;
        rom[1834]    = 26838;
        rom[1835]    = 26717;
        rom[1836]    = 26596;
        rom[1837]    = 26475;
        rom[1838]    = 26354;
        rom[1839]    = 26233;
        rom[1840]    = 26111;
        rom[1841]    = 25990;
        rom[1842]    = 25869;
        rom[1843]    = 25747;
        rom[1844]    = 25626;
        rom[1845]    = 25504;
        rom[1846]    = 25383;
        rom[1847]    = 25261;
        rom[1848]    = 25139;
        rom[1849]    = 25018;
        rom[1850]    = 24896;
        rom[1851]    = 24774;
        rom[1852]    = 24652;
        rom[1853]    = 24530;
        rom[1854]    = 24408;
        rom[1855]    = 24286;
        rom[1856]    = 24164;
        rom[1857]    = 24041;
        rom[1858]    = 23919;
        rom[1859]    = 23797;
        rom[1860]    = 23674;
        rom[1861]    = 23552;
        rom[1862]    = 23430;
        rom[1863]    = 23307;
        rom[1864]    = 23184;
        rom[1865]    = 23062;
        rom[1866]    = 22939;
        rom[1867]    = 22816;
        rom[1868]    = 22693;
        rom[1869]    = 22570;
        rom[1870]    = 22448;
        rom[1871]    = 22325;
        rom[1872]    = 22202;
        rom[1873]    = 22078;
        rom[1874]    = 21955;
        rom[1875]    = 21832;
        rom[1876]    = 21709;
        rom[1877]    = 21586;
        rom[1878]    = 21462;
        rom[1879]    = 21339;
        rom[1880]    = 21215;
        rom[1881]    = 21092;
        rom[1882]    = 20968;
        rom[1883]    = 20845;
        rom[1884]    = 20721;
        rom[1885]    = 20597;
        rom[1886]    = 20474;
        rom[1887]    = 20350;
        rom[1888]    = 20226;
        rom[1889]    = 20102;
        rom[1890]    = 19978;
        rom[1891]    = 19854;
        rom[1892]    = 19730;
        rom[1893]    = 19606;
        rom[1894]    = 19482;
        rom[1895]    = 19358;
        rom[1896]    = 19234;
        rom[1897]    = 19109;
        rom[1898]    = 18985;
        rom[1899]    = 18861;
        rom[1900]    = 18736;
        rom[1901]    = 18612;
        rom[1902]    = 18487;
        rom[1903]    = 18363;
        rom[1904]    = 18238;
        rom[1905]    = 18114;
        rom[1906]    = 17989;
        rom[1907]    = 17864;
        rom[1908]    = 17739;
        rom[1909]    = 17615;
        rom[1910]    = 17490;
        rom[1911]    = 17365;
        rom[1912]    = 17240;
        rom[1913]    = 17115;
        rom[1914]    = 16990;
        rom[1915]    = 16865;
        rom[1916]    = 16740;
        rom[1917]    = 16615;
        rom[1918]    = 16490;
        rom[1919]    = 16365;
        rom[1920]    = 16239;
        rom[1921]    = 16114;
        rom[1922]    = 15989;
        rom[1923]    = 15864;
        rom[1924]    = 15738;
        rom[1925]    = 15613;
        rom[1926]    = 15487;
        rom[1927]    = 15362;
        rom[1928]    = 15236;
        rom[1929]    = 15111;
        rom[1930]    = 14985;
        rom[1931]    = 14860;
        rom[1932]    = 14734;
        rom[1933]    = 14608;
        rom[1934]    = 14482;
        rom[1935]    = 14357;
        rom[1936]    = 14231;
        rom[1937]    = 14105;
        rom[1938]    = 13979;
        rom[1939]    = 13853;
        rom[1940]    = 13727;
        rom[1941]    = 13601;
        rom[1942]    = 13475;
        rom[1943]    = 13349;
        rom[1944]    = 13223;
        rom[1945]    = 13097;
        rom[1946]    = 12971;
        rom[1947]    = 12845;
        rom[1948]    = 12719;
        rom[1949]    = 12593;
        rom[1950]    = 12466;
        rom[1951]    = 12340;
        rom[1952]    = 12214;
        rom[1953]    = 12087;
        rom[1954]    = 11961;
        rom[1955]    = 11835;
        rom[1956]    = 11708;
        rom[1957]    = 11582;
        rom[1958]    = 11455;
        rom[1959]    = 11329;
        rom[1960]    = 11202;
        rom[1961]    = 11076;
        rom[1962]    = 10949;
        rom[1963]    = 10823;
        rom[1964]    = 10696;
        rom[1965]    = 10569;
        rom[1966]    = 10443;
        rom[1967]    = 10316;
        rom[1968]    = 10189;
        rom[1969]    = 10063;
        rom[1970]    = 9936;
        rom[1971]    = 9809;
        rom[1972]    = 9682;
        rom[1973]    = 9555;
        rom[1974]    = 9429;
        rom[1975]    = 9302;
        rom[1976]    = 9175;
        rom[1977]    = 9048;
        rom[1978]    = 8921;
        rom[1979]    = 8794;
        rom[1980]    = 8667;
        rom[1981]    = 8540;
        rom[1982]    = 8413;
        rom[1983]    = 8286;
        rom[1984]    = 8159;
        rom[1985]    = 8032;
        rom[1986]    = 7905;
        rom[1987]    = 7777;
        rom[1988]    = 7650;
        rom[1989]    = 7523;
        rom[1990]    = 7396;
        rom[1991]    = 7269;
        rom[1992]    = 7142;
        rom[1993]    = 7014;
        rom[1994]    = 6887;
        rom[1995]    = 6760;
        rom[1996]    = 6633;
        rom[1997]    = 6505;
        rom[1998]    = 6378;
        rom[1999]    = 6251;
        rom[2000]    = 6123;
        rom[2001]    = 5996;
        rom[2002]    = 5869;
        rom[2003]    = 5741;
        rom[2004]    = 5614;
        rom[2005]    = 5486;
        rom[2006]    = 5359;
        rom[2007]    = 5231;
        rom[2008]    = 5104;
        rom[2009]    = 4977;
        rom[2010]    = 4849;
        rom[2011]    = 4722;
        rom[2012]    = 4594;
        rom[2013]    = 4467;
        rom[2014]    = 4339;
        rom[2015]    = 4212;
        rom[2016]    = 4084;
        rom[2017]    = 3957;
        rom[2018]    = 3829;
        rom[2019]    = 3701;
        rom[2020]    = 3574;
        rom[2021]    = 3446;
        rom[2022]    = 3319;
        rom[2023]    = 3191;
        rom[2024]    = 3063;
        rom[2025]    = 2936;
        rom[2026]    = 2808;
        rom[2027]    = 2681;
        rom[2028]    = 2553;
        rom[2029]    = 2425;
        rom[2030]    = 2298;
        rom[2031]    = 2170;
        rom[2032]    = 2042;
        rom[2033]    = 1915;
        rom[2034]    = 1787;
        rom[2035]    = 1659;
        rom[2036]    = 1532;
        rom[2037]    = 1404;
        rom[2038]    = 1276;
        rom[2039]    = 1149;
        rom[2040]    = 1021;
        rom[2041]    = 893;
        rom[2042]    = 766;
        rom[2043]    = 638;
        rom[2044]    = 510;
        rom[2045]    = 383;
        rom[2046]    = 255;
        rom[2047]    = 127;
        rom[2048]    = 0;
        rom[2049]    = -127;
        rom[2050]    = -255;
        rom[2051]    = -383;
        rom[2052]    = -510;
        rom[2053]    = -638;
        rom[2054]    = -766;
        rom[2055]    = -893;
        rom[2056]    = -1021;
        rom[2057]    = -1149;
        rom[2058]    = -1276;
        rom[2059]    = -1404;
        rom[2060]    = -1532;
        rom[2061]    = -1659;
        rom[2062]    = -1787;
        rom[2063]    = -1915;
        rom[2064]    = -2042;
        rom[2065]    = -2170;
        rom[2066]    = -2298;
        rom[2067]    = -2425;
        rom[2068]    = -2553;
        rom[2069]    = -2681;
        rom[2070]    = -2808;
        rom[2071]    = -2936;
        rom[2072]    = -3063;
        rom[2073]    = -3191;
        rom[2074]    = -3319;
        rom[2075]    = -3446;
        rom[2076]    = -3574;
        rom[2077]    = -3701;
        rom[2078]    = -3829;
        rom[2079]    = -3957;
        rom[2080]    = -4084;
        rom[2081]    = -4212;
        rom[2082]    = -4339;
        rom[2083]    = -4467;
        rom[2084]    = -4594;
        rom[2085]    = -4722;
        rom[2086]    = -4849;
        rom[2087]    = -4977;
        rom[2088]    = -5104;
        rom[2089]    = -5231;
        rom[2090]    = -5359;
        rom[2091]    = -5486;
        rom[2092]    = -5614;
        rom[2093]    = -5741;
        rom[2094]    = -5869;
        rom[2095]    = -5996;
        rom[2096]    = -6123;
        rom[2097]    = -6251;
        rom[2098]    = -6378;
        rom[2099]    = -6505;
        rom[2100]    = -6633;
        rom[2101]    = -6760;
        rom[2102]    = -6887;
        rom[2103]    = -7014;
        rom[2104]    = -7142;
        rom[2105]    = -7269;
        rom[2106]    = -7396;
        rom[2107]    = -7523;
        rom[2108]    = -7650;
        rom[2109]    = -7777;
        rom[2110]    = -7905;
        rom[2111]    = -8032;
        rom[2112]    = -8159;
        rom[2113]    = -8286;
        rom[2114]    = -8413;
        rom[2115]    = -8540;
        rom[2116]    = -8667;
        rom[2117]    = -8794;
        rom[2118]    = -8921;
        rom[2119]    = -9048;
        rom[2120]    = -9175;
        rom[2121]    = -9302;
        rom[2122]    = -9429;
        rom[2123]    = -9555;
        rom[2124]    = -9682;
        rom[2125]    = -9809;
        rom[2126]    = -9936;
        rom[2127]    = -10063;
        rom[2128]    = -10189;
        rom[2129]    = -10316;
        rom[2130]    = -10443;
        rom[2131]    = -10569;
        rom[2132]    = -10696;
        rom[2133]    = -10823;
        rom[2134]    = -10949;
        rom[2135]    = -11076;
        rom[2136]    = -11202;
        rom[2137]    = -11329;
        rom[2138]    = -11455;
        rom[2139]    = -11582;
        rom[2140]    = -11708;
        rom[2141]    = -11835;
        rom[2142]    = -11961;
        rom[2143]    = -12087;
        rom[2144]    = -12214;
        rom[2145]    = -12340;
        rom[2146]    = -12466;
        rom[2147]    = -12593;
        rom[2148]    = -12719;
        rom[2149]    = -12845;
        rom[2150]    = -12971;
        rom[2151]    = -13097;
        rom[2152]    = -13223;
        rom[2153]    = -13349;
        rom[2154]    = -13475;
        rom[2155]    = -13601;
        rom[2156]    = -13727;
        rom[2157]    = -13853;
        rom[2158]    = -13979;
        rom[2159]    = -14105;
        rom[2160]    = -14231;
        rom[2161]    = -14357;
        rom[2162]    = -14482;
        rom[2163]    = -14608;
        rom[2164]    = -14734;
        rom[2165]    = -14860;
        rom[2166]    = -14985;
        rom[2167]    = -15111;
        rom[2168]    = -15236;
        rom[2169]    = -15362;
        rom[2170]    = -15487;
        rom[2171]    = -15613;
        rom[2172]    = -15738;
        rom[2173]    = -15864;
        rom[2174]    = -15989;
        rom[2175]    = -16114;
        rom[2176]    = -16239;
        rom[2177]    = -16365;
        rom[2178]    = -16490;
        rom[2179]    = -16615;
        rom[2180]    = -16740;
        rom[2181]    = -16865;
        rom[2182]    = -16990;
        rom[2183]    = -17115;
        rom[2184]    = -17240;
        rom[2185]    = -17365;
        rom[2186]    = -17490;
        rom[2187]    = -17615;
        rom[2188]    = -17739;
        rom[2189]    = -17864;
        rom[2190]    = -17989;
        rom[2191]    = -18114;
        rom[2192]    = -18238;
        rom[2193]    = -18363;
        rom[2194]    = -18487;
        rom[2195]    = -18612;
        rom[2196]    = -18736;
        rom[2197]    = -18861;
        rom[2198]    = -18985;
        rom[2199]    = -19109;
        rom[2200]    = -19234;
        rom[2201]    = -19358;
        rom[2202]    = -19482;
        rom[2203]    = -19606;
        rom[2204]    = -19730;
        rom[2205]    = -19854;
        rom[2206]    = -19978;
        rom[2207]    = -20102;
        rom[2208]    = -20226;
        rom[2209]    = -20350;
        rom[2210]    = -20474;
        rom[2211]    = -20597;
        rom[2212]    = -20721;
        rom[2213]    = -20845;
        rom[2214]    = -20968;
        rom[2215]    = -21092;
        rom[2216]    = -21215;
        rom[2217]    = -21339;
        rom[2218]    = -21462;
        rom[2219]    = -21586;
        rom[2220]    = -21709;
        rom[2221]    = -21832;
        rom[2222]    = -21955;
        rom[2223]    = -22078;
        rom[2224]    = -22202;
        rom[2225]    = -22325;
        rom[2226]    = -22448;
        rom[2227]    = -22570;
        rom[2228]    = -22693;
        rom[2229]    = -22816;
        rom[2230]    = -22939;
        rom[2231]    = -23062;
        rom[2232]    = -23184;
        rom[2233]    = -23307;
        rom[2234]    = -23430;
        rom[2235]    = -23552;
        rom[2236]    = -23674;
        rom[2237]    = -23797;
        rom[2238]    = -23919;
        rom[2239]    = -24041;
        rom[2240]    = -24164;
        rom[2241]    = -24286;
        rom[2242]    = -24408;
        rom[2243]    = -24530;
        rom[2244]    = -24652;
        rom[2245]    = -24774;
        rom[2246]    = -24896;
        rom[2247]    = -25018;
        rom[2248]    = -25139;
        rom[2249]    = -25261;
        rom[2250]    = -25383;
        rom[2251]    = -25504;
        rom[2252]    = -25626;
        rom[2253]    = -25747;
        rom[2254]    = -25869;
        rom[2255]    = -25990;
        rom[2256]    = -26111;
        rom[2257]    = -26233;
        rom[2258]    = -26354;
        rom[2259]    = -26475;
        rom[2260]    = -26596;
        rom[2261]    = -26717;
        rom[2262]    = -26838;
        rom[2263]    = -26959;
        rom[2264]    = -27079;
        rom[2265]    = -27200;
        rom[2266]    = -27321;
        rom[2267]    = -27441;
        rom[2268]    = -27562;
        rom[2269]    = -27682;
        rom[2270]    = -27803;
        rom[2271]    = -27923;
        rom[2272]    = -28043;
        rom[2273]    = -28163;
        rom[2274]    = -28284;
        rom[2275]    = -28404;
        rom[2276]    = -28524;
        rom[2277]    = -28644;
        rom[2278]    = -28763;
        rom[2279]    = -28883;
        rom[2280]    = -29003;
        rom[2281]    = -29123;
        rom[2282]    = -29242;
        rom[2283]    = -29362;
        rom[2284]    = -29481;
        rom[2285]    = -29601;
        rom[2286]    = -29720;
        rom[2287]    = -29839;
        rom[2288]    = -29958;
        rom[2289]    = -30077;
        rom[2290]    = -30196;
        rom[2291]    = -30315;
        rom[2292]    = -30434;
        rom[2293]    = -30553;
        rom[2294]    = -30672;
        rom[2295]    = -30791;
        rom[2296]    = -30909;
        rom[2297]    = -31028;
        rom[2298]    = -31146;
        rom[2299]    = -31264;
        rom[2300]    = -31383;
        rom[2301]    = -31501;
        rom[2302]    = -31619;
        rom[2303]    = -31737;
        rom[2304]    = -31855;
        rom[2305]    = -31973;
        rom[2306]    = -32091;
        rom[2307]    = -32209;
        rom[2308]    = -32327;
        rom[2309]    = -32444;
        rom[2310]    = -32562;
        rom[2311]    = -32679;
        rom[2312]    = -32797;
        rom[2313]    = -32914;
        rom[2314]    = -33031;
        rom[2315]    = -33148;
        rom[2316]    = -33265;
        rom[2317]    = -33383;
        rom[2318]    = -33499;
        rom[2319]    = -33616;
        rom[2320]    = -33733;
        rom[2321]    = -33850;
        rom[2322]    = -33966;
        rom[2323]    = -34083;
        rom[2324]    = -34199;
        rom[2325]    = -34316;
        rom[2326]    = -34432;
        rom[2327]    = -34548;
        rom[2328]    = -34664;
        rom[2329]    = -34780;
        rom[2330]    = -34896;
        rom[2331]    = -35012;
        rom[2332]    = -35128;
        rom[2333]    = -35244;
        rom[2334]    = -35360;
        rom[2335]    = -35475;
        rom[2336]    = -35591;
        rom[2337]    = -35706;
        rom[2338]    = -35821;
        rom[2339]    = -35936;
        rom[2340]    = -36052;
        rom[2341]    = -36167;
        rom[2342]    = -36282;
        rom[2343]    = -36397;
        rom[2344]    = -36511;
        rom[2345]    = -36626;
        rom[2346]    = -36741;
        rom[2347]    = -36855;
        rom[2348]    = -36970;
        rom[2349]    = -37084;
        rom[2350]    = -37198;
        rom[2351]    = -37312;
        rom[2352]    = -37427;
        rom[2353]    = -37541;
        rom[2354]    = -37655;
        rom[2355]    = -37768;
        rom[2356]    = -37882;
        rom[2357]    = -37996;
        rom[2358]    = -38109;
        rom[2359]    = -38223;
        rom[2360]    = -38336;
        rom[2361]    = -38450;
        rom[2362]    = -38563;
        rom[2363]    = -38676;
        rom[2364]    = -38789;
        rom[2365]    = -38902;
        rom[2366]    = -39015;
        rom[2367]    = -39127;
        rom[2368]    = -39240;
        rom[2369]    = -39353;
        rom[2370]    = -39465;
        rom[2371]    = -39577;
        rom[2372]    = -39690;
        rom[2373]    = -39802;
        rom[2374]    = -39914;
        rom[2375]    = -40026;
        rom[2376]    = -40138;
        rom[2377]    = -40250;
        rom[2378]    = -40362;
        rom[2379]    = -40473;
        rom[2380]    = -40585;
        rom[2381]    = -40696;
        rom[2382]    = -40808;
        rom[2383]    = -40919;
        rom[2384]    = -41030;
        rom[2385]    = -41141;
        rom[2386]    = -41252;
        rom[2387]    = -41363;
        rom[2388]    = -41474;
        rom[2389]    = -41584;
        rom[2390]    = -41695;
        rom[2391]    = -41805;
        rom[2392]    = -41916;
        rom[2393]    = -42026;
        rom[2394]    = -42136;
        rom[2395]    = -42246;
        rom[2396]    = -42356;
        rom[2397]    = -42466;
        rom[2398]    = -42576;
        rom[2399]    = -42685;
        rom[2400]    = -42795;
        rom[2401]    = -42905;
        rom[2402]    = -43014;
        rom[2403]    = -43123;
        rom[2404]    = -43232;
        rom[2405]    = -43341;
        rom[2406]    = -43450;
        rom[2407]    = -43559;
        rom[2408]    = -43668;
        rom[2409]    = -43777;
        rom[2410]    = -43885;
        rom[2411]    = -43994;
        rom[2412]    = -44102;
        rom[2413]    = -44210;
        rom[2414]    = -44318;
        rom[2415]    = -44426;
        rom[2416]    = -44534;
        rom[2417]    = -44642;
        rom[2418]    = -44750;
        rom[2419]    = -44858;
        rom[2420]    = -44965;
        rom[2421]    = -45073;
        rom[2422]    = -45180;
        rom[2423]    = -45287;
        rom[2424]    = -45394;
        rom[2425]    = -45501;
        rom[2426]    = -45608;
        rom[2427]    = -45715;
        rom[2428]    = -45821;
        rom[2429]    = -45928;
        rom[2430]    = -46034;
        rom[2431]    = -46141;
        rom[2432]    = -46247;
        rom[2433]    = -46353;
        rom[2434]    = -46459;
        rom[2435]    = -46565;
        rom[2436]    = -46671;
        rom[2437]    = -46776;
        rom[2438]    = -46882;
        rom[2439]    = -46987;
        rom[2440]    = -47093;
        rom[2441]    = -47198;
        rom[2442]    = -47303;
        rom[2443]    = -47408;
        rom[2444]    = -47513;
        rom[2445]    = -47618;
        rom[2446]    = -47723;
        rom[2447]    = -47827;
        rom[2448]    = -47932;
        rom[2449]    = -48036;
        rom[2450]    = -48140;
        rom[2451]    = -48244;
        rom[2452]    = -48348;
        rom[2453]    = -48452;
        rom[2454]    = -48556;
        rom[2455]    = -48660;
        rom[2456]    = -48763;
        rom[2457]    = -48867;
        rom[2458]    = -48970;
        rom[2459]    = -49073;
        rom[2460]    = -49176;
        rom[2461]    = -49279;
        rom[2462]    = -49382;
        rom[2463]    = -49485;
        rom[2464]    = -49587;
        rom[2465]    = -49690;
        rom[2466]    = -49792;
        rom[2467]    = -49895;
        rom[2468]    = -49997;
        rom[2469]    = -50099;
        rom[2470]    = -50201;
        rom[2471]    = -50302;
        rom[2472]    = -50404;
        rom[2473]    = -50506;
        rom[2474]    = -50607;
        rom[2475]    = -50709;
        rom[2476]    = -50810;
        rom[2477]    = -50911;
        rom[2478]    = -51012;
        rom[2479]    = -51113;
        rom[2480]    = -51213;
        rom[2481]    = -51314;
        rom[2482]    = -51414;
        rom[2483]    = -51515;
        rom[2484]    = -51615;
        rom[2485]    = -51715;
        rom[2486]    = -51815;
        rom[2487]    = -51915;
        rom[2488]    = -52015;
        rom[2489]    = -52114;
        rom[2490]    = -52214;
        rom[2491]    = -52313;
        rom[2492]    = -52413;
        rom[2493]    = -52512;
        rom[2494]    = -52611;
        rom[2495]    = -52710;
        rom[2496]    = -52808;
        rom[2497]    = -52907;
        rom[2498]    = -53006;
        rom[2499]    = -53104;
        rom[2500]    = -53202;
        rom[2501]    = -53300;
        rom[2502]    = -53398;
        rom[2503]    = -53496;
        rom[2504]    = -53594;
        rom[2505]    = -53692;
        rom[2506]    = -53789;
        rom[2507]    = -53887;
        rom[2508]    = -53984;
        rom[2509]    = -54081;
        rom[2510]    = -54178;
        rom[2511]    = -54275;
        rom[2512]    = -54372;
        rom[2513]    = -54468;
        rom[2514]    = -54565;
        rom[2515]    = -54661;
        rom[2516]    = -54757;
        rom[2517]    = -54854;
        rom[2518]    = -54950;
        rom[2519]    = -55045;
        rom[2520]    = -55141;
        rom[2521]    = -55237;
        rom[2522]    = -55332;
        rom[2523]    = -55427;
        rom[2524]    = -55523;
        rom[2525]    = -55618;
        rom[2526]    = -55713;
        rom[2527]    = -55808;
        rom[2528]    = -55902;
        rom[2529]    = -55997;
        rom[2530]    = -56091;
        rom[2531]    = -56185;
        rom[2532]    = -56280;
        rom[2533]    = -56374;
        rom[2534]    = -56468;
        rom[2535]    = -56561;
        rom[2536]    = -56655;
        rom[2537]    = -56748;
        rom[2538]    = -56842;
        rom[2539]    = -56935;
        rom[2540]    = -57028;
        rom[2541]    = -57121;
        rom[2542]    = -57214;
        rom[2543]    = -57307;
        rom[2544]    = -57399;
        rom[2545]    = -57491;
        rom[2546]    = -57584;
        rom[2547]    = -57676;
        rom[2548]    = -57768;
        rom[2549]    = -57860;
        rom[2550]    = -57952;
        rom[2551]    = -58043;
        rom[2552]    = -58135;
        rom[2553]    = -58226;
        rom[2554]    = -58317;
        rom[2555]    = -58408;
        rom[2556]    = -58499;
        rom[2557]    = -58590;
        rom[2558]    = -58680;
        rom[2559]    = -58771;
        rom[2560]    = -58861;
        rom[2561]    = -58952;
        rom[2562]    = -59042;
        rom[2563]    = -59132;
        rom[2564]    = -59221;
        rom[2565]    = -59311;
        rom[2566]    = -59401;
        rom[2567]    = -59490;
        rom[2568]    = -59579;
        rom[2569]    = -59668;
        rom[2570]    = -59757;
        rom[2571]    = -59846;
        rom[2572]    = -59935;
        rom[2573]    = -60023;
        rom[2574]    = -60112;
        rom[2575]    = -60200;
        rom[2576]    = -60288;
        rom[2577]    = -60376;
        rom[2578]    = -60464;
        rom[2579]    = -60552;
        rom[2580]    = -60639;
        rom[2581]    = -60727;
        rom[2582]    = -60814;
        rom[2583]    = -60901;
        rom[2584]    = -60988;
        rom[2585]    = -61075;
        rom[2586]    = -61162;
        rom[2587]    = -61248;
        rom[2588]    = -61334;
        rom[2589]    = -61421;
        rom[2590]    = -61507;
        rom[2591]    = -61593;
        rom[2592]    = -61679;
        rom[2593]    = -61764;
        rom[2594]    = -61850;
        rom[2595]    = -61935;
        rom[2596]    = -62020;
        rom[2597]    = -62106;
        rom[2598]    = -62191;
        rom[2599]    = -62275;
        rom[2600]    = -62360;
        rom[2601]    = -62445;
        rom[2602]    = -62529;
        rom[2603]    = -62613;
        rom[2604]    = -62697;
        rom[2605]    = -62781;
        rom[2606]    = -62865;
        rom[2607]    = -62949;
        rom[2608]    = -63032;
        rom[2609]    = -63115;
        rom[2610]    = -63198;
        rom[2611]    = -63282;
        rom[2612]    = -63364;
        rom[2613]    = -63447;
        rom[2614]    = -63530;
        rom[2615]    = -63612;
        rom[2616]    = -63694;
        rom[2617]    = -63777;
        rom[2618]    = -63859;
        rom[2619]    = -63940;
        rom[2620]    = -64022;
        rom[2621]    = -64104;
        rom[2622]    = -64185;
        rom[2623]    = -64266;
        rom[2624]    = -64347;
        rom[2625]    = -64428;
        rom[2626]    = -64509;
        rom[2627]    = -64590;
        rom[2628]    = -64670;
        rom[2629]    = -64751;
        rom[2630]    = -64831;
        rom[2631]    = -64911;
        rom[2632]    = -64991;
        rom[2633]    = -65070;
        rom[2634]    = -65150;
        rom[2635]    = -65229;
        rom[2636]    = -65308;
        rom[2637]    = -65388;
        rom[2638]    = -65467;
        rom[2639]    = -65545;
        rom[2640]    = -65624;
        rom[2641]    = -65702;
        rom[2642]    = -65781;
        rom[2643]    = -65859;
        rom[2644]    = -65937;
        rom[2645]    = -66015;
        rom[2646]    = -66093;
        rom[2647]    = -66170;
        rom[2648]    = -66248;
        rom[2649]    = -66325;
        rom[2650]    = -66402;
        rom[2651]    = -66479;
        rom[2652]    = -66556;
        rom[2653]    = -66632;
        rom[2654]    = -66709;
        rom[2655]    = -66785;
        rom[2656]    = -66861;
        rom[2657]    = -66937;
        rom[2658]    = -67013;
        rom[2659]    = -67089;
        rom[2660]    = -67164;
        rom[2661]    = -67239;
        rom[2662]    = -67315;
        rom[2663]    = -67390;
        rom[2664]    = -67465;
        rom[2665]    = -67539;
        rom[2666]    = -67614;
        rom[2667]    = -67688;
        rom[2668]    = -67762;
        rom[2669]    = -67837;
        rom[2670]    = -67910;
        rom[2671]    = -67984;
        rom[2672]    = -68058;
        rom[2673]    = -68131;
        rom[2674]    = -68205;
        rom[2675]    = -68278;
        rom[2676]    = -68351;
        rom[2677]    = -68423;
        rom[2678]    = -68496;
        rom[2679]    = -68569;
        rom[2680]    = -68641;
        rom[2681]    = -68713;
        rom[2682]    = -68785;
        rom[2683]    = -68857;
        rom[2684]    = -68929;
        rom[2685]    = -69000;
        rom[2686]    = -69071;
        rom[2687]    = -69143;
        rom[2688]    = -69214;
        rom[2689]    = -69285;
        rom[2690]    = -69355;
        rom[2691]    = -69426;
        rom[2692]    = -69496;
        rom[2693]    = -69566;
        rom[2694]    = -69636;
        rom[2695]    = -69706;
        rom[2696]    = -69776;
        rom[2697]    = -69846;
        rom[2698]    = -69915;
        rom[2699]    = -69984;
        rom[2700]    = -70053;
        rom[2701]    = -70122;
        rom[2702]    = -70191;
        rom[2703]    = -70259;
        rom[2704]    = -70328;
        rom[2705]    = -70396;
        rom[2706]    = -70464;
        rom[2707]    = -70532;
        rom[2708]    = -70600;
        rom[2709]    = -70667;
        rom[2710]    = -70735;
        rom[2711]    = -70802;
        rom[2712]    = -70869;
        rom[2713]    = -70936;
        rom[2714]    = -71003;
        rom[2715]    = -71069;
        rom[2716]    = -71136;
        rom[2717]    = -71202;
        rom[2718]    = -71268;
        rom[2719]    = -71334;
        rom[2720]    = -71400;
        rom[2721]    = -71465;
        rom[2722]    = -71531;
        rom[2723]    = -71596;
        rom[2724]    = -71661;
        rom[2725]    = -71726;
        rom[2726]    = -71790;
        rom[2727]    = -71855;
        rom[2728]    = -71919;
        rom[2729]    = -71984;
        rom[2730]    = -72048;
        rom[2731]    = -72111;
        rom[2732]    = -72175;
        rom[2733]    = -72239;
        rom[2734]    = -72302;
        rom[2735]    = -72365;
        rom[2736]    = -72428;
        rom[2737]    = -72491;
        rom[2738]    = -72554;
        rom[2739]    = -72616;
        rom[2740]    = -72679;
        rom[2741]    = -72741;
        rom[2742]    = -72803;
        rom[2743]    = -72865;
        rom[2744]    = -72926;
        rom[2745]    = -72988;
        rom[2746]    = -73049;
        rom[2747]    = -73110;
        rom[2748]    = -73171;
        rom[2749]    = -73232;
        rom[2750]    = -73293;
        rom[2751]    = -73353;
        rom[2752]    = -73413;
        rom[2753]    = -73474;
        rom[2754]    = -73533;
        rom[2755]    = -73593;
        rom[2756]    = -73653;
        rom[2757]    = -73712;
        rom[2758]    = -73771;
        rom[2759]    = -73831;
        rom[2760]    = -73889;
        rom[2761]    = -73948;
        rom[2762]    = -74007;
        rom[2763]    = -74065;
        rom[2764]    = -74123;
        rom[2765]    = -74181;
        rom[2766]    = -74239;
        rom[2767]    = -74297;
        rom[2768]    = -74354;
        rom[2769]    = -74412;
        rom[2770]    = -74469;
        rom[2771]    = -74526;
        rom[2772]    = -74583;
        rom[2773]    = -74639;
        rom[2774]    = -74696;
        rom[2775]    = -74752;
        rom[2776]    = -74808;
        rom[2777]    = -74864;
        rom[2778]    = -74920;
        rom[2779]    = -74975;
        rom[2780]    = -75031;
        rom[2781]    = -75086;
        rom[2782]    = -75141;
        rom[2783]    = -75196;
        rom[2784]    = -75250;
        rom[2785]    = -75305;
        rom[2786]    = -75359;
        rom[2787]    = -75413;
        rom[2788]    = -75467;
        rom[2789]    = -75521;
        rom[2790]    = -75575;
        rom[2791]    = -75628;
        rom[2792]    = -75682;
        rom[2793]    = -75735;
        rom[2794]    = -75788;
        rom[2795]    = -75840;
        rom[2796]    = -75893;
        rom[2797]    = -75945;
        rom[2798]    = -75997;
        rom[2799]    = -76049;
        rom[2800]    = -76101;
        rom[2801]    = -76153;
        rom[2802]    = -76204;
        rom[2803]    = -76256;
        rom[2804]    = -76307;
        rom[2805]    = -76358;
        rom[2806]    = -76408;
        rom[2807]    = -76459;
        rom[2808]    = -76509;
        rom[2809]    = -76560;
        rom[2810]    = -76610;
        rom[2811]    = -76660;
        rom[2812]    = -76709;
        rom[2813]    = -76759;
        rom[2814]    = -76808;
        rom[2815]    = -76857;
        rom[2816]    = -76906;
        rom[2817]    = -76955;
        rom[2818]    = -77004;
        rom[2819]    = -77052;
        rom[2820]    = -77100;
        rom[2821]    = -77148;
        rom[2822]    = -77196;
        rom[2823]    = -77244;
        rom[2824]    = -77291;
        rom[2825]    = -77339;
        rom[2826]    = -77386;
        rom[2827]    = -77433;
        rom[2828]    = -77480;
        rom[2829]    = -77526;
        rom[2830]    = -77573;
        rom[2831]    = -77619;
        rom[2832]    = -77665;
        rom[2833]    = -77711;
        rom[2834]    = -77756;
        rom[2835]    = -77802;
        rom[2836]    = -77847;
        rom[2837]    = -77892;
        rom[2838]    = -77937;
        rom[2839]    = -77982;
        rom[2840]    = -78027;
        rom[2841]    = -78071;
        rom[2842]    = -78115;
        rom[2843]    = -78159;
        rom[2844]    = -78203;
        rom[2845]    = -78247;
        rom[2846]    = -78290;
        rom[2847]    = -78334;
        rom[2848]    = -78377;
        rom[2849]    = -78420;
        rom[2850]    = -78462;
        rom[2851]    = -78505;
        rom[2852]    = -78547;
        rom[2853]    = -78589;
        rom[2854]    = -78631;
        rom[2855]    = -78673;
        rom[2856]    = -78715;
        rom[2857]    = -78756;
        rom[2858]    = -78798;
        rom[2859]    = -78839;
        rom[2860]    = -78880;
        rom[2861]    = -78920;
        rom[2862]    = -78961;
        rom[2863]    = -79001;
        rom[2864]    = -79041;
        rom[2865]    = -79081;
        rom[2866]    = -79121;
        rom[2867]    = -79161;
        rom[2868]    = -79200;
        rom[2869]    = -79239;
        rom[2870]    = -79278;
        rom[2871]    = -79317;
        rom[2872]    = -79356;
        rom[2873]    = -79394;
        rom[2874]    = -79432;
        rom[2875]    = -79471;
        rom[2876]    = -79508;
        rom[2877]    = -79546;
        rom[2878]    = -79584;
        rom[2879]    = -79621;
        rom[2880]    = -79658;
        rom[2881]    = -79695;
        rom[2882]    = -79732;
        rom[2883]    = -79769;
        rom[2884]    = -79805;
        rom[2885]    = -79841;
        rom[2886]    = -79877;
        rom[2887]    = -79913;
        rom[2888]    = -79949;
        rom[2889]    = -79984;
        rom[2890]    = -80020;
        rom[2891]    = -80055;
        rom[2892]    = -80090;
        rom[2893]    = -80124;
        rom[2894]    = -80159;
        rom[2895]    = -80193;
        rom[2896]    = -80227;
        rom[2897]    = -80261;
        rom[2898]    = -80295;
        rom[2899]    = -80329;
        rom[2900]    = -80362;
        rom[2901]    = -80395;
        rom[2902]    = -80428;
        rom[2903]    = -80461;
        rom[2904]    = -80494;
        rom[2905]    = -80526;
        rom[2906]    = -80558;
        rom[2907]    = -80590;
        rom[2908]    = -80622;
        rom[2909]    = -80654;
        rom[2910]    = -80686;
        rom[2911]    = -80717;
        rom[2912]    = -80748;
        rom[2913]    = -80779;
        rom[2914]    = -80810;
        rom[2915]    = -80840;
        rom[2916]    = -80871;
        rom[2917]    = -80901;
        rom[2918]    = -80931;
        rom[2919]    = -80961;
        rom[2920]    = -80990;
        rom[2921]    = -81020;
        rom[2922]    = -81049;
        rom[2923]    = -81078;
        rom[2924]    = -81107;
        rom[2925]    = -81135;
        rom[2926]    = -81164;
        rom[2927]    = -81192;
        rom[2928]    = -81220;
        rom[2929]    = -81248;
        rom[2930]    = -81276;
        rom[2931]    = -81303;
        rom[2932]    = -81330;
        rom[2933]    = -81358;
        rom[2934]    = -81384;
        rom[2935]    = -81411;
        rom[2936]    = -81438;
        rom[2937]    = -81464;
        rom[2938]    = -81490;
        rom[2939]    = -81516;
        rom[2940]    = -81542;
        rom[2941]    = -81568;
        rom[2942]    = -81593;
        rom[2943]    = -81618;
        rom[2944]    = -81643;
        rom[2945]    = -81668;
        rom[2946]    = -81693;
        rom[2947]    = -81717;
        rom[2948]    = -81741;
        rom[2949]    = -81765;
        rom[2950]    = -81789;
        rom[2951]    = -81813;
        rom[2952]    = -81836;
        rom[2953]    = -81860;
        rom[2954]    = -81883;
        rom[2955]    = -81906;
        rom[2956]    = -81928;
        rom[2957]    = -81951;
        rom[2958]    = -81973;
        rom[2959]    = -81995;
        rom[2960]    = -82017;
        rom[2961]    = -82039;
        rom[2962]    = -82060;
        rom[2963]    = -82082;
        rom[2964]    = -82103;
        rom[2965]    = -82124;
        rom[2966]    = -82145;
        rom[2967]    = -82165;
        rom[2968]    = -82186;
        rom[2969]    = -82206;
        rom[2970]    = -82226;
        rom[2971]    = -82246;
        rom[2972]    = -82265;
        rom[2973]    = -82285;
        rom[2974]    = -82304;
        rom[2975]    = -82323;
        rom[2976]    = -82342;
        rom[2977]    = -82360;
        rom[2978]    = -82379;
        rom[2979]    = -82397;
        rom[2980]    = -82415;
        rom[2981]    = -82433;
        rom[2982]    = -82451;
        rom[2983]    = -82468;
        rom[2984]    = -82485;
        rom[2985]    = -82502;
        rom[2986]    = -82519;
        rom[2987]    = -82536;
        rom[2988]    = -82553;
        rom[2989]    = -82569;
        rom[2990]    = -82585;
        rom[2991]    = -82601;
        rom[2992]    = -82617;
        rom[2993]    = -82632;
        rom[2994]    = -82648;
        rom[2995]    = -82663;
        rom[2996]    = -82678;
        rom[2997]    = -82692;
        rom[2998]    = -82707;
        rom[2999]    = -82721;
        rom[3000]    = -82735;
        rom[3001]    = -82749;
        rom[3002]    = -82763;
        rom[3003]    = -82777;
        rom[3004]    = -82790;
        rom[3005]    = -82803;
        rom[3006]    = -82816;
        rom[3007]    = -82829;
        rom[3008]    = -82842;
        rom[3009]    = -82854;
        rom[3010]    = -82866;
        rom[3011]    = -82879;
        rom[3012]    = -82890;
        rom[3013]    = -82902;
        rom[3014]    = -82913;
        rom[3015]    = -82925;
        rom[3016]    = -82936;
        rom[3017]    = -82947;
        rom[3018]    = -82957;
        rom[3019]    = -82968;
        rom[3020]    = -82978;
        rom[3021]    = -82988;
        rom[3022]    = -82998;
        rom[3023]    = -83008;
        rom[3024]    = -83017;
        rom[3025]    = -83026;
        rom[3026]    = -83036;
        rom[3027]    = -83044;
        rom[3028]    = -83053;
        rom[3029]    = -83062;
        rom[3030]    = -83070;
        rom[3031]    = -83078;
        rom[3032]    = -83086;
        rom[3033]    = -83094;
        rom[3034]    = -83101;
        rom[3035]    = -83109;
        rom[3036]    = -83116;
        rom[3037]    = -83123;
        rom[3038]    = -83129;
        rom[3039]    = -83136;
        rom[3040]    = -83142;
        rom[3041]    = -83149;
        rom[3042]    = -83155;
        rom[3043]    = -83160;
        rom[3044]    = -83166;
        rom[3045]    = -83171;
        rom[3046]    = -83176;
        rom[3047]    = -83181;
        rom[3048]    = -83186;
        rom[3049]    = -83191;
        rom[3050]    = -83195;
        rom[3051]    = -83200;
        rom[3052]    = -83204;
        rom[3053]    = -83207;
        rom[3054]    = -83211;
        rom[3055]    = -83214;
        rom[3056]    = -83218;
        rom[3057]    = -83221;
        rom[3058]    = -83223;
        rom[3059]    = -83226;
        rom[3060]    = -83229;
        rom[3061]    = -83231;
        rom[3062]    = -83233;
        rom[3063]    = -83235;
        rom[3064]    = -83236;
        rom[3065]    = -83238;
        rom[3066]    = -83239;
        rom[3067]    = -83240;
        rom[3068]    = -83241;
        rom[3069]    = -83242;
        rom[3070]    = -83242;
        rom[3071]    = -83243;
        rom[3072]    = -83243;
        rom[3073]    = -83243;
        rom[3074]    = -83242;
        rom[3075]    = -83242;
        rom[3076]    = -83241;
        rom[3077]    = -83240;
        rom[3078]    = -83239;
        rom[3079]    = -83238;
        rom[3080]    = -83236;
        rom[3081]    = -83235;
        rom[3082]    = -83233;
        rom[3083]    = -83231;
        rom[3084]    = -83229;
        rom[3085]    = -83226;
        rom[3086]    = -83223;
        rom[3087]    = -83221;
        rom[3088]    = -83218;
        rom[3089]    = -83214;
        rom[3090]    = -83211;
        rom[3091]    = -83207;
        rom[3092]    = -83204;
        rom[3093]    = -83200;
        rom[3094]    = -83195;
        rom[3095]    = -83191;
        rom[3096]    = -83186;
        rom[3097]    = -83181;
        rom[3098]    = -83176;
        rom[3099]    = -83171;
        rom[3100]    = -83166;
        rom[3101]    = -83160;
        rom[3102]    = -83155;
        rom[3103]    = -83149;
        rom[3104]    = -83142;
        rom[3105]    = -83136;
        rom[3106]    = -83129;
        rom[3107]    = -83123;
        rom[3108]    = -83116;
        rom[3109]    = -83109;
        rom[3110]    = -83101;
        rom[3111]    = -83094;
        rom[3112]    = -83086;
        rom[3113]    = -83078;
        rom[3114]    = -83070;
        rom[3115]    = -83062;
        rom[3116]    = -83053;
        rom[3117]    = -83044;
        rom[3118]    = -83036;
        rom[3119]    = -83026;
        rom[3120]    = -83017;
        rom[3121]    = -83008;
        rom[3122]    = -82998;
        rom[3123]    = -82988;
        rom[3124]    = -82978;
        rom[3125]    = -82968;
        rom[3126]    = -82957;
        rom[3127]    = -82947;
        rom[3128]    = -82936;
        rom[3129]    = -82925;
        rom[3130]    = -82913;
        rom[3131]    = -82902;
        rom[3132]    = -82890;
        rom[3133]    = -82879;
        rom[3134]    = -82866;
        rom[3135]    = -82854;
        rom[3136]    = -82842;
        rom[3137]    = -82829;
        rom[3138]    = -82816;
        rom[3139]    = -82803;
        rom[3140]    = -82790;
        rom[3141]    = -82777;
        rom[3142]    = -82763;
        rom[3143]    = -82749;
        rom[3144]    = -82735;
        rom[3145]    = -82721;
        rom[3146]    = -82707;
        rom[3147]    = -82692;
        rom[3148]    = -82678;
        rom[3149]    = -82663;
        rom[3150]    = -82648;
        rom[3151]    = -82632;
        rom[3152]    = -82617;
        rom[3153]    = -82601;
        rom[3154]    = -82585;
        rom[3155]    = -82569;
        rom[3156]    = -82553;
        rom[3157]    = -82536;
        rom[3158]    = -82519;
        rom[3159]    = -82502;
        rom[3160]    = -82485;
        rom[3161]    = -82468;
        rom[3162]    = -82451;
        rom[3163]    = -82433;
        rom[3164]    = -82415;
        rom[3165]    = -82397;
        rom[3166]    = -82379;
        rom[3167]    = -82360;
        rom[3168]    = -82342;
        rom[3169]    = -82323;
        rom[3170]    = -82304;
        rom[3171]    = -82285;
        rom[3172]    = -82265;
        rom[3173]    = -82246;
        rom[3174]    = -82226;
        rom[3175]    = -82206;
        rom[3176]    = -82186;
        rom[3177]    = -82165;
        rom[3178]    = -82145;
        rom[3179]    = -82124;
        rom[3180]    = -82103;
        rom[3181]    = -82082;
        rom[3182]    = -82060;
        rom[3183]    = -82039;
        rom[3184]    = -82017;
        rom[3185]    = -81995;
        rom[3186]    = -81973;
        rom[3187]    = -81951;
        rom[3188]    = -81928;
        rom[3189]    = -81906;
        rom[3190]    = -81883;
        rom[3191]    = -81860;
        rom[3192]    = -81836;
        rom[3193]    = -81813;
        rom[3194]    = -81789;
        rom[3195]    = -81765;
        rom[3196]    = -81741;
        rom[3197]    = -81717;
        rom[3198]    = -81693;
        rom[3199]    = -81668;
        rom[3200]    = -81643;
        rom[3201]    = -81618;
        rom[3202]    = -81593;
        rom[3203]    = -81568;
        rom[3204]    = -81542;
        rom[3205]    = -81516;
        rom[3206]    = -81490;
        rom[3207]    = -81464;
        rom[3208]    = -81438;
        rom[3209]    = -81411;
        rom[3210]    = -81384;
        rom[3211]    = -81358;
        rom[3212]    = -81330;
        rom[3213]    = -81303;
        rom[3214]    = -81276;
        rom[3215]    = -81248;
        rom[3216]    = -81220;
        rom[3217]    = -81192;
        rom[3218]    = -81164;
        rom[3219]    = -81135;
        rom[3220]    = -81107;
        rom[3221]    = -81078;
        rom[3222]    = -81049;
        rom[3223]    = -81020;
        rom[3224]    = -80990;
        rom[3225]    = -80961;
        rom[3226]    = -80931;
        rom[3227]    = -80901;
        rom[3228]    = -80871;
        rom[3229]    = -80840;
        rom[3230]    = -80810;
        rom[3231]    = -80779;
        rom[3232]    = -80748;
        rom[3233]    = -80717;
        rom[3234]    = -80686;
        rom[3235]    = -80654;
        rom[3236]    = -80622;
        rom[3237]    = -80590;
        rom[3238]    = -80558;
        rom[3239]    = -80526;
        rom[3240]    = -80494;
        rom[3241]    = -80461;
        rom[3242]    = -80428;
        rom[3243]    = -80395;
        rom[3244]    = -80362;
        rom[3245]    = -80329;
        rom[3246]    = -80295;
        rom[3247]    = -80261;
        rom[3248]    = -80227;
        rom[3249]    = -80193;
        rom[3250]    = -80159;
        rom[3251]    = -80124;
        rom[3252]    = -80090;
        rom[3253]    = -80055;
        rom[3254]    = -80020;
        rom[3255]    = -79984;
        rom[3256]    = -79949;
        rom[3257]    = -79913;
        rom[3258]    = -79877;
        rom[3259]    = -79841;
        rom[3260]    = -79805;
        rom[3261]    = -79769;
        rom[3262]    = -79732;
        rom[3263]    = -79695;
        rom[3264]    = -79658;
        rom[3265]    = -79621;
        rom[3266]    = -79584;
        rom[3267]    = -79546;
        rom[3268]    = -79508;
        rom[3269]    = -79471;
        rom[3270]    = -79432;
        rom[3271]    = -79394;
        rom[3272]    = -79356;
        rom[3273]    = -79317;
        rom[3274]    = -79278;
        rom[3275]    = -79239;
        rom[3276]    = -79200;
        rom[3277]    = -79161;
        rom[3278]    = -79121;
        rom[3279]    = -79081;
        rom[3280]    = -79041;
        rom[3281]    = -79001;
        rom[3282]    = -78961;
        rom[3283]    = -78920;
        rom[3284]    = -78880;
        rom[3285]    = -78839;
        rom[3286]    = -78798;
        rom[3287]    = -78756;
        rom[3288]    = -78715;
        rom[3289]    = -78673;
        rom[3290]    = -78631;
        rom[3291]    = -78589;
        rom[3292]    = -78547;
        rom[3293]    = -78505;
        rom[3294]    = -78462;
        rom[3295]    = -78420;
        rom[3296]    = -78377;
        rom[3297]    = -78334;
        rom[3298]    = -78290;
        rom[3299]    = -78247;
        rom[3300]    = -78203;
        rom[3301]    = -78159;
        rom[3302]    = -78115;
        rom[3303]    = -78071;
        rom[3304]    = -78027;
        rom[3305]    = -77982;
        rom[3306]    = -77937;
        rom[3307]    = -77892;
        rom[3308]    = -77847;
        rom[3309]    = -77802;
        rom[3310]    = -77756;
        rom[3311]    = -77711;
        rom[3312]    = -77665;
        rom[3313]    = -77619;
        rom[3314]    = -77573;
        rom[3315]    = -77526;
        rom[3316]    = -77480;
        rom[3317]    = -77433;
        rom[3318]    = -77386;
        rom[3319]    = -77339;
        rom[3320]    = -77291;
        rom[3321]    = -77244;
        rom[3322]    = -77196;
        rom[3323]    = -77148;
        rom[3324]    = -77100;
        rom[3325]    = -77052;
        rom[3326]    = -77004;
        rom[3327]    = -76955;
        rom[3328]    = -76906;
        rom[3329]    = -76857;
        rom[3330]    = -76808;
        rom[3331]    = -76759;
        rom[3332]    = -76709;
        rom[3333]    = -76660;
        rom[3334]    = -76610;
        rom[3335]    = -76560;
        rom[3336]    = -76509;
        rom[3337]    = -76459;
        rom[3338]    = -76408;
        rom[3339]    = -76358;
        rom[3340]    = -76307;
        rom[3341]    = -76256;
        rom[3342]    = -76204;
        rom[3343]    = -76153;
        rom[3344]    = -76101;
        rom[3345]    = -76049;
        rom[3346]    = -75997;
        rom[3347]    = -75945;
        rom[3348]    = -75893;
        rom[3349]    = -75840;
        rom[3350]    = -75788;
        rom[3351]    = -75735;
        rom[3352]    = -75682;
        rom[3353]    = -75628;
        rom[3354]    = -75575;
        rom[3355]    = -75521;
        rom[3356]    = -75467;
        rom[3357]    = -75413;
        rom[3358]    = -75359;
        rom[3359]    = -75305;
        rom[3360]    = -75250;
        rom[3361]    = -75196;
        rom[3362]    = -75141;
        rom[3363]    = -75086;
        rom[3364]    = -75031;
        rom[3365]    = -74975;
        rom[3366]    = -74920;
        rom[3367]    = -74864;
        rom[3368]    = -74808;
        rom[3369]    = -74752;
        rom[3370]    = -74696;
        rom[3371]    = -74639;
        rom[3372]    = -74583;
        rom[3373]    = -74526;
        rom[3374]    = -74469;
        rom[3375]    = -74412;
        rom[3376]    = -74354;
        rom[3377]    = -74297;
        rom[3378]    = -74239;
        rom[3379]    = -74181;
        rom[3380]    = -74123;
        rom[3381]    = -74065;
        rom[3382]    = -74007;
        rom[3383]    = -73948;
        rom[3384]    = -73889;
        rom[3385]    = -73831;
        rom[3386]    = -73771;
        rom[3387]    = -73712;
        rom[3388]    = -73653;
        rom[3389]    = -73593;
        rom[3390]    = -73533;
        rom[3391]    = -73474;
        rom[3392]    = -73413;
        rom[3393]    = -73353;
        rom[3394]    = -73293;
        rom[3395]    = -73232;
        rom[3396]    = -73171;
        rom[3397]    = -73110;
        rom[3398]    = -73049;
        rom[3399]    = -72988;
        rom[3400]    = -72926;
        rom[3401]    = -72865;
        rom[3402]    = -72803;
        rom[3403]    = -72741;
        rom[3404]    = -72679;
        rom[3405]    = -72616;
        rom[3406]    = -72554;
        rom[3407]    = -72491;
        rom[3408]    = -72428;
        rom[3409]    = -72365;
        rom[3410]    = -72302;
        rom[3411]    = -72239;
        rom[3412]    = -72175;
        rom[3413]    = -72111;
        rom[3414]    = -72048;
        rom[3415]    = -71984;
        rom[3416]    = -71919;
        rom[3417]    = -71855;
        rom[3418]    = -71790;
        rom[3419]    = -71726;
        rom[3420]    = -71661;
        rom[3421]    = -71596;
        rom[3422]    = -71531;
        rom[3423]    = -71465;
        rom[3424]    = -71400;
        rom[3425]    = -71334;
        rom[3426]    = -71268;
        rom[3427]    = -71202;
        rom[3428]    = -71136;
        rom[3429]    = -71069;
        rom[3430]    = -71003;
        rom[3431]    = -70936;
        rom[3432]    = -70869;
        rom[3433]    = -70802;
        rom[3434]    = -70735;
        rom[3435]    = -70667;
        rom[3436]    = -70600;
        rom[3437]    = -70532;
        rom[3438]    = -70464;
        rom[3439]    = -70396;
        rom[3440]    = -70328;
        rom[3441]    = -70259;
        rom[3442]    = -70191;
        rom[3443]    = -70122;
        rom[3444]    = -70053;
        rom[3445]    = -69984;
        rom[3446]    = -69915;
        rom[3447]    = -69846;
        rom[3448]    = -69776;
        rom[3449]    = -69706;
        rom[3450]    = -69636;
        rom[3451]    = -69566;
        rom[3452]    = -69496;
        rom[3453]    = -69426;
        rom[3454]    = -69355;
        rom[3455]    = -69285;
        rom[3456]    = -69214;
        rom[3457]    = -69143;
        rom[3458]    = -69071;
        rom[3459]    = -69000;
        rom[3460]    = -68929;
        rom[3461]    = -68857;
        rom[3462]    = -68785;
        rom[3463]    = -68713;
        rom[3464]    = -68641;
        rom[3465]    = -68569;
        rom[3466]    = -68496;
        rom[3467]    = -68423;
        rom[3468]    = -68351;
        rom[3469]    = -68278;
        rom[3470]    = -68205;
        rom[3471]    = -68131;
        rom[3472]    = -68058;
        rom[3473]    = -67984;
        rom[3474]    = -67910;
        rom[3475]    = -67837;
        rom[3476]    = -67762;
        rom[3477]    = -67688;
        rom[3478]    = -67614;
        rom[3479]    = -67539;
        rom[3480]    = -67465;
        rom[3481]    = -67390;
        rom[3482]    = -67315;
        rom[3483]    = -67239;
        rom[3484]    = -67164;
        rom[3485]    = -67089;
        rom[3486]    = -67013;
        rom[3487]    = -66937;
        rom[3488]    = -66861;
        rom[3489]    = -66785;
        rom[3490]    = -66709;
        rom[3491]    = -66632;
        rom[3492]    = -66556;
        rom[3493]    = -66479;
        rom[3494]    = -66402;
        rom[3495]    = -66325;
        rom[3496]    = -66248;
        rom[3497]    = -66170;
        rom[3498]    = -66093;
        rom[3499]    = -66015;
        rom[3500]    = -65937;
        rom[3501]    = -65859;
        rom[3502]    = -65781;
        rom[3503]    = -65702;
        rom[3504]    = -65624;
        rom[3505]    = -65545;
        rom[3506]    = -65467;
        rom[3507]    = -65388;
        rom[3508]    = -65308;
        rom[3509]    = -65229;
        rom[3510]    = -65150;
        rom[3511]    = -65070;
        rom[3512]    = -64991;
        rom[3513]    = -64911;
        rom[3514]    = -64831;
        rom[3515]    = -64751;
        rom[3516]    = -64670;
        rom[3517]    = -64590;
        rom[3518]    = -64509;
        rom[3519]    = -64428;
        rom[3520]    = -64347;
        rom[3521]    = -64266;
        rom[3522]    = -64185;
        rom[3523]    = -64104;
        rom[3524]    = -64022;
        rom[3525]    = -63940;
        rom[3526]    = -63859;
        rom[3527]    = -63777;
        rom[3528]    = -63694;
        rom[3529]    = -63612;
        rom[3530]    = -63530;
        rom[3531]    = -63447;
        rom[3532]    = -63364;
        rom[3533]    = -63282;
        rom[3534]    = -63198;
        rom[3535]    = -63115;
        rom[3536]    = -63032;
        rom[3537]    = -62949;
        rom[3538]    = -62865;
        rom[3539]    = -62781;
        rom[3540]    = -62697;
        rom[3541]    = -62613;
        rom[3542]    = -62529;
        rom[3543]    = -62445;
        rom[3544]    = -62360;
        rom[3545]    = -62275;
        rom[3546]    = -62191;
        rom[3547]    = -62106;
        rom[3548]    = -62020;
        rom[3549]    = -61935;
        rom[3550]    = -61850;
        rom[3551]    = -61764;
        rom[3552]    = -61679;
        rom[3553]    = -61593;
        rom[3554]    = -61507;
        rom[3555]    = -61421;
        rom[3556]    = -61334;
        rom[3557]    = -61248;
        rom[3558]    = -61162;
        rom[3559]    = -61075;
        rom[3560]    = -60988;
        rom[3561]    = -60901;
        rom[3562]    = -60814;
        rom[3563]    = -60727;
        rom[3564]    = -60639;
        rom[3565]    = -60552;
        rom[3566]    = -60464;
        rom[3567]    = -60376;
        rom[3568]    = -60288;
        rom[3569]    = -60200;
        rom[3570]    = -60112;
        rom[3571]    = -60023;
        rom[3572]    = -59935;
        rom[3573]    = -59846;
        rom[3574]    = -59757;
        rom[3575]    = -59668;
        rom[3576]    = -59579;
        rom[3577]    = -59490;
        rom[3578]    = -59401;
        rom[3579]    = -59311;
        rom[3580]    = -59221;
        rom[3581]    = -59132;
        rom[3582]    = -59042;
        rom[3583]    = -58952;
        rom[3584]    = -58861;
        rom[3585]    = -58771;
        rom[3586]    = -58680;
        rom[3587]    = -58590;
        rom[3588]    = -58499;
        rom[3589]    = -58408;
        rom[3590]    = -58317;
        rom[3591]    = -58226;
        rom[3592]    = -58135;
        rom[3593]    = -58043;
        rom[3594]    = -57952;
        rom[3595]    = -57860;
        rom[3596]    = -57768;
        rom[3597]    = -57676;
        rom[3598]    = -57584;
        rom[3599]    = -57491;
        rom[3600]    = -57399;
        rom[3601]    = -57307;
        rom[3602]    = -57214;
        rom[3603]    = -57121;
        rom[3604]    = -57028;
        rom[3605]    = -56935;
        rom[3606]    = -56842;
        rom[3607]    = -56748;
        rom[3608]    = -56655;
        rom[3609]    = -56561;
        rom[3610]    = -56468;
        rom[3611]    = -56374;
        rom[3612]    = -56280;
        rom[3613]    = -56185;
        rom[3614]    = -56091;
        rom[3615]    = -55997;
        rom[3616]    = -55902;
        rom[3617]    = -55808;
        rom[3618]    = -55713;
        rom[3619]    = -55618;
        rom[3620]    = -55523;
        rom[3621]    = -55427;
        rom[3622]    = -55332;
        rom[3623]    = -55237;
        rom[3624]    = -55141;
        rom[3625]    = -55045;
        rom[3626]    = -54950;
        rom[3627]    = -54854;
        rom[3628]    = -54757;
        rom[3629]    = -54661;
        rom[3630]    = -54565;
        rom[3631]    = -54468;
        rom[3632]    = -54372;
        rom[3633]    = -54275;
        rom[3634]    = -54178;
        rom[3635]    = -54081;
        rom[3636]    = -53984;
        rom[3637]    = -53887;
        rom[3638]    = -53789;
        rom[3639]    = -53692;
        rom[3640]    = -53594;
        rom[3641]    = -53496;
        rom[3642]    = -53398;
        rom[3643]    = -53300;
        rom[3644]    = -53202;
        rom[3645]    = -53104;
        rom[3646]    = -53006;
        rom[3647]    = -52907;
        rom[3648]    = -52808;
        rom[3649]    = -52710;
        rom[3650]    = -52611;
        rom[3651]    = -52512;
        rom[3652]    = -52413;
        rom[3653]    = -52313;
        rom[3654]    = -52214;
        rom[3655]    = -52114;
        rom[3656]    = -52015;
        rom[3657]    = -51915;
        rom[3658]    = -51815;
        rom[3659]    = -51715;
        rom[3660]    = -51615;
        rom[3661]    = -51515;
        rom[3662]    = -51414;
        rom[3663]    = -51314;
        rom[3664]    = -51213;
        rom[3665]    = -51113;
        rom[3666]    = -51012;
        rom[3667]    = -50911;
        rom[3668]    = -50810;
        rom[3669]    = -50709;
        rom[3670]    = -50607;
        rom[3671]    = -50506;
        rom[3672]    = -50404;
        rom[3673]    = -50302;
        rom[3674]    = -50201;
        rom[3675]    = -50099;
        rom[3676]    = -49997;
        rom[3677]    = -49895;
        rom[3678]    = -49792;
        rom[3679]    = -49690;
        rom[3680]    = -49587;
        rom[3681]    = -49485;
        rom[3682]    = -49382;
        rom[3683]    = -49279;
        rom[3684]    = -49176;
        rom[3685]    = -49073;
        rom[3686]    = -48970;
        rom[3687]    = -48867;
        rom[3688]    = -48763;
        rom[3689]    = -48660;
        rom[3690]    = -48556;
        rom[3691]    = -48452;
        rom[3692]    = -48348;
        rom[3693]    = -48244;
        rom[3694]    = -48140;
        rom[3695]    = -48036;
        rom[3696]    = -47932;
        rom[3697]    = -47827;
        rom[3698]    = -47723;
        rom[3699]    = -47618;
        rom[3700]    = -47513;
        rom[3701]    = -47408;
        rom[3702]    = -47303;
        rom[3703]    = -47198;
        rom[3704]    = -47093;
        rom[3705]    = -46987;
        rom[3706]    = -46882;
        rom[3707]    = -46776;
        rom[3708]    = -46671;
        rom[3709]    = -46565;
        rom[3710]    = -46459;
        rom[3711]    = -46353;
        rom[3712]    = -46247;
        rom[3713]    = -46141;
        rom[3714]    = -46034;
        rom[3715]    = -45928;
        rom[3716]    = -45821;
        rom[3717]    = -45715;
        rom[3718]    = -45608;
        rom[3719]    = -45501;
        rom[3720]    = -45394;
        rom[3721]    = -45287;
        rom[3722]    = -45180;
        rom[3723]    = -45073;
        rom[3724]    = -44965;
        rom[3725]    = -44858;
        rom[3726]    = -44750;
        rom[3727]    = -44642;
        rom[3728]    = -44534;
        rom[3729]    = -44426;
        rom[3730]    = -44318;
        rom[3731]    = -44210;
        rom[3732]    = -44102;
        rom[3733]    = -43994;
        rom[3734]    = -43885;
        rom[3735]    = -43777;
        rom[3736]    = -43668;
        rom[3737]    = -43559;
        rom[3738]    = -43450;
        rom[3739]    = -43341;
        rom[3740]    = -43232;
        rom[3741]    = -43123;
        rom[3742]    = -43014;
        rom[3743]    = -42905;
        rom[3744]    = -42795;
        rom[3745]    = -42685;
        rom[3746]    = -42576;
        rom[3747]    = -42466;
        rom[3748]    = -42356;
        rom[3749]    = -42246;
        rom[3750]    = -42136;
        rom[3751]    = -42026;
        rom[3752]    = -41916;
        rom[3753]    = -41805;
        rom[3754]    = -41695;
        rom[3755]    = -41584;
        rom[3756]    = -41474;
        rom[3757]    = -41363;
        rom[3758]    = -41252;
        rom[3759]    = -41141;
        rom[3760]    = -41030;
        rom[3761]    = -40919;
        rom[3762]    = -40808;
        rom[3763]    = -40696;
        rom[3764]    = -40585;
        rom[3765]    = -40473;
        rom[3766]    = -40362;
        rom[3767]    = -40250;
        rom[3768]    = -40138;
        rom[3769]    = -40026;
        rom[3770]    = -39914;
        rom[3771]    = -39802;
        rom[3772]    = -39690;
        rom[3773]    = -39577;
        rom[3774]    = -39465;
        rom[3775]    = -39353;
        rom[3776]    = -39240;
        rom[3777]    = -39127;
        rom[3778]    = -39015;
        rom[3779]    = -38902;
        rom[3780]    = -38789;
        rom[3781]    = -38676;
        rom[3782]    = -38563;
        rom[3783]    = -38450;
        rom[3784]    = -38336;
        rom[3785]    = -38223;
        rom[3786]    = -38109;
        rom[3787]    = -37996;
        rom[3788]    = -37882;
        rom[3789]    = -37768;
        rom[3790]    = -37655;
        rom[3791]    = -37541;
        rom[3792]    = -37427;
        rom[3793]    = -37312;
        rom[3794]    = -37198;
        rom[3795]    = -37084;
        rom[3796]    = -36970;
        rom[3797]    = -36855;
        rom[3798]    = -36741;
        rom[3799]    = -36626;
        rom[3800]    = -36511;
        rom[3801]    = -36397;
        rom[3802]    = -36282;
        rom[3803]    = -36167;
        rom[3804]    = -36052;
        rom[3805]    = -35936;
        rom[3806]    = -35821;
        rom[3807]    = -35706;
        rom[3808]    = -35591;
        rom[3809]    = -35475;
        rom[3810]    = -35360;
        rom[3811]    = -35244;
        rom[3812]    = -35128;
        rom[3813]    = -35012;
        rom[3814]    = -34896;
        rom[3815]    = -34780;
        rom[3816]    = -34664;
        rom[3817]    = -34548;
        rom[3818]    = -34432;
        rom[3819]    = -34316;
        rom[3820]    = -34199;
        rom[3821]    = -34083;
        rom[3822]    = -33966;
        rom[3823]    = -33850;
        rom[3824]    = -33733;
        rom[3825]    = -33616;
        rom[3826]    = -33499;
        rom[3827]    = -33383;
        rom[3828]    = -33265;
        rom[3829]    = -33148;
        rom[3830]    = -33031;
        rom[3831]    = -32914;
        rom[3832]    = -32797;
        rom[3833]    = -32679;
        rom[3834]    = -32562;
        rom[3835]    = -32444;
        rom[3836]    = -32327;
        rom[3837]    = -32209;
        rom[3838]    = -32091;
        rom[3839]    = -31973;
        rom[3840]    = -31855;
        rom[3841]    = -31737;
        rom[3842]    = -31619;
        rom[3843]    = -31501;
        rom[3844]    = -31383;
        rom[3845]    = -31264;
        rom[3846]    = -31146;
        rom[3847]    = -31028;
        rom[3848]    = -30909;
        rom[3849]    = -30791;
        rom[3850]    = -30672;
        rom[3851]    = -30553;
        rom[3852]    = -30434;
        rom[3853]    = -30315;
        rom[3854]    = -30196;
        rom[3855]    = -30077;
        rom[3856]    = -29958;
        rom[3857]    = -29839;
        rom[3858]    = -29720;
        rom[3859]    = -29601;
        rom[3860]    = -29481;
        rom[3861]    = -29362;
        rom[3862]    = -29242;
        rom[3863]    = -29123;
        rom[3864]    = -29003;
        rom[3865]    = -28883;
        rom[3866]    = -28763;
        rom[3867]    = -28644;
        rom[3868]    = -28524;
        rom[3869]    = -28404;
        rom[3870]    = -28284;
        rom[3871]    = -28163;
        rom[3872]    = -28043;
        rom[3873]    = -27923;
        rom[3874]    = -27803;
        rom[3875]    = -27682;
        rom[3876]    = -27562;
        rom[3877]    = -27441;
        rom[3878]    = -27321;
        rom[3879]    = -27200;
        rom[3880]    = -27079;
        rom[3881]    = -26959;
        rom[3882]    = -26838;
        rom[3883]    = -26717;
        rom[3884]    = -26596;
        rom[3885]    = -26475;
        rom[3886]    = -26354;
        rom[3887]    = -26233;
        rom[3888]    = -26111;
        rom[3889]    = -25990;
        rom[3890]    = -25869;
        rom[3891]    = -25747;
        rom[3892]    = -25626;
        rom[3893]    = -25504;
        rom[3894]    = -25383;
        rom[3895]    = -25261;
        rom[3896]    = -25139;
        rom[3897]    = -25018;
        rom[3898]    = -24896;
        rom[3899]    = -24774;
        rom[3900]    = -24652;
        rom[3901]    = -24530;
        rom[3902]    = -24408;
        rom[3903]    = -24286;
        rom[3904]    = -24164;
        rom[3905]    = -24041;
        rom[3906]    = -23919;
        rom[3907]    = -23797;
        rom[3908]    = -23674;
        rom[3909]    = -23552;
        rom[3910]    = -23430;
        rom[3911]    = -23307;
        rom[3912]    = -23184;
        rom[3913]    = -23062;
        rom[3914]    = -22939;
        rom[3915]    = -22816;
        rom[3916]    = -22693;
        rom[3917]    = -22570;
        rom[3918]    = -22448;
        rom[3919]    = -22325;
        rom[3920]    = -22202;
        rom[3921]    = -22078;
        rom[3922]    = -21955;
        rom[3923]    = -21832;
        rom[3924]    = -21709;
        rom[3925]    = -21586;
        rom[3926]    = -21462;
        rom[3927]    = -21339;
        rom[3928]    = -21215;
        rom[3929]    = -21092;
        rom[3930]    = -20968;
        rom[3931]    = -20845;
        rom[3932]    = -20721;
        rom[3933]    = -20597;
        rom[3934]    = -20474;
        rom[3935]    = -20350;
        rom[3936]    = -20226;
        rom[3937]    = -20102;
        rom[3938]    = -19978;
        rom[3939]    = -19854;
        rom[3940]    = -19730;
        rom[3941]    = -19606;
        rom[3942]    = -19482;
        rom[3943]    = -19358;
        rom[3944]    = -19234;
        rom[3945]    = -19109;
        rom[3946]    = -18985;
        rom[3947]    = -18861;
        rom[3948]    = -18736;
        rom[3949]    = -18612;
        rom[3950]    = -18487;
        rom[3951]    = -18363;
        rom[3952]    = -18238;
        rom[3953]    = -18114;
        rom[3954]    = -17989;
        rom[3955]    = -17864;
        rom[3956]    = -17739;
        rom[3957]    = -17615;
        rom[3958]    = -17490;
        rom[3959]    = -17365;
        rom[3960]    = -17240;
        rom[3961]    = -17115;
        rom[3962]    = -16990;
        rom[3963]    = -16865;
        rom[3964]    = -16740;
        rom[3965]    = -16615;
        rom[3966]    = -16490;
        rom[3967]    = -16365;
        rom[3968]    = -16239;
        rom[3969]    = -16114;
        rom[3970]    = -15989;
        rom[3971]    = -15864;
        rom[3972]    = -15738;
        rom[3973]    = -15613;
        rom[3974]    = -15487;
        rom[3975]    = -15362;
        rom[3976]    = -15236;
        rom[3977]    = -15111;
        rom[3978]    = -14985;
        rom[3979]    = -14860;
        rom[3980]    = -14734;
        rom[3981]    = -14608;
        rom[3982]    = -14482;
        rom[3983]    = -14357;
        rom[3984]    = -14231;
        rom[3985]    = -14105;
        rom[3986]    = -13979;
        rom[3987]    = -13853;
        rom[3988]    = -13727;
        rom[3989]    = -13601;
        rom[3990]    = -13475;
        rom[3991]    = -13349;
        rom[3992]    = -13223;
        rom[3993]    = -13097;
        rom[3994]    = -12971;
        rom[3995]    = -12845;
        rom[3996]    = -12719;
        rom[3997]    = -12593;
        rom[3998]    = -12466;
        rom[3999]    = -12340;
        rom[4000]    = -12214;
        rom[4001]    = -12087;
        rom[4002]    = -11961;
        rom[4003]    = -11835;
        rom[4004]    = -11708;
        rom[4005]    = -11582;
        rom[4006]    = -11455;
        rom[4007]    = -11329;
        rom[4008]    = -11202;
        rom[4009]    = -11076;
        rom[4010]    = -10949;
        rom[4011]    = -10823;
        rom[4012]    = -10696;
        rom[4013]    = -10569;
        rom[4014]    = -10443;
        rom[4015]    = -10316;
        rom[4016]    = -10189;
        rom[4017]    = -10063;
        rom[4018]    = -9936;
        rom[4019]    = -9809;
        rom[4020]    = -9682;
        rom[4021]    = -9555;
        rom[4022]    = -9429;
        rom[4023]    = -9302;
        rom[4024]    = -9175;
        rom[4025]    = -9048;
        rom[4026]    = -8921;
        rom[4027]    = -8794;
        rom[4028]    = -8667;
        rom[4029]    = -8540;
        rom[4030]    = -8413;
        rom[4031]    = -8286;
        rom[4032]    = -8159;
        rom[4033]    = -8032;
        rom[4034]    = -7905;
        rom[4035]    = -7777;
        rom[4036]    = -7650;
        rom[4037]    = -7523;
        rom[4038]    = -7396;
        rom[4039]    = -7269;
        rom[4040]    = -7142;
        rom[4041]    = -7014;
        rom[4042]    = -6887;
        rom[4043]    = -6760;
        rom[4044]    = -6633;
        rom[4045]    = -6505;
        rom[4046]    = -6378;
        rom[4047]    = -6251;
        rom[4048]    = -6123;
        rom[4049]    = -5996;
        rom[4050]    = -5869;
        rom[4051]    = -5741;
        rom[4052]    = -5614;
        rom[4053]    = -5486;
        rom[4054]    = -5359;
        rom[4055]    = -5231;
        rom[4056]    = -5104;
        rom[4057]    = -4977;
        rom[4058]    = -4849;
        rom[4059]    = -4722;
        rom[4060]    = -4594;
        rom[4061]    = -4467;
        rom[4062]    = -4339;
        rom[4063]    = -4212;
        rom[4064]    = -4084;
        rom[4065]    = -3957;
        rom[4066]    = -3829;
        rom[4067]    = -3701;
        rom[4068]    = -3574;
        rom[4069]    = -3446;
        rom[4070]    = -3319;
        rom[4071]    = -3191;
        rom[4072]    = -3063;
        rom[4073]    = -2936;
        rom[4074]    = -2808;
        rom[4075]    = -2681;
        rom[4076]    = -2553;
        rom[4077]    = -2425;
        rom[4078]    = -2298;
        rom[4079]    = -2170;
        rom[4080]    = -2042;
        rom[4081]    = -1915;
        rom[4082]    = -1787;
        rom[4083]    = -1659;
        rom[4084]    = -1532;
        rom[4085]    = -1404;
        rom[4086]    = -1276;
        rom[4087]    = -1149;
        rom[4088]    = -1021;
        rom[4089]    = -893;
        rom[4090]    = -766;
        rom[4091]    = -638;
        rom[4092]    = -510;
        rom[4093]    = -383;
        rom[4094]    = -255;
        rom[4095]    = -127;
    end                
    always @(posedge clka)        
    begin                
        douta    <= rom[addra];    
    end                
    always @(posedge clkb)        
    begin                
        doutb    <= rom[addrb];    
    end                
endmodule
rom_dds.v
import math

addr_width=12
data_width=18
amp=math.pow(2,data_width - 1) - 1
amp=amp*0.6351

power_addr_width=math.pow(2,addr_width)
power_addr_width=int(power_addr_width)
with open('rom_dds.v','wb') as f:
    str_out=                                                        \
        "module rom_dds                                                \n"+\
        "(                                                    \n"+\
        "    input            "+            "    clka,                    \n"+\
        "    input            ["+str(addr_width-1)+":0]    addra,                    \n"+\
        "    output    reg    signed    ["+str(data_width-1)+":0]    douta,                    \n"+\
        "    input            "+            "    clkb,                    \n"+\
        "    input            ["+str(addr_width-1)+":0]    addrb,                    \n"+\
        "    output    reg    signed    ["+str(data_width-1)+":0]    doutb                    \n"+\
        ");                                                    \n"+\
        "    (* RAM_STYLE=\"BLOCK\" *)                                    \n"+\
        "    reg    signed    ["+str(data_width-1)+":0]    rom    ["+str(power_addr_width-1)+":0];    \n"+\
        "    initial                                                \n"+\
        "    begin                                                \n"

    i=0
    while i < power_addr_width:
        radian=i*2*math.pi/power_addr_width
        v_sin=math.sin(radian)
        v_sin=v_sin*amp
        v_sin=int(v_sin)
        str_out=str_out+"\t\trom["+str(i)+"]\t= "+str(v_sin)+";\n"
        i=i+1

    str_out=str_out+                    \
        "    end                \n"+\
        "    always @(posedge clka)        \n"+\
        "    begin                \n"+\
        "        douta    <= rom[addra];    \n"+\
        "    end                \n"+\
        "    always @(posedge clkb)        \n"+\
        "    begin                \n"+\
        "        doutb    <= rom[addrb];    \n"+\
        "    end                \n"+\
        "endmodule\n"
    f.write(str_out.encode('utf-8'))
rom_dds.py

module cordic_dds                                            
#(                                                    
    parameter PHASE_WIDTH        = 32,                                
    parameter RAM_ADDR_WIDTH    = 12,                                
    parameter RAM_DATA_WIDTH    = 18,                                
    localparam DATA_WIDTH        = 20,                        
    localparam ROTATE_ORDER        = 8                        
)                                                    
(                                                    
    input                            clk,                    
    input        signed    [RAM_DATA_WIDTH - 1:0]        din_sin,                
    input        signed    [RAM_DATA_WIDTH - 1:0]        din_cos,                
    input            [PHASE_WIDTH - 1:0]        phase_in,                
    output        signed    [RAM_DATA_WIDTH - 1:0]        dout_sin,                
    output        signed    [RAM_DATA_WIDTH - 1:0]        dout_cos                
);                                                    
    /////////////////////////////////////////////////////////////////////////////////////////    
    wire        [PHASE_WIDTH - 1:0]            phase        [ROTATE_ORDER - 1:1];    
    wire        [PHASE_WIDTH - 1:0]            phase_target    [ROTATE_ORDER - 1:1];    
                                                    
    wire        [PHASE_WIDTH - 1:RAM_ADDR_WIDTH]    phase_zero    = 0;            
    wire        [DATA_WIDTH - 1:18]            data_zero    = 0;            
                                                    
    wire        [DATA_WIDTH - 1:0]            r_x        [ROTATE_ORDER - 1:1];    
    wire        [DATA_WIDTH - 1:0]            r_y        [ROTATE_ORDER - 1:1];    
                                                    
    ///////////////////////////////////////////////////////////////////////////////////        
    cordic_pipeline__rotate_begin                                    
    #(                                                
        .PHASE_WIDTH    (PHASE_WIDTH),                                
        .DATA_WIDTH    (DATA_WIDTH),                                
        .STEP        (10),                            
        .RAM_ADDR_WIDTH    (RAM_ADDR_WIDTH),                            
        .RAM_DATA_WIDTH    (RAM_DATA_WIDTH),                            
        .PHASE_INC    (32'ha2f98)                                
    )                                                
    rotate_0                                        
    (                                                
        .clk            (clk),                                
                                                    
        .din_x            (din_cos),                            
        .din_y            (din_sin),                            
        .phase_in        (phase_in[PHASE_WIDTH - 1:PHASE_WIDTH - RAM_ADDR_WIDTH]),    
        .phase_target        (phase_in),                            
                                                    
        .dout_x            (r_x[1]),                        
        .dout_y            (r_y[1]),                        
        .phase_out        (phase[1]),                        
        .phase_target_out    (phase_target[1])                    
    );                                                
    ////////////////////////////////////////////////////////                    
    cordic_pipeline__rotate                        
    #(                                
        .PHASE_WIDTH    (PHASE_WIDTH),                
        .DATA_WIDTH    (DATA_WIDTH),                
        .STEP        (11),            
        .PHASE_INC    (32'h517cc)                
    )                                
    rotate_1                        
    (                                
        .clk            (clk),                
                                    
        .din_x            (r_x[1]),        
        .din_y            (r_y[1]),        
        .phase_in        (phase[1]),        
        .phase_target        (phase_target[1]),    
                                    
        .dout_x            (r_x[2]),        
        .dout_y            (r_y[2]),        
        .phase_out        (phase[2]),        
        .phase_target_out    (phase_target[2])    
    );                                
    ////////////////////////////////////////////////////////    
    cordic_pipeline__rotate                        
    #(                                
        .PHASE_WIDTH    (PHASE_WIDTH),                
        .DATA_WIDTH    (DATA_WIDTH),                
        .STEP        (12),            
        .PHASE_INC    (32'h28be6)                
    )                                
    rotate_2                        
    (                                
        .clk            (clk),                
                                    
        .din_x            (r_x[2]),        
        .din_y            (r_y[2]),        
        .phase_in        (phase[2]),        
        .phase_target        (phase_target[2]),    
                                    
        .dout_x            (r_x[3]),        
        .dout_y            (r_y[3]),        
        .phase_out        (phase[3]),        
        .phase_target_out    (phase_target[3])    
    );                                
    ////////////////////////////////////////////////////////    
    cordic_pipeline__rotate                        
    #(                                
        .PHASE_WIDTH    (PHASE_WIDTH),                
        .DATA_WIDTH    (DATA_WIDTH),                
        .STEP        (13),            
        .PHASE_INC    (32'h145f3)                
    )                                
    rotate_3                        
    (                                
        .clk            (clk),                
                                    
        .din_x            (r_x[3]),        
        .din_y            (r_y[3]),        
        .phase_in        (phase[3]),        
        .phase_target        (phase_target[3]),    
                                    
        .dout_x            (r_x[4]),        
        .dout_y            (r_y[4]),        
        .phase_out        (phase[4]),        
        .phase_target_out    (phase_target[4])    
    );                                
    ////////////////////////////////////////////////////////    
    cordic_pipeline__rotate                        
    #(                                
        .PHASE_WIDTH    (PHASE_WIDTH),                
        .DATA_WIDTH    (DATA_WIDTH),                
        .STEP        (14),            
        .PHASE_INC    (32'ha2fa)                
    )                                
    rotate_4                        
    (                                
        .clk            (clk),                
                                    
        .din_x            (r_x[4]),        
        .din_y            (r_y[4]),        
        .phase_in        (phase[4]),        
        .phase_target        (phase_target[4]),    
                                    
        .dout_x            (r_x[5]),        
        .dout_y            (r_y[5]),        
        .phase_out        (phase[5]),        
        .phase_target_out    (phase_target[5])    
    );                                
    ////////////////////////////////////////////////////////    
    cordic_pipeline__rotate                        
    #(                                
        .PHASE_WIDTH    (PHASE_WIDTH),                
        .DATA_WIDTH    (DATA_WIDTH),                
        .STEP        (15),            
        .PHASE_INC    (32'h517d)                
    )                                
    rotate_5                        
    (                                
        .clk            (clk),                
                                    
        .din_x            (r_x[5]),        
        .din_y            (r_y[5]),        
        .phase_in        (phase[5]),        
        .phase_target        (phase_target[5]),    
                                    
        .dout_x            (r_x[6]),        
        .dout_y            (r_y[6]),        
        .phase_out        (phase[6]),        
        .phase_target_out    (phase_target[6])    
    );                                
    ////////////////////////////////////////////////////////    
    cordic_pipeline__rotate                        
    #(                                
        .PHASE_WIDTH    (PHASE_WIDTH),                
        .DATA_WIDTH    (DATA_WIDTH),                
        .STEP        (16),            
        .PHASE_INC    (32'h28be)                
    )                                
    rotate_6                        
    (                                
        .clk            (clk),                
                                    
        .din_x            (r_x[6]),        
        .din_y            (r_y[6]),        
        .phase_in        (phase[6]),        
        .phase_target        (phase_target[6]),    
                                    
        .dout_x            (r_x[7]),        
        .dout_y            (r_y[7]),        
        .phase_out        (phase[7]),        
        .phase_target_out    (phase_target[7])    
    );                                
    ////////////////////////////////////////////////////////    
    cordic_pipeline__rotate_end                    
    #(                                
        .PHASE_WIDTH    (PHASE_WIDTH),                
        .DATA_WIDTH    (DATA_WIDTH),                
        .RAM_DATA_WIDTH    (RAM_DATA_WIDTH),            
        .STEP        (17),            
        .PHASE_INC    (32'h145f)                
    )                                
    rotate_7                        
    (                                
        .clk            (clk),                
                                    
        .din_x            (r_x[7]),        
        .din_y            (r_y[7]),        
        .phase_in        (phase[7]),        
        .phase_target        (phase_target[7]),    
                                    
        .dout_x            (dout_cos),            
        .dout_y            (dout_sin)            
    );                                
    ////////////////////////////////////////////////////////    
endmodule            
cordic_dds.v
import math
rotate_order=8
phase_width=32
step_start=10
data_width=20
ram_addr_width=12
ram_data_width=18

def hex_arctan_2n(step):
    var_tan=math.pow(2,0-step)
    var_atan=math.atan(var_tan)
    var_angle=math.degrees(var_atan)
    var_phase=var_angle*math.pow(2,phase_width - 2)/90
    if(var_phase - int(var_phase) < 0.5):
        var_phase_int=int(var_phase)
    else:
        var_phase_int=int(var_phase+1)
    var_phase_hex=hex(var_phase_int)
    var_phase_hex=str(phase_width)+"'h"+var_phase_hex[2:]
    return var_phase_hex

with open('cordic_dds.v','wb') as f:

    str_out=                                                        \
            "module cordic_dds                                            \n"+\
            "#(                                                    \n"+\
            "    parameter PHASE_WIDTH        = 32,                                \n"+\
            "    parameter RAM_ADDR_WIDTH    = 12,                                \n"+\
            "    parameter RAM_DATA_WIDTH    = 18,                                \n"+\
            "    localparam DATA_WIDTH        = "+str(data_width)+",                        \n"+\
            "    localparam ROTATE_ORDER        = "+str(rotate_order)+"                        \n"+\
            ")                                                    \n"+\
            "(                                                    \n"+\
            "    input                            clk,                    \n"+\
            "    input        signed    [RAM_DATA_WIDTH - 1:0]        din_sin,                \n"+\
            "    input        signed    [RAM_DATA_WIDTH - 1:0]        din_cos,                \n"+\
            "    input            [PHASE_WIDTH - 1:0]        phase_in,                \n"+\
            "    output        signed    [RAM_DATA_WIDTH - 1:0]        dout_sin,                \n"+\
            "    output        signed    [RAM_DATA_WIDTH - 1:0]        dout_cos                \n"+\
            ");                                                    \n"+\
            "    /////////////////////////////////////////////////////////////////////////////////////////    \n"+\
            "    wire        [PHASE_WIDTH - 1:0]            phase        [ROTATE_ORDER - 1:1];    \n"+\
            "    wire        [PHASE_WIDTH - 1:0]            phase_target    [ROTATE_ORDER - 1:1];    \n"+\
            "                                                    \n"+\
            "    wire        [PHASE_WIDTH - 1:RAM_ADDR_WIDTH]    phase_zero    = 0;            \n"+\
            "    wire        [DATA_WIDTH - 1:18]            data_zero    = 0;            \n"+\
            "                                                    \n"+\
            "    wire        [DATA_WIDTH - 1:0]            r_x        [ROTATE_ORDER - 1:1];    \n"+\
            "    wire        [DATA_WIDTH - 1:0]            r_y        [ROTATE_ORDER - 1:1];    \n"+\
            "                                                    \n"+\
            "    ///////////////////////////////////////////////////////////////////////////////////        \n"

    i = 0
    while i < rotate_order:
        step        = i + step_start
        phase_hex    = hex_arctan_2n(step)
        if(i == 0):
            str_out=str_out+                                            \
            "    cordic_pipeline__rotate_begin                                    \n"+\
            "    #(                                                \n"+\
            "        .PHASE_WIDTH    (PHASE_WIDTH),                                \n"+\
            "        .DATA_WIDTH    (DATA_WIDTH),                                \n"+\
            "        .STEP        ("+str(step)+"),                            \n"+\
            "        .RAM_ADDR_WIDTH    (RAM_ADDR_WIDTH),                            \n"+\
            "        .RAM_DATA_WIDTH    (RAM_DATA_WIDTH),                            \n"+\
            "        .PHASE_INC    ("+phase_hex+")                                \n"+\
            "    )                                                \n"+\
            "    rotate_"+str(i)+"                                        \n"+\
            "    (                                                \n"+\
            "        .clk            (clk),                                \n"+\
            "                                                    \n"+\
            "        .din_x            (din_cos),                            \n"+\
            "        .din_y            (din_sin),                            \n"+\
            "        .phase_in        (phase_in[PHASE_WIDTH - 1:PHASE_WIDTH - RAM_ADDR_WIDTH]),    \n"+\
            "        .phase_target        (phase_in),                            \n"+\
            "                                                    \n"+\
            "        .dout_x            (r_x["+str(i+1)+"]),                        \n"+\
            "        .dout_y            (r_y["+str(i+1)+"]),                        \n"+\
            "        .phase_out        (phase["+str(i+1)+"]),                        \n"+\
            "        .phase_target_out    (phase_target["+str(i+1)+"])                    \n"+\
            "    );                                                \n"+\
            "    ////////////////////////////////////////////////////////                    \n"
        elif(i < rotate_order - 1):
            str_out=str_out+                            \
            "    cordic_pipeline__rotate                        \n"+\
            "    #(                                \n"+\
            "        .PHASE_WIDTH    (PHASE_WIDTH),                \n"+\
            "        .DATA_WIDTH    (DATA_WIDTH),                \n"+\
            "        .STEP        ("+str(step)+"),            \n"+\
            "        .PHASE_INC    ("+phase_hex+")                \n"+\
            "    )                                \n"+\
            "    rotate_"+str(i)+"                        \n"+\
            "    (                                \n"+\
            "        .clk            (clk),                \n"+\
            "                                    \n"+\
            "        .din_x            (r_x["+str(i)+"]),        \n"+\
            "        .din_y            (r_y["+str(i)+"]),        \n"+\
            "        .phase_in        (phase["+str(i)+"]),        \n"+\
            "        .phase_target        (phase_target["+str(i)+"]),    \n"+\
            "                                    \n"+\
            "        .dout_x            (r_x["+str(i+1)+"]),        \n"+\
            "        .dout_y            (r_y["+str(i+1)+"]),        \n"+\
            "        .phase_out        (phase["+str(i+1)+"]),        \n"+\
            "        .phase_target_out    (phase_target["+str(i+1)+"])    \n"+\
            "    );                                \n"+\
            "    ////////////////////////////////////////////////////////    \n"
        else:
            str_out=str_out+                            \
            "    cordic_pipeline__rotate_end                    \n"+\
            "    #(                                \n"+\
            "        .PHASE_WIDTH    (PHASE_WIDTH),                \n"+\
            "        .DATA_WIDTH    (DATA_WIDTH),                \n"+\
            "        .RAM_DATA_WIDTH    (RAM_DATA_WIDTH),            \n"+\
            "        .STEP        ("+str(step)+"),            \n"+\
            "        .PHASE_INC    ("+phase_hex+")                \n"+\
            "    )                                \n"+\
            "    rotate_"+str(i)+"                        \n"+\
            "    (                                \n"+\
            "        .clk            (clk),                \n"+\
            "                                    \n"+\
            "        .din_x            (r_x["+str(i)+"]),        \n"+\
            "        .din_y            (r_y["+str(i)+"]),        \n"+\
            "        .phase_in        (phase["+str(i)+"]),        \n"+\
            "        .phase_target        (phase_target["+str(i)+"]),    \n"+\
            "                                    \n"+\
            "        .dout_x            (dout_cos),            \n"+\
            "        .dout_y            (dout_sin)            \n"+\
            "    );                                \n"+\
            "    ////////////////////////////////////////////////////////    \n"
        i=i+1
    str_out=str_out+                \
            "endmodule            \n"
    f.write(str_out.encode('utf-8'))
cordic_dds.py

module cordic_pipeline__rotate_begin
#(
    parameter PHASE_WIDTH        = 32,
    parameter DATA_WIDTH        = 20,
    parameter STEP            = 0,
    parameter PHASE_INC        = 0,
    parameter RAM_ADDR_WIDTH    = 12,
    parameter RAM_DATA_WIDTH    = 18
)
(
    input                                    clk,

    input        signed    [DATA_WIDTH - 1:DATA_WIDTH - RAM_DATA_WIDTH]    din_x,
    input        signed    [DATA_WIDTH - 1:DATA_WIDTH - RAM_DATA_WIDTH]    din_y,
    input            [PHASE_WIDTH - 1:PHASE_WIDTH - RAM_ADDR_WIDTH]    phase_in,
    input            [PHASE_WIDTH - 1:0]                phase_target,

    output    reg    signed    [DATA_WIDTH - 1:0]                dout_x,
    output    reg    signed    [DATA_WIDTH - 1:0]                dout_y,
    output    reg        [PHASE_WIDTH - 1:0]                phase_out,
    output    reg        [PHASE_WIDTH - 1:0]                phase_target_out
);
    ///////////////////////////////////////////////////////////////////////////////////////
    reg        [PHASE_WIDTH - 1:PHASE_WIDTH - RAM_ADDR_WIDTH]    phase_last    = 0;
    reg    signed    [DATA_WIDTH - 1:DATA_WIDTH - RAM_DATA_WIDTH]    x_p            = 0;
    reg    signed    [DATA_WIDTH - 1:DATA_WIDTH - RAM_DATA_WIDTH]    y_p            = 0;
    reg                                direction        = 0;
    reg        [PHASE_WIDTH - 1:0]                phase_target_last    = 0;

    wire    [DATA_WIDTH - 1:0]    x_p_tana    = {{STEP{x_p[DATA_WIDTH - 1]}},x_p[DATA_WIDTH - 1:STEP]};
    wire    [DATA_WIDTH - 1:0]    y_p_tana    = {{STEP{y_p[DATA_WIDTH - 1]}},y_p[DATA_WIDTH - 1:STEP]};

    wire    [DATA_WIDTH - 1:0]    x_p_full    = {x_p,{(DATA_WIDTH - RAM_DATA_WIDTH){1'b0}}};
    wire    [DATA_WIDTH - 1:0]    y_p_full    = {y_p,{(DATA_WIDTH - RAM_DATA_WIDTH){1'b0}}};

    wire    [PHASE_WIDTH - 1:0]    phase_full    = {phase_last,{(PHASE_WIDTH - RAM_ADDR_WIDTH){1'b0}}};

    initial
    begin
        phase_out    = 0;
    end

    always @(posedge clk)
    begin
        direction        <= (phase_in < phase_target);
        phase_last        <= phase_in;
        x_p            <= din_x;
        y_p            <= din_y;
        phase_target_last    <= phase_target;
    end

    always @(negedge clk)
    begin
        if(direction)
        begin
            dout_x        <= x_p_full - y_p_tana;
            dout_y        <= y_p_full + x_p_tana;
            phase_out    <= phase_full + PHASE_INC;
        end
        else
        begin
            dout_x        <= x_p_full + y_p_tana;
            dout_y        <= y_p_full - x_p_tana;
            phase_out    <= phase_full - PHASE_INC;
        end

        phase_target_out    <= phase_target_last;
    end
endmodule
module cordic_pipeline__rotate
#(
    parameter PHASE_WIDTH        = 32,
    parameter DATA_WIDTH        = 20,
    parameter STEP            = 0,
    parameter PHASE_INC        = 0
)
(
    input                        clk,

    input        signed    [DATA_WIDTH - 1:0]    din_x,
    input        signed    [DATA_WIDTH - 1:0]    din_y,
    input            [PHASE_WIDTH - 1:0]    phase_in,
    input            [PHASE_WIDTH - 1:0]    phase_target,

    output    reg    signed    [DATA_WIDTH - 1:0]    dout_x,
    output    reg    signed    [DATA_WIDTH - 1:0]    dout_y,
    output    reg        [PHASE_WIDTH - 1:0]    phase_out,
    output    reg        [PHASE_WIDTH - 1:0]    phase_target_out
);
    ////////////////////////////////////////////////////////////////
    reg        [PHASE_WIDTH - 1:0]    phase_last    = 0;

    reg    signed    [DATA_WIDTH - 1:0]    x_p            = 0;
    reg    signed    [DATA_WIDTH - 1:0]    y_p            = 0;
    reg                    direction        = 0;
    reg        [PHASE_WIDTH - 1:0]    phase_target_last    = 0;

    always @(posedge clk)
    begin
        direction        <= (phase_in < phase_target);
        phase_last        <= phase_in;
        x_p            <= din_x;
        y_p            <= din_y;
        phase_target_last    <= phase_target;
    end

    always @(negedge clk)
    begin
        if(direction)
        begin
            dout_x        <= x_p - (y_p >>> STEP);
            dout_y        <= y_p + (x_p >>> STEP);
            phase_out    <= phase_last + PHASE_INC;
        end
        else
        begin
            dout_x        <= x_p + (y_p >>> STEP);
            dout_y        <= y_p - (x_p >>> STEP);
            phase_out    <= phase_last - PHASE_INC;
        end

        phase_target_out    <= phase_target_last;
    end
endmodule
module cordic_pipeline__rotate_end
#(
    parameter PHASE_WIDTH        = 32,
    parameter DATA_WIDTH        = 20,
    parameter STEP            = 0,
    parameter PHASE_INC        = 0,
    parameter RAM_DATA_WIDTH    = 18
)
(
    input                        clk,

    input        signed    [DATA_WIDTH - 1:0]    din_x,
    input        signed    [DATA_WIDTH - 1:0]    din_y,
    input            [PHASE_WIDTH - 1:0]    phase_in,
    input            [PHASE_WIDTH - 1:0]    phase_target,

    output    reg    signed    [DATA_WIDTH - 1:DATA_WIDTH - RAM_DATA_WIDTH]    dout_x,
    output    reg    signed    [DATA_WIDTH - 1:DATA_WIDTH - RAM_DATA_WIDTH]    dout_y
);
    //////////////////////////////////////////////////////////////////
    reg        [PHASE_WIDTH - 1:0]    phase_last    = 0;

    reg    signed    [DATA_WIDTH - 1:0]    x_p        = 0;
    reg    signed    [DATA_WIDTH - 1:0]    y_p        = 0;
    reg    signed    [DATA_WIDTH - 1:0]    x_q        = 0;
    reg    signed    [DATA_WIDTH - 1:0]    y_q        = 0;
    reg                    direction    = 0;

    always @(posedge clk)
    begin
        direction        <= (phase_in < phase_target);
        x_p            <= din_x;
        y_p            <= din_y;
    end

    always @(*)
    begin
        if(direction)
        begin
            x_q    = x_p - (y_p >>> STEP);
            y_q    = y_p + (x_p >>> STEP);
        end
        else
        begin
            x_q    = x_p + (y_p >>> STEP);
            y_q    = y_p - (x_p >>> STEP);
        end
    end
    always @(negedge clk)
    begin
        dout_x        <= x_q[(DATA_WIDTH - 1)-:RAM_DATA_WIDTH];
        dout_y        <= y_q[(DATA_WIDTH - 1)-:RAM_DATA_WIDTH];
    end
endmodule
cordic_pipeline__rotate.v

 

module cic__integral_step
#(
    parameter    DATA_WIDTH        = 32
)
(
    input                        clk,
    input                        rst,
    input        signed    [DATA_WIDTH - 1:0]    din,
    output        signed    [DATA_WIDTH - 1:0]    dout
);
    reg        signed    [DATA_WIDTH - 1:0]    integral    = 0;
    reg        signed    [DATA_WIDTH - 1:0]    integral_last    = 0;

    always @(posedge clk)
    begin
        if(rst)
            integral    <= 0;
        else
            integral    <= integral_last + din;
    end
    always @(negedge clk)
    begin
        integral_last    <= integral;
    end
    assign dout = integral_last;
endmodule

module cic__integral
#(
    parameter    CIC_ORDER    = 4,
    parameter    DATA_WIDTH    = 40
)
(
    input                        rst,
    input                        clk,
    input        signed    [DATA_WIDTH - 1:0]    din,
    output        signed    [DATA_WIDTH - 1:0]    dout
);
    wire    [DATA_WIDTH - 1:0]    data[CIC_ORDER:0];
    assign data[0]    = din;
    assign dout    = data[CIC_ORDER];

generate
genvar gen_i;
    for (gen_i = 0; gen_i < CIC_ORDER;gen_i = gen_i + 1)
    begin:gen__cic_integral
        cic__integral_step
        #(
            .DATA_WIDTH    (DATA_WIDTH)
        )
        integral
        (
            .rst        (rst),
            .clk        (clk),
            .din        (data[gen_i]),
            .dout        (data[gen_i + 1])
        );
    end
endgenerate

endmodule

module cic__comb_neg
#(
    parameter    DOUT_LSB    = 0,
    parameter    DATA_WIDTH    = 32
)
(
    input                            clk,
    input                            en,
    input        signed    [DATA_WIDTH - 1:0]        din,
    output reg    signed    [DATA_WIDTH - 1:DOUT_LSB]    dout
);
    /////////////////////////////////////////////////////////////

    reg    signed    [DATA_WIDTH - 1:0]    comb_delay    = 0;
    reg    signed    [DATA_WIDTH - 1:0]    comb_delay_last    = 0;
    wire    signed    [DATA_WIDTH - 1:0]    dout_sub    = din - comb_delay_last;

    reg                    en_last = 0;
    ////////////////////////////////////////////////////////////////
    always @(posedge clk)
    begin
        en_last    <= en;
    end

    always @(negedge clk)
    begin
        if(en_last)
            comb_delay    <= din;
    end
    always @(posedge clk)
    begin
        comb_delay_last    <= comb_delay;
    end
    always @(negedge clk)
    begin
        if(en_last)
            dout        <= dout_sub[DATA_WIDTH - 1:DOUT_LSB];
    end
endmodule

module cic__comb_pos
#(
    parameter    DOUT_LSB    = 0,
    parameter    DATA_WIDTH    = 32
)
(
    input                            clk,
    input                            en,
    input        signed    [DATA_WIDTH - 1:0]        din,
    output    reg    signed    [DATA_WIDTH - 1:DOUT_LSB]    dout
);
    reg        signed    [DATA_WIDTH - 1:0]    comb_delay    = 0;
    reg        signed    [DATA_WIDTH - 1:0]    comb_delay_last    = 0;
    wire        signed    [DATA_WIDTH - 1:0]    dout_sub    = din - comb_delay_last;

    always @(posedge clk)
    begin
        if(en)
            comb_delay    <= din;
    end
    always @(negedge clk)
    begin
        comb_delay_last    <= comb_delay;
    end
    always @(posedge clk)
    begin
        if(en)
            dout        <= dout_sub[DATA_WIDTH - 1:DOUT_LSB];
    end
endmodule

module cic__comb
#(
    parameter    CIC_ORDER    = 4,
    parameter    DATA_WIDTH    = 40
)
(
    input                        clk,
    input                        en,
    input        signed    [DATA_WIDTH - 1:0]    din,
    output        signed    [17:0]            dout
);
    wire    signed    [DATA_WIDTH - 1:0]    data[CIC_ORDER - 1:0];
    assign data[0]    = din;

    wire        [17:0]    data_pos_last;
    reg    signed    [17:0]    dout_reg    = 0;
generate
genvar gen_i;
    for (gen_i = 0; gen_i < CIC_ORDER; gen_i = gen_i + 2)
    begin:gen__cic_comb_pos
        if(gen_i == CIC_ORDER - 1) begin:gen__cic_comb__odd_pos_last        // CIC_ORDER是奇数,这是最后一级
            cic__comb_pos
            #(
                .DOUT_LSB    (DATA_WIDTH - 18),            // 保证输出位数为18位
                .DATA_WIDTH    (DATA_WIDTH)
            )
            comb_pos
            (
                .clk        (clk),
                .en        (en),
                .din        (data[gen_i]),
                .dout        (data_pos_last)
            );
        end else begin:gen__cic_comb__pos                    // 普通的cic_comb_pos
            cic__comb_pos
            #(
                .DOUT_LSB    (0),
                .DATA_WIDTH    (DATA_WIDTH)
            )
            comb_pos
            (
                .clk        (clk),
                .en        (en),
                .din        (data[gen_i]),
                .dout        (data[gen_i + 1])
            );
        end

        if(gen_i == CIC_ORDER - 2) begin:gen__cic_comb__even_neg_last            // CIC_ORDER是偶数,这是最后一级
            cic__comb_neg
            #(
                .DOUT_LSB    (DATA_WIDTH - 18),            // 保证输出位数为18位
                .DATA_WIDTH    (DATA_WIDTH)
            )
            comb_neg
            (
                .clk        (clk),
                .en        (en),
                .din        (data[gen_i + 1]),
                .dout        (dout)
            );

        end else if(gen_i == CIC_ORDER - 1) begin:gen__cic_comb__odd_neg_last    // CIC_ORDER是奇数,只需要锁存一下,保证下降沿输出
            always @(negedge clk)
            begin
                dout_reg    <= data_pos_last;
            end
            assign dout    = dout_reg;

        end else begin:gen__cic_comb__neg                    // 普通的cic_comb_neg
            cic__comb_neg
            #(
                .DOUT_LSB    (0),
                .DATA_WIDTH    (DATA_WIDTH)
            )
            comb_neg
            (
                .clk        (clk),
                .en        (en),
                .din        (data[gen_i + 1]),
                .dout        (data[gen_i + 2])
            );
        end
    end
endgenerate

endmodule
module cic__ctrl
(
    input            rst,
    input            clk,
    input        [1:0]    ratio_sel,
    output    reg        en
);
    localparam     COUNT_WIDTH        = 6;

    reg            [COUNT_WIDTH - 1:0]    count        = 0;
    reg            [COUNT_WIDTH - 1:0]    count_next    = 0;
    reg                        condition_rst    = 0;
    reg                        rst_last    = 0;

    reg    [COUNT_WIDTH - 1:0]    ratio;

    always @(*)
    begin
        case(ratio_sel)
            0:    ratio    = 24 - 1;
            1:    ratio    = 27 - 1;
            2:    ratio    = 48 - 1;
            3:    ratio    = 52 - 1;
        endcase
    end

    always @(posedge clk)
    begin
        if(rst)
        begin
            count        <= 0;
            condition_rst    <= 1'b1;
        end
        else
        begin
            count        <= count_next;
            condition_rst    <= (count_next    == 0);
        end
        rst_last    <= rst;
    end

    always @(negedge clk)
    begin
        if(condition_rst)
            count_next    <= ratio;
        else
            count_next    <= count - 1'b1;

        if(rst_last)
            en    <= 1'b0;
        else
            en    <= condition_rst;
    end

endmodule
module cic_iq
#(
    parameter    CIC_ORDER    = 4,
    parameter    DATA_WIDTH    = 36
)
(
    input                rst,
    input                clk,
    input            [1:0]    ratio_sel,
    input        signed    [17:0]    din_i,
    input        signed    [17:0]    din_q,
    output        signed    [17:0]    dout_i,
    output        signed    [17:0]    dout_q,
    output    reg            dout_latch
);
    wire                    en;
    wire    signed    [DATA_WIDTH - 1:0]    integral_out_i;
    wire    signed    [DATA_WIDTH - 1:0]    integral_out_q;

    ////////////////////////////////////////////////////////////////
    cic__ctrl
    ctrl
    (
        .rst        (rst),
        .clk        (clk),
        .ratio_sel    (ratio_sel),
        .en        (en)
    );
    ////////////////////////////////////////////////////////////////
    cic__integral
    #(
        .DATA_WIDTH    (DATA_WIDTH),
        .CIC_ORDER    (CIC_ORDER)
    )
    integral_i
    (
        .rst    (rst),
        .clk    (clk),
        .din    ({{(DATA_WIDTH - 18){din_i[17]}},din_i}),
        .dout    (integral_out_i)
    );
    cic__comb
    #(
        .DATA_WIDTH    (DATA_WIDTH),
        .CIC_ORDER    (CIC_ORDER)
    )
    comb_i
    (
        .clk    (clk),
        .en    (en),
        .din    (integral_out_i),
        .dout    (dout_i)
    );
    ////////////////////////////////////////////////////////////////
    cic__integral
    #(
        .DATA_WIDTH    (DATA_WIDTH),
        .CIC_ORDER    (CIC_ORDER)
    )
    integral_q
    (
        .rst    (rst),
        .clk    (clk),
        .din    ({{(DATA_WIDTH - 18){din_q[17]}},din_q}),
        .dout    (integral_out_q)
    );
    cic__comb
    #(
        .DATA_WIDTH    (DATA_WIDTH),
        .CIC_ORDER    (CIC_ORDER)
    )comb_q
    (
        .clk    (clk),
        .en    (en),
        .din    (integral_out_q),
        .dout    (dout_q)
    );

    always @(negedge clk)
    begin
        dout_latch        <= en;
    end

endmodule
cic_iq.v
% Design a minimum-order CIC
% It will be 4-order for the parameter below
cic_DD	= 1;     	% Differential delay
cic_Fp	= 200e3;    % Passband of interest
%Fst	= 1.2e6;	% Stopband of interest
cic_Ast	= 80;    	% Minimum attenuation of alias components in passband
Fs	= 64.8e6; 	% Sampling frequency for input signal
cic_dec	= 27;    	% Decimation factor
d_cic	= fdesign.decimator(cic_dec,'cic',cic_DD,'Fp,Ast',cic_Fp,cic_Ast,Fs);
h_cic	= design(d_cic);

fcfwrite([h_cic h_comp],'CICdesciption_27x','dec'); % 其中,生成的.fcf文件描述滤波器的结构

% Analyze filters individually plus compound response
hfvt = fvtool(h_cic,'Fs', [Fs], 'ShowReference', 'off');
legend(hfvt, 'CIC decimator');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


d_cic

h_cic
cic_dec_64800KSPS_27x_200k_80db.m
% Generated by MATLAB(R) 8.1 and the Signal Processing Toolbox 6.19.
% Generated on: 14-Oct-2019 14:07:32

% Coefficient Format: Decimal

% Discrete-Time FIR Multirate Filter (real)                                     
% -----------------------------------------                                     
% Filter Structure        : Cascaded Integrator-Comb Decimator                  
% Decimation Factor       : 27                                                  
% Differential Delay      : 1                                                   
% Number of Sections      : 4                                                   
% Stable                  : Yes                                                 
% Linear Phase            : Yes (Type 1)                                        
%                                                                               
% Input                   : s16,15                                              
% Output                  : s36,15                                              
% Filter Internals        : Full Precision                                      
%   Integrator Section 1  : s36,15                                              
%   Integrator Section 2  : s36,15                                              
%   Integrator Section 3  : s36,15                                              
%   Integrator Section 4  : s36,15                                              
%   Comb Section 1        : s36,15                                              
%   Comb Section 2        : s36,15                                              
%   Comb Section 3        : s36,15                                              
%   Comb Section 4        : s36,15                                              

                                                                               
CIC filters have no coefficients.                                               

                                                                               
% Discrete-Time FIR Multirate Filter (real)                                     
% -----------------------------------------                                     
% Filter Structure   : Direct-Form FIR Polyphase Decimator                      
% Decimation Factor  : 5                                                        
% Polyphase Length   : 96                                                       
% Filter Length      : 480                                                      
% Stable             : Yes                                                      
% Linear Phase       : Yes (Type 2)                                             
%                                                                               
% Arithmetic         : fixed                                                    
% Numerator          : s16,17 -> [-2.500000e-01 2.500000e-01)                   
% Input              : s16,15 -> [-1 1)                                         
% Filter Internals   : Full Precision                                           
%   Output           : s35,32 -> [-4 4)  (auto determined)                      
%   Product          : s31,32 -> [-2.500000e-01 2.500000e-01)  (auto determined)
%   Accumulator      : s35,32 -> [-4 4)  (auto determined)                      
%   Round Mode       : No rounding                                              
%   Overflow Mode    : No overflow                                              

                                                                               
Numerator:                                                                      
 0.00000762939453125                                                            
 0.0000152587890625                                                             
 0.00002288818359375                                                            
 0.00003814697265625                                                            
 0.0000457763671875                                                             
 0.00005340576171875                                                            
 0.00006103515625                                                               
 0.00005340576171875                                                            
 0.00003814697265625                                                            
 0.00002288818359375                                                            
 0                                                                              
-0.00002288818359375                                                            
-0.00003814697265625                                                            
-0.00003814697265625                                                            
-0.000030517578125                                                              
-0.0000152587890625                                                             
 0.00000762939453125                                                            
 0.000030517578125                                                              
 0.0000457763671875                                                             
 0.0000457763671875                                                             
 0.00003814697265625                                                            
 0.0000152587890625                                                             
-0.0000152587890625                                                             
-0.00003814697265625                                                            
-0.00005340576171875                                                            
-0.00006103515625                                                               
-0.0000457763671875                                                             
-0.0000152587890625                                                             
 0.00002288818359375                                                            
 0.00005340576171875                                                            
 0.0000762939453125                                                             
 0.0000762939453125                                                             
 0.00005340576171875                                                            
 0.00000762939453125                                                            
-0.00003814697265625                                                            
-0.0000762939453125                                                             
-0.00009918212890625                                                            
-0.000091552734375                                                              
-0.00005340576171875                                                            
 0                                                                              
 0.00006103515625                                                               
 0.00009918212890625                                                            
 0.0001220703125                                                                
 0.0001068115234375                                                             
 0.00005340576171875                                                            
-0.0000152587890625                                                             
-0.00008392333984375                                                            
-0.0001373291015625                                                             
-0.000152587890625                                                              
-0.0001220703125                                                                
-0.00005340576171875                                                            
 0.00003814697265625                                                            
 0.0001220703125                                                                
 0.00017547607421875                                                            
 0.00018310546875                                                               
 0.00012969970703125                                                            
 0.00003814697265625                                                            
-0.00006866455078125                                                            
-0.0001678466796875                                                             
-0.00022125244140625                                                            
-0.00020599365234375                                                            
-0.0001373291015625                                                             
-0.0000152587890625                                                             
 0.00011444091796875                                                            
 0.00022125244140625                                                            
 0.00026702880859375                                                            
 0.00023651123046875                                                            
 0.00012969970703125                                                            
-0.00002288818359375                                                            
-0.00017547607421875                                                            
-0.0002899169921875                                                             
-0.0003204345703125                                                             
-0.0002593994140625                                                             
-0.00011444091796875                                                            
 0.00006866455078125                                                            
 0.00025177001953125                                                            
 0.0003662109375                                                                
 0.00037384033203125                                                            
 0.000274658203125                                                              
 0.00008392333984375                                                            
-0.00014495849609375                                                            
-0.000335693359375                                                              
-0.0004425048828125                                                             
-0.00041961669921875                                                            
-0.000274658203125                                                              
-0.000030517578125                                                              
 0.00023651123046875                                                            
 0.0004425048828125                                                             
 0.0005340576171875                                                             
 0.00046539306640625                                                            
 0.00025177001953125                                                            
-0.0000457763671875                                                             
-0.00034332275390625                                                            
-0.00055694580078125                                                            
-0.00061798095703125                                                            
-0.00048828125                                                                  
-0.00020599365234375                                                            
 0.000152587890625                                                              
 0.00048065185546875                                                            
 0.0006866455078125                                                             
 0.00069427490234375                                                            
 0.00049591064453125                                                            
 0.0001373291015625                                                             
-0.00028228759765625                                                            
-0.000640869140625                                                              
-0.000823974609375                                                              
-0.00077056884765625                                                            
-0.0004730224609375                                                             
-0.00002288818359375                                                            
 0.000457763671875                                                              
 0.000823974609375                                                              
 0.0009613037109375                                                             
 0.00081634521484375                                                            
 0.00041961669921875                                                            
-0.0001220703125                                                                
-0.0006561279296875                                                             
-0.00101470947265625                                                            
-0.00109100341796875                                                            
-0.0008392333984375                                                             
-0.0003204345703125                                                             
 0.0003204345703125                                                             
 0.00089263916015625                                                            
 0.001220703125                                                                 
 0.0012054443359375                                                             
 0.00081634521484375                                                            
 0.0001678466796875                                                             
-0.0005645751953125                                                             
-0.00115966796875                                                               
-0.001434326171875                                                              
-0.00128936767578125                                                            
-0.0007476806640625                                                             
 0.00003814697265625                                                            
 0.0008544921875                                                                
 0.0014495849609375                                                             
 0.0016326904296875                                                             
 0.00133514404296875                                                            
 0.00061798095703125                                                            
-0.00031280517578125                                                            
-0.00119781494140625                                                            
-0.00176239013671875                                                            
-0.0018157958984375                                                             
-0.0013275146484375                                                             
-0.00041961669921875                                                            
 0.0006561279296875                                                             
 0.0015869140625                                                                
 0.00208282470703125                                                            
 0.0019683837890625                                                             
 0.00125885009765625                                                            
 0.0001373291015625                                                             
-0.00107574462890625                                                            
-0.00202178955078125                                                            
-0.0023956298828125                                                             
-0.00206756591796875                                                            
-0.0010986328125                                                                
 0.000244140625                                                                 
 0.0015716552734375                                                             
 0.0024871826171875                                                             
 0.00269317626953125                                                            
 0.00209808349609375                                                            
 0.0008392333984375                                                             
-0.00072479248046875                                                            
-0.00214385986328125                                                            
-0.0029754638671875                                                             
-0.00295257568359375                                                            
-0.00203704833984375                                                            
-0.00046539306640625                                                            
 0.00131988525390625                                                            
 0.00278472900390625                                                            
 0.00347900390625                                                               
 0.00315093994140625                                                            
 0.001861572265625                                                              
-0.00005340576171875                                                            
-0.00203704833984375                                                            
-0.00350189208984375                                                            
-0.00397491455078125                                                            
-0.00327301025390625                                                            
-0.0015411376953125                                                             
 0.000732421875                                                                 
 0.00289154052734375                                                            
 0.0042877197265625                                                             
 0.00444793701171875                                                            
 0.00327301025390625                                                            
 0.0010528564453125                                                             
-0.00159454345703125                                                            
-0.00389862060546875                                                            
-0.005126953125                                                                 
-0.00487518310546875                                                            
-0.0031280517578125                                                             
-0.0003509521484375                                                             
 0.002685546875                                                                 
 0.00506591796875                                                               
 0.00603485107421875                                                            
 0.00522613525390625                                                            
 0.0027923583984375                                                             
-0.0006256103515625                                                             
-0.0040435791015625                                                             
-0.0064239501953125                                                             
-0.00699615478515625                                                            
-0.00547027587890625                                                            
-0.002197265625                                                                 
 0.001953125                                                                    
 0.0057525634765625                                                             
 0.00804901123046875                                                            
 0.00803375244140625                                                            
 0.0055694580078125                                                             
 0.00124359130859375                                                            
-0.003753662109375                                                              
-0.00795745849609375                                                            
-0.0100250244140625                                                             
-0.00917816162109375                                                            
-0.00545501708984375                                                            
 0.0002288818359375                                                             
 0.00629425048828125                                                            
 0.01092529296875                                                               
 0.01258087158203125                                                            
 0.0105133056640625                                                             
 0.0050048828125                                                                
-0.0025634765625                                                                
-0.0100860595703125                                                             
-0.01525115966796875                                                            
-0.0162353515625                                                                
-0.01226806640625                                                               
-0.003997802734375                                                              
 0.006561279296875                                                              
 0.01645660400390625                                                            
 0.0225677490234375                                                             
 0.0224456787109375                                                             
 0.01515960693359375                                                            
 0.001739501953125                                                              
-0.01482391357421875                                                            
-0.03006744384765625                                                            
-0.039031982421875                                                              
-0.0374298095703125                                                             
-0.0227508544921875                                                             
 0.00496673583984375                                                            
 0.04282379150390625                                                            
 0.085540771484375                                                              
 0.1263275146484375                                                             
 0.15830230712890625                                                            
 0.1758575439453125                                                             
 0.1758575439453125                                                             
 0.15830230712890625                                                            
 0.1263275146484375                                                             
 0.085540771484375                                                              
 0.04282379150390625                                                            
 0.00496673583984375                                                            
-0.0227508544921875                                                             
-0.0374298095703125                                                             
-0.039031982421875                                                              
-0.03006744384765625                                                            
-0.01482391357421875                                                            
 0.001739501953125                                                              
 0.01515960693359375                                                            
 0.0224456787109375                                                             
 0.0225677490234375                                                             
 0.01645660400390625                                                            
 0.006561279296875                                                              
-0.003997802734375                                                              
-0.01226806640625                                                               
-0.0162353515625                                                                
-0.01525115966796875                                                            
-0.0100860595703125                                                             
-0.0025634765625                                                                
 0.0050048828125                                                                
 0.0105133056640625                                                             
 0.01258087158203125                                                            
 0.01092529296875                                                               
 0.00629425048828125                                                            
 0.0002288818359375                                                             
-0.00545501708984375                                                            
-0.00917816162109375                                                            
-0.0100250244140625                                                             
-0.00795745849609375                                                            
-0.003753662109375                                                              
 0.00124359130859375                                                            
 0.0055694580078125                                                             
 0.00803375244140625                                                            
 0.00804901123046875                                                            
 0.0057525634765625                                                             
 0.001953125                                                                    
-0.002197265625                                                                 
-0.00547027587890625                                                            
-0.00699615478515625                                                            
-0.0064239501953125                                                             
-0.0040435791015625                                                             
-0.0006256103515625                                                             
 0.0027923583984375                                                             
 0.00522613525390625                                                            
 0.00603485107421875                                                            
 0.00506591796875                                                               
 0.002685546875                                                                 
-0.0003509521484375                                                             
-0.0031280517578125                                                             
-0.00487518310546875                                                            
-0.005126953125                                                                 
-0.00389862060546875                                                            
-0.00159454345703125                                                            
 0.0010528564453125                                                             
 0.00327301025390625                                                            
 0.00444793701171875                                                            
 0.0042877197265625                                                             
 0.00289154052734375                                                            
 0.000732421875                                                                 
-0.0015411376953125                                                             
-0.00327301025390625                                                            
-0.00397491455078125                                                            
-0.00350189208984375                                                            
-0.00203704833984375                                                            
-0.00005340576171875                                                            
 0.001861572265625                                                              
 0.00315093994140625                                                            
 0.00347900390625                                                               
 0.00278472900390625                                                            
 0.00131988525390625                                                            
-0.00046539306640625                                                            
-0.00203704833984375                                                            
-0.00295257568359375                                                            
-0.0029754638671875                                                             
-0.00214385986328125                                                            
-0.00072479248046875                                                            
 0.0008392333984375                                                             
 0.00209808349609375                                                            
 0.00269317626953125                                                            
 0.0024871826171875                                                             
 0.0015716552734375                                                             
 0.000244140625                                                                 
-0.0010986328125                                                                
-0.00206756591796875                                                            
-0.0023956298828125                                                             
-0.00202178955078125                                                            
-0.00107574462890625                                                            
 0.0001373291015625                                                             
 0.00125885009765625                                                            
 0.0019683837890625                                                             
 0.00208282470703125                                                            
 0.0015869140625                                                                
 0.0006561279296875                                                             
-0.00041961669921875                                                            
-0.0013275146484375                                                             
-0.0018157958984375                                                             
-0.00176239013671875                                                            
-0.00119781494140625                                                            
-0.00031280517578125                                                            
 0.00061798095703125                                                            
 0.00133514404296875                                                            
 0.0016326904296875                                                             
 0.0014495849609375                                                             
 0.0008544921875                                                                
 0.00003814697265625                                                            
-0.0007476806640625                                                             
-0.00128936767578125                                                            
-0.001434326171875                                                              
-0.00115966796875                                                               
-0.0005645751953125                                                             
 0.0001678466796875                                                             
 0.00081634521484375                                                            
 0.0012054443359375                                                             
 0.001220703125                                                                 
 0.00089263916015625                                                            
 0.0003204345703125                                                             
-0.0003204345703125                                                             
-0.0008392333984375                                                             
-0.00109100341796875                                                            
-0.00101470947265625                                                            
-0.0006561279296875                                                             
-0.0001220703125                                                                
 0.00041961669921875                                                            
 0.00081634521484375                                                            
 0.0009613037109375                                                             
 0.000823974609375                                                              
 0.000457763671875                                                              
-0.00002288818359375                                                            
-0.0004730224609375                                                             
-0.00077056884765625                                                            
-0.000823974609375                                                              
-0.000640869140625                                                              
-0.00028228759765625                                                            
 0.0001373291015625                                                             
 0.00049591064453125                                                            
 0.00069427490234375                                                            
 0.0006866455078125                                                             
 0.00048065185546875                                                            
 0.000152587890625                                                              
-0.00020599365234375                                                            
-0.00048828125                                                                  
-0.00061798095703125                                                            
-0.00055694580078125                                                            
-0.00034332275390625                                                            
-0.0000457763671875                                                             
 0.00025177001953125                                                            
 0.00046539306640625                                                            
 0.0005340576171875                                                             
 0.0004425048828125                                                             
 0.00023651123046875                                                            
-0.000030517578125                                                              
-0.000274658203125                                                              
-0.00041961669921875                                                            
-0.0004425048828125                                                             
-0.000335693359375                                                              
-0.00014495849609375                                                            
 0.00008392333984375                                                            
 0.000274658203125                                                              
 0.00037384033203125                                                            
 0.0003662109375                                                                
 0.00025177001953125                                                            
 0.00006866455078125                                                            
-0.00011444091796875                                                            
-0.0002593994140625                                                             
-0.0003204345703125                                                             
-0.0002899169921875                                                             
-0.00017547607421875                                                            
-0.00002288818359375                                                            
 0.00012969970703125                                                            
 0.00023651123046875                                                            
 0.00026702880859375                                                            
 0.00022125244140625                                                            
 0.00011444091796875                                                            
-0.0000152587890625                                                             
-0.0001373291015625                                                             
-0.00020599365234375                                                            
-0.00022125244140625                                                            
-0.0001678466796875                                                             
-0.00006866455078125                                                            
 0.00003814697265625                                                            
 0.00012969970703125                                                            
 0.00018310546875                                                               
 0.00017547607421875                                                            
 0.0001220703125                                                                
 0.00003814697265625                                                            
-0.00005340576171875                                                            
-0.0001220703125                                                                
-0.000152587890625                                                              
-0.0001373291015625                                                             
-0.00008392333984375                                                            
-0.0000152587890625                                                             
 0.00005340576171875                                                            
 0.0001068115234375                                                             
 0.0001220703125                                                                
 0.00009918212890625                                                            
 0.00006103515625                                                               
 0                                                                              
-0.00005340576171875                                                            
-0.000091552734375                                                              
-0.00009918212890625                                                            
-0.0000762939453125                                                             
-0.00003814697265625                                                            
 0.00000762939453125                                                            
 0.00005340576171875                                                            
 0.0000762939453125                                                             
 0.0000762939453125                                                             
 0.00005340576171875                                                            
 0.00002288818359375                                                            
-0.0000152587890625                                                             
-0.0000457763671875                                                             
-0.00006103515625                                                               
-0.00005340576171875                                                            
-0.00003814697265625                                                            
-0.0000152587890625                                                             
 0.0000152587890625                                                             
 0.00003814697265625                                                            
 0.0000457763671875                                                             
 0.0000457763671875                                                             
 0.000030517578125                                                              
 0.00000762939453125                                                            
-0.0000152587890625                                                             
-0.000030517578125                                                              
-0.00003814697265625                                                            
-0.00003814697265625                                                            
-0.00002288818359375                                                            
 0                                                                              
 0.00002288818359375                                                            
 0.00003814697265625                                                            
 0.00005340576171875                                                            
 0.00006103515625                                                               
 0.00005340576171875                                                            
 0.0000457763671875                                                             
 0.00003814697265625                                                            
 0.00002288818359375                                                            
 0.0000152587890625                                                             
 0.00000762939453125                                                            

                                                                               
CICdesciption_27x.fcf

module cic_comp_dec_iq
#(
    parameter    RAM_ADDR_WIDTH    = 8,
    localparam    DECIMATION_RATIO    = 5,
    localparam    HALF_DEPTH        = 240
)
(
    input                        rst,
    input                        clk,
    input                        din_latch,
    input        signed    [17:0]            din_i,
    input        signed    [17:0]            din_q,

    input                        coef_in_clk,
    input                        coef_in_we,
    input            [RAM_ADDR_WIDTH - 1:0]    coef_in_addr,
    input        signed    [17:0]            coef_in_d,

    //input            [7:0]            decimation_ratio,

    output        signed    [17:0]            dout_i,
    output        signed    [17:0]            dout_q,
    output                        dout_latch,
    output                        error_conflicted,
    output                        error_overflow
);
    //////////////////////////////////////////////////////////////

    wire            [RAM_ADDR_WIDTH - 1:0]    coef_addr;
    wire            [RAM_ADDR_WIDTH - 1:0]    din_addr;
    wire            [RAM_ADDR_WIDTH - 1:0]    dout_addr_f;
    wire            [RAM_ADDR_WIDTH - 1:0]    din_addr_b;
    wire            [RAM_ADDR_WIDTH - 1:0]    dout_addr_b;
    wire                        din_we_b;
    wire                        proc_begin;
    wire                        proc_done;
    wire            [35:0]            ram_out_f;
    wire            [35:0]            ram_out_b;
    wire        signed    [17:0]            coef_out;

    wire            [RAM_ADDR_WIDTH - 1:0]    half_depth = HALF_DEPTH;

    fir_ls__din_ctrl
    #(
        .RAM_ADDR_WIDTH        (RAM_ADDR_WIDTH),
        .DECIMATION_RATIO    (DECIMATION_RATIO)
    )din_ctrl
    (
        .rst            (rst),
        .clk            (clk),
        .din_latch        (din_latch),
        .din_addr        (din_addr),
        .proc_begin        (proc_begin)
    );
    fir_ls__proc_ctrl
    #(
        .RAM_ADDR_WIDTH        (RAM_ADDR_WIDTH),
        .DECIMATION_RATIO    (DECIMATION_RATIO)
    )proc_ctrl
    (
        .rst            (rst),
        .clk            (clk),
        .din_addr        (din_addr),
        .proc_begin        (proc_begin),
        .half_depth        (half_depth),
        .dout_addr_f        (dout_addr_f),
        .din_addr_b        (din_addr_b),
        .coef_addr        (coef_addr),
        .din_we_b        (din_we_b),
        .dout_addr_b        (dout_addr_b),
        .proc_done        (proc_done),
        .error_conflicted    (error_conflicted),
        .error_overflow        (error_overflow)
    );
    fir_ls__ram_loop
    #(
        .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH)
    )ram_loop
    (
        .clk        (clk),
        .din        ({din_i,din_q}),
        .din_latch    (din_latch),
        .din_addr    (din_addr),
        .dout_addr_f    (dout_addr_f),
        .dout_addr_b    (dout_addr_b),
        .din_addr_b    (din_addr_b),
        .din_we_b    (din_we_b),
        .ram_out_f    (ram_out_f),
        .ram_out_b    (ram_out_b)
    );

    cic_comp_dec__ram_coef
    #(
        .RAM_ADDR_WIDTH    (RAM_ADDR_WIDTH)
    )
    ram_coef
    (
        .clka(coef_in_clk),
        .addra(coef_in_addr),
        .wea(coef_in_we),
        .dina(coef_in_d),

        .clkb(clk),
        .addrb(coef_addr),
        .doutb(coef_out)
    );

    fir_ls_iq__product_sum
    #(
        .SUMOUT_MSB(25 + RAM_ADDR_WIDTH)
    )sum
    (
        .rst        (rst),
        .clk        (clk),

        .ram_data_f_i    (ram_out_f[18+:18]),
        .ram_data_b_i    (ram_out_b[18+:18]),

        .ram_data_f_q    (ram_out_f[0+:18]),
        .ram_data_b_q    (ram_out_b[0+:18]),

        .coef_data    (coef_out),

        .proc_done    (proc_done),
        .dout_i        (dout_i),
        .dout_q        (dout_q),
        .dout_latch    (dout_latch)
    );
endmodule
cic_comp_dec_iq.v
% Design a minimum-order CIC
% It will be 4-order for the parameter below
cic_DD	= 1;     	% Differential delay
cic_Fp	= 200e3;    % Passband of interest
%Fst	= 1.2e6;	% Stopband of interest
cic_Ast	= 80;    	% Minimum attenuation of alias components in passband
Fs	= 64.8e6; 	% Sampling frequency for input signal
cic_dec	= 27;    	% Decimation factor
d_cic	= fdesign.decimator(cic_dec,'cic',cic_DD,'Fp,Ast',cic_Fp,cic_Ast,Fs);
h_cic	= design(d_cic);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
comp_dec	= 5;	% DecimationFactor of the CIC compensator
comp_Fp		= 200e3;
comp_order	= 480 - 1;
comp_Ap		= 0.01;
comp_Ast	= 100;

d_comp	= fdesign.decimator(	comp_dec,						...
				'CIC compensator',					...
				h_cic.DifferentialDelay,				...
				h_cic.NumberOfSections,					...
				h_cic.DecimationFactor,					...
				'N,Fp,Ap,Ast',comp_order,comp_Fp,comp_Ap,comp_Ast,	...
				Fs/cic_dec);
%%  help fdesign.ciccomp

%	>> get(d_comp,'Specification')
%	ans =
%	N,Fp,Ap,Ast

%	>> get(dd_comp,'Description')
%	ans =
%	    'Filter Order'
%	    'Passband Frequency'
%	    'Passband Ripple (dB)'
%	    'Stopband Attenuation (dB)'
%
h_comp	= design(d_comp, 'equiripple');
h_comp.Arithmetic = 'fixed';

fcfwrite([h_cic h_comp],'cic_4order_27x_dec_200k__comp_480order_5x_dec_200k__64800KSPS.fcf','dec'); % 其中,生成的.fcf文件描述滤波器的结构

% Analyze filters individually plus compound response
hfvt = fvtool(h_cic, h_comp, cascade(h_cic, h_comp), 'Fs', [Fs,Fs/cic_dec,Fs], 'ShowReference', 'off');
legend(hfvt, 'CIC decimator', 'CIC compensator', 'Overall response');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




coef=round((2^20)*h_comp.numerator);
fd=fopen('F:\Projects\sdr\fpga\ise_prj\src\recv\costas_loop\ddc\cic_comp_dec_iq\cic_comp_dec_iq__coef.txt','wt');
fprintf(fd,'%d\n',coef);
fclose(fd);




%d_cic

%h_cic

%d_comp

%h_comp












%cic_comp_coef=round((2^16)*hmc.numerator);

%fd=fopen('E:\workspace\Projects\sdr\fpga\ise_prj\src\recv\ddc\cic_comp_dec\coef.coe','wt');
%fprintf(fd,'%s\n','MEMORY_INITIALIZATION_RADIX=10;');
%fprintf(fd,'%s\n','MEMORY_INITIALIZATION_VECTOR=');

%fprintf(fd,'%d\n',cic_comp_coef);

%fclose(fd);
cic_4order_27x_dec_200k__comp_480order_5x_dec_200k__64800KSPS.m
% Generated by MATLAB(R) 8.1 and the Signal Processing Toolbox 6.19.
% Generated on: 04-Jan-2022 16:13:35

% Coefficient Format: Decimal

% Discrete-Time FIR Multirate Filter (real)                                     
% -----------------------------------------                                     
% Filter Structure        : Cascaded Integrator-Comb Decimator                  
% Decimation Factor       : 27                                                  
% Differential Delay      : 1                                                   
% Number of Sections      : 4                                                   
% Stable                  : Yes                                                 
% Linear Phase            : Yes (Type 1)                                        
%                                                                               
% Input                   : s16,15                                              
% Output                  : s36,15                                              
% Filter Internals        : Full Precision                                      
%   Integrator Section 1  : s36,15                                              
%   Integrator Section 2  : s36,15                                              
%   Integrator Section 3  : s36,15                                              
%   Integrator Section 4  : s36,15                                              
%   Comb Section 1        : s36,15                                              
%   Comb Section 2        : s36,15                                              
%   Comb Section 3        : s36,15                                              
%   Comb Section 4        : s36,15                                              

                                                                               
CIC filters have no coefficients.                                               

                                                                               
% Discrete-Time FIR Multirate Filter (real)                                     
% -----------------------------------------                                     
% Filter Structure   : Direct-Form FIR Polyphase Decimator                      
% Decimation Factor  : 5                                                        
% Polyphase Length   : 96                                                       
% Filter Length      : 480                                                      
% Stable             : Yes                                                      
% Linear Phase       : Yes (Type 2)                                             
%                                                                               
% Arithmetic         : fixed                                                    
% Numerator          : s16,17 -> [-2.500000e-01 2.500000e-01)                   
% Input              : s16,15 -> [-1 1)                                         
% Filter Internals   : Full Precision                                           
%   Output           : s35,32 -> [-4 4)  (auto determined)                      
%   Product          : s31,32 -> [-2.500000e-01 2.500000e-01)  (auto determined)
%   Accumulator      : s35,32 -> [-4 4)  (auto determined)                      
%   Round Mode       : No rounding                                              
%   Overflow Mode    : No overflow                                              

                                                                               
Numerator:                                                                      
 0.00000762939453125                                                            
 0.0000152587890625                                                             
 0.00002288818359375                                                            
 0.00003814697265625                                                            
 0.0000457763671875                                                             
 0.00005340576171875                                                            
 0.00006103515625                                                               
 0.00005340576171875                                                            
 0.00003814697265625                                                            
 0.00002288818359375                                                            
 0                                                                              
-0.00002288818359375                                                            
-0.00003814697265625                                                            
-0.00003814697265625                                                            
-0.000030517578125                                                              
-0.0000152587890625                                                             
 0.00000762939453125                                                            
 0.000030517578125                                                              
 0.0000457763671875                                                             
 0.0000457763671875                                                             
 0.00003814697265625                                                            
 0.0000152587890625                                                             
-0.0000152587890625                                                             
-0.00003814697265625                                                            
-0.00005340576171875                                                            
-0.00006103515625                                                               
-0.0000457763671875                                                             
-0.0000152587890625                                                             
 0.00002288818359375                                                            
 0.00005340576171875                                                            
 0.0000762939453125                                                             
 0.0000762939453125                                                             
 0.00005340576171875                                                            
 0.00000762939453125                                                            
-0.00003814697265625                                                            
-0.0000762939453125                                                             
-0.00009918212890625                                                            
-0.000091552734375                                                              
-0.00005340576171875                                                            
 0                                                                              
 0.00006103515625                                                               
 0.00009918212890625                                                            
 0.0001220703125                                                                
 0.0001068115234375                                                             
 0.00005340576171875                                                            
-0.0000152587890625                                                             
-0.00008392333984375                                                            
-0.0001373291015625                                                             
-0.000152587890625                                                              
-0.0001220703125                                                                
-0.00005340576171875                                                            
 0.00003814697265625                                                            
 0.0001220703125                                                                
 0.00017547607421875                                                            
 0.00018310546875                                                               
 0.00012969970703125                                                            
 0.00003814697265625                                                            
-0.00006866455078125                                                            
-0.0001678466796875                                                             
-0.00022125244140625                                                            
-0.00020599365234375                                                            
-0.0001373291015625                                                             
-0.0000152587890625                                                             
 0.00011444091796875                                                            
 0.00022125244140625                                                            
 0.00026702880859375                                                            
 0.00023651123046875                                                            
 0.00012969970703125                                                            
-0.00002288818359375                                                            
-0.00017547607421875                                                            
-0.0002899169921875                                                             
-0.0003204345703125                                                             
-0.0002593994140625                                                             
-0.00011444091796875                                                            
 0.00006866455078125                                                            
 0.00025177001953125                                                            
 0.0003662109375                                                                
 0.00037384033203125                                                            
 0.000274658203125                                                              
 0.00008392333984375                                                            
-0.00014495849609375                                                            
-0.000335693359375                                                              
-0.0004425048828125                                                             
-0.00041961669921875                                                            
-0.000274658203125                                                              
-0.000030517578125                                                              
 0.00023651123046875                                                            
 0.0004425048828125                                                             
 0.0005340576171875                                                             
 0.00046539306640625                                                            
 0.00025177001953125                                                            
-0.0000457763671875                                                             
-0.00034332275390625                                                            
-0.00055694580078125                                                            
-0.00061798095703125                                                            
-0.00048828125                                                                  
-0.00020599365234375                                                            
 0.000152587890625                                                              
 0.00048065185546875                                                            
 0.0006866455078125                                                             
 0.00069427490234375                                                            
 0.00049591064453125                                                            
 0.0001373291015625                                                             
-0.00028228759765625                                                            
-0.000640869140625                                                              
-0.000823974609375                                                              
-0.00077056884765625                                                            
-0.0004730224609375                                                             
-0.00002288818359375                                                            
 0.000457763671875                                                              
 0.000823974609375                                                              
 0.0009613037109375                                                             
 0.00081634521484375                                                            
 0.00041961669921875                                                            
-0.0001220703125                                                                
-0.0006561279296875                                                             
-0.00101470947265625                                                            
-0.00109100341796875                                                            
-0.0008392333984375                                                             
-0.0003204345703125                                                             
 0.0003204345703125                                                             
 0.00089263916015625                                                            
 0.001220703125                                                                 
 0.0012054443359375                                                             
 0.00081634521484375                                                            
 0.0001678466796875                                                             
-0.0005645751953125                                                             
-0.00115966796875                                                               
-0.001434326171875                                                              
-0.00128936767578125                                                            
-0.0007476806640625                                                             
 0.00003814697265625                                                            
 0.0008544921875                                                                
 0.0014495849609375                                                             
 0.0016326904296875                                                             
 0.00133514404296875                                                            
 0.00061798095703125                                                            
-0.00031280517578125                                                            
-0.00119781494140625                                                            
-0.00176239013671875                                                            
-0.0018157958984375                                                             
-0.0013275146484375                                                             
-0.00041961669921875                                                            
 0.0006561279296875                                                             
 0.0015869140625                                                                
 0.00208282470703125                                                            
 0.0019683837890625                                                             
 0.00125885009765625                                                            
 0.0001373291015625                                                             
-0.00107574462890625                                                            
-0.00202178955078125                                                            
-0.0023956298828125                                                             
-0.00206756591796875                                                            
-0.0010986328125                                                                
 0.000244140625                                                                 
 0.0015716552734375                                                             
 0.0024871826171875                                                             
 0.00269317626953125                                                            
 0.00209808349609375                                                            
 0.0008392333984375                                                             
-0.00072479248046875                                                            
-0.00214385986328125                                                            
-0.0029754638671875                                                             
-0.00295257568359375                                                            
-0.00203704833984375                                                            
-0.00046539306640625                                                            
 0.00131988525390625                                                            
 0.00278472900390625                                                            
 0.00347900390625                                                               
 0.00315093994140625                                                            
 0.001861572265625                                                              
-0.00005340576171875                                                            
-0.00203704833984375                                                            
-0.00350189208984375                                                            
-0.00397491455078125                                                            
-0.00327301025390625                                                            
-0.0015411376953125                                                             
 0.000732421875                                                                 
 0.00289154052734375                                                            
 0.0042877197265625                                                             
 0.00444793701171875                                                            
 0.00327301025390625                                                            
 0.0010528564453125                                                             
-0.00159454345703125                                                            
-0.00389862060546875                                                            
-0.005126953125                                                                 
-0.00487518310546875                                                            
-0.0031280517578125                                                             
-0.0003509521484375                                                             
 0.002685546875                                                                 
 0.00506591796875                                                               
 0.00603485107421875                                                            
 0.00522613525390625                                                            
 0.0027923583984375                                                             
-0.0006256103515625                                                             
-0.0040435791015625                                                             
-0.0064239501953125                                                             
-0.00699615478515625                                                            
-0.00547027587890625                                                            
-0.002197265625                                                                 
 0.001953125                                                                    
 0.0057525634765625                                                             
 0.00804901123046875                                                            
 0.00803375244140625                                                            
 0.0055694580078125                                                             
 0.00124359130859375                                                            
-0.003753662109375                                                              
-0.00795745849609375                                                            
-0.0100250244140625                                                             
-0.00917816162109375                                                            
-0.00545501708984375                                                            
 0.0002288818359375                                                             
 0.00629425048828125                                                            
 0.01092529296875                                                               
 0.01258087158203125                                                            
 0.0105133056640625                                                             
 0.0050048828125                                                                
-0.0025634765625                                                                
-0.0100860595703125                                                             
-0.01525115966796875                                                            
-0.0162353515625                                                                
-0.01226806640625                                                               
-0.003997802734375                                                              
 0.006561279296875                                                              
 0.01645660400390625                                                            
 0.0225677490234375                                                             
 0.0224456787109375                                                             
 0.01515960693359375                                                            
 0.001739501953125                                                              
-0.01482391357421875                                                            
-0.03006744384765625                                                            
-0.039031982421875                                                              
-0.0374298095703125                                                             
-0.0227508544921875                                                             
 0.00496673583984375                                                            
 0.04282379150390625                                                            
 0.085540771484375                                                              
 0.1263275146484375                                                             
 0.15830230712890625                                                            
 0.1758575439453125                                                             
 0.1758575439453125                                                             
 0.15830230712890625                                                            
 0.1263275146484375                                                             
 0.085540771484375                                                              
 0.04282379150390625                                                            
 0.00496673583984375                                                            
-0.0227508544921875                                                             
-0.0374298095703125                                                             
-0.039031982421875                                                              
-0.03006744384765625                                                            
-0.01482391357421875                                                            
 0.001739501953125                                                              
 0.01515960693359375                                                            
 0.0224456787109375                                                             
 0.0225677490234375                                                             
 0.01645660400390625                                                            
 0.006561279296875                                                              
-0.003997802734375                                                              
-0.01226806640625                                                               
-0.0162353515625                                                                
-0.01525115966796875                                                            
-0.0100860595703125                                                             
-0.0025634765625                                                                
 0.0050048828125                                                                
 0.0105133056640625                                                             
 0.01258087158203125                                                            
 0.01092529296875                                                               
 0.00629425048828125                                                            
 0.0002288818359375                                                             
-0.00545501708984375                                                            
-0.00917816162109375                                                            
-0.0100250244140625                                                             
-0.00795745849609375                                                            
-0.003753662109375                                                              
 0.00124359130859375                                                            
 0.0055694580078125                                                             
 0.00803375244140625                                                            
 0.00804901123046875                                                            
 0.0057525634765625                                                             
 0.001953125                                                                    
-0.002197265625                                                                 
-0.00547027587890625                                                            
-0.00699615478515625                                                            
-0.0064239501953125                                                             
-0.0040435791015625                                                             
-0.0006256103515625                                                             
 0.0027923583984375                                                             
 0.00522613525390625                                                            
 0.00603485107421875                                                            
 0.00506591796875                                                               
 0.002685546875                                                                 
-0.0003509521484375                                                             
-0.0031280517578125                                                             
-0.00487518310546875                                                            
-0.005126953125                                                                 
-0.00389862060546875                                                            
-0.00159454345703125                                                            
 0.0010528564453125                                                             
 0.00327301025390625                                                            
 0.00444793701171875                                                            
 0.0042877197265625                                                             
 0.00289154052734375                                                            
 0.000732421875                                                                 
-0.0015411376953125                                                             
-0.00327301025390625                                                            
-0.00397491455078125                                                            
-0.00350189208984375                                                            
-0.00203704833984375                                                            
-0.00005340576171875                                                            
 0.001861572265625                                                              
 0.00315093994140625                                                            
 0.00347900390625                                                               
 0.00278472900390625                                                            
 0.00131988525390625                                                            
-0.00046539306640625                                                            
-0.00203704833984375                                                            
-0.00295257568359375                                                            
-0.0029754638671875                                                             
-0.00214385986328125                                                            
-0.00072479248046875                                                            
 0.0008392333984375                                                             
 0.00209808349609375                                                            
 0.00269317626953125                                                            
 0.0024871826171875                                                             
 0.0015716552734375                                                             
 0.000244140625                                                                 
-0.0010986328125                                                                
-0.00206756591796875                                                            
-0.0023956298828125                                                             
-0.00202178955078125                                                            
-0.00107574462890625                                                            
 0.0001373291015625                                                             
 0.00125885009765625                                                            
 0.0019683837890625                                                             
 0.00208282470703125                                                            
 0.0015869140625                                                                
 0.0006561279296875                                                             
-0.00041961669921875                                                            
-0.0013275146484375                                                             
-0.0018157958984375                                                             
-0.00176239013671875                                                            
-0.00119781494140625                                                            
-0.00031280517578125                                                            
 0.00061798095703125                                                            
 0.00133514404296875                                                            
 0.0016326904296875                                                             
 0.0014495849609375                                                             
 0.0008544921875                                                                
 0.00003814697265625                                                            
-0.0007476806640625                                                             
-0.00128936767578125                                                            
-0.001434326171875                                                              
-0.00115966796875                                                               
-0.0005645751953125                                                             
 0.0001678466796875                                                             
 0.00081634521484375                                                            
 0.0012054443359375                                                             
 0.001220703125                                                                 
 0.00089263916015625                                                            
 0.0003204345703125                                                             
-0.0003204345703125                                                             
-0.0008392333984375                                                             
-0.00109100341796875                                                            
-0.00101470947265625                                                            
-0.0006561279296875                                                             
-0.0001220703125                                                                
 0.00041961669921875                                                            
 0.00081634521484375                                                            
 0.0009613037109375                                                             
 0.000823974609375                                                              
 0.000457763671875                                                              
-0.00002288818359375                                                            
-0.0004730224609375                                                             
-0.00077056884765625                                                            
-0.000823974609375                                                              
-0.000640869140625                                                              
-0.00028228759765625                                                            
 0.0001373291015625                                                             
 0.00049591064453125                                                            
 0.00069427490234375                                                            
 0.0006866455078125                                                             
 0.00048065185546875                                                            
 0.000152587890625                                                              
-0.00020599365234375                                                            
-0.00048828125                                                                  
-0.00061798095703125                                                            
-0.00055694580078125                                                            
-0.00034332275390625                                                            
-0.0000457763671875                                                             
 0.00025177001953125                                                            
 0.00046539306640625                                                            
 0.0005340576171875                                                             
 0.0004425048828125                                                             
 0.00023651123046875                                                            
-0.000030517578125                                                              
-0.000274658203125                                                              
-0.00041961669921875                                                            
-0.0004425048828125                                                             
-0.000335693359375                                                              
-0.00014495849609375                                                            
 0.00008392333984375                                                            
 0.000274658203125                                                              
 0.00037384033203125                                                            
 0.0003662109375                                                                
 0.00025177001953125                                                            
 0.00006866455078125                                                            
-0.00011444091796875                                                            
-0.0002593994140625                                                             
-0.0003204345703125                                                             
-0.0002899169921875                                                             
-0.00017547607421875                                                            
-0.00002288818359375                                                            
 0.00012969970703125                                                            
 0.00023651123046875                                                            
 0.00026702880859375                                                            
 0.00022125244140625                                                            
 0.00011444091796875                                                            
-0.0000152587890625                                                             
-0.0001373291015625                                                             
-0.00020599365234375                                                            
-0.00022125244140625                                                            
-0.0001678466796875                                                             
-0.00006866455078125                                                            
 0.00003814697265625                                                            
 0.00012969970703125                                                            
 0.00018310546875                                                               
 0.00017547607421875                                                            
 0.0001220703125                                                                
 0.00003814697265625                                                            
-0.00005340576171875                                                            
-0.0001220703125                                                                
-0.000152587890625                                                              
-0.0001373291015625                                                             
-0.00008392333984375                                                            
-0.0000152587890625                                                             
 0.00005340576171875                                                            
 0.0001068115234375                                                             
 0.0001220703125                                                                
 0.00009918212890625                                                            
 0.00006103515625                                                               
 0                                                                              
-0.00005340576171875                                                            
-0.000091552734375                                                              
-0.00009918212890625                                                            
-0.0000762939453125                                                             
-0.00003814697265625                                                            
 0.00000762939453125                                                            
 0.00005340576171875                                                            
 0.0000762939453125                                                             
 0.0000762939453125                                                             
 0.00005340576171875                                                            
 0.00002288818359375                                                            
-0.0000152587890625                                                             
-0.0000457763671875                                                             
-0.00006103515625                                                               
-0.00005340576171875                                                            
-0.00003814697265625                                                            
-0.0000152587890625                                                             
 0.0000152587890625                                                             
 0.00003814697265625                                                            
 0.0000457763671875                                                             
 0.0000457763671875                                                             
 0.000030517578125                                                              
 0.00000762939453125                                                            
-0.0000152587890625                                                             
-0.000030517578125                                                              
-0.00003814697265625                                                            
-0.00003814697265625                                                            
-0.00002288818359375                                                            
 0                                                                              
 0.00002288818359375                                                            
 0.00003814697265625                                                            
 0.00005340576171875                                                            
 0.00006103515625                                                               
 0.00005340576171875                                                            
 0.0000457763671875                                                             
 0.00003814697265625                                                            
 0.00002288818359375                                                            
 0.0000152587890625                                                             
 0.00000762939453125                                                            

                                                                               
cic_4order_27x_dec_200k__comp_480order_5x_dec_200k__64800KSPS.fcf
module cic_comp_dec__ram_coef                            
#(                                        
    parameter RAM_ADDR_WIDTH=8                            
)                                        
(                                        
    input                        clka,            
    input            [RAM_ADDR_WIDTH - 1:0]    addra,            
    input        signed    [17:0]            dina,            
    input                        wea,            
                                        
    input                        clkb,            
    input            [RAM_ADDR_WIDTH - 1:0]    addrb,            
    output    reg    signed    [17:0]            doutb            
);                                        
    ////////////////////////////////////////////////////////////////    
    (* RAM_STYLE="BLOCK" *)                        
    reg    [17:0]    ram_coef    [2**RAM_ADDR_WIDTH - 1:0];            
                                        
    initial                                    
    begin                                    
        ram_coef[0]    = -60;        
        ram_coef[1]    = -11;        
        ram_coef[2]    = 0;        
        ram_coef[3]    = 19;        
        ram_coef[4]    = 42;        
        ram_coef[5]    = 64;        
        ram_coef[6]    = 80;        
        ram_coef[7]    = 83;        
        ram_coef[8]    = 72;        
        ram_coef[9]    = 48;        
        ram_coef[10]    = 16;        
        ram_coef[11]    = -17;        
        ram_coef[12]    = -42;        
        ram_coef[13]    = -53;        
        ram_coef[14]    = -46;        
        ram_coef[15]    = -22;        
        ram_coef[16]    = 12;        
        ram_coef[17]    = 46;        
        ram_coef[18]    = 69;        
        ram_coef[19]    = 74;        
        ram_coef[20]    = 57;        
        ram_coef[21]    = 22;        
        ram_coef[22]    = -23;        
        ram_coef[23]    = -64;        
        ram_coef[24]    = -89;        
        ram_coef[25]    = -90;        
        ram_coef[26]    = -63;        
        ram_coef[27]    = -15;        
        ram_coef[28]    = 42;        
        ram_coef[29]    = 90;        
        ram_coef[30]    = 115;        
        ram_coef[31]    = 107;        
        ram_coef[32]    = 66;        
        ram_coef[33]    = 2;        
        ram_coef[34]    = -67;        
        ram_coef[35]    = -122;        
        ram_coef[36]    = -143;        
        ram_coef[37]    = -123;        
        ram_coef[38]    = -65;        
        ram_coef[39]    = 18;        
        ram_coef[40]    = 101;        
        ram_coef[41]    = 159;        
        ram_coef[42]    = 174;        
        ram_coef[43]    = 137;        
        ram_coef[44]    = 56;        
        ram_coef[45]    = -47;        
        ram_coef[46]    = -143;        
        ram_coef[47]    = -202;        
        ram_coef[48]    = -205;        
        ram_coef[49]    = -145;        
        ram_coef[50]    = -38;        
        ram_coef[51]    = 87;        
        ram_coef[52]    = 194;        
        ram_coef[53]    = 250;        
        ram_coef[54]    = 234;        
        ram_coef[55]    = 146;        
        ram_coef[56]    = 9;        
        ram_coef[57]    = -139;        
        ram_coef[58]    = -255;        
        ram_coef[59]    = -301;        
        ram_coef[60]    = -259;        
        ram_coef[61]    = -137;        
        ram_coef[62]    = 34;        
        ram_coef[63]    = 204;        
        ram_coef[64]    = 323;        
        ram_coef[65]    = 352;        
        ram_coef[66]    = 276;        
        ram_coef[67]    = 113;        
        ram_coef[68]    = -93;        
        ram_coef[69]    = -283;        
        ram_coef[70]    = -399;        
        ram_coef[71]    = -401;        
        ram_coef[72]    = -283;        
        ram_coef[73]    = -73;        
        ram_coef[74]    = 170;        
        ram_coef[75]    = 376;        
        ram_coef[76]    = 479;        
        ram_coef[77]    = 444;        
        ram_coef[78]    = 274;        
        ram_coef[79]    = 12;        
        ram_coef[80]    = -267;        
        ram_coef[81]    = -480;        
        ram_coef[82]    = -561;        
        ram_coef[83]    = -477;        
        ram_coef[84]    = -245;        
        ram_coef[85]    = 72;        
        ram_coef[86]    = 383;        
        ram_coef[87]    = 596;        
        ram_coef[88]    = 640;        
        ram_coef[89]    = 494;        
        ram_coef[90]    = 193;        
        ram_coef[91]    = -181;        
        ram_coef[92]    = -519;        
        ram_coef[93]    = -718;        
        ram_coef[94]    = -711;        
        ram_coef[95]    = -490;        
        ram_coef[96]    = -112;        
        ram_coef[97]    = 318;        
        ram_coef[98]    = 674;        
        ram_coef[99]    = 844;        
        ram_coef[100]    = 769;        
        ram_coef[101]    = 460;        
        ram_coef[102]    = -2;        
        ram_coef[103]    = -485;        
        ram_coef[104]    = -844;        
        ram_coef[105]    = -967;        
        ram_coef[106]    = -806;        
        ram_coef[107]    = -396;        
        ram_coef[108]    = 152;        
        ram_coef[109]    = 679;        
        ram_coef[110]    = 1027;        
        ram_coef[111]    = 1082;        
        ram_coef[112]    = 815;        
        ram_coef[113]    = 292;        
        ram_coef[114]    = -342;        
        ram_coef[115]    = -901;        
        ram_coef[116]    = -1216;        
        ram_coef[117]    = -1179;        
        ram_coef[118]    = -788;        
        ram_coef[119]    = -144;        
        ram_coef[120]    = 572;        
        ram_coef[121]    = 1148;        
        ram_coef[122]    = 1404;        
        ram_coef[123]    = 1251;        
        ram_coef[124]    = 716;        
        ram_coef[125]    = -56;        
        ram_coef[126]    = -845;        
        ram_coef[127]    = -1414;        
        ram_coef[128]    = -1584;        
        ram_coef[129]    = -1287;        
        ram_coef[130]    = -591;        
        ram_coef[131]    = 311;        
        ram_coef[132]    = 1158;        
        ram_coef[133]    = 1694;        
        ram_coef[134]    = 1745;        
        ram_coef[135]    = 1275;        
        ram_coef[136]    = 404;        
        ram_coef[137]    = -625;        
        ram_coef[138]    = -1510;        
        ram_coef[139]    = -1979;        
        ram_coef[140]    = -1875;        
        ram_coef[141]    = -1205;        
        ram_coef[142]    = -146;        
        ram_coef[143]    = 1001;        
        ram_coef[144]    = 1896;        
        ram_coef[145]    = 2260;        
        ram_coef[146]    = 1962;        
        ram_coef[147]    = 1064;        
        ram_coef[148]    = -190;        
        ram_coef[149]    = -1439;        
        ram_coef[150]    = -2309;        
        ram_coef[151]    = -2524;        
        ram_coef[152]    = -1991;        
        ram_coef[153]    = -839;        
        ram_coef[154]    = 612;        
        ram_coef[155]    = 1940;        
        ram_coef[156]    = 2742;        
        ram_coef[157]    = 2756;        
        ram_coef[158]    = 1945;        
        ram_coef[159]    = 517;        
        ram_coef[160]    = -1127;        
        ram_coef[161]    = -2501;        
        ram_coef[162]    = -3185;        
        ram_coef[163]    = -2942;        
        ram_coef[164]    = -1807;        
        ram_coef[165]    = -82;        
        ram_coef[166]    = 1742;        
        ram_coef[167]    = 3121;        
        ram_coef[168]    = 3624;        
        ram_coef[169]    = 3061;        
        ram_coef[170]    = 1556;        
        ram_coef[171]    = -481;        
        ram_coef[172]    = -2464;        
        ram_coef[173]    = -3795;        
        ram_coef[174]    = -4046;        
        ram_coef[175]    = -3093;        
        ram_coef[176]    = -1169;        
        ram_coef[177]    = 1192;        
        ram_coef[178]    = 3303;        
        ram_coef[179]    = 4519;        
        ram_coef[180]    = 4433;        
        ram_coef[181]    = 3011;        
        ram_coef[182]    = 618;        
        ram_coef[183]    = -2074;        
        ram_coef[184]    = -4271;        
        ram_coef[185]    = -5289;        
        ram_coef[186]    = -4766;        
        ram_coef[187]    = -2783;        
        ram_coef[188]    = 136;        
        ram_coef[189]    = 3160;        
        ram_coef[190]    = 5387;        
        ram_coef[191]    = 6106;        
        ram_coef[192]    = 5022;        
        ram_coef[193]    = 2368;        
        ram_coef[194]    = -1143;        
        ram_coef[195]    = -4500;        
        ram_coef[196]    = -6684;        
        ram_coef[197]    = -6972;        
        ram_coef[198]    = -5171;        
        ram_coef[199]    = -1703;        
        ram_coef[200]    = 2485;        
        ram_coef[201]    = 6172;        
        ram_coef[202]    = 8218;        
        ram_coef[203]    = 7902;        
        ram_coef[204]    = 5172;        
        ram_coef[205]    = 694;        
        ram_coef[206]    = -4293;        
        ram_coef[207]    = -8319;        
        ram_coef[208]    = -10098;        
        ram_coef[209]    = -8932;        
        ram_coef[210]    = -4960;        
        ram_coef[211]    = 828;        
        ram_coef[212]    = 6819;        
        ram_coef[213]    = 11212;        
        ram_coef[214]    = 12543;        
        ram_coef[215]    = 10146;        
        ram_coef[216]    = 4418;        
        ram_coef[217]    = -3207;        
        ram_coef[218]    = -10589;        
        ram_coef[219]    = -15456;        
        ram_coef[220]    = -16062;        
        ram_coef[221]    = -11753;        
        ram_coef[222]    = -3278;        
        ram_coef[223]    = 7279;        
        ram_coef[224]    = 16957;        
        ram_coef[225]    = 22671;        
        ram_coef[226]    = 22087;        
        ram_coef[227]    = 14391;        
        ram_coef[228]    = 735;        
        ram_coef[229]    = -15795;        
        ram_coef[230]    = -30713;        
        ram_coef[231]    = -39082;        
        ram_coef[232]    = -36679;        
        ram_coef[233]    = -21091;        
        ram_coef[234]    = 7518;        
        ram_coef[235]    = 46187;        
        ram_coef[236]    = 89553;        
        ram_coef[237]    = 130825;        
        ram_coef[238]    = 163109;        
        ram_coef[239]    = 180812;        
    end                            
                                
    always @(posedge clka)                    
    begin                            
        if(wea)                        
            ram_coef[addra]    <= dina;        
    end                            
    always @(posedge clkb)                    
    begin                            
        doutb    <= ram_coef[addrb];            
    end                            
                                
endmodule    
cic_comp_dec__ram_coef.v
coef = []
with open('cic_comp_dec_iq__coef.txt','rb') as f:
    lines = f.readlines()
    for line in lines:
        line    = line.decode('utf-8')
        line    = line.split()
        coef.append(line[0])

RAM_ADDR_WIDTH=8

file_name="cic_comp_dec__ram_coef.v"
with open(file_name,'wb') as f:
    str_out=                                            \
        "module cic_comp_dec__ram_coef                            \n"+\
        "#(                                        \n"+\
        "    parameter RAM_ADDR_WIDTH=8                            \n"+\
        ")                                        \n"+\
        "(                                        \n";
    str_out=str_out+                                        \
        "    input                        clka,            \n"+\
        "    input            [RAM_ADDR_WIDTH - 1:0]    addra,            \n"+\
        "    input        signed    [17:0]            dina,            \n"+\
        "    input                        wea,            \n"+\
        "                                        \n";
    str_out=str_out+                                        \
        "    input                        clkb,            \n"+\
        "    input            [RAM_ADDR_WIDTH - 1:0]    addrb,            \n"+\
        "    output    reg    signed    [17:0]            doutb            \n"+\
        ");                                        \n"+\
        "    ////////////////////////////////////////////////////////////////    \n"+\
        "    (* RAM_STYLE=\"BLOCK\" *)                        \n"+\
        "    reg    [17:0]    ram_coef    [2**RAM_ADDR_WIDTH - 1:0];            \n"+\
        "                                        \n"+\
        "    initial                                    \n"+\
        "    begin                                    \n"

    ################
    i = 0
    while i < len(coef)/2:
        str_out = str_out +"\t\tram_coef["+ str(i) + "]    = "+coef[i]+";        \n"
        i=i+1
    #######################
    str_out=str_out+                            \
        "    end                            \n";
    str_out=str_out+                            \
        "                                \n"+\
        "    always @(posedge clka)                    \n"+\
        "    begin                            \n"+\
        "        if(wea)                        \n"+\
        "            ram_coef[addra]    <= dina;        \n"+\
        "    end                            \n";
    str_out=str_out+                            \
        "    always @(posedge clkb)                    \n"+\
        "    begin                            \n"+\
        "        doutb    <= ram_coef[addrb];            \n"+\
        "    end                            \n"+\
        "                                \n"+\
        "endmodule    "

    ####################
    f.write(str_out.encode('utf-8'))
cic_comp_dec_iq__ram_coef.py
/*
    --------------------------------
         din_addr
             |>>
    345678901--------------------012
           !!                    |>>
                            dout_addr_f
    --------------------------------
    01234567890123456789012345678901
    --------------------------------
                        din_addr_b
                          <<|
    210----------------------9876543
                             |>>
                        dout_addr_b
    --------------------------------
*/


module fir_ls__din_ctrl__count
#(
    parameter    RAM_ADDR_WIDTH        = 8,
    parameter    DECIMATION_RATIO    = 1
)
(
    input            rst,
    input            clk,
    input            din_latch,
    output    reg        proc_begin
);
    wire    [RAM_ADDR_WIDTH - 1:0]    count_max    = DECIMATION_RATIO - 1;
    reg    [RAM_ADDR_WIDTH - 1:0]    din_count    = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    din_count_next    = 0;

    reg                condition_rst    = 0;
    reg                proc_begin_0    = 0;
    reg                din_latch_last    = 0;
    //reg                din_latch_0    = 0;
    //reg                din_latch_0_last    = 0;

    //always @(negedge clk)
    //begin
        //din_latch_last        <= din_latch;
    //end
    //always @(posedge clk)
    //begin
        //din_latch_0    <= din_latch_last;
    //end

    always @(negedge clk)
    begin
        if(rst)
        begin
            din_count    <= {RAM_ADDR_WIDTH{1'b1}};
            condition_rst    <= 1;
        end
        else
        begin
            if(din_latch)
            begin
                din_count    <= din_count_next;
                condition_rst    <= (din_count_next == count_max);
            end
        end
        din_latch_last    <= din_latch;
    end
    always @(posedge clk)
    begin
        if(condition_rst)
            din_count_next    <= 0;
        else
            din_count_next    <= din_count + 1'b1;
        proc_begin    <= (din_count == 0) && din_latch_last;
    end

endmodule

module fir_ls__din_ctrl__addr
#(
    parameter    RAM_ADDR_WIDTH = 8
)
(
    input                    rst,
    input                    clk,
    input                    din_latch,
    output    reg    [RAM_ADDR_WIDTH - 1:0]    din_addr
);
    /////////////////////////////////////////////////////

    reg    [RAM_ADDR_WIDTH - 1:0]        din_addr_0    = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]        din_addr_0_next    = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]        din_addr_0_last    = 0;
    reg                    rst_last    = 0;
    reg                    din_addr_en    = 0;

    always @(posedge clk)
    begin
        if(rst)
            din_addr_en    <= 1;
        else
            din_addr_en    <= din_latch;
        rst_last    <= rst;
    end
    always @(negedge clk)
    begin
        if(din_addr_en)
        begin
            if(rst_last)
                din_addr_0    <= 0;
            else
                din_addr_0    <= din_addr_0_next;
        end
    end
    always @(posedge clk)
    begin
        din_addr_0_next        <= din_addr_0 + 1'b1;

        din_addr_0_last        <= din_addr_0;
    end
    always @(negedge clk)
    begin
        din_addr    <= din_addr_0_last;
    end
endmodule
module fir_ls__din_ctrl
#(
    parameter    RAM_ADDR_WIDTH        = 8,
    parameter    DECIMATION_RATIO    = 1
)
(
    input                    rst,
    input                    clk,
    input                    din_latch,
    output        [RAM_ADDR_WIDTH - 1:0]    din_addr,
    output                    proc_begin
);
    /////////////////////////////////////////////////////

    fir_ls__din_ctrl__addr
    #(
        .RAM_ADDR_WIDTH    (RAM_ADDR_WIDTH)
    )
    addr_ctrl
    (
        .rst            (rst),
        .clk            (clk),
        .din_latch        (din_latch),
        .din_addr        (din_addr)
    );

    fir_ls__din_ctrl__count
    #(
        .RAM_ADDR_WIDTH        (RAM_ADDR_WIDTH),
        .DECIMATION_RATIO    (DECIMATION_RATIO)
    )
    count_ctrl
    (
        .rst            (rst),
        .clk            (clk),
        .din_latch        (din_latch),
        .proc_begin        (proc_begin)
    );
endmodule
module fir_ls__proc_ctrl
#(
    parameter RAM_ADDR_WIDTH        = 8,
    parameter DECIMATION_RATIO    = 1
)
(
    input                    rst,
    input                    clk,
    input                    proc_begin,
    input        [RAM_ADDR_WIDTH - 1:0]    din_addr,
    input        [RAM_ADDR_WIDTH - 1:0]    half_depth,
    output    reg    [RAM_ADDR_WIDTH - 1:0]    dout_addr_f,
    output    reg    [RAM_ADDR_WIDTH - 1:0]    din_addr_b,
    output    reg    [RAM_ADDR_WIDTH - 1:0]    coef_addr,
    output    reg                din_we_b,
    output    reg    [RAM_ADDR_WIDTH - 1:0]    dout_addr_b,
    output    reg                proc_done,
    output    reg                error_conflicted,    // clock_period * HALF_DEPTH * 2 < din_data_period * DECIMATION_RATIO
    output    reg                error_overflow        // DECIMATION_RATIO + HALF_DEPTH > 2**RAM_ADDR_WIDTH - 1
);
    ////////////////////////////////////////////////////////////

    reg    [RAM_ADDR_WIDTH - 1:0]    coef_addr_0        = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    coef_addr_0_last    = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    coef_addr_0_next    = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    coef_addr_1        = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    coef_addr_1_last    = 0;
    reg                condition_next        = 0;

    reg    [RAM_ADDR_WIDTH - 1:0]    din_end            = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    dout_addr_f_begin    = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    dout_addr_b_begin    = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    din_addr_b_begin    = 0;

    reg    [RAM_ADDR_WIDTH - 1:0]    din_addr_last        = 0;
    reg    [RAM_ADDR_WIDTH - 1:0]    dout_addr_f_last    = 0;

    wire    [RAM_ADDR_WIDTH - 1:0]    addr_max        = half_depth - 1;
    wire    [RAM_ADDR_WIDTH - 1:0]    decimation_ratio    = DECIMATION_RATIO;

    reg                proc_done_0        = 1;
    reg                din_we_b_0    = 0;
    reg                din_we_b_0_last    = 0;
    reg                din_we_b_1    = 0;
    reg                proc_begin_last    = 0;
    reg                proc_begin_0    = 0;
    reg                rst_last    = 0;

    wire    [RAM_ADDR_WIDTH - 1:0]    addr_zero    = 0;
    wire    [RAM_ADDR_WIDTH - 1:0]    addr_full    = -1;

    always @(negedge clk)
    begin
        if(rst)
            error_conflicted        <= 1'b0;
        else
        begin
            if(!proc_done && proc_begin)
                error_conflicted    <= 1'b1;
        end
        proc_begin_last        <= proc_begin;
    end
    always @(posedge clk)
    begin
        if(!error_conflicted)
            proc_begin_0    <= proc_begin_last;
    end

    always @(negedge clk)
    begin
        if(rst)
        begin
            coef_addr_0    <= addr_full;
            condition_next    <= 0;
        end
        else
        begin
            if(proc_begin_0)
            begin
                coef_addr_0    <= 0;
                condition_next    <= 1'b1;
            end
            else
            begin
                coef_addr_0    <= coef_addr_0_next;
                condition_next    <= (coef_addr_0_next < addr_max);
            end
        end

        rst_last    <= rst;
    end
    always @(posedge clk)
    begin
        if(rst_last)
            coef_addr_0_next    <= addr_full;
        else
        begin
            if(condition_next)
                coef_addr_0_next    <= coef_addr_0 + 1'b1;
        end

        coef_addr_0_last    <= coef_addr_0;
        proc_done        <= ~condition_next;
    end

    ////////////////////////////////////////////////////////////////

    always @(negedge clk)
    begin
        if(proc_begin_0)
        begin
            din_end    <= din_addr - decimation_ratio;
        end
        coef_addr_1    <= coef_addr_0_last;
    end

    always @(posedge clk)
    begin
        dout_addr_f_begin    <= din_end - half_depth;
        dout_addr_b_begin    <= addr_zero - din_end;
        din_addr_b_begin    <= addr_zero - din_end;
        coef_addr_1_last    <= coef_addr_1;
        din_we_b_0        <= (coef_addr_1 < DECIMATION_RATIO);
    end

    always @(negedge clk)
    begin
        dout_addr_f        <= dout_addr_f_begin    + coef_addr_1_last;
        dout_addr_b        <= dout_addr_b_begin    + coef_addr_1_last;
        din_addr_b        <= din_addr_b_begin    - coef_addr_1_last;
        coef_addr        <= addr_max        - coef_addr_1_last;
        din_we_b_0_last        <= din_we_b_0;
    end
    always @(posedge clk)
    begin
        din_we_b_1        <= din_we_b_0_last;
        dout_addr_f_last    <= dout_addr_f;
        din_addr_last        <= din_addr;
    end
    always @(negedge clk)
    begin
        din_we_b    <= din_we_b_1;

        if(rst)
            error_overflow    <= 1'b0;
        else
            if(din_addr_last == dout_addr_f_last)
                error_overflow    <= 1'b1;
    end
endmodule

module fir_ls__ram_loop
#(
    parameter RAM_ADDR_WIDTH    = 8,
    parameter DATA_WIDTH    = 36
)
(
    input                    clk,
    input        [DATA_WIDTH - 1:0]    din,
    input                    din_latch,
    input        [RAM_ADDR_WIDTH - 1:0]    din_addr,
    input        [RAM_ADDR_WIDTH - 1:0]    dout_addr_f,
    input        [RAM_ADDR_WIDTH - 1:0]    dout_addr_b,
    input        [RAM_ADDR_WIDTH - 1:0]    din_addr_b,
    input                    din_we_b,
    output    reg    [DATA_WIDTH - 1:0]    ram_out_f,
    output    reg    [DATA_WIDTH - 1:0]    ram_out_b
);
    ////////////////////////////////////////////////////////////////

    reg [DATA_WIDTH - 1:0]        ram_forward [2**RAM_ADDR_WIDTH - 1:0];
    reg [DATA_WIDTH - 1:0]        ram_backword [2**RAM_ADDR_WIDTH - 1:0];

    integer i;
    initial
    begin
        for(i=0;i<2**RAM_ADDR_WIDTH;i=i+1)
        begin
            ram_forward[i]    = 0;
            ram_backword[i]    = 0;
        end
    end

    reg    [DATA_WIDTH - 1:0]    ram_out_f_last    = 0;

    always @(posedge clk)
    begin
        if(din_latch)
            ram_forward[din_addr]    <= din;
        ram_out_f            <= ram_forward[dout_addr_f];
    end
    always @(negedge clk)
    begin
        ram_out_f_last    <= ram_out_f;
    end
    always @(posedge clk)
    begin
        if(din_we_b)
            ram_backword[din_addr_b]    <= ram_out_f_last;
        ram_out_b                <= ram_backword[dout_addr_b];
    end
endmodule

module fir_ls__product_sum__ctrl
(
    input        rst,
    input        clk,
    input        proc_done,
    output    reg    sum_latch,
    output    reg    clr_abd,
    output    reg    clr_p
);
    reg            proc_done_last        = 0;
    reg            proc_done_a        = 0;

    reg            clr_abd_0    = 0;
    reg            clr_abd_0_last    = 0;

    reg            clr_p_0_next    = 0;
    reg            clr_p_0        = 0;
    reg            clr_p_1_next    = 0;
    reg            clr_p_1        = 0;
    reg            clr_p_next    = 0;

    reg            sum_latch_a        = 0;
    reg            sum_latch_a_last    = 0;

    always @(negedge clk)
    begin
        if(rst)
            proc_done_last    <= 1;
        else
            proc_done_last    <= proc_done;
    end
    always @(posedge clk)
    begin
        proc_done_a    <= proc_done_last;
    end
    ////////////////////////////////////////////////////////////////
    always @(negedge clk)
    begin
        clr_abd_0        <= ({proc_done_a,proc_done}==2'b10);
    end
    always @(posedge clk)
    begin
        clr_abd_0_last        <= clr_abd_0;
    end
    always @(negedge clk)
    begin
        clr_abd            <= clr_abd_0_last;
    end
    ///////////////////////////////////////////
    always @(posedge clk)
    begin
        clr_p_0_next        <= clr_abd;
    end
    always @(negedge clk)
    begin
        clr_p_0            <= clr_p_0_next;
    end
    always @(posedge clk)
    begin
        clr_p_1_next        <= clr_p_0;
    end
    always @(negedge clk)
    begin
        clr_p_1            <= clr_p_1_next;
    end
    always @(posedge clk)
    begin
        clr_p_next        <= clr_p_1;
    end
    always @(negedge clk)
    begin
        clr_p            <= clr_p_next;
    end
    ////////////////////////////////////////////////////////////////
    always @(negedge clk)
    begin
        sum_latch_a        <= ({proc_done_a,proc_done}==2'b01);
    end
    always @(posedge clk)
    begin
        sum_latch_a_last    <= sum_latch_a;
    end
    always @(negedge clk)
    begin
        sum_latch        <= sum_latch_a_last;
    end

endmodule
module mul_fir
(
    input                clk,
    input        signed    [17:0]    a,
    input        signed    [17:0]    b,
    input        signed    [17:0]    d,
    output        signed    [47:0]    p,
    input                sclra,
    input                sclrb,
    input                sclrd,
    input                sclrp
);
    // see ug389 Figure 1-3

    wire [7:0] opmode=
    {
        1'd0,//post-add
        1'd0,//pre-add
        1'd0,//Force a value on carry-in to the post-adder,not usefull here
        1'd1,//Use the pre-adder
        2'd2,//Z input to the post-add==Use the POUT port
        2'd1//X input to the post-add== Use the multiplier product
    };
    DSP48A1 #(
        .A0REG(1),                  // First stage A input pipeline register (0/1)
        .A1REG(1),                  // Second stage A input pipeline register (0/1)
        .B0REG(1),                  // First stage B input pipeline register (0/1)
        .B1REG(1),                  // Second stage B input pipeline register (0/1)
        .CARRYINREG(1),            // CARRYIN input pipeline register (0/1)
        .CARRYINSEL("OPMODE5"), // Specify carry-in source, "CARRYIN" or "OPMODE5"
        .CARRYOUTREG(1),          // CARRYOUT output pipeline register (0/1)
        .CREG(1),                    // C input pipeline register (0/1)
        .DREG(1),                    // D pre-adder input pipeline register (0/1)
        .MREG(1),                    // M pipeline register (0/1)
        .OPMODEREG(0),             // Enable=1/disable=0 OPMODE input pipeline registers
        .PREG(1),                    // P output pipeline register (0/1)
        .RSTTYPE("SYNC")          // Specify reset type, "SYNC" or "ASYNC"
    )
    DSP48A1_inst (
        // Cascade Ports: 18-bit (each) output: Ports to cascade from one DSP48 to another
        .BCOUT(),              // 18-bit output: B port cascade output
        .PCOUT(),              // 48-bit output"OPMODE5" : P cascade output (if used, connect to PCIN of another DSP48A1)
        // Data Ports: 1-bit (each) output: Data input and output ports
        .CARRYOUT(),      // 1-bit output: carry output (if used, connect to CARRYIN pin of another
                                         // DSP48A1)

        .CARRYOUTF(),    // 1-bit output: fabric carry output
        .M(),                         // 36-bit output: fabric multiplier data output
        .P(p),                         // 48-bit output: data output
        // Cascade Ports: 48-bit (each) input: Ports to cascade from one DSP48 to another
        .PCIN(48'd0),                 // 48-bit input: P cascade input (if used, connect to PCOUT of another DSP48A1)
        // Control Input Ports: 1-bit (each) input: Clocking and operation mode
        .CLK(clk),                    // 1-bit input: clock input
        .OPMODE(opmode),            // 8-bit input: operation mode input
        // Data Ports: 18-bit (each) input: Data input and output ports
        .A(b),                         // 18-bit input: A data input
        .B(a),                         // 18-bit input: B data input (connected to fabric or BCOUT of adjacent DSP48A1)
        .C(48'd0),                         // 48-bit input: C data input
        .CARRYIN(1'b0),         // 1-bit input: carry input signal (if used, connect to CARRYOUT pin of another
                                         // DSP48A1)

        .D(d),                         // 18-bit input: B pre-adder data input
        // Reset/Clock Enable Input Ports: 1-bit (each) input: Reset and enable input ports
        .CEA(1'b1),                    // 1-bit input: active high clock enable input for A registers
        .CEB(1'b1),                    // 1-bit input: active high clock enable input for B registers
        .CEC(1'b1),                    // 1-bit input: active high clock enable input for C registers
        .CECARRYIN(1'b1),    // 1-bit input: active high clock enable input for CARRYIN registers
        .CED(1'b1),                    // 1-bit input: active high clock enable input for D registers
        .CEM(1'b1),                    // 1-bit input: active high clock enable input for multiplier registers
        .CEOPMODE(1'b1),      // 1-bit input: active high clock enable input for OPMODE registers
        .CEP(1'b1),                    // 1-bit input: active high clock enable input for P registers
        .RSTA(sclrb),                 // 1-bit input: reset input for A pipeline registers
        .RSTB(sclra),                 // 1-bit input: reset input for B pipeline registers
        .RSTC(1'b0),                 // 1-bit input: reset input for C pipeline registers
        .RSTCARRYIN(1'b0), // 1-bit input: reset input for CARRYIN pipeline registers
        .RSTD(sclrd),                 // 1-bit input: reset input for D pipeline registers
        .RSTM(1'b0),                 // 1-bit input: reset input for M pipeline registers
        .RSTOPMODE(1'b0),    // 1-bit input: reset input for OPMODE pipeline registers
        .RSTP(sclrp)                  // 1-bit input: reset input for P pipeline registers
    );
endmodule
module fir_ls_iq__product_sum
#(
    parameter    SUMOUT_MSB = 31
)
(
    input                rst,
    input                clk,
    input                proc_done,
    input        signed    [17:0]    ram_data_f_i,
    input        signed    [17:0]    ram_data_b_i,

    input        signed    [17:0]    ram_data_f_q,
    input        signed    [17:0]    ram_data_b_q,

    input        signed    [17:0]    coef_data,

    output    reg    signed    [17:0]    dout_i,
    output    reg    signed    [17:0]    dout_q,
    output    reg            dout_latch
);
    wire    signed    [47:0]    mul_out_i;
    wire    signed    [47:0]    mul_out_q;

    wire            clr_abd;
    wire            clr_p;

    reg    signed    [17:0]    coef_data_last        = 0;
    reg    signed    [17:0]    ram_data_f_i_last    = 0;
    reg    signed    [17:0]    ram_data_b_i_last    = 0;
    reg    signed    [17:0]    ram_data_f_q_last    = 0;
    reg    signed    [17:0]    ram_data_b_q_last    = 0;

    wire            sum_latch;

    always @(negedge clk)
    begin
        coef_data_last        <= coef_data;
        ram_data_f_i_last    <= ram_data_f_i;
        ram_data_b_i_last    <= ram_data_b_i;
        ram_data_f_q_last    <= ram_data_f_q;
        ram_data_b_q_last    <= ram_data_b_q;
    end

    fir_ls__product_sum__ctrl ctrl
    (
        .rst        (rst),
        .clk        (clk),
        .proc_done    (proc_done),
        .sum_latch    (sum_latch),
        .clr_abd    (clr_abd),
        .clr_p        (clr_p)
    );

    mul_fir mul_i
    (
        .clk    (clk),
        .sclrd    (clr_abd),
        .sclra    (clr_abd),
        .sclrb    (clr_abd),
        .sclrp    (clr_p),
        .a    (ram_data_f_i_last),
        .b    (coef_data_last),
        .d    (ram_data_b_i_last),
        .p    (mul_out_i)
    );
    mul_fir mul_q
    (
        .clk    (clk),
        .sclrd    (clr_abd),
        .sclra    (clr_abd),
        .sclrb    (clr_abd),
        .sclrp    (clr_p),
        .a    (ram_data_f_q_last),
        .b    (coef_data_last),
        .d    (ram_data_b_q_last),
        .p    (mul_out_q)
    );
    always @(negedge clk)
    begin
        if(sum_latch)
        begin
            dout_i    <= mul_out_i[SUMOUT_MSB-:18];
            dout_q    <= mul_out_q[SUMOUT_MSB-:18];
        end
        dout_latch    <= sum_latch;
    end
endmodule
module fir_ls__ram_coef
#(
    parameter RAM_ADDR_WIDTH    = 8
)
(
    input                        clka,
    input            [RAM_ADDR_WIDTH - 1:0]    addra,
    input        signed    [17:0]            dina,
    input                        wea,

    input                        clkb,
    input            [RAM_ADDR_WIDTH - 1:0]    addrb,
    output    reg    signed    [17:0]            doutb
);
    ///////////////////////////////////////////////////////////

    reg    [17:0]    ram_coef    [2**RAM_ADDR_WIDTH - 1:0];

    always @(posedge clka)
    begin
        if(wea)
            ram_coef[addra]    <= dina;
    end
    always @(posedge clkb)
    begin
        doutb    <= ram_coef[addrb];
    end

endmodule
module fir_ls_iq
#(
    parameter RAM_ADDR_WIDTH        = 9,
    parameter DECIMATION_RATIO    = 1,
    parameter HALF_DEPTH        = 500
)
(
    input                        rst,
    input                        clk,
    input                        din_latch,
    input        signed    [17:0]            din_i,
    input        signed    [17:0]            din_q,

    input                        coef_in_clk,
    input                        coef_in_we,
    input            [RAM_ADDR_WIDTH - 1:0]    coef_in_addr,
    input        signed    [17:0]            coef_in_d,

    output        signed    [17:0]            dout_i,
    output        signed    [17:0]            dout_q,
    output                        dout_latch,
    output                        error_conflicted,
    output                        error_overflow
);
    //////////////////////////////////////////////////////////////

    wire            [RAM_ADDR_WIDTH - 1:0]    coef_addr;
    wire            [RAM_ADDR_WIDTH - 1:0]    din_addr;
    wire            [RAM_ADDR_WIDTH - 1:0]    dout_addr_f;
    wire            [RAM_ADDR_WIDTH - 1:0]    din_addr_b;
    wire            [RAM_ADDR_WIDTH - 1:0]    dout_addr_b;
    wire                        din_we_b;
    wire                        proc_begin;
    wire                        proc_done;
    wire            [35:0]            ram_out_f;
    wire            [35:0]            ram_out_b;
    wire        signed    [17:0]            coef_out;

    wire            [RAM_ADDR_WIDTH - 1:0]    half_depth = HALF_DEPTH;

    fir_ls__din_ctrl
    #(
        .RAM_ADDR_WIDTH        (RAM_ADDR_WIDTH),
        .DECIMATION_RATIO    (DECIMATION_RATIO)
    )din_ctrl
    (
        .rst            (rst),
        .clk            (clk),
        .din_latch        (din_latch),
        .din_addr        (din_addr),
        .proc_begin        (proc_begin)
    );
    fir_ls__proc_ctrl
    #(
        .RAM_ADDR_WIDTH        (RAM_ADDR_WIDTH),
        .DECIMATION_RATIO    (DECIMATION_RATIO)
    )proc_ctrl
    (
        .rst            (rst),
        .clk            (clk),
        .din_addr        (din_addr),
        .proc_begin        (proc_begin),
        .half_depth        (half_depth),
        .dout_addr_f        (dout_addr_f),
        .din_addr_b        (din_addr_b),
        .coef_addr        (coef_addr),
        .din_we_b        (din_we_b),
        .dout_addr_b        (dout_addr_b),
        .proc_done        (proc_done),
        .error_conflicted    (error_conflicted),
        .error_overflow        (error_overflow)
    );
    fir_ls__ram_loop
    #(
        .RAM_ADDR_WIDTH(RAM_ADDR_WIDTH)
    )ram_loop
    (
        .clk        (clk),
        .din        ({din_i,din_q}),
        .din_latch    (din_latch),
        .din_addr    (din_addr),
        .dout_addr_f    (dout_addr_f),
        .dout_addr_b    (dout_addr_b),
        .din_addr_b    (din_addr_b),
        .din_we_b    (din_we_b),
        .ram_out_f    (ram_out_f),
        .ram_out_b    (ram_out_b)
    );

    fir_ls__ram_coef
    #(
        .RAM_ADDR_WIDTH    (RAM_ADDR_WIDTH)
    )
    ram_coef
    (
        .clka(coef_in_clk),
        .addra(coef_in_addr),
        .wea(coef_in_we),
        .dina(coef_in_d),
        .clkb(clk),
        .addrb(coef_addr),
        .doutb(coef_out)
    );

    fir_ls_iq__product_sum
    #(
        .SUMOUT_MSB(40)
    )sum
    (
        .rst        (rst),
        .clk        (clk),

        .ram_data_f_i    (ram_out_f[18+:18]),
        .ram_data_b_i    (ram_out_b[18+:18]),

        .ram_data_f_q    (ram_out_f[0+:18]),
        .ram_data_b_q    (ram_out_b[0+:18]),

        .coef_data    (coef_out),

        .proc_done    (proc_done),
        .dout_i        (dout_i),
        .dout_q        (dout_q),
        .dout_latch    (dout_latch)
    );
endmodule
fir_ls_iq.v
#import math
import numpy as np
from scipy import signal
fs=4800
bpass = signal.remez(500, [0, 75, 240, 0.5*fs], [1, 0],fs=fs)
freq, response = signal.freqz(bpass)
ampl = np.abs(response)



print(str(len(bpass)))
print("")
with open('fir_coef_500n_4800k.txt','wb') as f:
    str_out=""
    for x in bpass:
        y=int(x * 65536 * 32)
        str_out=str_out+(str(y))+"\n"
    f.write(str_out.encode('utf-8'))

import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.semilogy(fs*freq/(2*np.pi), ampl, 'b-')  # freq in Hz
plt.show()
fir_coef_remez.py
d = fdesign.lowpass( 'N,Fp,Ap,Ast',479,200e3,0.01,80,2.4e6);
%designopts(d,'equiripple') % List equiripple design options
hd = design(d,'equiripple');
fvtool(hd);

coef=round((2^20)*hd.numerator);
fd=fopen('F:\Projects\sdr\fpga\ise_prj\src\recv\costas_loop\ddc\cic_comp_dec_iq\cic_comp_dec_iq__coef.txt','wt');
fprintf(fd,'%d\n',coef);
fclose(fd);
fir_ddc_dec_iq__design.m
-60
-11
0
19
42
64
80
83
72
48
16
-17
-42
-53
-46
-22
12
46
69
74
57
22
-23
-64
-89
-90
-63
-15
42
90
115
107
66
2
-67
-122
-143
-123
-65
18
101
159
174
137
56
-47
-143
-202
-205
-145
-38
87
194
250
234
146
9
-139
-255
-301
-259
-137
34
204
323
352
276
113
-93
-283
-399
-401
-283
-73
170
376
479
444
274
12
-267
-480
-561
-477
-245
72
383
596
640
494
193
-181
-519
-718
-711
-490
-112
318
674
844
769
460
-2
-485
-844
-967
-806
-396
152
679
1027
1082
815
292
-342
-901
-1216
-1179
-788
-144
572
1148
1404
1251
716
-56
-845
-1414
-1584
-1287
-591
311
1158
1694
1745
1275
404
-625
-1510
-1979
-1875
-1205
-146
1001
1896
2260
1962
1064
-190
-1439
-2309
-2524
-1991
-839
612
1940
2742
2756
1945
517
-1127
-2501
-3185
-2942
-1807
-82
1742
3121
3624
3061
1556
-481
-2464
-3795
-4046
-3093
-1169
1192
3303
4519
4433
3011
618
-2074
-4271
-5289
-4766
-2783
136
3160
5387
6106
5022
2368
-1143
-4500
-6684
-6972
-5171
-1703
2485
6172
8218
7902
5172
694
-4293
-8319
-10098
-8932
-4960
828
6819
11212
12543
10146
4418
-3207
-10589
-15456
-16062
-11753
-3278
7279
16957
22671
22087
14391
735
-15795
-30713
-39082
-36679
-21091
7518
46187
89553
130825
163109
180812
180812
163109
130825
89553
46187
7518
-21091
-36679
-39082
-30713
-15795
735
14391
22087
22671
16957
7279
-3278
-11753
-16062
-15456
-10589
-3207
4418
10146
12543
11212
6819
828
-4960
-8932
-10098
-8319
-4293
694
5172
7902
8218
6172
2485
-1703
-5171
-6972
-6684
-4500
-1143
2368
5022
6106
5387
3160
136
-2783
-4766
-5289
-4271
-2074
618
3011
4433
4519
3303
1192
-1169
-3093
-4046
-3795
-2464
-481
1556
3061
3624
3121
1742
-82
-1807
-2942
-3185
-2501
-1127
517
1945
2756
2742
1940
612
-839
-1991
-2524
-2309
-1439
-190
1064
1962
2260
1896
1001
-146
-1205
-1875
-1979
-1510
-625
404
1275
1745
1694
1158
311
-591
-1287
-1584
-1414
-845
-56
716
1251
1404
1148
572
-144
-788
-1179
-1216
-901
-342
292
815
1082
1027
679
152
-396
-806
-967
-844
-485
-2
460
769
844
674
318
-112
-490
-711
-718
-519
-181
193
494
640
596
383
72
-245
-477
-561
-480
-267
12
274
444
479
376
170
-73
-283
-401
-399
-283
-93
113
276
352
323
204
34
-137
-259
-301
-255
-139
9
146
234
250
194
87
-38
-145
-205
-202
-143
-47
56
137
174
159
101
18
-65
-123
-143
-122
-67
2
66
107
115
90
42
-15
-63
-90
-89
-64
-23
22
57
74
69
46
12
-22
-46
-53
-42
-17
16
48
72
83
80
64
42
19
0
-11
-60
cic_comp_dec_iq__coef.txt

 


 

/*
cos(a) was not multiplied,
the magnitude is 0.5*1.64676025812107 of the real result
*/


/*
                            calc_begin
                                 |
    +<-----------------+<--------+------>+
    |                  |                 |
    |          +<-----step           direction
    |          |      |  |               |
    |      calc_done  |  +<--------------+<-----+
    |                 |                         |
    |                 |(rotate_begin)           |
    |                 |                         |
    |                 +------>+                 |
    |                 |       |                 |
    |               angle   rotate              |
    |                 |     |    |              |
    |                 |     |    |(rotate_done) |
    +---------------->+---->+    +------------->+
*/

module cordic_arctan_and_magnitude
#(
    parameter PORT_D_WIDTH = 18,
    parameter ANGLE_WIDTH = 36,
    parameter STEP_DEPTH = 31,
    parameter DATA_WIDTH = 32,
    parameter STEP_WIDTH = 5
)
(
    input                        rst,
    input                        clk,
    input                        calc_begin,
    output                        error_conflict,
    input        signed    [PORT_D_WIDTH - 1:0]    din_x,
    input        signed    [PORT_D_WIDTH - 1:0]    din_y,
    output    reg    signed    [ANGLE_WIDTH - 1:0]    dout_angle,
    output    reg        [PORT_D_WIDTH - 1:0]    magnitude,
    output    reg                    dout_latch
);
    reg    signed    [ANGLE_WIDTH - 1:0]    angle_start;
    wire    signed    [ANGLE_WIDTH - 1:0]    angle_step;

    reg                    calc_begin_last = 0;
    wire                    rotate_begin;
    wire                    rotate_done;
    wire        [4:0]            rotate_step;
    wire                    direction;
    wire    signed    [DATA_WIDTH - 1:0]    dout_x;
    wire    signed    [DATA_WIDTH - 1:0]    dout_y;
    wire    signed    [PORT_D_WIDTH:0]    magnitude_0;
    reg    signed    [PORT_D_WIDTH:0]    magnitude_1 = 0;
    wire                    dout_latch_step;
    wire        [PORT_D_WIDTH:0]    magnitude_zero = 0;

    always @(negedge clk)
    begin
        calc_begin_last        <= calc_begin;
    end

    always @(*)
    begin
        case ({din_x[PORT_D_WIDTH - 1],din_y[PORT_D_WIDTH - 1]})
            2'b00:angle_start    = 0;
            2'b01:angle_start    = 0;
            2'b10:angle_start    = (1 << (ANGLE_WIDTH - 1));
            2'b11:angle_start    = (1 << (ANGLE_WIDTH - 1));
        endcase
    end
    cordic__step
    #(
        .STEP_WIDTH    (STEP_WIDTH),
        .STEP_DEPTH    (STEP_DEPTH)
    )
    step_ctrl
    (
        .rst        (rst),
        .clk        (clk),
        .calc_begin    (calc_begin_last),
        .error_conflict    (error_conflict),
        .rotate_done    (rotate_done),
        .rotate_begin    (rotate_begin),
        .step        (rotate_step),
        .dout_latch    (dout_latch_step)
    );
    cordic__direction_xy direction_ctrl
    (
        .clk        (clk),
        .calc_begin    (calc_begin_last),
        .rotate_done    (rotate_done),
        .din_x_sign    (din_x[PORT_D_WIDTH - 1]),
        .din_y_sign    (din_y[PORT_D_WIDTH - 1]),
        .dout_x_sign    (dout_x[DATA_WIDTH - 1]),
        .dout_y_sign    (dout_y[DATA_WIDTH - 1]),
        .direction    (direction)
    );
    cordic__angle
    #(
        .ANGLE_WIDTH    (ANGLE_WIDTH)
    )
    angle_ctrl
    (
        .clk        (clk),
        .angle_start    (angle_start),
        .direction    (direction),
        .calc_begin    (calc_begin_last),
        .rotate_begin    (rotate_begin),
        .rotate_step    (rotate_step),
        .dout_angle    (angle_step)
    );
    cordic__rotate
    #(
        .PORT_D_WIDTH    (PORT_D_WIDTH),
        .DATA_WIDTH    (DATA_WIDTH)
    )
    rotate_ctrl
    (
        .clk        (clk),
        .step        (rotate_step),
        .calc_begin    (calc_begin_last),
        .rotate_begin    (rotate_begin),
        .direction    (direction),
        .din_x        (din_x),
        .din_y        (din_y),
        .dout_x        (dout_x),
        .dout_y        (dout_y),
        .rotate_done    (rotate_done)
    );
    assign magnitude_0 = dout_x[(DATA_WIDTH - 1)-:PORT_D_WIDTH + 1];

    always @(*)
    begin
        if(magnitude_0[PORT_D_WIDTH])
            magnitude_1    = magnitude_zero - magnitude_0;
        else
            magnitude_1    = magnitude_0;
    end
    always @(posedge clk)
    begin
        if(dout_latch_step)
        begin
            magnitude    <= magnitude_1[PORT_D_WIDTH - 1:0];
            dout_angle    <= angle_step;
        end
        dout_latch    <= dout_latch_step;
    end
endmodule

module cordic_arctan
#(
    parameter PORT_D_WIDTH = 18,
    parameter ANGLE_WIDTH = 36,
    parameter STEP_DEPTH = 31,
    parameter DATA_WIDTH = 32,
    parameter STEP_WIDTH = 5
)
(
    input                        rst,
    input                        clk,
    input                        calc_begin,
    output                        error_conflict,
    input        signed    [PORT_D_WIDTH - 1:0]    din_x,
    input        signed    [PORT_D_WIDTH - 1:0]    din_y,
    output    reg    signed    [ANGLE_WIDTH - 1:0]    dout_angle,
    output    reg                    dout_latch
);
    reg    signed    [ANGLE_WIDTH - 1:0]    angle_start;
    wire    signed    [ANGLE_WIDTH - 1:0]    angle_step;

    reg                    calc_begin_last = 0;
    wire                    rotate_begin;
    wire                    rotate_done;
    wire        [STEP_WIDTH - 1:0]    rotate_step;
    wire                    direction;
    wire    signed    [DATA_WIDTH - 1:0]    dout_x;
    wire    signed    [DATA_WIDTH - 1:0]    dout_y;
    wire                    dout_latch_step;

    always @(negedge clk)
    begin
        calc_begin_last        <= calc_begin;
    end

    always @(*)
    begin
        case ({din_x[PORT_D_WIDTH - 1],din_y[PORT_D_WIDTH - 1]})
            2'b00:angle_start    = 0;
            2'b01:angle_start    = 0;
            2'b10:angle_start    = (1 << (ANGLE_WIDTH - 1));
            2'b11:angle_start    = (1 << (ANGLE_WIDTH - 1));
        endcase
    end
    cordic__step
    #(
        .STEP_WIDTH    (STEP_WIDTH),
        .STEP_DEPTH    (STEP_DEPTH)
    )
    step_ctrl
    (
        .rst        (rst),
        .clk        (clk),
        .calc_begin    (calc_begin_last),
        .error_conflict    (error_conflict),
        .rotate_done    (rotate_done),
        .rotate_begin    (rotate_begin),
        .step        (rotate_step),
        .dout_latch    (dout_latch_step)
    );
    cordic__direction_xy direction_ctrl
    (
        .clk        (clk),
        .calc_begin    (calc_begin_last),
        .rotate_done    (rotate_done),
        .din_x_sign    (din_x[PORT_D_WIDTH - 1]),
        .din_y_sign    (din_y[PORT_D_WIDTH - 1]),
        .dout_x_sign    (dout_x[DATA_WIDTH - 1]),
        .dout_y_sign    (dout_y[DATA_WIDTH - 1]),
        .direction    (direction)
    );
    cordic__angle
    #(
        .ANGLE_WIDTH    (ANGLE_WIDTH)
    )
    angle_ctrl
    (
        .clk        (clk),
        .angle_start    (angle_start),
        .direction    (direction),
        .calc_begin    (calc_begin_last),
        .rotate_begin    (rotate_begin),
        .rotate_step    (rotate_step),
        .dout_angle    (angle_step)
    );
    cordic__rotate
    #(
        .PORT_D_WIDTH    (PORT_D_WIDTH),
        .DATA_WIDTH    (DATA_WIDTH)
    )
    rotate_ctrl
    (
        .clk        (clk),
        .step        (rotate_step),
        .calc_begin    (calc_begin_last),
        .rotate_begin    (rotate_begin),
        .direction    (direction),
        .din_x        (din_x),
        .din_y        (din_y),
        .dout_x        (dout_x),
        .dout_y        (dout_y),
        .rotate_done    (rotate_done)
    );

    always @(posedge clk)
    begin
        if(rst)
        begin
            dout_angle    <= 0;
        end
        else
        begin
            if(dout_latch_step)
            begin
                dout_angle    <= angle_step;
            end
        end
        dout_latch    <= dout_latch_step;
    end
endmodule

module cordic__direction_xy
(
    input                        clk,
    input                        calc_begin,
    input                        rotate_done,
    input        signed                din_x_sign,
    input        signed                din_y_sign,
    input        signed                dout_x_sign,
    input        signed                dout_y_sign,

    output    reg                    direction
);
    reg        calc_begin_last = 0;
    reg        calc_begin_0 = 0;
    reg        rotate_done_last = 0;
    reg        direction_begin = 0;
    reg        direction_next = 0;
    reg        direction_0 = 0;

    always @(posedge clk)
    begin
        calc_begin_last    <= calc_begin;
        rotate_done_last    <= rotate_done;
    end

    always @(negedge clk)
    begin
        if(calc_begin_last)
        begin
            case({din_x_sign,din_y_sign})
                2'b00:direction <= 0;
                2'b01:direction <= 1;
                2'b10:direction <= 1;
                2'b11:direction <= 0;
            endcase
        end
        else
        begin
            if(rotate_done_last)
            begin
                case({dout_x_sign,dout_y_sign})
                    2'b00:direction <= 0;
                    2'b01:direction <= 1;
                    2'b10:direction <= 1;
                    2'b11:direction <= 0;
                endcase
            end
        end
    end
endmodule
module cordic__step
#(
    parameter STEP_DEPTH = 31,
    parameter STEP_WIDTH = 5
)
(
    input                        rst,
    input                        clk,
    input                        calc_begin,
    output    reg                    error_conflict,
    input                        rotate_done,
    output    reg                    rotate_begin,
    output    reg        [STEP_WIDTH - 1:0]    step,
    output    reg                    dout_latch
);
    reg                condition_next    = 0;
    reg                rotate_done_last    = 0;
    reg                calc_begin_last    = 0;
    reg                calc_on_0    = 0;
    reg                calc_on_0_last    = 0;
    reg                calc_on_1    = 0;
    reg    [STEP_WIDTH - 1:0]    step_next    = 0;

    always @(posedge clk)
    begin
        if(!error_conflict)
            calc_begin_last        <= calc_begin;
    end
    always @(negedge clk)
    begin
        if(rst)
            error_conflict    <= 0;
        else
        begin
            if(calc_begin_last && calc_on_0)
                error_conflict    <= 1'b1;
        end
    end

    always @(negedge clk)
    begin
        if(rst)
        begin
            step            <= 5'h1f;
            condition_next        <= 1'b0;
            rotate_done_last    <= 1'b0;
        end
        else
        begin
            if(calc_begin_last)
            begin
                step            <= 1'b0;
                condition_next        <= 1'b1;
                rotate_done_last    <= 1'b1;
            end
            else
            begin
                if(rotate_done)
                begin
                    step        <= step_next;
                    condition_next    <= (step_next < STEP_DEPTH);
                end
                rotate_done_last    <= rotate_done;
            end
        end
    end
    always @(posedge clk)
    begin
        if(condition_next)
            step_next    <= step + 1'b1;

        if(condition_next)
            rotate_begin    <= rotate_done_last;
        else
            rotate_begin    <= 1'b0;

        calc_on_0    <= condition_next;
    end

    always @(negedge clk)
    begin
        calc_on_0_last    <= calc_on_0;
    end
    always @(posedge clk)
    begin
        calc_on_1    <= calc_on_0_last;
    end
    always @(negedge clk)
    begin
        dout_latch    <= ({calc_on_1,calc_on_0} == 2'b10);
    end

endmodule

module cordic__angle
#(
    parameter ANGLE_WIDTH = 36
)
(
    input                        clk,
    input        signed    [ANGLE_WIDTH - 1:0]    angle_start,
    input                        direction,
    input                        calc_begin,
    input                        rotate_begin,
    input            [4:0]            rotate_step,
    output    reg    signed    [ANGLE_WIDTH - 1:0]    dout_angle
);
    reg    signed    [ANGLE_WIDTH - 1:0]    dout_angle_next    = 0;
    reg        [ANGLE_WIDTH - 3:0]    angle_increase    = 0;
    reg                    rotate_begin_last = 0;
    reg                    calc_begin_last = 0;
    reg                    rotate_begin_0 = 0;
    reg                    direction_last = 0;
    reg                    direction_0 = 0;
    reg                    direction_0_last = 0;
    reg                    dout_angle_en = 0;
    reg                    calc_begin_0= 0;
    wire        [ANGLE_WIDTH - 3:0]    rom_out_angle;

    always @(negedge clk)
    begin
        rotate_begin_last    <= rotate_begin;
    end

    rom_angle_arctan_2n
    #(.ANGLE_WIDTH    (ANGLE_WIDTH))
    rom_angle
    (
        .step        (rotate_step),
        .angle        (rom_out_angle)
    );

    always @(posedge clk)
    begin
        angle_increase        <= rom_out_angle;
        direction_last        <= direction;
        calc_begin_last        <= calc_begin;
        rotate_begin_0        <= rotate_begin_last;
    end

    always @(negedge clk)
    begin
        if(direction_last)
            dout_angle_next        <= dout_angle - angle_increase;
        else
            dout_angle_next        <= dout_angle + angle_increase;

        calc_begin_0            <= calc_begin_last;

        if(calc_begin_last)
            dout_angle_en    <= 1'b1;
        else
            dout_angle_en    <= rotate_begin_0;
    end

    always @(posedge clk)
    begin
        if(dout_angle_en)
        begin
            if(calc_begin_0)
                dout_angle    <= angle_start;
            else
                dout_angle    <= dout_angle_next;
        end
    end
endmodule

module cordic__rotate
#(
    parameter PORT_D_WIDTH = 18,
    parameter DATA_WIDTH = 32
)
(
    input                        clk,
    input            [4:0]            step,
    input                        calc_begin,
    input                        rotate_begin,
    input                        direction,
    input        signed    [PORT_D_WIDTH - 1:0]    din_x,
    input        signed    [PORT_D_WIDTH - 1:0]    din_y,
    output    reg    signed    [DATA_WIDTH - 1:0]    dout_x,
    output    reg    signed    [DATA_WIDTH - 1:0]    dout_y,
    output    reg                    rotate_done
);
    reg    signed    [DATA_WIDTH - 1:0]    x_p    = 0;
    reg    signed    [DATA_WIDTH - 1:0]    y_p    = 0;
    wire    signed    [DATA_WIDTH - 1:0]    x_p_tana;
    wire    signed    [DATA_WIDTH - 1:0]    y_p_tana;
    wire                    shift_done;
    reg                    rotate_done_0 = 0;
    reg                    calc_begin_last = 0;
    reg                    p_en = 0;

    wire        [DATA_WIDTH - PORT_D_WIDTH - 3:0]    zero_right = 0;

    always @(posedge clk)
    begin
        calc_begin_last    <= calc_begin;

        if(calc_begin)
            p_en    <= 1'b1;
        else
            p_en    <= shift_done;
    end

    always @(negedge clk)
    begin
        if(p_en)
        begin
            if(calc_begin_last)
            begin    // manually right shift to avoid overflow
                x_p    <= {din_x[PORT_D_WIDTH - 1],din_x[PORT_D_WIDTH - 1],din_x[PORT_D_WIDTH - 1:0],zero_right};
                y_p    <= {din_y[PORT_D_WIDTH - 1],din_y[PORT_D_WIDTH - 1],din_y[PORT_D_WIDTH - 1:0],zero_right};
            end
            else
            begin
                x_p    <= dout_x;
                y_p    <= dout_y;
            end
        end
    end

    cordic__tan_shift tan_shift
    (
        .start    (rotate_begin),
        .clk    (clk),
        .din_x    (x_p),
        .din_y    (y_p),
        .shift    (step),
        .dout_x    (x_p_tana),
        .dout_y    (y_p_tana),
        .done    (shift_done)
    );

    always @(posedge clk)
    begin
        if(shift_done)
        begin
            if(direction)
            begin
                dout_x    <= x_p - y_p_tana;
                dout_y    <= y_p + x_p_tana;
            end
            else
            begin
                dout_x    <= x_p + y_p_tana;
                dout_y    <= y_p - x_p_tana;
            end
        end

        rotate_done_0    <= shift_done;
    end
    always @(negedge clk)
    begin
        rotate_done    <= rotate_done_0;
    end
endmodule

module cordic__tan_shift
#(
    parameter DATA_WIDTH = 32
)
(
    input                        start,
    input                        clk,
    input        signed    [DATA_WIDTH - 1:0]    din_x,
    input        signed    [DATA_WIDTH - 1:0]    din_y,
    input            [4:0]            shift,
    output    reg    signed    [DATA_WIDTH - 1:0]    dout_x,
    output    reg    signed    [DATA_WIDTH - 1:0]    dout_y,
    output    reg                    done
);
    reg    signed    [DATA_WIDTH - 1:0]    x_p_4 = 0;
    reg    signed    [DATA_WIDTH - 1:0]    y_p_4 = 0;

    reg    signed    [DATA_WIDTH - 1:0]    x_p_2 = 0;
    reg    signed    [DATA_WIDTH - 1:0]    y_p_2 = 0;

    reg    signed    [DATA_WIDTH - 1:0]    x_p_0 = 0;
    reg    signed    [DATA_WIDTH - 1:0]    y_p_0 = 0;

    always @(*)
    begin
        //case(shift[5:4])
        case(shift[4])
            0:
            begin
                x_p_4    = din_x;
                y_p_4    = din_y;
            end
            1:
            begin
                x_p_4    = din_x >>> 16;
                y_p_4    = din_y >>> 16;
            end
            //2:
            //begin
                //x_p_4    = din_x >>> 32;
                //y_p_4    = din_y >>> 32;
            //end
            //3:
            //begin
                //x_p_4    = din_x >>> 48;
                //y_p_4    = din_y >>> 48;
            //end
        endcase
        case(shift[3:2])
            0:
            begin
                x_p_2    = x_p_4;
                y_p_2    = y_p_4;
            end
            1:
            begin
                x_p_2    = x_p_4 >>> 4;
                y_p_2    = y_p_4 >>> 4;
            end
            2:
            begin
                x_p_2    = x_p_4 >>> 8;
                y_p_2    = y_p_4 >>> 8;
            end
            3:
            begin
                x_p_2    = x_p_4 >>> 12;
                y_p_2    = y_p_4 >>> 12;
            end
        endcase
        case(shift[1:0])
            0:
            begin
                x_p_0    = x_p_2;
                y_p_0    = y_p_2;
            end
            1:
            begin
                x_p_0    = x_p_2 >>> 1;
                y_p_0    = y_p_2 >>> 1;
            end
            2:
            begin
                x_p_0    = x_p_2 >>> 2;
                y_p_0    = y_p_2 >>> 2;
            end
            3:
            begin
                x_p_0    = x_p_2 >>> 3;
                y_p_0    = y_p_2 >>> 3;
            end
        endcase
    end
    always @(negedge clk)
    begin
        if(start)
        begin
            dout_x    <= x_p_0;
            dout_y    <= y_p_0;
        end
        done        <= start;
    end
endmodule
cordic_arctan.v
import math
step_width=5
step_depth=math.pow(2,step_width)
phase_width=36

file_name="rom_angle_arctan_2n.v"
with open(file_name,'wb') as f:
    str_out=                                            \
        "module rom_angle_arctan_2n                            \n"+\
        "#(                                        \n"+\
        "    parameter ANGLE_WIDTH = 32                        \n"+\
        ")                                        \n"+\
        "(                                        \n"+\
        "    input            ["+str(step_width-1)+":0]\t\t    step,        \n"+\
        "    output    reg        [ANGLE_WIDTH - 3:0]    "+    "angle        \n"+\
        ");                                        \n"+\
        "    ////////////////////////////////////////////////////////////////    \n"+\
        "    always @(*)                                \n"+\
        "    begin                                    \n"+\
        "        case(step)                            \n"
    ################
    i = 0
    while i < step_depth:
        var_tan=math.pow(2,0-i)
        var_atan=math.atan(var_tan)
        var_angle=math.degrees(var_atan)
        var_phase=var_angle*math.pow(2,phase_width - 2)/90
        if(var_phase - int(var_phase) < 0.5):
            var_phase_int=int(var_phase)
        else:
            var_phase_int=int(var_phase+1)
        var_phase_hex=hex(var_phase_int)
        var_phase_hex=str(phase_width)+"'h"+var_phase_hex[2:]
        str_out=str_out+"\t\t\t"+str(i)+":\tangle = "+var_phase_hex+" >> ("+str(phase_width)+" - ANGLE_WIDTH);\t// "+str(var_phase_int)+"\t\t"+str(var_phase)+"\t"+str(var_angle)+"\n"
        i=i+1
    #######################
    str_out=str_out+                \
        "        endcase        \n"+    \
        "    end            \n"+    \
        "endmodule"
    ####################
    f.write(str_out.encode('utf-8'))
rom_angle_arctan_2n.py
module rom_angle_arctan_2n                            
#(                                        
    parameter ANGLE_WIDTH = 32                        
)                                        
(                                        
    input            [4:0]            step,        
    output    reg        [ANGLE_WIDTH - 3:0]    angle        
);                                        
    ////////////////////////////////////////////////////////////////    
    always @(*)                                
    begin                                    
        case(step)                            
            0:    angle = 36'h200000000 >> (36 - ANGLE_WIDTH);    // 8589934592        8589934592.0    45.0
            1:    angle = 36'h12e4051da >> (36 - ANGLE_WIDTH);    // 5070934490        5070934489.871835    26.56505117707799
            2:    angle = 36'h9fb385b6 >> (36 - ANGLE_WIDTH);    // 2679342518        2679342517.930571    14.036243467926479
            3:    angle = 36'h51111d42 >> (36 - ANGLE_WIDTH);    // 1360076098        1360076097.8666022    7.125016348901798
            4:    angle = 36'h28b0d431 >> (36 - ANGLE_WIDTH);    // 682677297        682677296.8966321    3.576334374997351
            5:    angle = 36'h145d7e16 >> (36 - ANGLE_WIDTH);    // 341671446        341671445.5635705    1.7899106082460694
            6:    angle = 36'ha2f61e6 >> (36 - ANGLE_WIDTH);    // 170877414        170877413.75980204    0.8951737102110744
            7:    angle = 36'h517c551 >> (36 - ANGLE_WIDTH);    // 85443921        85443921.11432141    0.4476141708605531
            8:    angle = 36'h28be534 >> (36 - ANGLE_WIDTH);    // 42722612        42722612.425967425    0.22381050036853808
            9:    angle = 36'h145f2ec >> (36 - ANGLE_WIDTH);    // 21361388        21361387.699382037    0.1119056770662069
            10:    angle = 36'ha2f980 >> (36 - ANGLE_WIDTH);    // 10680704        10680704.035578234    0.055952891893803675
            11:    angle = 36'h517cc1 >> (36 - ANGLE_WIDTH);    // 5340353        5340353.291027751    0.027976452617003676
            12:    angle = 36'h28be61 >> (36 - ANGLE_WIDTH);    // 2670177        2670176.8046687907    0.013988227142265016
            13:    angle = 36'h145f30 >> (36 - ANGLE_WIDTH);    // 1335088        1335088.4222287622    0.006994113675352919
            14:    angle = 36'ha2f98 >> (36 - ANGLE_WIDTH);    // 667544        667544.213601177    0.003497056850704011
            15:    angle = 36'h517cc >> (36 - ANGLE_WIDTH);    // 333772        333772.107111438    0.0017485284269804495
            16:    angle = 36'h28be6 >> (36 - ANGLE_WIDTH);    // 166886        166886.05359457518    0.0008742642136937803
            17:    angle = 36'h145f3 >> (36 - ANGLE_WIDTH);    // 83443        83443.02680214461    0.00043713210687233457
            18:    angle = 36'ha2fa >> (36 - ANGLE_WIDTH);    // 41722        41721.51340167943    0.00021856605343934784
            19:    angle = 36'h517d >> (36 - ANGLE_WIDTH);    // 20861        20860.75670091561    0.00010928302672007149
            20:    angle = 36'h28be >> (36 - ANGLE_WIDTH);    // 10430        10430.37835046729    5.464151336008544e-05
            21:    angle = 36'h145f >> (36 - ANGLE_WIDTH);    // 5215        5215.189175234831    2.7320756680048934e-05
            22:    angle = 36'ha30 >> (36 - ANGLE_WIDTH);    // 2608        2607.594587617564    1.3660378340025243e-05
            23:    angle = 36'h518 >> (36 - ANGLE_WIDTH);    // 1304        1303.7972938088005    6.830189170012719e-06
            24:    angle = 36'h28c >> (36 - ANGLE_WIDTH);    // 652        651.8986469044025    3.4150945850063712e-06
            25:    angle = 36'h146 >> (36 - ANGLE_WIDTH);    // 326        325.94932345220155    1.7075472925031871e-06
            26:    angle = 36'ha3 >> (36 - ANGLE_WIDTH);    // 163        162.9746617261008    8.537736462515938e-07
            27:    angle = 36'h51 >> (36 - ANGLE_WIDTH);    // 81        81.48733086305042    4.2688682312579694e-07
            28:    angle = 36'h29 >> (36 - ANGLE_WIDTH);    // 41        40.74366543152521    2.1344341156289847e-07
            29:    angle = 36'h14 >> (36 - ANGLE_WIDTH);    // 20        20.371832715762604    1.0672170578144923e-07
            30:    angle = 36'ha >> (36 - ANGLE_WIDTH);    // 10        10.185916357881302    5.336085289072462e-08
            31:    angle = 36'h5 >> (36 - ANGLE_WIDTH);    // 5        5.092958178940651    2.668042644536231e-08
        endcase        
    end            
endmodule
rom_angle_arctan_2n.v

 


 

posted on 2024-07-14 09:34  jacob1934  阅读(35)  评论(0)    收藏  举报

导航