diff --git a/gateware/cores/util/wavetable_osc.sv b/gateware/cores/util/wavetable_osc.sv index b627122..e570b5f 100644 --- a/gateware/cores/util/wavetable_osc.sv +++ b/gateware/cores/util/wavetable_osc.sv @@ -1,30 +1,29 @@ module wavetable_osc #( parameter W = 16, + parameter FRAC_BITS = 10, parameter WAVETABLE_PATH = "cores/util/vco/wavetable.hex", - parameter WAVETABLE_SIZE = 256, + parameter WAVETABLE_SIZE = 256 )( input rst, input sample_clk, input [31:0] wavetable_inc, - output signed [W-1:0] out, + output logic signed [W-1:0] out ); logic [W-1:0] wavetable [0:WAVETABLE_SIZE-1]; initial $readmemh(WAVETABLE_PATH, wavetable); -logic [31:0] wavetable_pos = 32'h0; +// Position in wavetable - N.F fixed-point where BIT_START is size of F. +logic [31:0] wavetable_pos = 0; always_ff @(posedge sample_clk) begin - // TODO: linear interpolation between frequencies, silence oscillator - // whenever we are outside the LUT bounds. - wavetable_pos <= wavetable_pos + wavetable_inc; + if (rst) begin + wavetable_pos <= 0; + end else begin + wavetable_pos <= wavetable_pos + wavetable_inc; + // Take top N bits of wavetable_pos as output. + out <= wavetable[wavetable_pos[FRAC_BITS+$clog2(WAVETABLE_SIZE)-1:FRAC_BITS]]; + end end -// Top 8 bits of the N.F fixed-point representation are index into wavetable. -localparam BIT_START = 10; -wire [$clog2(WAVETABLE_SIZE)-1:0] wavetable_idx = - wavetable_pos[BIT_START+$clog2(WAVETABLE_SIZE)-1:BIT_START]; - -assign out = wavetable[wavetable_idx]; - endmodule diff --git a/gateware/cores/vco.sv b/gateware/cores/vco.sv index 11e742d..0fab58b 100644 --- a/gateware/cores/vco.sv +++ b/gateware/cores/vco.sv @@ -2,7 +2,7 @@ // // Mapping: // - Input 0: V/Oct input, C3 is +3V -// - Output 0-3: VCO output (from wavetable) phased at 0, 90, 120, 270deg. +// - Output 0: VCO output (from wavetable) module vco #( parameter W = 16, @@ -35,31 +35,30 @@ module vco #( logic [W-1:0] v_oct_lut [0:V_OCT_LUT_SIZE-1]; initial $readmemh(V_OCT_LUT_PATH, v_oct_lut); -logic [W-1:0] wavetable [0:WAVETABLE_SIZE-1]; -initial $readmemh(WAVETABLE_PATH, wavetable); - // For < 0V input, clamp to bottom note. -logic signed [W-1:0] lut_index; -logic [$clog2(V_OCT_LUT_SIZE)-1:0] lut_index_clamped; -logic [31:0] wavetable_pos = 32'h0; - -assign lut_index = sample_in0 >>> 6; -assign lut_index_clamped = $clog2(V_OCT_LUT_SIZE)'(lut_index < 0 ? W'(0) : lut_index); +logic signed [W-1:0] lut_index = 0; +logic signed [W-1:0] lut_index_clamp_lo = 0; always_ff @(posedge sample_clk) begin - // TODO: linear interpolation between frequencies, silence oscillator - // whenever we are outside the LUT bounds. - wavetable_pos <= wavetable_pos + 32'(v_oct_lut[lut_index_clamped]); + if (rst) begin + lut_index <= 0; + lut_index_clamp_lo <= 0; + end else begin + lut_index <= sample_in0 >>> 6; + lut_index_clamp_lo <= lut_index < 0 ? 0 : lut_index; + end end -// Top 8 bits of the N.F fixed-point representation are index into wavetable. -localparam BIT_START = 10 + FDIV; -wire [$clog2(WAVETABLE_SIZE)-1:0] wavetable_idx = - wavetable_pos[BIT_START+$clog2(WAVETABLE_SIZE)-1:BIT_START]; - -assign sample_out0 = wavetable[wavetable_idx]; -assign sample_out1 = wavetable[wavetable_idx+WAVETABLE_SIZE/4]; -assign sample_out2 = wavetable[wavetable_idx+WAVETABLE_SIZE/2]; -assign sample_out3 = wavetable[wavetable_idx+WAVETABLE_SIZE/2+WAVETABLE_SIZE/4]; +wavetable_osc #( + .W(W), + .FRAC_BITS(10), + .WAVETABLE_PATH(WAVETABLE_PATH), + .WAVETABLE_SIZE(WAVETABLE_SIZE) +) osc_0 ( + .rst(rst), + .sample_clk(sample_clk), + .wavetable_inc(32'(v_oct_lut[$clog2(V_OCT_LUT_SIZE)'(lut_index_clamp_lo)])), + .out(sample_out0) +); endmodule diff --git a/gateware/mk/common.mk b/gateware/mk/common.mk index 0574e21..5873876 100644 --- a/gateware/mk/common.mk +++ b/gateware/mk/common.mk @@ -20,4 +20,5 @@ SRC_COMMON = eurorack_pmod.sv \ cores/util/transpose.sv \ cores/util/echo.sv \ cores/util/delayline.sv \ - cores/util/dc_block.sv + cores/util/dc_block.sv \ + cores/util/wavetable_osc.sv diff --git a/gateware/scripts/verilator_lint.sh b/gateware/scripts/verilator_lint.sh index 6df31ce..0f69147 100755 --- a/gateware/scripts/verilator_lint.sh +++ b/gateware/scripts/verilator_lint.sh @@ -35,10 +35,11 @@ verilator --lint-only -Icores clkdiv.sv verilator --lint-only -Icores sampler.sv verilator --lint-only -Icores seqswitch.sv verilator --lint-only -Icores vca.sv -verilator --lint-only -Icores vco.sv +verilator --lint-only -Icores -Icores/util vco.sv verilator --lint-only cores/util/filter/karlsen_lpf.sv verilator --lint-only cores/util/filter/karlsen_lpf_pipelined.sv verilator --lint-only -Icores -Icores/util/filter filter.sv verilator --lint-only -Icores -Icores/util pitch_shift.sv verilator --lint-only -Icores -Icores/util stereo_echo.sv verilator --lint-only -Icores -Icores/util dc_block.sv +verilator --lint-only -Icores -Icores/util wavetable_osc.sv