From: Florent Kermarrec Date: Sun, 22 Sep 2013 16:41:44 +0000 (+0200) Subject: mila: test rle X-Git-Tag: 24jan2021_ls180~2575^2~86 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=69009c84057d75ce0970fad5e9adcf8a2c2e2de4;p=litex.git mila: test rle --- diff --git a/examples/de0_nano/client/test_mila.py b/examples/de0_nano/client/test_mila.py index 86775388..ceeedb30 100644 --- a/examples/de0_nano/client/test_mila.py +++ b/examples/de0_nano/client/test_mila.py @@ -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") \ No newline at end of file diff --git a/examples/de0_nano/top.py b/examples/de0_nano/top.py index 67502829..0582762a 100644 --- a/examples/de0_nano/top.py +++ b/examples/de0_nano/top.py @@ -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) diff --git a/miscope/com/uart2vb/host/uart2wb.py b/miscope/com/uart2vb/host/uart2wb.py deleted file mode 100644 index 2d86cc00..00000000 --- a/miscope/com/uart2vb/host/uart2wb.py +++ /dev/null @@ -1,89 +0,0 @@ -import string -import time -import serial -from struct import * -import time - -WRITE_CMD = 0x01 -READ_CMD = 0x02 -CLOSE_CMD = 0x03 - -def write_b(uart, data): - uart.write(pack('B',data)) - -class Uart2Wb: - def __init__(self, port, baudrate, debug = False): - self.port = port - self.baudrate = baudrate - self.debug = debug - self.uart = serial.Serial(port, baudrate, timeout=0.25) - - def open(self): - self.uart.write("\nuart2wb\n".encode('ascii')) - self.uart.flush() - time.sleep(0.1) - self.uart.close() - self.uart.open() - - def close(self): - for i in range(16): - write_b(self.uart, CLOSE_CMD) - self.uart.close() - - def read(self, addr, burst_length=1): - write_b(self.uart, READ_CMD) - write_b(self.uart, burst_length) - write_b(self.uart, (addr & 0xff000000) >> 24) - write_b(self.uart, (addr & 0x00ff0000) >> 16) - write_b(self.uart, (addr & 0x0000ff00) >> 8) - write_b(self.uart, (addr & 0x000000ff)) - values = [] - for i in range(burst_length): - read = self.uart.read(4) - val = (int(read[0]) << 24) | (int(read[1]) << 16) | (int(read[2]) << 8) | int(read[3]) - if self.debug: - print("RD %08X @ %08X" %(val, addr + 4*i)) - values.append(val) - if burst_length == 1: - return values[0] - else: - return values - - def read_csr(self, addr, burst_length=1): - values = self.read(addr, burst_length) - if isinstance(values, list): - for i in range(len(values)): - values[i] = values[i]&0xff - else: - values = values & 0xff - return values - - def write(self, addr, data): - if isinstance(data, list): - burst_length = len(data) - else: - burst_length = 1 - write_b(self.uart, WRITE_CMD) - write_b(self.uart, burst_length) - self.uart.write([(addr & 0xff000000) >> 24, - (addr & 0x00ff0000) >> 16, - (addr & 0x0000ff00) >> 8, - (addr & 0x000000ff)]) - if isinstance(data, list): - for i in range(len(data)): - self.uart.write([(data[i] & 0xff000000) >> 24, - (data[i] & 0x00ff0000) >> 16, - (data[i] & 0x0000ff00) >> 8, - (data[i] & 0x000000ff)]) - if self.debug: - print("WR %08X @ %08X" %(elt, addr + 4*i)) - else: - self.uart.write([(data & 0xff000000) >> 24, - (data & 0x00ff0000) >> 16, - (data & 0x0000ff00) >> 8, - (data & 0x000000ff)]) - if self.debug: - print("WR %08X @ %08X" %(data, addr)) - - def write_csr(self, addr, data): - self.write(addr, data) \ No newline at end of file diff --git a/miscope/com/uart2vb/lm32/uart2wb.c b/miscope/com/uart2vb/lm32/uart2wb.c deleted file mode 100644 index dcd9cada..00000000 --- a/miscope/com/uart2vb/lm32/uart2wb.c +++ /dev/null @@ -1,53 +0,0 @@ -// Use this code in your LM32 code to control CSR -// over uart - -#define WRITE_CMD 0x01 -#define READ_CMD 0x02 -#define CLOSE_CMD 0x03 -#define MMPTR(x) (*((volatile unsigned int *)(x))) - -static void uart2wb(void) -{ - unsigned char cmd; - unsigned char burst_length; - unsigned char adr_t[4]; - unsigned int adr; - char data_t[4]; - unsigned int data; - unsigned char i; - unsigned char j; - - while(cmd != CLOSE_CMD) - { - cmd = readchar(); - - if (cmd == WRITE_CMD) - { - burst_length = readchar(); - for(i=0;i<4;i++) adr_t[i] = readchar(); - adr = adr_t[0]<<24 | adr_t[1]<<16 | adr_t[2]<<8 | adr_t[3]; - for(i=0;i>24; - data_t[1] = (data & 0x00ff0000)>>16; - data_t[2] = (data & 0x0000ff00)>>8; - data_t[3] = (data & 0x000000ff); - for(j=0;j<4;j++) putchar(data_t[j]); - } - } - } -} diff --git a/miscope/com/uart2wb/__init__.py b/miscope/com/uart2wb/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/miscope/com/uart2wb/host/__init__.py b/miscope/com/uart2wb/host/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/miscope/com/uart2wb/host/uart2wb.py b/miscope/com/uart2wb/host/uart2wb.py new file mode 100644 index 00000000..2d86cc00 --- /dev/null +++ b/miscope/com/uart2wb/host/uart2wb.py @@ -0,0 +1,89 @@ +import string +import time +import serial +from struct import * +import time + +WRITE_CMD = 0x01 +READ_CMD = 0x02 +CLOSE_CMD = 0x03 + +def write_b(uart, data): + uart.write(pack('B',data)) + +class Uart2Wb: + def __init__(self, port, baudrate, debug = False): + self.port = port + self.baudrate = baudrate + self.debug = debug + self.uart = serial.Serial(port, baudrate, timeout=0.25) + + def open(self): + self.uart.write("\nuart2wb\n".encode('ascii')) + self.uart.flush() + time.sleep(0.1) + self.uart.close() + self.uart.open() + + def close(self): + for i in range(16): + write_b(self.uart, CLOSE_CMD) + self.uart.close() + + def read(self, addr, burst_length=1): + write_b(self.uart, READ_CMD) + write_b(self.uart, burst_length) + write_b(self.uart, (addr & 0xff000000) >> 24) + write_b(self.uart, (addr & 0x00ff0000) >> 16) + write_b(self.uart, (addr & 0x0000ff00) >> 8) + write_b(self.uart, (addr & 0x000000ff)) + values = [] + for i in range(burst_length): + read = self.uart.read(4) + val = (int(read[0]) << 24) | (int(read[1]) << 16) | (int(read[2]) << 8) | int(read[3]) + if self.debug: + print("RD %08X @ %08X" %(val, addr + 4*i)) + values.append(val) + if burst_length == 1: + return values[0] + else: + return values + + def read_csr(self, addr, burst_length=1): + values = self.read(addr, burst_length) + if isinstance(values, list): + for i in range(len(values)): + values[i] = values[i]&0xff + else: + values = values & 0xff + return values + + def write(self, addr, data): + if isinstance(data, list): + burst_length = len(data) + else: + burst_length = 1 + write_b(self.uart, WRITE_CMD) + write_b(self.uart, burst_length) + self.uart.write([(addr & 0xff000000) >> 24, + (addr & 0x00ff0000) >> 16, + (addr & 0x0000ff00) >> 8, + (addr & 0x000000ff)]) + if isinstance(data, list): + for i in range(len(data)): + self.uart.write([(data[i] & 0xff000000) >> 24, + (data[i] & 0x00ff0000) >> 16, + (data[i] & 0x0000ff00) >> 8, + (data[i] & 0x000000ff)]) + if self.debug: + print("WR %08X @ %08X" %(elt, addr + 4*i)) + else: + self.uart.write([(data & 0xff000000) >> 24, + (data & 0x00ff0000) >> 16, + (data & 0x0000ff00) >> 8, + (data & 0x000000ff)]) + if self.debug: + print("WR %08X @ %08X" %(data, addr)) + + def write_csr(self, addr, data): + self.write(addr, data) \ No newline at end of file diff --git a/miscope/com/uart2wb/lm32/uart2wb.c b/miscope/com/uart2wb/lm32/uart2wb.c new file mode 100644 index 00000000..dcd9cada --- /dev/null +++ b/miscope/com/uart2wb/lm32/uart2wb.c @@ -0,0 +1,53 @@ +// Use this code in your LM32 code to control CSR +// over uart + +#define WRITE_CMD 0x01 +#define READ_CMD 0x02 +#define CLOSE_CMD 0x03 +#define MMPTR(x) (*((volatile unsigned int *)(x))) + +static void uart2wb(void) +{ + unsigned char cmd; + unsigned char burst_length; + unsigned char adr_t[4]; + unsigned int adr; + char data_t[4]; + unsigned int data; + unsigned char i; + unsigned char j; + + while(cmd != CLOSE_CMD) + { + cmd = readchar(); + + if (cmd == WRITE_CMD) + { + burst_length = readchar(); + for(i=0;i<4;i++) adr_t[i] = readchar(); + adr = adr_t[0]<<24 | adr_t[1]<<16 | adr_t[2]<<8 | adr_t[3]; + for(i=0;i>24; + data_t[1] = (data & 0x00ff0000)>>16; + data_t[2] = (data & 0x0000ff00)>>8; + data_t[3] = (data & 0x000000ff); + for(j=0;j<4;j++) putchar(data_t[j]); + } + } + } +} diff --git a/miscope/mila.py b/miscope/mila.py index 9d5ab7bb..530082b2 100644 --- a/miscope/mila.py +++ b/miscope/mila.py @@ -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), - ] \ No newline at end of file + 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), + ] \ No newline at end of file diff --git a/miscope/std/vcd.py b/miscope/std/vcd.py index b3a0251c..438410de 100644 --- a/miscope/std/vcd.py +++ b/miscope/std/vcd.py @@ -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: diff --git a/miscope/storage.py b/miscope/storage.py index 8cc7f5ec..e89b7b5d 100644 --- a/miscope/storage.py +++ b/miscope/storage.py @@ -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 diff --git a/miscope/trigger.py b/miscope/trigger.py index ee075c0e..91070e08 100644 --- a/miscope/trigger.py +++ b/miscope/trigger.py @@ -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 diff --git a/sim/tb_rle.py b/sim/tb_rle.py new file mode 100644 index 00000000..bd68a1ed --- /dev/null +++ b/sim/tb_rle.py @@ -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()