mila: test rle

This commit is contained in:
Florent Kermarrec 2013-09-22 18:41:44 +02:00
parent a880862628
commit 69009c8405
11 changed files with 113 additions and 32 deletions

View File

@ -23,6 +23,12 @@ class MiLaCtrl():
mila_trigger_sum_prog_adr_write(self.bus, adr)
mila_trigger_sum_prog_dat_write(self.bus, dat)
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):
return mila_recorder_done_read(self.bus)
@ -46,6 +52,7 @@ trig_w = 16
dat_w = 16
rec_length = 512
rec_offset = 0
rle = True
#==============================================================================
# T E S T M I L A
@ -72,6 +79,8 @@ def capture():
print("Capturing ...")
print("----------------------")
if rle:
mila.enable_rle()
mila.prog_term(0x0000, 0xFFFF)
capture()
@ -82,6 +91,9 @@ mila_layout = [
("cnt", 8),
]
if rle:
dat_vcd = dat_vcd.decode_rle()
myvcd = Vcd()
myvcd.add_from_layout(mila_layout, dat_vcd)
myvcd.write("test_mila.vcd")

View File

@ -55,7 +55,7 @@ class SoC(Module):
# MiLa
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
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)])
# Misc
self.cnt = Signal(9)
self.cnt = Signal(16)
self.submodules.freqgen = FreqGen(clk_freq, 500*KHz)
self.submodules.eventgen_rising = EventGen(RISING_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.eventgen_rising.o,
self.eventgen_falling.o,
self.cnt)
self.cnt[8:12])
)
]
self.sync += self.cnt.eq(self.cnt+1)

View File

View File

View File

@ -5,30 +5,46 @@ from migen.bus import csr
from migen.bank import description, csrgen
from migen.bank.description import *
from miscope.std import *
from miscope.trigger import Trigger
from miscope.storage import Recorder
from miscope.storage import RunLengthEncoder, Recorder
class MiLa(Module, AutoCSR):
def __init__(self, width, depth, ports):
def __init__(self, width, depth, ports, rle=False):
self.width = width
self.sink = rec_dat(width)
trigger = Trigger(width, ports)
recorder = Recorder(width, depth)
self.submodules.trigger = trigger
self.submodules.recorder = recorder
self.sink = trigger.sink
self.comb +=[
recorder.sink.stb.eq(trigger.source.stb),
recorder.sink.hit.eq(trigger.source.hit),
trigger.source.ack.eq(recorder.sink.ack)
self.comb += [
trigger.sink.stb.eq(self.sink.stb),
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
# triggers elements
self.comb +=[
recorder.sink.dat.eq(self.sink.dat),
]
if rle:
self.submodules.rle = RunLengthEncoder(width, 1024)
self.comb +=[
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),
]

View File

@ -50,7 +50,7 @@ class VcdDat(list):
for d in self:
if rle_bit[i]:
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)):
dat.append(last)
else:

View File

@ -9,7 +9,7 @@ from migen.genlib.fifo import SyncFIFO
from miscope.std import *
class RunLenghEncoder(Module, AutoCSR):
class RunLengthEncoder(Module, AutoCSR):
def __init__(self, width, length):
self.width = width
self.length = length
@ -30,26 +30,28 @@ class RunLenghEncoder(Module, AutoCSR):
dat_i_d = Signal(width)
self.sync += [
dat_i_d.eq(dat_i),
stb_i_d.eq(stb_i)
If(stb_i,
dat_i_d.eq(dat_i),
stb_i_d.eq(stb_i)
)
]
# Detect change
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_rising = Signal()
self.sync += change_d.eq(change)
self.comb += change_rising.eq(change & ~change_d)
self.sync += If(stb_i, change_d.eq(change))
self.comb += change_rising.eq(stb_i & (change & ~change_d))
# Generate RLE word
rle_cnt = Signal(max=length)
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,
rle_cnt.eq(0)
).Else(
@ -62,7 +64,7 @@ class RunLenghEncoder(Module, AutoCSR):
dat_o = self.source.dat
ack_o = self.source.ack
comb +=[
self.comb +=[
If(change_rising & ~rle_max,
stb_o.eq(1),
dat_o[width-1].eq(1),
@ -80,7 +82,8 @@ class Recorder(Module, AutoCSR):
def __init__(self, width, depth):
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_length = CSRStorage(bits_for(depth))
@ -107,9 +110,9 @@ class Recorder(Module, AutoCSR):
# Fifo must always be pulled by software between
# acquisition (Todo: add a flush funtionnality)
self.comb +=[
fifo.we.eq(self.sink.stb & ~done),
fifo.din.eq(self.sink.dat),
self.sink.ack.eq(1)
fifo.we.eq(self.dat_sink.stb & ~done),
fifo.din.eq(self.dat_sink.dat),
self.dat_sink.ack.eq(fifo.writable)
]
# Done, Ongoing:
@ -132,8 +135,9 @@ class Recorder(Module, AutoCSR):
If(self._r_trigger.re & self._r_trigger.r, done.eq(0)
).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)),
self.trig_sink.ack.eq(1)
]
# fifo ack & csr connection

View File

@ -18,7 +18,7 @@ class Term(Module, AutoCSR):
self._r_trig = CSRStorage(width)
self._r_mask = CSRStorage(width)
###
###
trig = self._r_trig.storage
mask = self._r_mask.storage

49
sim/tb_rle.py Normal file
View File

@ -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()