Increase CORDIC time to 7 cycles from 3, reduce osc to 32

This commit is contained in:
Aadi Desai 2023-06-25 12:15:05 +01:00
parent 3fe1a457ab
commit 2227bb8afa
No known key found for this signature in database
3 changed files with 26 additions and 27 deletions

View file

@ -5,7 +5,7 @@
#ifdef CSR_AUDIO_BASE #ifdef CSR_AUDIO_BASE
// Set all oscillators to (0Hz, sawtooth) // Set all oscillators to (0Hz, sawtooth)
void reset_audio(void) { void reset_audio(void) {
for (int i = 0; i < 64; i++) { for (int i = 0; i < 32; i++) {
audio_osc_write(i); audio_osc_write(i);
audio_tf_write(0); audio_tf_write(0);
audio_wav_write(0); audio_wav_write(0);

View file

@ -355,18 +355,18 @@ static void can_watch_cmd() {
const char *notes[85] = {"None", "C1", "C1#", "D1", "D1#", "E1", "F1", "F1#", "G1", "G1#", "A1", "A1#", "B1", "C2", "C2#", "D2", "D2#", "E2", "F2", "F2#", "G2", "G2#", "A2", "A2#", "B2", "C3", "C3#", "D3", "D3#", "E3", "F3", "F3#", "G3", "G3#", "A3", "A3#", "B3", "C4", "C4#", "D4", "D4#", "E4", "F4", "F4#", "G4", "G4#", "A4", "A4#", "B4", "C5", "C5#", "D5", "D5#", "E5", "F5", "F5#", "G5", "G5#", "A5", "A5#", "B5", "C6", "C6#", "D6", "D6#", "E6", "F6", "F6#", "G6", "G6#", "A6", "A6#", "B6", "C7", "C7#", "D7", "D7#", "E7", "F7", "F7#", "G7", "G7#", "A7", "A7#", "B7"}; const char *notes[85] = {"None", "C1", "C1#", "D1", "D1#", "E1", "F1", "F1#", "G1", "G1#", "A1", "A1#", "B1", "C2", "C2#", "D2", "D2#", "E2", "F2", "F2#", "G2", "G2#", "A2", "A2#", "B2", "C3", "C3#", "D3", "D3#", "E3", "F3", "F3#", "G3", "G3#", "A3", "A3#", "B3", "C4", "C4#", "D4", "D4#", "E4", "F4", "F4#", "G4", "G4#", "A4", "A4#", "B4", "C5", "C5#", "D5", "D5#", "E5", "F5", "F5#", "G5", "G5#", "A5", "A5#", "B5", "C6", "C6#", "D6", "D6#", "E6", "F6", "F6#", "G6", "G6#", "A6", "A6#", "B6", "C7", "C7#", "D7", "D7#", "E7", "F7", "F7#", "G7", "G7#", "A7", "A7#", "B7"};
const uint32_t freqs[85] = {0, 33, 35, 37, 39, 41, 44, 46, 49, 52, 55, 58, 62, 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, 117, 123, 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951}; const uint32_t freqs[85] = {0, 33, 35, 37, 39, 41, 44, 46, 49, 52, 55, 58, 62, 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, 117, 123, 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951};
static void can_listen_cmd() { static void can_listen_cmd() {
for (int i = 0; i < 64; i++) { for (int i = 0; i < 32; i++) {
set_wave(i, WAVE_SINE); set_wave(i, WAVE_SINE);
} }
bool active_notes[85] = {0}; bool active_notes[85] = {0};
uint32_t active_osc[64] = {0}; uint32_t active_osc[32] = {0};
uint32_t active_oscs = 0; uint32_t active_oscs = 0;
while (true) { while (true) {
can_frame frame = can_read(); can_frame frame = can_read();
switch (frame.data[0]) { switch (frame.data[0]) {
case 'P': { case 'P': {
uint32_t note = (frame.data[1] - 1) * 12 + frame.data[2]; uint32_t note = (frame.data[1] - 1) * 12 + frame.data[2];
if (active_notes[note] || active_oscs == 64) // ALready active or all oscillators in use, ignore if (active_notes[note] || active_oscs == 32) // ALready active or all oscillators in use, ignore
break; break;
active_notes[note] = true; // Mark note as active active_notes[note] = true; // Mark note as active
active_osc[active_oscs] = note; // Set oscillator to note active_osc[active_oscs] = note; // Set oscillator to note
@ -416,7 +416,7 @@ static void can_listen_cmd() {
done: done:
if (readchar_nonblock()) { if (readchar_nonblock()) {
getchar(); getchar();
for (int i = 0; i < 64; i++) { for (int i = 0; i < 32; i++) {
audio(i, WAVE_SAWTOOTH, 0); audio(i, WAVE_SAWTOOTH, 0);
} }
return; return;

View file

@ -4,7 +4,7 @@ module genWave
( input var i_clk48 // 48MHz clock ( input var i_clk48 // 48MHz clock
, input var i_rst48_n // Active low reset , input var i_rst48_n // Active low reset
, input var i_pause // Pause sample generation (backpressure) , input var i_pause // Pause sample generation (backpressure)
, input var [ 5:0] i_osc_sel // Oscillator select, to update target freq / waveform , input var [ 4:0] i_osc_sel // Oscillator select, to update target freq / waveform
, input var [23:0] i_t_freq // Target frequency for selected oscillator , input var [23:0] i_t_freq // Target frequency for selected oscillator
, input var i_tf_valid // Target frequency valid pulse (i_osc_sel must be set first) , input var i_tf_valid // Target frequency valid pulse (i_osc_sel must be set first)
, input var [ 7:0] i_wav_sel // Waveform select for selected oscillator , input var [ 7:0] i_wav_sel // Waveform select for selected oscillator
@ -34,31 +34,31 @@ always_comb o_pulse = clk_48k && !clk_48k_past; // Detect rising edge of 48kHz c
// Per Oscillator Settings Capture ################################################################# // Per Oscillator Settings Capture #################################################################
logic [23:0] t_freq [0:63]; logic [23:0] t_freq [0:31];
always_ff @(posedge i_clk48) always_ff @(posedge i_clk48)
if (i_tf_valid) t_freq[i_osc_sel] <= i_t_freq; // Capture target frequency if (i_tf_valid) t_freq[i_osc_sel] <= i_t_freq; // Capture target frequency
logic [7:0] wav_sel [0:63]; logic [7:0] wav_sel [0:31];
always_ff @(posedge i_clk48) always_ff @(posedge i_clk48)
if (i_ws_valid) wav_sel[i_osc_sel] <= i_wav_sel; // Capture waveform select if (i_ws_valid) wav_sel[i_osc_sel] <= i_wav_sel; // Capture waveform select
// Per Oscillator Phase Step Generation ############################################################ // Per Oscillator Phase Step Generation ############################################################
logic [5:0] ps_clk; logic [4:0] ps_clk;
always_ff @(posedge i_clk48) // Count to 64 at 48MHz always_ff @(posedge i_clk48) // Count to 32 at 48MHz
if (!i_rst48_n) ps_clk <= '0; // Reset if (!i_rst48_n) ps_clk <= '0; // Reset
else ps_clk <= ps_clk + 1; // Increment else ps_clk <= ps_clk + 1; // Increment
logic [23:0] int_phase_step; // Phase step calc from target frequency logic [23:0] int_phase_step; // Phase step calc from target frequency
always_comb int_phase_step = (24'd699 * t_freq[ps_clk]); // 699 = (2^24 / 48000) * 2 (Approximately) always_comb int_phase_step = (24'd699 * t_freq[ps_clk]); // 699 = (2^24 / 48000) * 2 (Approximately)
logic [15:0] phase_step [0:63]; // Shift step right correctly (2^9) logic [15:0] phase_step [0:31]; // Shift step right correctly (2^9)
always_ff @(posedge i_clk48) phase_step[ps_clk] <= {1'b0, int_phase_step[23:9]}; always_ff @(posedge i_clk48) phase_step[ps_clk] <= {1'b0, int_phase_step[23:9]};
// Per Oscillator Phase Generation ################################################################# // Per Oscillator Phase Generation #################################################################
logic [15:0] phase [0:63]; logic [15:0] phase [0:31];
for (genvar i = 0; i < 64; i++) begin: l_gen_phase for (genvar i = 0; i < 32; i++) begin: l_gen_phase
always_ff @(posedge clk_48k) // Generate new phase sample on rising edge of 48kHz clock always_ff @(posedge clk_48k) // Generate new phase sample on rising edge of 48kHz clock
if (!i_rst48_n) phase[i] <= 16'd0; // Reset saw if (!i_rst48_n) phase[i] <= 16'd0; // Reset saw
else if (phase_step[i] == 16'd0) phase[i] <= {phase[i][15], phase[i][15:1]};// Divide by 2 if phase_step is 0 else if (phase_step[i] == 16'd0) phase[i] <= {phase[i][15], phase[i][15:1]};// Divide by 2 if phase_step is 0
@ -68,7 +68,7 @@ end
// Per Oscillator Sample Generation ################################################################ // Per Oscillator Sample Generation ################################################################
logic [15:0] saw; logic [15:0] saw;
always_ff @(posedge i_clk48) if (clk_div[1:0] == 2'd0) saw <= phase[clk_div[7:2]]; // Load saw to calculate sample for always_ff @(posedge i_clk48) if (clk_div[2:0] == 3'd0) saw <= phase[clk_div[8:3]]; // Load saw to calculate sample for
logic [15:0] square; logic [15:0] square;
always_ff @(posedge i_clk48) square <= {~saw[15], {15{saw[15]}}}; // Square wave is MSB of saw always_ff @(posedge i_clk48) square <= {~saw[15], {15{saw[15]}}}; // Square wave is MSB of saw
@ -85,7 +85,7 @@ saw2sin m_saw2sin // Sine wave calculation
logic [15:0] sample; logic [15:0] sample;
always_comb // Select waveform sample based on wav_sel always_comb // Select waveform sample based on wav_sel
case (wav_sel[clk_div[7:2]]) case (wav_sel[clk_div[8:3]])
8'd0: sample = saw; // Saw wave 8'd0: sample = saw; // Saw wave
8'd1: sample = square; // Square wave 8'd1: sample = square; // Square wave
8'd2: sample = triangle; // Triangle wave 8'd2: sample = triangle; // Triangle wave
@ -95,31 +95,30 @@ always_comb // Select waveform sample based on wav_sel
logic osc_valid; logic osc_valid;
always_comb osc_valid = (clk_div < 9'd256); // 64 oscillators * 4 stages = 256 cycles always_comb osc_valid = (clk_div < 9'd256); // 32 oscillators * 8 stages = 256 cycles
logic [15:0] samples [0:63]; // Store samples per oscillator logic [15:0] samples [0:31]; // Store samples per oscillator
always_ff @(posedge i_clk48) if ((clk_div[1:0] == 2'd3) && osc_valid) samples[clk_div[7:2]] <= sample; always_ff @(posedge i_clk48) if ((clk_div[2:0] == 3'd7) && osc_valid) samples[clk_div[8:3]] <= sample;
// Combine Samples into Single Sample ############################################################## // Combine Samples into Single Sample ##############################################################
logic [23:0] samples_long [0:63]; // Sum all samples to get final output sample logic [23:0] samples_long [0:31]; // Sum all samples to get final output sample
always_comb samples_long[0] = {{8{samples[0][15]}}, samples[0]}; always_comb samples_long[0] = {{8{samples[0][15]}}, samples[0]};
for (genvar i = 1; i < 64; i++) begin: l_gen_sample_long for (genvar i = 1; i < 32; i++) begin: l_gen_sample_long
always_comb samples_long[i] = samples_long[i-1] + {{8{samples[i][15]}}, samples[i]}; always_comb samples_long[i] = samples_long[i-1] + {{8{samples[i][15]}}, samples[i]};
end end
logic [6:0] waves_count [0:63]; logic [5:0] waves_count [0:31];
always_comb waves_count[0] = (phase[0] != 16'd0); always_comb waves_count[0] = (phase[0] != 16'd0);
for (genvar i = 1; i < 64; i++) begin: l_gen_waves_count for (genvar i = 1; i < 32; i++) begin: l_gen_waves_count
always_comb waves_count[i] = waves_count[i-1] + (phase[i] != 16'd0); // Count non-zeroes always_comb waves_count[i] = waves_count[i-1] + (phase[i] != 16'd0); // Count non-zeroes
end end
logic [6:0] wv_cnt_1; logic [5:0] wv_cnt_1;
always_comb wv_cnt_1 = waves_count[63] - 1; // Subtract 1 from wave count always_comb wv_cnt_1 = waves_count[31] - 1; // Subtract 1 from wave count
logic [2:0] shift; // Calculate shift amount logic [2:0] shift; // Calculate shift amount
always_comb shift = wv_cnt_1[6] ? 3'd7 always_comb shift = wv_cnt_1[5] ? 3'd6
: wv_cnt_1[5] ? 3'd6
: wv_cnt_1[4] ? 3'd5 : wv_cnt_1[4] ? 3'd5
: wv_cnt_1[3] ? 3'd4 : wv_cnt_1[3] ? 3'd4
: wv_cnt_1[2] ? 3'd3 : wv_cnt_1[2] ? 3'd3
@ -128,7 +127,7 @@ always_comb shift = wv_cnt_1[6] ? 3'd7
: 3'd0; : 3'd0;
logic [23:0] samples_sum; // Shift output sample right to get normalised output logic [23:0] samples_sum; // Shift output sample right to get normalised output
always_ff @(posedge i_clk48) samples_sum <= samples_long[63] >> shift; always_ff @(posedge i_clk48) samples_sum <= samples_long[31] >> shift;
always_comb o_sample = samples_sum[15:0]; // Output sample is 16 bits always_comb o_sample = samples_sum[15:0]; // Output sample is 16 bits