Skip to content

Commit

Permalink
8voice: works, flawless
Browse files Browse the repository at this point in the history
  • Loading branch information
vk2seb committed Dec 13, 2023
1 parent 43d19e6 commit 93464c8
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 25 deletions.
21 changes: 18 additions & 3 deletions example-colorlight-i5.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,23 @@ def into_mirror(soc, eurorack_pmod):
]

def into_shifter(soc, eurorack_pmod):
N_VOICES = 4
create_voices(soc, eurorack_pmod, N_VOICES)
N_VOICES = 8

create_voices(soc, eurorack_pmod, n_voices=4, start=0, prefix="group0")
create_voices(soc, eurorack_pmod, n_voices=4, start=4, prefix="group1")

# Hacky 8 -> stereo
soc.sync.clk_fs += [
eurorack_pmod.cal_out2.eq((soc.group0cdc_vout0.source.out0 >> 2) +
(soc.group0cdc_vout0.source.out2 >> 2) +
(soc.group1cdc_vout0.source.out0 >> 2) +
(soc.group1cdc_vout0.source.out2 >> 2)),
eurorack_pmod.cal_out3.eq((soc.group0cdc_vout0.source.out1 >> 2) +
(soc.group0cdc_vout0.source.out3 >> 2) +
(soc.group1cdc_vout0.source.out1 >> 2) +
(soc.group1cdc_vout0.source.out3 >> 2)),
]

add_dma_router(soc, eurorack_pmod, output_capable=False)

def add_oled(soc):
Expand Down Expand Up @@ -248,7 +263,7 @@ def main():

add_programn_gpio(soc)

add_usb(soc)
#add_usb(soc)

add_audio_clocks(soc)

Expand Down
20 changes: 18 additions & 2 deletions firmware/polyvec-hal/src/gw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,18 @@ pitch_shift!(pac::PITCH_SHIFT0);
pitch_shift!(pac::PITCH_SHIFT1);
pitch_shift!(pac::PITCH_SHIFT2);
pitch_shift!(pac::PITCH_SHIFT3);
pitch_shift!(pac::PITCH_SHIFT4);
pitch_shift!(pac::PITCH_SHIFT5);
pitch_shift!(pac::PITCH_SHIFT6);
pitch_shift!(pac::PITCH_SHIFT7);
karlsen_lpf!(pac::KARLSEN_LPF0);
karlsen_lpf!(pac::KARLSEN_LPF1);
karlsen_lpf!(pac::KARLSEN_LPF2);
karlsen_lpf!(pac::KARLSEN_LPF3);
karlsen_lpf!(pac::KARLSEN_LPF4);
karlsen_lpf!(pac::KARLSEN_LPF5);
karlsen_lpf!(pac::KARLSEN_LPF6);
karlsen_lpf!(pac::KARLSEN_LPF7);

litex_hal::uart! {
UartMidi: litex_pac::UART_MIDI,
Expand All @@ -192,21 +200,29 @@ litex_hal::spi! {
OledSpi: (litex_pac::OLED_SPI, u8),
}

pub fn get_shifters(p: &pac::Peripherals) -> [&dyn PitchShift; 4] {
pub fn get_shifters(p: &pac::Peripherals) -> [&dyn PitchShift; 8] {
[
&p.PITCH_SHIFT0,
&p.PITCH_SHIFT1,
&p.PITCH_SHIFT2,
&p.PITCH_SHIFT3,
&p.PITCH_SHIFT4,
&p.PITCH_SHIFT5,
&p.PITCH_SHIFT6,
&p.PITCH_SHIFT7,
]
}

pub fn get_lpfs(p: &pac::Peripherals) -> [&dyn KarlsenLpf; 4] {
pub fn get_lpfs(p: &pac::Peripherals) -> [&dyn KarlsenLpf; 8] {
[
&p.KARLSEN_LPF0,
&p.KARLSEN_LPF1,
&p.KARLSEN_LPF2,
&p.KARLSEN_LPF3,
&p.KARLSEN_LPF4,
&p.KARLSEN_LPF5,
&p.KARLSEN_LPF6,
&p.KARLSEN_LPF7,
]
}

Expand Down
2 changes: 1 addition & 1 deletion firmware/polyvec-lib/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ where
if opts.screen.value == opt::Screen::Adsr {

for (n_voice, voice) in voices.iter().enumerate() {
draw_voice(d, (32*n_voice) as i32, 0,
draw_voice(d, (32*(n_voice % 4)) as i32, 32*(n_voice/4) as u32,
n_voice as u32, voice)?;
}

Expand Down
6 changes: 5 additions & 1 deletion firmware/polyvec-lib/src/voice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ufmt::derive::uDebug;

use crate::opt::Options;

pub const N_VOICES: usize = 4;
pub const N_VOICES: usize = 8;

#[derive(Copy, Clone, Debug, PartialEq, uDebug)]
pub enum VoiceState {
Expand Down Expand Up @@ -70,6 +70,10 @@ impl VoiceManager {
Voice::new(0, 0, VoiceState::Idle, 0),
Voice::new(0, 0, VoiceState::Idle, 0),
Voice::new(0, 0, VoiceState::Idle, 0),
Voice::new(0, 0, VoiceState::Idle, 0),
Voice::new(0, 0, VoiceState::Idle, 0),
Voice::new(0, 0, VoiceState::Idle, 0),
Voice::new(0, 0, VoiceState::Idle, 0),
]
}
}
Expand Down
6 changes: 3 additions & 3 deletions firmware/polyvec/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use polyvec_hal::gw::*;
use polyvec_hal::log::*;
use polyvec_hal::*;

const N_VOICES: usize = 4;
const N_VOICES: usize = 8;
const SCOPE_SAMPLES: usize = 128;
const N_CHANNELS: usize = 4;
const BUF_SZ_WORDS: usize = 1024;
Expand Down Expand Up @@ -281,8 +281,8 @@ impl State {

let minor_map: [i8; 24] = [
-12,-12+2,-12+3,-12+5,-12+7,-12+8,-12+10, -1,
0, 2, 3, 5, 7, 8, 10, 13,
12, 12+2, 12+3, 12+5, 12+7, 12+8, 12+10, 25,
0, 2, 3, 5, 7, 8, 10, 11,
12, 12+2, 12+3, 12+5, 12+7, 12+8, 12+10, 23,
];

let index_to_note = |idx| (minor_map[idx] + 60) as u8;
Expand Down
31 changes: 16 additions & 15 deletions rtl/dsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,30 +455,30 @@ def __init__(self, lpf, dw=32):
]


def create_voices(soc, eurorack_pmod, n_voices=4):
def create_voices(soc, eurorack_pmod, n_voices, start, prefix):

multi_shift = MultiPitchShifter(n_shifters=n_voices)
multi_lpf = MultiDcBlockedLpf(n_lpfs=n_voices)
multi_shift = ClockDomainsRenamer("clk_256fs")(MultiPitchShifter(n_shifters=n_voices))
multi_lpf = ClockDomainsRenamer("clk_256fs")(MultiDcBlockedLpf(n_lpfs=n_voices))

soc.comb += [multi_shift.sources[n].connect(multi_lpf.lpfs[n].sink) for n in range(n_voices)]

soc.add_module("multi_shift0", multi_shift);
soc.add_module("multi_lpf0", multi_lpf);
soc.add_module(f"{prefix}multi_shift0", multi_shift);
soc.add_module(f"{prefix}multi_lpf0", multi_lpf);

for n in range(n_voices):
shifter_csr = PitchShifterDecorator(multi_shift.shifters[n])
soc.add_module(f'pitch_shift{n}', shifter_csr)
soc.add_module(f'pitch_shift{n+start}', shifter_csr)
lpf_csr = LpfDecorator(multi_lpf.lpfs[n])
soc.add_module(f'karlsen_lpf{n}', lpf_csr)
soc.add_module(f'karlsen_lpf{n+start}', lpf_csr)

# CDC: PMOD -> shifter delayline write

cdc_vin0 = ClockDomainCrossing(
layout=[("sample", 16)],
cd_from="clk_fs",
cd_to="sys",
cd_to="clk_256fs",
)
soc.add_module("cdc_voice_in0", cdc_vin0)
soc.add_module(f"{prefix}cdc_voice_in0", cdc_vin0)
soc.comb += [
cdc_vin0.sink.valid.eq(1),
cdc_vin0.sink.sample.eq(eurorack_pmod.cal_in0),
Expand All @@ -488,11 +488,11 @@ def create_voices(soc, eurorack_pmod, n_voices=4):
# CDC: DcBlock out -> PMOD channels

cdc_vout0 = ClockDomainCrossing(
layout=[(f"out{n}", 16) for n in range(n_voices)],
cd_from="sys",
layout=[(f"out{n}", (16, True)) for n in range(n_voices)],
cd_from="clk_256fs",
cd_to="clk_fs",
)
soc.add_module("cdc_vout0", cdc_vout0)
soc.add_module(f"{prefix}cdc_vout0", cdc_vout0)

outputs_valids = [b.source.valid for b in multi_lpf.dc_blocks]
soc.comb += cdc_vout0.sink.valid.eq(reduce(lambda x, y: x & y, outputs_valids))
Expand All @@ -503,10 +503,11 @@ def create_voices(soc, eurorack_pmod, n_voices=4):
# Only transfer when sink.valid (all dc_blocks outputs_valid) and sink.ready.
soc.comb += multi_lpf.dc_blocks[n].source.ready.eq(cdc_vout0.sink.valid & cdc_vout0.sink.ready)

# Route CDC exit to eurorack-pmod
soc.comb += cdc_vout0.source.ready.eq(1),
for n in range(n_voices):
soc.comb += getattr(eurorack_pmod, f"cal_out{n}").eq(getattr(cdc_vout0.source, f"out{n}"))

# Route CDC exit to eurorack-pmod
#for n in range(n_voices):
# soc.comb += getattr(eurorack_pmod, f"cal_out{n}").eq(getattr(cdc_vout0.source, f"out{n}"))

class TestDSP(unittest.TestCase):
def test_fixmac(self):
Expand Down

0 comments on commit 93464c8

Please sign in to comment.