Skip to content

Commit ad7e95b

Browse files
committed
ad_dds: Add selectable out data width and fair rounding
The CORDIC has a selectable width range for phase and data of 8-24. Regarding the width of phase and data, the wider they are the smaller the precision loss when shifting but with the cost of more FPGA utilization. The user must decide between precision and utilization. The DDS_WD parameter is independent of CORDIC(CORDIC_DW) or Polynomial(16bit), letting the user chose the output width. Here we encounter two scenarios: * DDS_DW < DDS data width - in this case, a fair rounding will be implemented corresponding to the truncated bits * DDS_DW > DDS data width - DDS out data left shift to get the corresponding concatenation bits.
1 parent 2c1f919 commit ad7e95b

File tree

1 file changed

+55
-23
lines changed

1 file changed

+55
-23
lines changed

library/common/ad_dds.v

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,51 +37,83 @@
3737

3838
module ad_dds #(
3939

40-
// data path disable
41-
40+
// Disable DDS
4241
parameter DISABLE = 0,
42+
// Range = 8-24
43+
parameter DDS_DW = 16,
44+
// Set 1 for CORDIC or 2 for Polynomial
4345
parameter DDS_TYPE = 1,
46+
// Range = 8-24
4447
parameter CORDIC_DW = 16,
48+
// Range = 8-24 ( make sure CORDIC_PHASE_DW < CORDIC_DW)
4549
parameter CORDIC_PHASE_DW = 16) (
4650

4751
// interface
4852

49-
input clk,
50-
input dds_format,
51-
input [15:0] dds_phase_0,
52-
input [15:0] dds_scale_0,
53-
input [15:0] dds_phase_1,
54-
input [15:0] dds_scale_1,
55-
output [15:0] dds_data);
53+
input clk,
54+
input dds_format,
55+
input [ 15:0] dds_phase_0,
56+
input [ 15:0] dds_scale_0,
57+
input [ 15:0] dds_phase_1,
58+
input [ 15:0] dds_scale_1,
59+
output [DDS_DW-1:0] dds_data);
60+
61+
// Local parameters
62+
63+
localparam CORDIC = 1;
64+
localparam POLYNOMIAL = 2;
65+
66+
// The width for Polynomial DDS is fixed (16)
67+
localparam DDS_D_DW = (DDS_TYPE == CORDIC) ? CORDIC_DW : 16;
68+
localparam DDS_P_DW = (DDS_TYPE == CORDIC) ? CORDIC_PHASE_DW : 16;
69+
// concatenation or truncation width
70+
localparam C_T_WIDTH = (DDS_D_DW > DDS_DW) ? (DDS_D_DW - DDS_DW) : (DDS_DW - DDS_D_DW);
5671

5772
// internal registers
5873

59-
reg [15:0] dds_data_int = 'd0;
60-
reg [15:0] dds_data_out = 'd0;
61-
reg [15:0] dds_scale_0_d = 'd0;
62-
reg [15:0] dds_scale_1_d = 'd0;
74+
reg [ DDS_DW-1:0] dds_data_width = 0;
75+
reg [DDS_D_DW-1:0] dds_data_rownd = 0;
76+
reg [DDS_D_DW-1:0] dds_data_int = 0;
77+
reg [ 15:0] dds_scale_0_d = 0;
78+
reg [ 15:0] dds_scale_1_d = 0;
79+
reg [ DDS_DW-1:0] dds_data_out = 0;
6380

6481
// internal signals
6582

6683
wire [15:0] dds_data_0_s;
6784
wire [15:0] dds_data_1_s;
6885

69-
// disable
70-
86+
// disable DDS
7187
generate
7288
if (DISABLE == 1) begin
73-
assign dds_data = 16'd0;
89+
// assign 0 for the exact buss width to avoid warnings
90+
assign dds_data = {DDS_DW{1'b0}};
7491
end else begin
7592

93+
// dds channel output
7694
assign dds_data = dds_data_out;
7795

78-
// dds channel output
79-
80-
always @(posedge clk) begin
81-
dds_data_int <= dds_data_0_s + dds_data_1_s;
82-
dds_data_out[15:15] <= dds_data_int[15] ^ dds_format;
83-
dds_data_out[14: 0] <= dds_data_int[14:0];
84-
end
96+
// output data format
97+
always @(posedge clk) begin
98+
dds_data_out[DDS_DW-1] <= dds_data_width[DDS_DW-1] ^ dds_format;
99+
dds_data_out[DDS_DW-2: 0] <= dds_data_width[DDS_DW-2: 0];
100+
end
101+
102+
// set desired data width
103+
always @(posedge clk) begin
104+
if (DDS_DW <= DDS_D_DW) begin // truncation
105+
// fair rownding
106+
dds_data_rownd <= dds_data_int + {(C_T_WIDTH){dds_data_int[DDS_D_DW-1]}};
107+
dds_data_width <= dds_data_rownd[DDS_D_DW-1:DDS_D_DW-DDS_DW];
108+
end else begin // concatenation
109+
dds_data_width <= dds_data_int << C_T_WIDTH;
110+
end
111+
end
112+
113+
// dual tone
114+
always @(posedge clk) begin
115+
dds_data_int <= dds_data_0_s + dds_data_1_s;
116+
end
85117

86118
always @(posedge clk) begin
87119
dds_scale_0_d <= dds_scale_0;

0 commit comments

Comments
 (0)