def make_wavgen_ios(): clk = Signal(False) reset = Signal(False) select = unsigned_bus(2) threshold = unsigned_bus(N) delta_phase = unsigned_bus(PHASEWIDTH) _output = signed_bus(N) return (clk, reset, select, threshold, delta_phase, _output)
def vca(clk, input_signed, input_unsigned, output_signed): a = signed_bus(18) b = unsigned_bus(18) ab = signed_bus(36) @always(clk.posedge) def get_inputs(): a.next = input_signed b.next = input_unsigned @always_comb def multiply(): ab.next = a * b @always_comb def drive_output(): output_signed.next = (ab >> N) return (get_inputs, multiply, drive_output)
def interpolator(fastclk, clk, reset, input_data, interp_out): # There are 800 fastclk periods during each clk period, so on each fastclk we want to # advance 1/800th from the previous sound sample to the current sample. 800 is pretty # close to (1<<22) divided by 5243, so we can compute a delta by multiplying the # difference between samples by 5243, which is easy because it's constant and not too # many non-zero bits. By accumulating this difference and right-shifting 22 bits, we # arrive almost exactly where we want to end up after 800 accumulations. FRACTION_BITS = 16 delay_1 = signed_bus(N) x = signed_bus(N) interp_step = signed_bus(N + FRACTION_BITS) interp_data = signed_bus(N + FRACTION_BITS) @always(fastclk.posedge, reset.posedge) def do_stuff(): if reset: delay_1.next = 0 interp_data.next = 0 interp_step.next = 0 else: if clk: interp_data.next = delay_1 << FRACTION_BITS delay_1.next = input_data # multiply by 5243 in binary interp_step.next = (x << 12) + (x << 10) + (x << 6) + (x << 5) + \ (x << 4) + (x << 3) + (x << 1) + x elif (interp_data + interp_step) < interp_data.min: interp_data.next = interp_data.min elif (interp_data + interp_step) >= interp_data.max: interp_data.next = interp_data.max - 1 else: interp_data.next = interp_data + interp_step @always_comb def rightshift_for_output(): x.next = input_data - delay_1 interp_out.next = interp_data >> FRACTION_BITS return (do_stuff, rightshift_for_output)
def delta_sigma_dac(fastclk, clk, reset, input_data, dac_bit): interp_result = signed_bus(N) interp_result_unsigned = unsigned_bus(N) # the input of the Xilinx multiplier is an 18-bit factor vc_estimate = unsigned_bus(16) # the output of the Xilinx multiplier is a 36-bit product sum_of_products = unsigned_bus(32) dac_bit_internal = Signal(False) @always_comb def drive_dac_bit(): dac_bit.next = dac_bit_internal @always(fastclk.posedge, reset.posedge) def do_stuff(): # sum_of_products is the next value for vc_estimate, with lots of fraction # bits. vc_estimate already has fraction bits beyond N. All these fraction # bits are helpful in keeping out audible artifacts. if reset: dac_bit_internal.next = 0 vc_estimate.next = 1 << 15 else: dac_bit_internal.next = interp_result_unsigned > ( sum_of_products >> (32 - N)) vc_estimate.next = sum_of_products >> 16 @always_comb def multiply(): if dac_bit_internal: if A + (B * vc_estimate) >= (1 << 32): sum_of_products.next = (1 << 32) - 1 else: sum_of_products.next = A + (B * vc_estimate) else: sum_of_products.next = B * vc_estimate things = [ # Interpolation is a huge help with anti-aliasing. interpolator(fastclk, clk, reset, input_data, interp_result), drive_dac_bit, do_stuff, multiply, signed_to_unsigned(N, interp_result, interp_result_unsigned) ] return things
def delta_sigma_dac(fastclk, clk, reset, input_data, dac_bit): interp_result = signed_bus(N) interp_result_unsigned = unsigned_bus(N) # the input of the Xilinx multiplier is an 18-bit factor vc_estimate = unsigned_bus(16) # the output of the Xilinx multiplier is a 36-bit product sum_of_products = unsigned_bus(32) dac_bit_internal = Signal(False) @always_comb def drive_dac_bit(): dac_bit.next = dac_bit_internal @always(fastclk.posedge, reset.posedge) def do_stuff(): # sum_of_products is the next value for vc_estimate, with lots of fraction # bits. vc_estimate already has fraction bits beyond N. All these fraction # bits are helpful in keeping out audible artifacts. if reset: dac_bit_internal.next = 0 vc_estimate.next = 1 << 15 else: dac_bit_internal.next = interp_result_unsigned > (sum_of_products >> (32 - N)) vc_estimate.next = sum_of_products >> 16 @always_comb def multiply(): if dac_bit_internal: if A + (B * vc_estimate) >= (1 << 32): sum_of_products.next = (1 << 32) - 1 else: sum_of_products.next = A + (B * vc_estimate) else: sum_of_products.next = B * vc_estimate things = [ # Interpolation is a huge help with anti-aliasing. interpolator(fastclk, clk, reset, input_data, interp_result), drive_dac_bit, do_stuff, multiply, signed_to_unsigned(N, interp_result, interp_result_unsigned) ] return things
def fpga(fastclk, reset, param_data, param_clk, audio_req, audio_ack, dac_bit): aclk_counter = unsigned_bus(10) clk = Signal(False) # audio rate clock @always(fastclk.posedge, reset.posedge) def drive_audio_clock(): if reset: aclk_counter.next = 0 clk.next = True elif aclk_counter >= 800: aclk_counter.next = 0 clk.next = True else: aclk_counter.next = aclk_counter + 1 clk.next = False ignored, ignored2, select, threshold, delta_phase, wavgen_output = make_wavgen_ios() keydown = Signal(False) select = unsigned_bus(2) attack = unsigned_bus(4) decay = unsigned_bus(4) sustain = unsigned_bus(4) _release = unsigned_bus(4) amplitude = unsigned_bus(N) _output = signed_bus(N) # more bits than we really need, 18 bits would give 6.5536 seconds input_driver_count = unsigned_bus(24) @always(clk.posedge, reset.posedge) def drive_inputs(): attack.next = 3 decay.next = 5 sustain.next = 8 _release.next = 0 delta_phase.next = DELTA_PHASE select.next = 1 threshold.next = HALF keydown.next = 0 if reset: keydown.next = 0 input_driver_count.next = 0 elif input_driver_count >= 5 * SECOND: keydown.next = 0 input_driver_count.next = 0 elif input_driver_count < 2 * SECOND: keydown.next = 1 input_driver_count.next = input_driver_count + 1 else: keydown.next = 0 input_driver_count.next = input_driver_count + 1 drivers = [ drive_audio_clock, drive_inputs, waveform_generator(clk, reset, select, threshold, delta_phase, wavgen_output), # adsr(clk, reset, keydown, attack, decay, sustain, _release, amplitude), # vca(fastclk, reset, wavgen_output, amplitude, _output), delta_sigma_dac(fastclk, clk, reset, wavgen_output, dac_bit), ] return drivers
def make_dsig_ios(): fastclk = Signal(False) clk = Signal(False) input_data = signed_bus(N) dac_bit = Signal(False) return (fastclk, clk, input_data, dac_bit)
def make_ios(): clk = Signal(False) input_signed = signed_bus(N) input_unsigned = unsigned_bus(N) output_signed = signed_bus(N) return (clk, input_signed, input_unsigned, output_signed)
def fpga(fastclk, reset, param_data, param_clk, audio_req, audio_ack, dac_bit): aclk_counter = unsigned_bus(10) clk = Signal(False) # audio rate clock @always(fastclk.posedge, reset.posedge) def drive_audio_clock(): if reset: aclk_counter.next = 0 clk.next = True elif aclk_counter >= 800: aclk_counter.next = 0 clk.next = True else: aclk_counter.next = aclk_counter + 1 clk.next = False ignored, ignored2, select, threshold, delta_phase, wavgen_output = make_wavgen_ios( ) keydown = Signal(False) select = unsigned_bus(2) attack = unsigned_bus(4) decay = unsigned_bus(4) sustain = unsigned_bus(4) _release = unsigned_bus(4) amplitude = unsigned_bus(N) _output = signed_bus(N) # more bits than we really need, 18 bits would give 6.5536 seconds input_driver_count = unsigned_bus(24) @always(clk.posedge, reset.posedge) def drive_inputs(): attack.next = 3 decay.next = 5 sustain.next = 8 _release.next = 0 delta_phase.next = DELTA_PHASE select.next = 1 threshold.next = HALF keydown.next = 0 if reset: keydown.next = 0 input_driver_count.next = 0 elif input_driver_count >= 5 * SECOND: keydown.next = 0 input_driver_count.next = 0 elif input_driver_count < 2 * SECOND: keydown.next = 1 input_driver_count.next = input_driver_count + 1 else: keydown.next = 0 input_driver_count.next = input_driver_count + 1 drivers = [ drive_audio_clock, drive_inputs, waveform_generator(clk, reset, select, threshold, delta_phase, wavgen_output), # adsr(clk, reset, keydown, attack, decay, sustain, _release, amplitude), # vca(fastclk, reset, wavgen_output, amplitude, _output), delta_sigma_dac(fastclk, clk, reset, wavgen_output, dac_bit), ] return drivers