mila: test rle
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 22 Sep 2013 16:41:44 +0000 (18:41 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 22 Sep 2013 19:23:51 +0000 (21:23 +0200)
13 files changed:
examples/de0_nano/client/test_mila.py
examples/de0_nano/top.py
miscope/com/uart2vb/host/uart2wb.py [deleted file]
miscope/com/uart2vb/lm32/uart2wb.c [deleted file]
miscope/com/uart2wb/__init__.py [new file with mode: 0644]
miscope/com/uart2wb/host/__init__.py [new file with mode: 0644]
miscope/com/uart2wb/host/uart2wb.py [new file with mode: 0644]
miscope/com/uart2wb/lm32/uart2wb.c [new file with mode: 0644]
miscope/mila.py
miscope/std/vcd.py
miscope/storage.py
miscope/trigger.py
sim/tb_rle.py [new file with mode: 0644]

index 86775388bd81115a161ea35ca6929f0d2e1681ee..ceeedb301f4c5f293f20d25990dff4f21e2c864e 100644 (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")
\ No newline at end of file
index 67502829f20bf4c3966e83056cac702f88724224..0582762aa643e648413b03d673debf311b3bca05 100644 (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)
diff --git a/miscope/com/uart2vb/host/uart2wb.py b/miscope/com/uart2vb/host/uart2wb.py
deleted file mode 100644 (file)
index 2d86cc0..0000000
+++ /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 (file)
index dcd9cad..0000000
+++ /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<burst_length;i++)
-                       {
-                               for(j=0;j<4;j++) data_t[j] = readchar();
-                               data = data_t[0]<<24 | data_t[1]<<16 | data_t[2]<<8 | data_t[3];
-                               MMPTR(adr+4*i) = data;
-                       }
-               }
-       
-               if (cmd == READ_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<burst_length;i++)
-                       {
-                               data = MMPTR(adr+4*i);
-                               data_t[0] = (data & 0xff000000)>>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 (file)
index 0000000..e69de29
diff --git a/miscope/com/uart2wb/host/__init__.py b/miscope/com/uart2wb/host/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/miscope/com/uart2wb/host/uart2wb.py b/miscope/com/uart2wb/host/uart2wb.py
new file mode 100644 (file)
index 0000000..2d86cc0
--- /dev/null
@@ -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 (file)
index 0000000..dcd9cad
--- /dev/null
@@ -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<burst_length;i++)
+                       {
+                               for(j=0;j<4;j++) data_t[j] = readchar();
+                               data = data_t[0]<<24 | data_t[1]<<16 | data_t[2]<<8 | data_t[3];
+                               MMPTR(adr+4*i) = data;
+                       }
+               }
+       
+               if (cmd == READ_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<burst_length;i++)
+                       {
+                               data = MMPTR(adr+4*i);
+                               data_t[0] = (data & 0xff000000)>>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]);
+                       }
+               }
+       }
+}
index 9d5ab7bbb4122e9b05b542f76efb914500cece3a..530082b2d0281023ce09c5972cd27477395ec60d 100644 (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),
-               ]
\ 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
index b3a0251c7093b1f7e070a450b4c962b5f5b46473..438410de885a249083e8e59b37b9ec2d7de8de0f 100644 (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:
index 8cc7f5ec85cec962cd0ec53403f6fbbe1e6ebf79..e89b7b5da20070872c74e6cd5d4305eb8914d9ad 100644 (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
index ee075c0e11d4449703cf8446344242f471511bbe..91070e08a87ff69b33b4325771d288a78a96890e 100644 (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
diff --git a/sim/tb_rle.py b/sim/tb_rle.py
new file mode 100644 (file)
index 0000000..bd68a1e
--- /dev/null
@@ -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()