ad_dds: Fix synthesis updates

- remove reset logic
- add wait for dac valid logic
- rewrite sine concatenation on wires for different path width to
suppress warnings
- use computed atan LUT tables
main
AndreiGrozav 2018-06-27 15:08:21 +01:00 committed by AndreiGrozav
parent 892febe68a
commit 79003c53db
3 changed files with 300 additions and 122 deletions

View File

@ -50,14 +50,15 @@ module ad_dds #(
// range 8-24 (make sure CORDIC_PHASE_DW < CORDIC_DW)
parameter CORDIC_PHASE_DW = 16,
// the clock radtio between the device clock(sample rate) and the dac_core clock
// 2^N, 1<N<6
parameter CLK_RATIO = 1) (
// interface
input clk,
input rst,
input dac_dds_format,
input dac_data_sync,
input dac_valid,
input [ 15:0] tone_1_scale,
input [ 15:0] tone_2_scale,
input [ 15:0] tone_1_init_offset,
@ -67,56 +68,46 @@ module ad_dds #(
output reg [DDS_DW*CLK_RATIO-1:0] dac_dds_data
);
// internal registers
wire [DDS_DW*CLK_RATIO-1:0] dac_dds_data_s;
reg [PHASE_DW-1:0] dac_dds_incr_0 = 'd0;
reg [PHASE_DW-1:0] dac_dds_incr_1 = 'd0;
// dds solution
always @(posedge clk) begin
dac_dds_data <= dac_dds_data_s;
end
genvar i;
generate
if (DISABLE == 1) begin
always @(posedge clk) begin
dac_dds_data <= {(DDS_DW*CLK_RATIO-1){1'b0}};
end
assign dac_dds_data_s = {(DDS_DW*CLK_RATIO-1){1'b0}};
end else begin
// enable dds
reg [PHASE_DW-1:0] dac_dds_phase_0[1:CLK_RATIO];
reg [PHASE_DW-1:0] dac_dds_phase_1[1:CLK_RATIO];
wire [ DDS_DW-1:0] dac_dds_data_s[1:CLK_RATIO];
reg [PHASE_DW-1:0] dac_dds_incr_0 = 'd0;
reg [PHASE_DW-1:0] dac_dds_incr_1 = 'd0;
always @(posedge clk) begin
dac_dds_incr_0 <= tone_1_freq_word * CLK_RATIO;
dac_dds_incr_1 <= tone_2_freq_word * CLK_RATIO;
end
// phase accumulator
for (i=1; i <= CLK_RATIO; i=i+1) begin: dds_phase
always @(posedge clk) begin
if (dac_data_sync == 1'b1) begin
dac_dds_data[DDS_DW*i-1:DDS_DW*(i-1)] <= {(DDS_DW-1){1'b0}};
end else begin
dac_dds_data[DDS_DW*i-1:DDS_DW*(i-1)] <= dac_dds_data_s[i];
end
end
// phase accumulator
always @(posedge clk) begin
// phase incrementaion accross 2^N (0<N<5) phase clock ratio
dac_dds_incr_0 <= tone_1_freq_word * CLK_RATIO;
dac_dds_incr_1 <= tone_2_freq_word * CLK_RATIO;
if (dac_data_sync == 1'b1) begin
if (i == 1) begin
dac_dds_phase_0[1] <= tone_1_init_offset;
dac_dds_phase_1[1] <= tone_2_init_offset;
end else begin
dac_dds_phase_0[i] <= dac_dds_phase_0[i-1] + tone_1_freq_word;
dac_dds_phase_1[i] <= dac_dds_phase_1[i-1] + tone_2_freq_word;
end
end else begin
dac_dds_phase_0[i] <= dac_dds_phase_0[i] + dac_dds_incr_0;
dac_dds_phase_1[i] <= dac_dds_phase_1[i] + dac_dds_incr_1;
if (dac_data_sync == 1'b1) begin
if (i == 1) begin
dac_dds_phase_0[1] <= tone_1_init_offset;
dac_dds_phase_1[1] <= tone_2_init_offset;
end else if (CLK_RATIO > 1)begin
dac_dds_phase_0[i] <= dac_dds_phase_0[i-1] + tone_1_freq_word;
dac_dds_phase_1[i] <= dac_dds_phase_1[i-1] + tone_2_freq_word;
end
end else if (dac_valid == 1'b1) begin
dac_dds_phase_0[i] <= dac_dds_phase_0[i] + dac_dds_incr_0;
dac_dds_phase_1[i] <= dac_dds_phase_1[i] + dac_dds_incr_1;
end
end
// phase to amplitude convertor
@ -133,9 +124,7 @@ module ad_dds #(
.dds_scale_0 (tone_1_scale),
.dds_phase_1 (dac_dds_phase_1[i]),
.dds_scale_1 (tone_2_scale),
.dds_data (dac_dds_data_s[i])
);
.dds_data (dac_dds_data_s[(DDS_DW*i)-1:DDS_DW*(i-1)]));
end
end
endgenerate

View File

@ -37,8 +37,6 @@
module ad_dds_2 #(
// Disable DDS
parameter DISABLE = 0,
// Range = 8-24
parameter DDS_DW = 16,
// Range = 8-24

View File

@ -54,36 +54,9 @@ module ad_dds_sine_cordic #(
output reg [ DELAY_DW-1:0] ddata_out);
// Local Parameters
// angle rotation values
localparam LUT_FSCALE = 1 << (PHASE_DW);
localparam ANGLE_ROT_VAL_0 = 45.000000000000000;
localparam ANGLE_ROT_VAL_1 = 26.565051177078000;
localparam ANGLE_ROT_VAL_2 = 14.036243467926500;
localparam ANGLE_ROT_VAL_3 = 7.1250163489018000;
localparam ANGLE_ROT_VAL_4 = 3.5763343749973500;
localparam ANGLE_ROT_VAL_5 = 1.7899106082460700;
localparam ANGLE_ROT_VAL_6 = 0.8951737102110740;
localparam ANGLE_ROT_VAL_7 = 0.4476141708605530;
localparam ANGLE_ROT_VAL_8 = 0.2238105003685380;
localparam ANGLE_ROT_VAL_9 = 0.1119056770662070;
localparam ANGLE_ROT_VAL_10 = 0.0559528918938037;
localparam ANGLE_ROT_VAL_11 = 0.0279764526170037;
localparam ANGLE_ROT_VAL_12 = 0.0139882271422650;
localparam ANGLE_ROT_VAL_13 = 0.0069941136753529;
localparam ANGLE_ROT_VAL_14 = 0.0034970568507040;
localparam ANGLE_ROT_VAL_15 = 0.0017485284269805;
localparam ANGLE_ROT_VAL_16 = 0.0008742642136938;
localparam ANGLE_ROT_VAL_17 = 0.0004371321068723;
localparam ANGLE_ROT_VAL_18 = 0.0002185660534393;
localparam ANGLE_ROT_VAL_19 = 0.0001092830267201;
localparam ANGLE_ROT_VAL_20 = 0.0000546415133601;
localparam ANGLE_ROT_VAL_21 = 0.0000273207566800;
localparam ANGLE_ROT_VAL_22 = 0.0000136603783400;
localparam ANGLE_ROT_VAL_23 = 0.0000068301891700;
// 1.64676025812 =~ system gain
localparam X_FSCALE = 1 << (CORDIC_DW);
localparam APROX_DW_GAIN_ERR = (CORDIC_DW < 21) ? 4 :
(CORDIC_DW <= 24) ? 7 : 0;
@ -106,62 +79,280 @@ module ad_dds_sine_cordic #(
wire [ 1:0] quadrant;
// arc tangent LUT
generate
assign atan_table[0 ] = (LUT_FSCALE * ANGLE_ROT_VAL_0 )/360;
assign atan_table[1 ] = (LUT_FSCALE * ANGLE_ROT_VAL_1 )/360;
assign atan_table[2 ] = (LUT_FSCALE * ANGLE_ROT_VAL_2 )/360;
assign atan_table[3 ] = (LUT_FSCALE * ANGLE_ROT_VAL_3 )/360;
assign atan_table[4 ] = (LUT_FSCALE * ANGLE_ROT_VAL_4 )/360;
assign atan_table[5 ] = (LUT_FSCALE * ANGLE_ROT_VAL_5 )/360;
assign atan_table[6 ] = (LUT_FSCALE * ANGLE_ROT_VAL_6 )/360;
assign atan_table[7 ] = (LUT_FSCALE * ANGLE_ROT_VAL_7 )/360;
if (PHASE_DW >= 9) begin
assign atan_table[8 ] = (LUT_FSCALE * ANGLE_ROT_VAL_8 )/360;
end
if (PHASE_DW >= 10) begin
assign atan_table[9 ] = (LUT_FSCALE * ANGLE_ROT_VAL_9 )/360;
end
if (PHASE_DW >= 11) begin
assign atan_table[10] = (LUT_FSCALE * ANGLE_ROT_VAL_10)/360;
end
if (PHASE_DW >= 12) begin
assign atan_table[11] = (LUT_FSCALE * ANGLE_ROT_VAL_11)/360;
end
if (PHASE_DW >= 13) begin
assign atan_table[12] = (LUT_FSCALE * ANGLE_ROT_VAL_12)/360;
end
if (PHASE_DW >= 14) begin
assign atan_table[13] = (LUT_FSCALE * ANGLE_ROT_VAL_13)/360;
end
if (PHASE_DW >= 15) begin
assign atan_table[14] = (LUT_FSCALE * ANGLE_ROT_VAL_14)/360;
end
if (PHASE_DW >= 16) begin
assign atan_table[15] = (LUT_FSCALE * ANGLE_ROT_VAL_15)/360;
end
if (PHASE_DW >= 17) begin
assign atan_table[16] = (LUT_FSCALE * ANGLE_ROT_VAL_16)/360;
end
if (PHASE_DW >= 18) begin
assign atan_table[17] = (LUT_FSCALE * ANGLE_ROT_VAL_17)/360;
end
if (PHASE_DW >= 19) begin
assign atan_table[18] = (LUT_FSCALE * ANGLE_ROT_VAL_18)/360;
end
if (PHASE_DW >= 20) begin
assign atan_table[19] = (LUT_FSCALE * ANGLE_ROT_VAL_19)/360;
end
if (PHASE_DW >= 21) begin
assign atan_table[20] = (LUT_FSCALE * ANGLE_ROT_VAL_20)/360;
end
if (PHASE_DW >= 22) begin
assign atan_table[21] = (LUT_FSCALE * ANGLE_ROT_VAL_21)/360;
end
if (PHASE_DW >= 23) begin
assign atan_table[22] = (LUT_FSCALE * ANGLE_ROT_VAL_22)/360;
end
if (PHASE_DW == 24) begin
assign atan_table[23] = (LUT_FSCALE * ANGLE_ROT_VAL_23)/360;
assign atan_table[ 0] = 24'd2097152; // 45.0000000000000
assign atan_table[ 1] = 24'd1238021; // 26.5650511770780
assign atan_table[ 2] = 24'd654136; // 14.0362434679265
assign atan_table[ 3] = 24'd332050; // 7.12501634890180
assign atan_table[ 4] = 24'd166669; // 3.57633437499735
assign atan_table[ 5] = 24'd83416; // 1.78991060824607
assign atan_table[ 6] = 24'd41718; // 0.89517371021107
assign atan_table[ 7] = 24'd20860; // 0.44761417086055
assign atan_table[ 8] = 24'd10430; // 0.22381050036853
assign atan_table[ 9] = 24'd5215; // 0.11190567706620
assign atan_table[10] = 24'd2608; // 0.05595289189380
assign atan_table[11] = 24'd1304; // 0.02797645261700
assign atan_table[12] = 24'd652; // 0.01398822714226
assign atan_table[13] = 24'd326; // 0.00699411367535
assign atan_table[14] = 24'd163; // 0.00349705685070
assign atan_table[15] = 24'd81; // 0.00174852842698
assign atan_table[16] = 24'd41; // 0.00087426421369
assign atan_table[17] = 24'd20; // 0.00043713210687
assign atan_table[18] = 24'd10; // 0.00021856605343
assign atan_table[19] = 24'd5; // 0.00010928302672
assign atan_table[20] = 24'd3; // 0.00005464151336
assign atan_table[21] = 24'd1; // 0.00002732075668
assign atan_table[22] = 24'd1; // 0.00001366037834
end else if (PHASE_DW == 23) begin
assign atan_table[ 0] = 23'd1048576; // 45.0000000000000
assign atan_table[ 1] = 23'd619011; // 26.5650511770780
assign atan_table[ 2] = 23'd327068; // 14.0362434679265
assign atan_table[ 3] = 23'd166025; // 7.12501634890180
assign atan_table[ 4] = 23'd83335; // 3.57633437499735
assign atan_table[ 5] = 23'd41708; // 1.78991060824607
assign atan_table[ 6] = 23'd20859; // 0.89517371021107
assign atan_table[ 7] = 23'd10430; // 0.44761417086055
assign atan_table[ 8] = 23'd5215; // 0.22381050036853
assign atan_table[ 9] = 23'd2608; // 0.11190567706620
assign atan_table[10] = 23'd1304; // 0.05595289189380
assign atan_table[11] = 23'd652; // 0.02797645261700
assign atan_table[12] = 23'd326; // 0.01398822714226
assign atan_table[13] = 23'd163; // 0.00699411367535
assign atan_table[14] = 23'd81; // 0.00349705685070
assign atan_table[15] = 23'd41; // 0.00174852842698
assign atan_table[16] = 23'd20; // 0.00087426421369
assign atan_table[17] = 23'd10; // 0.00043713210687
assign atan_table[18] = 23'd5; // 0.00021856605343
assign atan_table[19] = 23'd3; // 0.00010928302672
assign atan_table[20] = 23'd1; // 0.00005464151336
assign atan_table[21] = 23'd1; // 0.00002732075668
end else if (PHASE_DW == 22) begin
assign atan_table[ 0] = 22'd524288; // ...
assign atan_table[ 1] = 22'd309505;
assign atan_table[ 2] = 22'd163534;
assign atan_table[ 3] = 22'd83012;
assign atan_table[ 4] = 22'd41667;
assign atan_table[ 5] = 22'd20854;
assign atan_table[ 6] = 22'd10430;
assign atan_table[ 7] = 22'd5215;
assign atan_table[ 8] = 22'd2608;
assign atan_table[ 9] = 22'd1304;
assign atan_table[10] = 22'd652;
assign atan_table[11] = 22'd326;
assign atan_table[12] = 22'd163;
assign atan_table[13] = 22'd81;
assign atan_table[14] = 22'd41;
assign atan_table[15] = 22'd20;
assign atan_table[16] = 22'd10;
assign atan_table[17] = 22'd5;
assign atan_table[18] = 22'd3;
assign atan_table[19] = 22'd1;
assign atan_table[20] = 22'd1;
end else if (PHASE_DW == 21) begin
assign atan_table[ 0] = 21'd262144;
assign atan_table[ 1] = 21'd154753;
assign atan_table[ 2] = 21'd81767;
assign atan_table[ 3] = 21'd41506;
assign atan_table[ 4] = 21'd20834;
assign atan_table[ 5] = 21'd10427;
assign atan_table[ 6] = 21'd5215;
assign atan_table[ 7] = 21'd2608;
assign atan_table[ 8] = 21'd1304;
assign atan_table[ 9] = 21'd652;
assign atan_table[10] = 21'd326;
assign atan_table[11] = 21'd163;
assign atan_table[12] = 21'd81;
assign atan_table[13] = 21'd41;
assign atan_table[14] = 21'd20;
assign atan_table[15] = 21'd10;
assign atan_table[16] = 21'd5;
assign atan_table[17] = 21'd3;
assign atan_table[18] = 21'd1;
assign atan_table[19] = 21'd1;
end else if (PHASE_DW == 20) begin
assign atan_table[ 0] = 20'd131072;
assign atan_table[ 1] = 20'd77376;
assign atan_table[ 2] = 20'd40884;
assign atan_table[ 3] = 20'd20753;
assign atan_table[ 4] = 20'd10417;
assign atan_table[ 5] = 20'd5213;
assign atan_table[ 6] = 20'd2607;
assign atan_table[ 7] = 20'd1304;
assign atan_table[ 8] = 20'd652;
assign atan_table[ 9] = 20'd326;
assign atan_table[10] = 20'd163;
assign atan_table[11] = 20'd81;
assign atan_table[12] = 20'd41;
assign atan_table[13] = 20'd20;
assign atan_table[14] = 20'd10;
assign atan_table[15] = 20'd5;
assign atan_table[16] = 20'd3;
assign atan_table[17] = 20'd1;
assign atan_table[18] = 20'd1;
end else if (PHASE_DW == 19) begin
assign atan_table[ 0] = 19'd65536;
assign atan_table[ 1] = 19'd38688;
assign atan_table[ 2] = 19'd20442;
assign atan_table[ 3] = 19'd10377;
assign atan_table[ 4] = 19'd5208;
assign atan_table[ 5] = 19'd2607;
assign atan_table[ 6] = 19'd1304;
assign atan_table[ 7] = 19'd652;
assign atan_table[ 8] = 19'd326;
assign atan_table[ 9] = 19'd163;
assign atan_table[10] = 19'd81;
assign atan_table[11] = 19'd41;
assign atan_table[12] = 19'd20;
assign atan_table[13] = 19'd10;
assign atan_table[14] = 19'd5;
assign atan_table[15] = 19'd3;
assign atan_table[16] = 19'd1;
assign atan_table[17] = 19'd1;
end else if (PHASE_DW == 18) begin
assign atan_table[ 0] = 18'd32768;
assign atan_table[ 1] = 18'd19344;
assign atan_table[ 2] = 18'd10221;
assign atan_table[ 3] = 18'd5188;
assign atan_table[ 4] = 18'd2604;
assign atan_table[ 5] = 18'd1303;
assign atan_table[ 6] = 18'd652;
assign atan_table[ 7] = 18'd326;
assign atan_table[ 8] = 18'd163;
assign atan_table[ 9] = 18'd81;
assign atan_table[10] = 18'd41;
assign atan_table[11] = 18'd20;
assign atan_table[12] = 18'd10;
assign atan_table[13] = 18'd5;
assign atan_table[14] = 18'd3;
assign atan_table[15] = 18'd1;
assign atan_table[16] = 18'd1;
end else if (PHASE_DW == 17) begin
assign atan_table[ 0] = 17'd16384;
assign atan_table[ 1] = 17'd9672;
assign atan_table[ 2] = 17'd5110;
assign atan_table[ 3] = 17'd2594;
assign atan_table[ 4] = 17'd1302;
assign atan_table[ 5] = 17'd652;
assign atan_table[ 6] = 17'd326;
assign atan_table[ 7] = 17'd163;
assign atan_table[ 8] = 17'd81;
assign atan_table[ 9] = 17'd41;
assign atan_table[10] = 17'd20;
assign atan_table[11] = 17'd10;
assign atan_table[12] = 17'd5;
assign atan_table[13] = 17'd3;
assign atan_table[14] = 17'd1;
assign atan_table[15] = 17'd1;
end else if (PHASE_DW == 16) begin
assign atan_table[ 0] = 16'd8192;
assign atan_table[ 1] = 16'd4836;
assign atan_table[ 2] = 16'd2555;
assign atan_table[ 3] = 16'd1297;
assign atan_table[ 4] = 16'd651;
assign atan_table[ 5] = 16'd326;
assign atan_table[ 6] = 16'd163;
assign atan_table[ 7] = 16'd81;
assign atan_table[ 8] = 16'd41;
assign atan_table[ 9] = 16'd20;
assign atan_table[10] = 16'd10;
assign atan_table[11] = 16'd5;
assign atan_table[12] = 16'd3;
assign atan_table[13] = 16'd1;
assign atan_table[14] = 16'd1;
end else if (PHASE_DW == 15) begin
assign atan_table[ 0] = 15'd4096;
assign atan_table[ 1] = 15'd2418;
assign atan_table[ 2] = 15'd1278;
assign atan_table[ 3] = 15'd649;
assign atan_table[ 4] = 15'd326;
assign atan_table[ 5] = 15'd163;
assign atan_table[ 6] = 15'd81;
assign atan_table[ 7] = 15'd41;
assign atan_table[ 8] = 15'd20;
assign atan_table[ 9] = 15'd10;
assign atan_table[10] = 15'd5;
assign atan_table[11] = 15'd3;
assign atan_table[12] = 15'd1;
assign atan_table[13] = 15'd1;
end else if (PHASE_DW == 14) begin
assign atan_table[ 0] = 14'd2048;
assign atan_table[ 1] = 14'd1209;
assign atan_table[ 2] = 14'd639;
assign atan_table[ 3] = 14'd324;
assign atan_table[ 4] = 14'd163;
assign atan_table[ 5] = 14'd81;
assign atan_table[ 6] = 14'd41;
assign atan_table[ 7] = 14'd20;
assign atan_table[ 8] = 14'd10;
assign atan_table[ 9] = 14'd5;
assign atan_table[10] = 14'd3;
assign atan_table[11] = 14'd1;
assign atan_table[12] = 14'd1;
end else if (PHASE_DW == 13) begin
assign atan_table[ 0] = 13'd1024;
assign atan_table[ 1] = 13'd605;
assign atan_table[ 2] = 13'd319;
assign atan_table[ 3] = 13'd162;
assign atan_table[ 4] = 13'd81;
assign atan_table[ 5] = 13'd41;
assign atan_table[ 6] = 13'd20;
assign atan_table[ 7] = 13'd10;
assign atan_table[ 8] = 13'd5;
assign atan_table[ 9] = 13'd3;
assign atan_table[10] = 13'd1;
assign atan_table[11] = 13'd1;
end else if (PHASE_DW == 12) begin
assign atan_table[ 0] = 12'd512;
assign atan_table[ 1] = 12'd302;
assign atan_table[ 2] = 12'd160;
assign atan_table[ 3] = 12'd81;
assign atan_table[ 4] = 12'd41;
assign atan_table[ 5] = 12'd20;
assign atan_table[ 6] = 12'd10;
assign atan_table[ 7] = 12'd5;
assign atan_table[ 8] = 12'd3;
assign atan_table[ 9] = 12'd1;
assign atan_table[10] = 12'd1;
end else if (PHASE_DW == 11) begin
assign atan_table[ 0] = 11'd256;
assign atan_table[ 1] = 11'd151;
assign atan_table[ 2] = 11'd80;
assign atan_table[ 3] = 11'd41;
assign atan_table[ 4] = 11'd20;
assign atan_table[ 5] = 11'd10;
assign atan_table[ 6] = 11'd5;
assign atan_table[ 7] = 11'd3;
assign atan_table[ 8] = 11'd1;
assign atan_table[ 9] = 11'd1;
end else if (PHASE_DW == 10) begin
assign atan_table[ 0] = 10'd128;
assign atan_table[ 1] = 10'd76;
assign atan_table[ 2] = 10'd40;
assign atan_table[ 3] = 10'd20;
assign atan_table[ 4] = 10'd10;
assign atan_table[ 5] = 10'd5;
assign atan_table[ 6] = 10'd3;
assign atan_table[ 7] = 10'd1;
assign atan_table[ 8] = 10'd1;
end else if (PHASE_DW == 9) begin
assign atan_table[ 0] = 9'd64;
assign atan_table[ 1] = 9'd38;
assign atan_table[ 2] = 9'd20;
assign atan_table[ 3] = 9'd10;
assign atan_table[ 4] = 9'd5;
assign atan_table[ 5] = 9'd3;
assign atan_table[ 6] = 9'd1;
assign atan_table[ 7] = 9'd1;
end else if (PHASE_DW == 8) begin
assign atan_table[ 0] = 8'd32;
assign atan_table[ 1] = 8'd19;
assign atan_table[ 2] = 8'd10;
assign atan_table[ 3] = 8'd5;
assign atan_table[ 4] = 8'd3;
assign atan_table[ 5] = 8'd1;
assign atan_table[ 6] = 8'd1;
end
endgenerate