Skip to content

Commit

Permalink
ad_dds: Add selectable out data width and fair rounding
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
AndreiGrozav committed Jul 18, 2018
1 parent 2c1f919 commit ad7e95b
Showing 1 changed file with 55 additions and 23 deletions.
78 changes: 55 additions & 23 deletions library/common/ad_dds.v
Original file line number Diff line number Diff line change
Expand Up @@ -37,51 +37,83 @@

module ad_dds #(

// data path disable

// Disable DDS
parameter DISABLE = 0,
// Range = 8-24
parameter DDS_DW = 16,
// Set 1 for CORDIC or 2 for Polynomial
parameter DDS_TYPE = 1,
// Range = 8-24
parameter CORDIC_DW = 16,
// Range = 8-24 ( make sure CORDIC_PHASE_DW < CORDIC_DW)
parameter CORDIC_PHASE_DW = 16) (

// interface

input clk,
input dds_format,
input [15:0] dds_phase_0,
input [15:0] dds_scale_0,
input [15:0] dds_phase_1,
input [15:0] dds_scale_1,
output [15:0] dds_data);
input clk,
input dds_format,
input [ 15:0] dds_phase_0,
input [ 15:0] dds_scale_0,
input [ 15:0] dds_phase_1,
input [ 15:0] dds_scale_1,
output [DDS_DW-1:0] dds_data);

// Local parameters

localparam CORDIC = 1;
localparam POLYNOMIAL = 2;

// The width for Polynomial DDS is fixed (16)
localparam DDS_D_DW = (DDS_TYPE == CORDIC) ? CORDIC_DW : 16;
localparam DDS_P_DW = (DDS_TYPE == CORDIC) ? CORDIC_PHASE_DW : 16;
// concatenation or truncation width
localparam C_T_WIDTH = (DDS_D_DW > DDS_DW) ? (DDS_D_DW - DDS_DW) : (DDS_DW - DDS_D_DW);

// internal registers

reg [15:0] dds_data_int = 'd0;
reg [15:0] dds_data_out = 'd0;
reg [15:0] dds_scale_0_d = 'd0;
reg [15:0] dds_scale_1_d = 'd0;
reg [ DDS_DW-1:0] dds_data_width = 0;
reg [DDS_D_DW-1:0] dds_data_rownd = 0;
reg [DDS_D_DW-1:0] dds_data_int = 0;
reg [ 15:0] dds_scale_0_d = 0;
reg [ 15:0] dds_scale_1_d = 0;
reg [ DDS_DW-1:0] dds_data_out = 0;

// internal signals

wire [15:0] dds_data_0_s;
wire [15:0] dds_data_1_s;

// disable

// disable DDS
generate
if (DISABLE == 1) begin
assign dds_data = 16'd0;
// assign 0 for the exact buss width to avoid warnings
assign dds_data = {DDS_DW{1'b0}};
end else begin

// dds channel output
assign dds_data = dds_data_out;

// dds channel output

always @(posedge clk) begin
dds_data_int <= dds_data_0_s + dds_data_1_s;
dds_data_out[15:15] <= dds_data_int[15] ^ dds_format;
dds_data_out[14: 0] <= dds_data_int[14:0];
end
// output data format
always @(posedge clk) begin
dds_data_out[DDS_DW-1] <= dds_data_width[DDS_DW-1] ^ dds_format;
dds_data_out[DDS_DW-2: 0] <= dds_data_width[DDS_DW-2: 0];
end

// set desired data width
always @(posedge clk) begin
if (DDS_DW <= DDS_D_DW) begin // truncation
// fair rownding
dds_data_rownd <= dds_data_int + {(C_T_WIDTH){dds_data_int[DDS_D_DW-1]}};
dds_data_width <= dds_data_rownd[DDS_D_DW-1:DDS_D_DW-DDS_DW];
end else begin // concatenation
dds_data_width <= dds_data_int << C_T_WIDTH;
end
end

// dual tone
always @(posedge clk) begin
dds_data_int <= dds_data_0_s + dds_data_1_s;
end

always @(posedge clk) begin
dds_scale_0_d <= dds_scale_0;
Expand Down

0 comments on commit ad7e95b

Please sign in to comment.