waveform sucessfully runs
This commit is contained in:
parent
3fac5747cc
commit
26fcd0af59
|
@ -93,41 +93,40 @@ class Waveform(LiteXModule):
|
||||||
force_stop = Signal()
|
force_stop = Signal()
|
||||||
|
|
||||||
self.sync += If(b.cyc & b.stb & ~b.ack,
|
self.sync += If(b.cyc & b.stb & ~b.ack,
|
||||||
Case(b.adr, {
|
Case(b.adr[0:5], {
|
||||||
0x0: If(b.we,
|
0x0: If(b.we,
|
||||||
run.eq(b.dat_w[0]),
|
run.eq(b.dat_w[0]),
|
||||||
).Else(
|
).Else(
|
||||||
b.dat_r[0].eq(run)
|
b.dat_r.eq(run)
|
||||||
),
|
),
|
||||||
0x4: [
|
0x4: [
|
||||||
b.dat_r[0:counter_max_wid].eq(cntr),
|
b.dat_r.eq(cntr),
|
||||||
],
|
],
|
||||||
0x8: [
|
0x8: [
|
||||||
If(b.we,
|
If(b.we,
|
||||||
do_loop.eq(b.dat_w[0]),
|
do_loop.eq(b.dat_w[0]),
|
||||||
).Else(
|
).Else(
|
||||||
b.dat_r[0].eq(do_loop),
|
b.dat_r.eq(do_loop),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
0xC: [
|
0xC: [
|
||||||
b.dat_r[0].eq(ready),
|
b.dat_r.eq(finished << 1 | ready),
|
||||||
b.dat_r[1].eq(finished),
|
|
||||||
],
|
],
|
||||||
0x10: If(b.we,
|
0x10: If(b.we,
|
||||||
wform_size.eq(b.dat_w[0:counter_max_wid]),
|
wform_size.eq(b.dat_w[0:counter_max_wid]),
|
||||||
).Else(
|
).Else(
|
||||||
b.dat_r[0:counter_max_wid].eq(wform_size)
|
b.dat_r.eq(wform_size)
|
||||||
),
|
),
|
||||||
0x14: b.dat_r[0:timer_wid].eq(timer),
|
0x14: b.dat_r.eq(timer),
|
||||||
0x18: If(b.we,
|
0x18: If(b.we,
|
||||||
timer_spacing.eq(b.dat_w[0:timer_wid]),
|
timer_spacing.eq(b.dat_w[0:timer_wid]),
|
||||||
).Else(
|
).Else(
|
||||||
b.dat_r[0:timer_wid].eq(timer_spacing),
|
b.dat_r.eq(timer_spacing),
|
||||||
),
|
),
|
||||||
0x1C: If(b.we,
|
0x1C: If(b.we,
|
||||||
force_stop.eq(b.dat_w[0]),
|
force_stop.eq(b.dat_w[0]),
|
||||||
).Else(
|
).Else(
|
||||||
b.dat_r[0].eq(force_stop),
|
b.dat_r.eq(force_stop),
|
||||||
),
|
),
|
||||||
# (W)A(V)EFO(RM)
|
# (W)A(V)EFO(RM)
|
||||||
"default": b.dat_r.eq(0xAEF0AEF0),
|
"default": b.dat_r.eq(0xAEF0AEF0),
|
||||||
|
|
|
@ -67,6 +67,7 @@ CHECK_START: if (run) begin
|
||||||
state <= CHECK_LEN;
|
state <= CHECK_LEN;
|
||||||
end else begin
|
end else begin
|
||||||
ready <= 1;
|
ready <= 1;
|
||||||
|
finished <= 0;
|
||||||
end
|
end
|
||||||
CHECK_LEN: if (cntr >= wform_size) begin
|
CHECK_LEN: if (cntr >= wform_size) begin
|
||||||
if (do_loop) begin
|
if (do_loop) begin
|
||||||
|
@ -79,11 +80,9 @@ CHECK_LEN: if (cntr >= wform_size) begin
|
||||||
state <= READ_RAM;
|
state <= READ_RAM;
|
||||||
end
|
end
|
||||||
WAIT_FINISHED: if (!run) begin
|
WAIT_FINISHED: if (!run) begin
|
||||||
finished <= 0;
|
|
||||||
state <= CHECK_START;
|
state <= CHECK_START;
|
||||||
end else if (do_loop) begin
|
end else if (do_loop) begin
|
||||||
state <= READ_RAM;
|
state <= READ_RAM;
|
||||||
finished <= 0;
|
|
||||||
cntr <= 0;
|
cntr <= 0;
|
||||||
end else begin
|
end else begin
|
||||||
finished <= 1;
|
finished <= 1;
|
||||||
|
@ -174,7 +173,6 @@ end
|
||||||
* master switch for the DAC to the main CPU.
|
* master switch for the DAC to the main CPU.
|
||||||
*/
|
*/
|
||||||
WAIT_PERIOD: if (!run) begin
|
WAIT_PERIOD: if (!run) begin
|
||||||
finished <= 0;
|
|
||||||
state <= CHECK_START;
|
state <= CHECK_START;
|
||||||
end else if (timer < timer_spacing) begin
|
end else if (timer < timer_spacing) begin
|
||||||
timer <= timer + 1;
|
timer <= timer + 1;
|
||||||
|
|
|
@ -305,6 +305,9 @@ class UpsilonSoC(SoCCore):
|
||||||
return self.add_spi_master(name, **args)
|
return self.add_spi_master(name, **args)
|
||||||
|
|
||||||
def add_waveform(self, name, ram_len, **kwargs):
|
def add_waveform(self, name, ram_len, **kwargs):
|
||||||
|
# TODO: Either set the SPI interface at instantiation time,
|
||||||
|
# or allow waveform to read more than one SPI bus (either by
|
||||||
|
# master switching or addressing by Waveform).
|
||||||
kwargs['counter_max_wid'] = minbits(ram_len)
|
kwargs['counter_max_wid'] = minbits(ram_len)
|
||||||
wf = Waveform(**kwargs)
|
wf = Waveform(**kwargs)
|
||||||
|
|
||||||
|
@ -316,8 +319,8 @@ class UpsilonSoC(SoCCore):
|
||||||
wf.add_ram(bram_pi.add_master(name), ram_len)
|
wf.add_ram(bram_pi.add_master(name), ram_len)
|
||||||
|
|
||||||
def f(csrs):
|
def f(csrs):
|
||||||
origin = csrs["memories"][name.lower() + "_pi"]["base"]
|
param_origin = csrs["memories"][name.lower() + "_pi"]["base"]
|
||||||
return f'{name} = RegisterRegion({origin}, {wf.mmio(origin)})'
|
return f'{name} = Waveform({name}_ram, {name}_PI, {name}_ram_PI, RegisterRegion({param_origin}, {wf.mmio(param_origin)}))'
|
||||||
self.mmio_closures.append(f)
|
self.mmio_closures.append(f)
|
||||||
return wf, pi
|
return wf, pi
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
.SUFFIXES: .mpy .py
|
.SUFFIXES: .mpy .py
|
||||||
|
|
||||||
MPY=picorv32.mpy registers.mpy spi.mpy waveform.mpy mmio.mpy
|
MPY=picorv32.mpy registers.mpy spi.mpy waveform.mpy mmio.mpy random.mpy
|
||||||
|
|
||||||
all: $(MPY)
|
all: $(MPY)
|
||||||
.py.mpy:
|
.py.mpy:
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
class RandomGenerator:
|
||||||
|
# XorShift
|
||||||
|
def __init__(self, seed=2463534242):
|
||||||
|
self.seed = seed
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
self.seed = self.seed ^ ((self.seed << 13) & 0xFFFFFFFF)
|
||||||
|
self.seed = self.seed ^ ((self.seed >> 17) & 0xFFFFFFFF)
|
||||||
|
self.seed = self.seed ^ ((self.seed << 5) & 0xFFFFFFFF)
|
||||||
|
return self.seed
|
|
@ -3,14 +3,14 @@ from registers import *
|
||||||
class SPI(RegisterRegion):
|
class SPI(RegisterRegion):
|
||||||
def __init__(self, spiwid, spi_PI, origin, **regs):
|
def __init__(self, spiwid, spi_PI, origin, **regs):
|
||||||
self.spiwid = spiwid
|
self.spiwid = spiwid
|
||||||
self.spi_PI = spi_PI
|
self.PI = spi_PI
|
||||||
super().__init__(origin, **regs)
|
super().__init__(origin, **regs)
|
||||||
|
|
||||||
def send(self, val, force=False):
|
def send(self, val, force=False):
|
||||||
if self.spi_PI.v != 0 and not force:
|
if self.PI.v != 0 and not force:
|
||||||
raise Exception("SPI is controlled by another master")
|
raise Exception("SPI is controlled by another master")
|
||||||
|
|
||||||
self.spi_PI.v = 0
|
self.PI.v = 0
|
||||||
|
|
||||||
self.arm.v = 0
|
self.arm.v = 0
|
||||||
while self.finished_or_ready.v == 0:
|
while self.finished_or_ready.v == 0:
|
||||||
|
|
|
@ -1,23 +1,34 @@
|
||||||
from registers import *
|
from registers import *
|
||||||
|
|
||||||
class Waveform(Immutable):
|
class Waveform(Immutable):
|
||||||
def __init__(self, ram, ram_pi, regs):
|
def __init__(self, ram, wf_pi, ram_pi, regs):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
self.wf_pi = wf_pi
|
||||||
self.ram = ram
|
self.ram = ram
|
||||||
self.ram_pi = ram_pi
|
self.ram_pi = ram_pi
|
||||||
self.regs = regs
|
self.regs = regs
|
||||||
|
|
||||||
self.make_immutable()
|
self.make_immutable()
|
||||||
|
|
||||||
def run(self, wf, timer_spacing, do_loop = False):
|
def start(self, wf, timer_spacing, do_loop = False, force_control=False):
|
||||||
""" Start waveform with signal.
|
""" Start waveform with signal.
|
||||||
|
Note that a transfer of control of the SPI bus to the Waveform
|
||||||
|
must be done manually.
|
||||||
|
|
||||||
:param wf: Array of integers that describe the waveform.
|
:param wf: Array of integers that describe the waveform.
|
||||||
These are twos-complement 20-bit integers.
|
These are twos-complement 20-bit integers.
|
||||||
:param timer_spacing: The amount of time to wait between
|
:param timer_spacing: The amount of time to wait between
|
||||||
points on the waveform.
|
points on the waveform.
|
||||||
:param do_loop: If True, the waveform will repeat.
|
:param do_loop: If True, the waveform will repeat.
|
||||||
|
:param force_control: If True, will take control of the Waveform
|
||||||
|
even if it is being controlled by another Wishbone bus.
|
||||||
"""
|
"""
|
||||||
|
if self.wf_pi.v != 0:
|
||||||
|
if not force_control:
|
||||||
|
raise Exception("Waveform is not controlled by master")
|
||||||
|
self.wf_pi.v = 0
|
||||||
|
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
self.ram_pi.v = 0
|
self.ram_pi.v = 0
|
||||||
|
@ -32,15 +43,15 @@ class Waveform(Immutable):
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
""" Stop the waveform and wait until it is ready. """
|
""" Stop the waveform and wait until it is ready. """
|
||||||
self.regs.run = 0
|
self.regs.run.v = 0
|
||||||
self.regs.do_loop = 0
|
self.regs.do_loop.v = 0
|
||||||
|
|
||||||
while self.regs.finished_or_ready == 0:
|
while self.regs.finished_or_ready.v == 0:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def force_stop(self):
|
def force_stop(self):
|
||||||
self.regs.force_stop = 1
|
self.regs.force_stop.v = 1
|
||||||
selff.regs.force_stop = 0
|
selff.regs.force_stop.v = 0
|
||||||
|
|
||||||
def dump(self):
|
def dump(self):
|
||||||
""" Dump contents of control registers. """
|
""" Dump contents of control registers. """
|
||||||
|
|
Loading…
Reference in New Issue