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

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

View File

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

View File

View File

View File

@ -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),
] ]

View File

@ -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:

View File

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

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