mila: test rle
This commit is contained in:
parent
a880862628
commit
69009c8405
|
@ -24,6 +24,12 @@ class MiLaCtrl():
|
||||||
mila_trigger_sum_prog_dat_write(self.bus, dat)
|
mila_trigger_sum_prog_dat_write(self.bus, dat)
|
||||||
mila_trigger_sum_prog_we_write(self.bus, 1)
|
mila_trigger_sum_prog_we_write(self.bus, 1)
|
||||||
|
|
||||||
|
def enable_rle(self):
|
||||||
|
mila_rle_enable_write(self.bus, 1)
|
||||||
|
|
||||||
|
def disable_rle(self):
|
||||||
|
mila_rle_enable_write(self.bus, 0)
|
||||||
|
|
||||||
def is_done(self):
|
def is_done(self):
|
||||||
return mila_recorder_done_read(self.bus)
|
return mila_recorder_done_read(self.bus)
|
||||||
|
|
||||||
|
@ -46,6 +52,7 @@ trig_w = 16
|
||||||
dat_w = 16
|
dat_w = 16
|
||||||
rec_length = 512
|
rec_length = 512
|
||||||
rec_offset = 0
|
rec_offset = 0
|
||||||
|
rle = True
|
||||||
|
|
||||||
#==============================================================================
|
#==============================================================================
|
||||||
# T E S T M I L A
|
# T E S T M I L A
|
||||||
|
@ -72,6 +79,8 @@ def capture():
|
||||||
|
|
||||||
print("Capturing ...")
|
print("Capturing ...")
|
||||||
print("----------------------")
|
print("----------------------")
|
||||||
|
if rle:
|
||||||
|
mila.enable_rle()
|
||||||
mila.prog_term(0x0000, 0xFFFF)
|
mila.prog_term(0x0000, 0xFFFF)
|
||||||
capture()
|
capture()
|
||||||
|
|
||||||
|
@ -82,6 +91,9 @@ mila_layout = [
|
||||||
("cnt", 8),
|
("cnt", 8),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if rle:
|
||||||
|
dat_vcd = dat_vcd.decode_rle()
|
||||||
|
|
||||||
myvcd = Vcd()
|
myvcd = Vcd()
|
||||||
myvcd.add_from_layout(mila_layout, dat_vcd)
|
myvcd.add_from_layout(mila_layout, dat_vcd)
|
||||||
myvcd.write("test_mila.vcd")
|
myvcd.write("test_mila.vcd")
|
|
@ -55,7 +55,7 @@ class SoC(Module):
|
||||||
|
|
||||||
# MiLa
|
# MiLa
|
||||||
term = Term(mila_width)
|
term = Term(mila_width)
|
||||||
self.submodules.mila = MiLa(mila_width, mila_depth, [term])
|
self.submodules.mila = MiLa(mila_width, mila_depth, [term], rle=True)
|
||||||
|
|
||||||
# Uart2Csr
|
# Uart2Csr
|
||||||
self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200)
|
self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200)
|
||||||
|
@ -72,7 +72,7 @@ class SoC(Module):
|
||||||
self.led = Cat(*[platform.request("user_led", i) for i in range(8)])
|
self.led = Cat(*[platform.request("user_led", i) for i in range(8)])
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
self.cnt = Signal(9)
|
self.cnt = Signal(16)
|
||||||
self.submodules.freqgen = FreqGen(clk_freq, 500*KHz)
|
self.submodules.freqgen = FreqGen(clk_freq, 500*KHz)
|
||||||
self.submodules.eventgen_rising = EventGen(RISING_EDGE, clk_freq, 100*ns)
|
self.submodules.eventgen_rising = EventGen(RISING_EDGE, clk_freq, 100*ns)
|
||||||
self.submodules.eventgen_falling = EventGen(FALLING_EDGE, clk_freq, 100*ns)
|
self.submodules.eventgen_falling = EventGen(FALLING_EDGE, clk_freq, 100*ns)
|
||||||
|
@ -103,7 +103,7 @@ class SoC(Module):
|
||||||
self.freqgen.o,
|
self.freqgen.o,
|
||||||
self.eventgen_rising.o,
|
self.eventgen_rising.o,
|
||||||
self.eventgen_falling.o,
|
self.eventgen_falling.o,
|
||||||
self.cnt)
|
self.cnt[8:12])
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
self.sync += self.cnt.eq(self.cnt+1)
|
self.sync += self.cnt.eq(self.cnt+1)
|
||||||
|
|
|
@ -5,30 +5,46 @@ from migen.bus import csr
|
||||||
from migen.bank import description, csrgen
|
from migen.bank import description, csrgen
|
||||||
from migen.bank.description import *
|
from migen.bank.description import *
|
||||||
|
|
||||||
|
from miscope.std import *
|
||||||
from miscope.trigger import Trigger
|
from miscope.trigger import Trigger
|
||||||
from miscope.storage import Recorder
|
from miscope.storage import RunLengthEncoder, Recorder
|
||||||
|
|
||||||
class MiLa(Module, AutoCSR):
|
class MiLa(Module, AutoCSR):
|
||||||
def __init__(self, width, depth, ports):
|
def __init__(self, width, depth, ports, rle=False):
|
||||||
self.width = width
|
self.width = width
|
||||||
|
|
||||||
|
self.sink = rec_dat(width)
|
||||||
|
|
||||||
trigger = Trigger(width, ports)
|
trigger = Trigger(width, ports)
|
||||||
recorder = Recorder(width, depth)
|
recorder = Recorder(width, depth)
|
||||||
|
|
||||||
self.submodules.trigger = trigger
|
self.submodules.trigger = trigger
|
||||||
self.submodules.recorder = recorder
|
self.submodules.recorder = recorder
|
||||||
|
|
||||||
self.sink = trigger.sink
|
|
||||||
|
|
||||||
self.comb += [
|
self.comb += [
|
||||||
recorder.sink.stb.eq(trigger.source.stb),
|
|
||||||
|
|
||||||
recorder.sink.hit.eq(trigger.source.hit),
|
trigger.sink.stb.eq(self.sink.stb),
|
||||||
trigger.source.ack.eq(recorder.sink.ack)
|
trigger.sink.dat.eq(self.sink.dat),
|
||||||
|
|
||||||
|
recorder.trig_sink.stb.eq(trigger.source.stb),
|
||||||
|
recorder.trig_sink.hit.eq(trigger.source.hit),
|
||||||
|
trigger.source.ack.eq(recorder.trig_sink.ack),
|
||||||
|
|
||||||
|
self.sink.ack.eq(1), #FIXME
|
||||||
]
|
]
|
||||||
|
|
||||||
# Todo; Insert configurable delay to support pipelined
|
if rle:
|
||||||
# triggers elements
|
self.submodules.rle = RunLengthEncoder(width, 1024)
|
||||||
self.comb +=[
|
self.comb +=[
|
||||||
recorder.sink.dat.eq(self.sink.dat),
|
self.rle.sink.stb.eq(self.sink.stb),
|
||||||
|
self.rle.sink.dat.eq(self.sink.dat),
|
||||||
|
|
||||||
|
recorder.dat_sink.stb.eq(self.rle.source.stb),
|
||||||
|
recorder.dat_sink.dat.eq(self.rle.source.dat),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
self.comb +=[
|
||||||
|
recorder.dat_sink.stb.eq(self.sink.stb),
|
||||||
|
recorder.dat_sink.dat.eq(self.sink.dat),
|
||||||
]
|
]
|
|
@ -50,7 +50,7 @@ class VcdDat(list):
|
||||||
for d in self:
|
for d in self:
|
||||||
if rle_bit[i]:
|
if rle_bit[i]:
|
||||||
if len(dat) >= 1:
|
if len(dat) >= 1:
|
||||||
# FIX ME... why is rle_dat in reverse orderd...
|
# FIX ME... why is rle_dat in reverse order...
|
||||||
for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
|
for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
|
||||||
dat.append(last)
|
dat.append(last)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -9,7 +9,7 @@ from migen.genlib.fifo import SyncFIFO
|
||||||
|
|
||||||
from miscope.std import *
|
from miscope.std import *
|
||||||
|
|
||||||
class RunLenghEncoder(Module, AutoCSR):
|
class RunLengthEncoder(Module, AutoCSR):
|
||||||
def __init__(self, width, length):
|
def __init__(self, width, length):
|
||||||
self.width = width
|
self.width = width
|
||||||
self.length = length
|
self.length = length
|
||||||
|
@ -30,26 +30,28 @@ class RunLenghEncoder(Module, AutoCSR):
|
||||||
dat_i_d = Signal(width)
|
dat_i_d = Signal(width)
|
||||||
|
|
||||||
self.sync += [
|
self.sync += [
|
||||||
|
If(stb_i,
|
||||||
dat_i_d.eq(dat_i),
|
dat_i_d.eq(dat_i),
|
||||||
stb_i_d.eq(stb_i)
|
stb_i_d.eq(stb_i)
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
# Detect change
|
# Detect change
|
||||||
change = Signal()
|
change = Signal()
|
||||||
comb = [diff.eq(stb_i & (~enable | (dat_i_d != dat_i)))]
|
self.comb += [change.eq(stb_i & (~enable | (dat_i_d != dat_i)))]
|
||||||
|
|
||||||
change_d = Signal()
|
change_d = Signal()
|
||||||
change_rising = Signal()
|
change_rising = Signal()
|
||||||
self.sync += change_d.eq(change)
|
self.sync += If(stb_i, change_d.eq(change))
|
||||||
self.comb += change_rising.eq(change & ~change_d)
|
self.comb += change_rising.eq(stb_i & (change & ~change_d))
|
||||||
|
|
||||||
# Generate RLE word
|
# Generate RLE word
|
||||||
rle_cnt = Signal(max=length)
|
rle_cnt = Signal(max=length)
|
||||||
rle_max = Signal()
|
rle_max = Signal()
|
||||||
|
|
||||||
comb +=[If(rle_cnt == length, rle_max.eq(enable))]
|
self.comb +=[If(rle_cnt == length, rle_max.eq(enable))]
|
||||||
|
|
||||||
sync +=[
|
self.sync +=[
|
||||||
If(change | rle_max,
|
If(change | rle_max,
|
||||||
rle_cnt.eq(0)
|
rle_cnt.eq(0)
|
||||||
).Else(
|
).Else(
|
||||||
|
@ -62,7 +64,7 @@ class RunLenghEncoder(Module, AutoCSR):
|
||||||
dat_o = self.source.dat
|
dat_o = self.source.dat
|
||||||
ack_o = self.source.ack
|
ack_o = self.source.ack
|
||||||
|
|
||||||
comb +=[
|
self.comb +=[
|
||||||
If(change_rising & ~rle_max,
|
If(change_rising & ~rle_max,
|
||||||
stb_o.eq(1),
|
stb_o.eq(1),
|
||||||
dat_o[width-1].eq(1),
|
dat_o[width-1].eq(1),
|
||||||
|
@ -80,7 +82,8 @@ class Recorder(Module, AutoCSR):
|
||||||
def __init__(self, width, depth):
|
def __init__(self, width, depth):
|
||||||
self.width = width
|
self.width = width
|
||||||
|
|
||||||
self.sink = rec_dat_hit(width)
|
self.trig_sink = rec_hit()
|
||||||
|
self.dat_sink = rec_dat(width)
|
||||||
|
|
||||||
self._r_trigger = CSR()
|
self._r_trigger = CSR()
|
||||||
self._r_length = CSRStorage(bits_for(depth))
|
self._r_length = CSRStorage(bits_for(depth))
|
||||||
|
@ -107,9 +110,9 @@ class Recorder(Module, AutoCSR):
|
||||||
# Fifo must always be pulled by software between
|
# Fifo must always be pulled by software between
|
||||||
# acquisition (Todo: add a flush funtionnality)
|
# acquisition (Todo: add a flush funtionnality)
|
||||||
self.comb +=[
|
self.comb +=[
|
||||||
fifo.we.eq(self.sink.stb & ~done),
|
fifo.we.eq(self.dat_sink.stb & ~done),
|
||||||
fifo.din.eq(self.sink.dat),
|
fifo.din.eq(self.dat_sink.dat),
|
||||||
self.sink.ack.eq(1)
|
self.dat_sink.ack.eq(fifo.writable)
|
||||||
]
|
]
|
||||||
|
|
||||||
# Done, Ongoing:
|
# Done, Ongoing:
|
||||||
|
@ -132,8 +135,9 @@ class Recorder(Module, AutoCSR):
|
||||||
If(self._r_trigger.re & self._r_trigger.r, done.eq(0)
|
If(self._r_trigger.re & self._r_trigger.r, done.eq(0)
|
||||||
).Elif(cnt==length, done.eq(1)),
|
).Elif(cnt==length, done.eq(1)),
|
||||||
|
|
||||||
If(self.sink.stb & self.sink.hit & ~done, ongoing.eq(1)
|
If(self.trig_sink.stb & self.trig_sink.hit & ~done, ongoing.eq(1)
|
||||||
).Elif(done, ongoing.eq(0)),
|
).Elif(done, ongoing.eq(0)),
|
||||||
|
self.trig_sink.ack.eq(1)
|
||||||
]
|
]
|
||||||
|
|
||||||
# fifo ack & csr connection
|
# fifo ack & csr connection
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
from migen.fhdl.std import *
|
||||||
|
from migen.fhdl import verilog
|
||||||
|
from migen.sim.generic import Simulator, TopLevel
|
||||||
|
from migen.sim.icarus import Runner
|
||||||
|
|
||||||
|
from miscope.storage import RunLengthEncoder
|
||||||
|
|
||||||
|
|
||||||
|
rle_test_seq = iter(
|
||||||
|
[ 0x00AA,
|
||||||
|
0x00AB,
|
||||||
|
0x00AC,
|
||||||
|
0x00AC,
|
||||||
|
0x00AC,
|
||||||
|
0x00AC,
|
||||||
|
0x00AD,
|
||||||
|
0x00AE,
|
||||||
|
0x00AE,
|
||||||
|
0x00AE,
|
||||||
|
0x00AE,
|
||||||
|
0x00AE,
|
||||||
|
0x00AE,
|
||||||
|
0x00AE,
|
||||||
|
0x00AE
|
||||||
|
]*10
|
||||||
|
)
|
||||||
|
|
||||||
|
class TB(Module):
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
# Rle
|
||||||
|
self.submodules.rle = RunLengthEncoder(16, 32)
|
||||||
|
|
||||||
|
def do_simulation(self, s):
|
||||||
|
s.wr(self.rle._r_enable.storage, 1)
|
||||||
|
s.wr(self.rle.sink.stb, 1)
|
||||||
|
try:
|
||||||
|
s.wr(self.rle.sink.dat, next(rle_test_seq))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def main():
|
||||||
|
tb = TB()
|
||||||
|
sim = Simulator(tb, TopLevel("tb_rle.vcd"))
|
||||||
|
sim.run(2000)
|
||||||
|
print("Sim Done")
|
||||||
|
input()
|
||||||
|
|
||||||
|
main()
|
Loading…
Reference in New Issue