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)
dat_w = 16
rec_length = 512
rec_offset = 0
+rle = True
#==============================================================================
# T E S T M I L A
print("Capturing ...")
print("----------------------")
+if rle:
+ mila.enable_rle()
mila.prog_term(0x0000, 0xFFFF)
capture()
("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
# 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)
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)
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)
+++ /dev/null
-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
+++ /dev/null
-// 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]);
- }
- }
- }
-}
--- /dev/null
+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
--- /dev/null
+// 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]);
+ }
+ }
+ }
+}
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
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:
from miscope.std import *
-class RunLenghEncoder(Module, AutoCSR):
+class RunLengthEncoder(Module, AutoCSR):
def __init__(self, width, length):
self.width = width
self.length = length
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(
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),
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))
# 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:
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
self._r_trig = CSRStorage(width)
self._r_mask = CSRStorage(width)
- ###
+ ###
trig = self._r_trig.storage
mask = self._r_mask.storage
--- /dev/null
+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()