【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

/* | | | | | | | | | | | | 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

`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

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

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'))

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

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'))

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

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

% 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

% 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

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

% 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);

% 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

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

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'))

/* -------------------------------- 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

#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()

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);

-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

/* 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

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'))

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