Update cordic.sv and saw2sin.sv for better accuracy, genSaw.sv to fix polarity of tri/sin

This commit is contained in:
Aadi Desai 2023-06-04 12:05:45 +01:00
parent 59ec852558
commit 4b57bdfa80
No known key found for this signature in database
3 changed files with 27 additions and 11 deletions

View file

@ -33,9 +33,11 @@ always_comb cordic_angle[16] = 23'h000028; // 0.000437 degrees
always_comb cordic_angle[17] = 23'h000014; // 0.000219 degrees always_comb cordic_angle[17] = 23'h000014; // 0.000219 degrees
always_comb cordic_angle[18] = 23'h00000A; // 0.000109 degrees always_comb cordic_angle[18] = 23'h00000A; // 0.000109 degrees
/* verilator lint_off UNOPTFLAT */
logic [18:0] x [0:19]; logic [18:0] x [0:19];
logic [18:0] y [0:19]; logic [18:0] y [0:19];
logic [22:0] p [0:19]; logic [22:0] p [0:19];
/* verilator lint_on UNOPTFLAT */
// Extend input from input to working widths // Extend input from input to working widths
always_comb x[0] = {1'b0, i_x, {2{1'b0}}}; always_comb x[0] = {1'b0, i_x, {2{1'b0}}};
@ -43,15 +45,24 @@ always_comb y[0] = {1'b0, i_y, {2{1'b0}}};
always_comb p[0] = {i_qph, {7{1'b0}}}; always_comb p[0] = {i_qph, {7{1'b0}}};
// Max pos = 23'h3FFF80, Max neg = 23'h400000 // Max pos = 23'h3FFF80, Max neg = 23'h400000
/* verilator lint_off ALWCOMBORDER */
for (genvar i = 0; i < 19; i = i + 1) begin: l_cordic_steps for (genvar i = 0; i < 19; i = i + 1) begin: l_cordic_steps
// If phase is negative, rotate CW, otherwise CCW // If phase is negative, rotate CW, otherwise CCW
always_comb x[i+1] = (p[i][22]) ? x[i] + (y[i] >>> (i+1)) : x[i] - (y[i] >>> (i+1)); always_comb
always_comb y[i+1] = (p[i][22]) ? y[i] - (x[i] >>> (i+1)) : y[i] + (x[i] >>> (i+1)); if (p[i][22]) begin
always_comb p[i+1] = (p[i][22]) ? p[i] + cordic_angle[i] : p[i] - cordic_angle[i]; x[i+1] = x[i] + (y[i] >>> (i+1));
y[i+1] = y[i] - (x[i] >>> (i+1));
p[i+1] = p[i] + cordic_angle[i];
end else begin
x[i+1] = x[i] - (y[i] >>> (i+1));
y[i+1] = y[i] + (x[i] >>> (i+1));
p[i+1] = p[i] - cordic_angle[i];
end end
end
/* verilator lint_on ALWCOMBORDER */
always_comb always_comb
if (i_qph > 16'd65508) o_sin = 16'hFFFF; if (i_qph > 16'd65508) o_sin = 16'hFFFE;
else if (i_qph < 16'd32) o_sin = i_qph + (i_qph >> 1); else if (i_qph < 16'd32) o_sin = i_qph + (i_qph >> 1);
else o_sin = y[19][17:2]; else o_sin = y[19][17:2];

View file

@ -54,8 +54,8 @@ always_comb // Select output waveform
case (i_wave[1:0]) case (i_wave[1:0])
2'd0: o_sample = saw; 2'd0: o_sample = saw;
2'd1: o_sample = square; 2'd1: o_sample = square;
2'd2: o_sample = triangle; 2'd2: o_sample = {~triangle[15], triangle[14:0]};
2'd3: o_sample = sine; 2'd3: o_sample = {~sine[15], sine[14:0]};
endcase endcase
endmodule endmodule

View file

@ -13,8 +13,8 @@ always_comb reverse = i_saw[14];
logic [15:0] qsaw; logic [15:0] qsaw;
always_comb qsaw = reverse always_comb qsaw = reverse
? {~i_saw[13:0], 2'b01} // Reverse ? {~i_saw[13:0], 2'b11} // Reverse
: {i_saw[13:0], 2'b00}; // Normal : {i_saw[13:0], 2'b01}; // Normal
logic [15:0] qsin; logic [15:0] qsin;
cordic cordic cordic cordic
@ -22,8 +22,13 @@ cordic cordic
, .o_sin (qsin) , .o_sin (qsin)
); );
always_comb o_sin = invert logic [16:0] sin;
? ~{1'b1, qsin[15:1]} + 1 // Invert always_comb sin = reverse
: {1'b1, qsin[15:1]}; // Normal ? (invert ? ~{1'b1, qsin[15:0]} // Reverse, Invert
: {1'b1, qsin[15:0]} + 17'd1) // Reverse, Normal
: (invert ? ~{1'b1, qsin[15:0]} + 17'd2 // Normal, Invert
: {1'b1, qsin[15:0]} + 17'd0); // Normal, Normal
always_comb o_sin = sin[16:1];
endmodule endmodule