Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions gateware/src/rs/hal/src/persist.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/// Unified persistence control.
///
/// Maps a single 1-80 value to decay, holdoff and probabilistic skip:
/// 1-15: decay ramps 15->1, holdoff=32, skip=0
/// 16-64: decay=1, holdoff=32, skip ramps up
/// 65-80: decay=1, holdoff ramps 32->256, skip continues ramping
pub trait Persist {
fn set_persist(&mut self, value: u16);
fn set_decay(&mut self, value: u8);
fn set_persistence(&mut self, value: u8);
}

#[macro_export]
Expand All @@ -18,17 +23,39 @@ macro_rules! impl_persist {
pub fn new(registers: $PACPERSISTX) -> Self {
Self { registers }
}
}

impl hal::persist::Persist for $PERSISTX {
fn set_persist(&mut self, value: u16) {
fn set_holdoff(&mut self, value: u16) {
self.registers.persist().write(|w| unsafe { w.persist().bits(value) } );
}

fn set_decay(&mut self, value: u8) {
self.registers.decay().write(|w| unsafe { w.decay().bits(value) } );
}

fn set_skip(&mut self, value: u8) {
self.registers.skip().write(|w| unsafe { w.skip().bits(value) } );
}
}

impl hal::persist::Persist for $PERSISTX {
fn set_persistence(&mut self, value: u8) {
let p = value as u32;
if p <= 15 {
self.set_decay((16 - p) as u8);
self.set_holdoff(32);
self.set_skip(0);
} else {
let t = p - 16; // 0..64
self.set_decay(1);
self.set_skip(core::cmp::min(t << 2, 255) as u8);
if p <= 64 {
self.set_holdoff(32);
} else {
let h = p - 65; // 0..15
self.set_holdoff(core::cmp::min(32 + (h << 5), 256) as u16);
}
}
}
}
)+
};
Expand Down
30 changes: 27 additions & 3 deletions gateware/src/tiliqua/raster/persist.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def __init__(self, *, bus_signature,
# Tweakables
"holdoff": In(16, init=holdoff_default),
"decay": In(4, init=1),
"skip": In(8, init=0),
# DMA bus / fb
"bus": Out(bus_signature),
"fbp": In(DMAFramebuffer.Properties()),
Expand Down Expand Up @@ -70,11 +71,21 @@ def elaborate(self, platform) -> Module:

# Latched version of decay speed control input
decay_latch = Signal.like(self.decay)
# Latched version of skip probability control input
skip_latch = Signal.like(self.skip)
# Track delay between read/write bursts
holdoff_count = Signal(32)
# Incoming pixel array (read from FIFO)
pixels_r = Signal(data.ArrayLayout(Pixel, 4))

# Free-running LFSR for probabilistic pixel skipping.
lfsr0 = Signal(unsigned(32), init=0x67452301)
lfsr1 = Signal(unsigned(32), init=0xefcdab89)
lfsr1_next = Signal(unsigned(32))
m.d.comb += lfsr1_next.eq(lfsr1 + lfsr0)
m.d.sync += lfsr1.eq(lfsr1_next)
m.d.sync += lfsr0.eq(lfsr0 ^ lfsr1_next)

m.d.comb += self.fifo.w_data.eq(bus.dat_r)

# Used for fastpath when all pixels are zero
Expand All @@ -101,6 +112,7 @@ def elaborate(self, platform) -> Module:

with m.State('BURST-IN'):
m.d.sync += decay_latch.eq(self.decay)
m.d.sync += skip_latch.eq(self.skip)
m.d.comb += [
bus.stb.eq(1),
bus.cyc.eq(1),
Expand Down Expand Up @@ -135,12 +147,17 @@ def elaborate(self, platform) -> Module:

with m.State('BURST-OUT'):
# The actual persistance calculation. 4 pixels at a time.
#
# Per-pixel LFSR comparison decides whether to decay or
# write back unchanged (probabilistic skip).
pixels_w = Signal(data.ArrayLayout(Pixel, 4))
for n in range(4):
# color
skip_this = Signal(name=f"skip_{n}")
m.d.comb += skip_this.eq(lfsr1[n*8:(n*8)+8] < skip_latch)
m.d.comb += pixels_w[n].color.eq(pixels_r[n].color)
# intensity
with m.If(pixels_r[n].intensity >= decay_latch):
with m.If(skip_this):
m.d.comb += pixels_w[n].intensity.eq(pixels_r[n].intensity)
with m.Elif(pixels_r[n].intensity >= decay_latch):
m.d.comb += pixels_w[n].intensity.eq(pixels_r[n].intensity - decay_latch)
with m.Else():
m.d.comb += pixels_w[n].intensity.eq(0)
Expand Down Expand Up @@ -184,6 +201,9 @@ class PersistReg(csr.Register, access="w"):
class DecayReg(csr.Register, access="w"):
decay: csr.Field(csr.action.W, unsigned(8))

class SkipReg(csr.Register, access="w"):
skip: csr.Field(csr.action.W, unsigned(8))

def __init__(self, bus_dma):
self.en = Signal()
self.persist = Persistance(bus_signature=bus_dma.bus.signature.flip())
Expand All @@ -193,6 +213,7 @@ def __init__(self, bus_dma):

self._persist = regs.add("persist", self.PersistReg(), offset=0x0)
self._decay = regs.add("decay", self.DecayReg(), offset=0x4)
self._skip = regs.add("skip", self.SkipReg(), offset=0x8)

self._bridge = csr.Bridge(regs.as_memory_map())

Expand All @@ -216,4 +237,7 @@ def elaborate(self, platform):
with m.If(self._decay.f.decay.w_stb):
m.d.sync += self.persist.decay.eq(self._decay.f.decay.w_data)

with m.If(self._skip.f.skip.w_stb):
m.d.sync += self.persist.skip.eq(self._skip.f.skip.w_data)

return m
2 changes: 1 addition & 1 deletion gateware/src/top/bootloader/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ fn main() -> ! {
let mut logo_coord_ix = 0u32;
let mut rng = fastrand::Rng::with_seed(0);

persist.set_persist(256);
persist.set_persistence(64);

let stroke = PrimitiveStyleBuilder::new()
.stroke_color(HI8::new(0, 10))
Expand Down
6 changes: 2 additions & 4 deletions gateware/src/top/macro_osc/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,9 @@ fn main() -> ! {
}

if on_help_page {
persist.set_persist(256);
persist.set_decay(1);
persist.set_persistence(64);
} else {
persist.set_persist(opts.beam.persist.value);
persist.set_decay(opts.beam.decay.value);
persist.set_persistence(opts.beam.persist.value);
}

vscope.set_hue(opts.beam.hue.value);
Expand Down
7 changes: 2 additions & 5 deletions gateware/src/top/macro_osc/fw/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ int_params!(NoteParams<u8> { step: 1, min: 0, max: 128 });
int_params!(HarmonicsParams<u8> { step: 8, min: 0, max: 240 });
int_params!(TimbreParams<u8> { step: 8, min: 0, max: 240 });
int_params!(MorphParams<u8> { step: 8, min: 0, max: 240 });
int_params!(PersistParams<u16> { step: 128, min: 128, max: 8192 });
int_params!(DecayParams<u8> { step: 1, min: 0, max: 15 });
int_params!(PersistParams<u8> { step: 1, min: 1, max: 80 });
int_params!(IntensityParams<u8> { step: 1, min: 0, max: 15 });
int_params!(HueParams<u8> { step: 1, min: 0, max: 15 });
int_params!(TriggerLvlParams<i16> { step: 500, min: -16000, max: 16000, format: IntFormat::Scaled { divisor: 4000, precision: 2, suffix: "V" } });
Expand Down Expand Up @@ -113,10 +112,8 @@ pub struct VectorOpts {

#[derive(OptionPage, Clone)]
pub struct BeamOpts {
#[option(256)]
#[option(15)]
pub persist: IntOption<PersistParams>,
#[option(1)]
pub decay: IntOption<DecayParams>,
#[option(8)]
pub intensity: IntOption<IntensityParams>,
#[option(10)]
Expand Down
9 changes: 3 additions & 6 deletions gateware/src/top/polysyn/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,9 @@ fn build_cc_mapper(opts: &Opts) -> MidiCcMapper {
// Effect page (CC 40-41)
m.add(40, global_index(opts, &opts.effect.drive), CcMapMode::Absolute);
m.add(41, global_index(opts, &opts.effect.diffuse), CcMapMode::Absolute);
// Beam page (CC 50-55)
// Beam page (CC 50-55, CC 52 formerly decay now unused)
m.add(50, global_index(opts, &opts.beam.scale), CcMapMode::Absolute);
m.add(51, global_index(opts, &opts.beam.persist), CcMapMode::Absolute);
m.add(52, global_index(opts, &opts.beam.decay), CcMapMode::Absolute);
m.add(53, global_index(opts, &opts.beam.intensity), CcMapMode::Absolute);
m.add(54, global_index(opts, &opts.beam.hue), CcMapMode::Absolute);
m.add(55, global_index(opts, &opts.beam.palette), CcMapMode::Absolute);
Expand Down Expand Up @@ -484,12 +483,10 @@ fn main() -> ! {
v_active,
opts.help.scroll.value,
opts.beam.hue.value).ok();
persist.set_persist(128);
persist.set_decay(1);
persist.set_persistence(64);
vscope.set_enabled(false);
} else {
persist.set_persist(opts.beam.persist.value);
persist.set_decay(opts.beam.decay.value);
persist.set_persistence(opts.beam.persist.value);
vscope.set_enabled(true);
}

Expand Down
7 changes: 2 additions & 5 deletions gateware/src/top/polysyn/fw/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ int_params!(ResoParams<u16> { step: 2048, min: 0, max: 32768, format: IntF
int_params!(DiffuseParams<u16> { step: 2048, min: 0, max: 32768, format: IntFormat::Scaled { divisor: 32768, precision: 2, suffix: "" } });
int_params!(AdsrTimeParams<u16> { step: 1024, min: 0, max: 16384, format: IntFormat::Scaled { divisor: 16384, precision: 2, suffix: "" } });
int_params!(AdsrLevelParams<u16> { step: 1024, min: 0, max: 32768, format: IntFormat::Scaled { divisor: 32768, precision: 2, suffix: "" } });
int_params!(PersistParams<u16> { step: 32, min: 32, max: 4096 });
int_params!(DecayParams<u8> { step: 1, min: 0, max: 15 });
int_params!(PersistParams<u8> { step: 1, min: 1, max: 80 });
int_params!(IntensityParams<u8> { step: 1, min: 0, max: 15 });
int_params!(HueParams<u8> { step: 1, min: 0, max: 15 });
int_params!(ScrollParams<u8> { step: 1, min: 0, max: 125 });
Expand Down Expand Up @@ -139,10 +138,8 @@ pub struct AdsrOpts {
pub struct BeamOpts {
#[option(VScale::Scale2V)]
pub scale: EnumOption<VScale>,
#[option(32)]
#[option(15)]
pub persist: IntOption<PersistParams>,
#[option(1)]
pub decay: IntOption<DecayParams>,
#[option(8)]
pub intensity: IntOption<IntensityParams>,
#[option(10)]
Expand Down
4 changes: 2 additions & 2 deletions gateware/src/top/polysyn/top.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@
EFFECT diffuse 41 diffusion wet/dry mix

BEAM scale 50 vectorscope volts/div
BEAM persist 51 phosphor decay speed (high = slow)
BEAM decay 52 phosphor decay amount (low = slow)
BEAM persist 51 phosphor persistence (high = slow)
- (CC 52 deprecated)
BEAM intensity 53 trace intensity
BEAM hue 54 trace and menu hue
BEAM palette 55 color palette
Expand Down
6 changes: 2 additions & 4 deletions gateware/src/top/sampler/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,9 @@ fn main() -> ! {
v_active,
opts.help.scroll.value,
hue).ok();
persist.set_persist(128);
persist.set_decay(1);
persist.set_persistence(64);
} else {
persist.set_persist(128);
persist.set_decay(1);
persist.set_persistence(32);
}


Expand Down
2 changes: 1 addition & 1 deletion gateware/src/top/selftest/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ fn main() -> ! {
irq::scope(|s| {

palette::ColorPalette::default().write_to_hardware(&mut display);
persist.set_persist(128);
persist.set_persistence(20);

s.register(handlers::Interrupt::TIMER0, timer0);

Expand Down
4 changes: 2 additions & 2 deletions gateware/src/top/sid/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ fn main() -> ! {

// Draw UI elements
if on_help_page {
persist.set_persist(128);
persist.set_persistence(64);
draw::draw_options(&mut display, &opts, h_active/2-30, v_active-100, hue).ok();
draw::draw_name(&mut display, h_active/2, v_active-50, hue,
&bootinfo.manifest.name, &bootinfo.manifest.tag, &modeline).ok();
Expand All @@ -284,7 +284,7 @@ fn main() -> ! {
opts.help.scroll.value,
hue).ok();
} else {
persist.set_persist(64);
persist.set_persistence(15);
draw::draw_options(&mut display, &opts, 100, v_active/2, hue).ok();
draw::draw_name(&mut display, h_active/2, v_active-50, hue,
&bootinfo.manifest.name, &bootinfo.manifest.tag, &modeline).ok();
Expand Down
9 changes: 3 additions & 6 deletions gateware/src/top/xbeam/fw/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ fn build_cc_mapper(opts: &Opts) -> MidiCcMapper {
m.add(31, global_index(opts, &opts.delay.delay_y), CcMapMode::Absolute);
m.add(32, global_index(opts, &opts.delay.delay_i), CcMapMode::Absolute);
m.add(33, global_index(opts, &opts.delay.delay_c), CcMapMode::Absolute);
// Beam page (CC 40-45)
// Beam page (CC 40-45, CC 41 formerly decay now unused)
m.add(40, global_index(opts, &opts.beam.persist), CcMapMode::Absolute);
m.add(41, global_index(opts, &opts.beam.decay), CcMapMode::Absolute);
m.add(42, global_index(opts, &opts.beam.ui_hue), CcMapMode::Absolute);
m.add(43, global_index(opts, &opts.beam.palette), CcMapMode::Absolute);
m.add(44, global_index(opts, &opts.beam.grid), CcMapMode::Absolute);
Expand Down Expand Up @@ -281,11 +280,9 @@ fn main() -> ! {
v_active,
opts.help.scroll.value,
opts.beam.ui_hue.value).ok();
persist.set_persist(128);
persist.set_decay(1);
persist.set_persistence(64);
} else {
persist.set_persist(opts.beam.persist.value);
persist.set_decay(opts.beam.decay.value);
persist.set_persistence(opts.beam.persist.value);
}


Expand Down
7 changes: 2 additions & 5 deletions gateware/src/top/xbeam/fw/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ pub enum XZoom {

int_params!(DelayParams<u16> { step: 8, min: 0, max: 512, format: IntFormat::Scaled { divisor: AUDIO_FS / 1000, precision: 1, suffix: "ms" } });
int_params!(PCScaleParams<u8> { step: 1, min: 0, max: 15 });
int_params!(PersistParams<u16> { step: 32, min: 32, max: 4096 });
int_params!(DecayParams<u8> { step: 1, min: 0, max: 15 });
int_params!(PersistParams<u8> { step: 1, min: 1, max: 80 });
int_params!(IntensityParams<u8> { step: 1, min: 0, max: 15 });
int_params!(HueParams<u8> { step: 1, min: 0, max: 15 });
int_params!(TriggerLvlParams<i16> { step: 500, min: -16000, max: 16000, format: IntFormat::Scaled { divisor: 4000, precision: 2, suffix: "V" } });
Expand Down Expand Up @@ -141,10 +140,8 @@ pub struct DelayOpts {

#[derive(OptionPage, Clone)]
pub struct BeamOpts {
#[option(32)]
#[option(15)]
pub persist: IntOption<PersistParams>,
#[option(1)]
pub decay: IntOption<DecayParams>,
#[option(10)]
pub ui_hue: IntOption<HueParams>,
#[option]
Expand Down
4 changes: 2 additions & 2 deletions gateware/src/top/xbeam/top.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@
DELAY delay-i 32 in2/intensity delayline length
DELAY delay-c 33 in3/color delayline length

BEAM persist 40 phosphor decay speed (high = slow)
BEAM decay 41 phosphor decay amount (low = slow)
BEAM persist 40 phosphor persistence (high = slow)
- (CC 41 deprecated)
BEAM ui-hue 42 menu and grid overlay hue
BEAM palette 43 color palette
BEAM grid 44 grid overlay style
Expand Down
Loading