refactoring
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 21 Sep 2013 11:04:07 +0000 (13:04 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 22 Sep 2013 00:49:59 +0000 (02:49 +0200)
46 files changed:
examples/de0_nano/Makefile
examples/de0_nano/build.py [deleted file]
examples/de0_nano/client/test_miio.py
examples/de0_nano/client/test_mila.py
examples/de0_nano/make.py [new file with mode: 0644]
examples/de0_nano/misc.py [deleted file]
examples/de0_nano/top.py
miscope/bridges/__init__.py [deleted file]
miscope/bridges/spi2csr/__init__.py [deleted file]
miscope/bridges/spi2csr/tools/__init__.py [deleted file]
miscope/bridges/spi2csr/tools/arduino/spiFpga.cpp [deleted file]
miscope/bridges/spi2csr/tools/arduino/spiFpga.h [deleted file]
miscope/bridges/spi2csr/tools/arduino/uart2Spi.pde [deleted file]
miscope/bridges/spi2csr/tools/uart2Spi.py [deleted file]
miscope/bridges/uart2csr/__init__.py [deleted file]
miscope/bridges/uart2csr/tools/__init__.py [deleted file]
miscope/bridges/uart2csr/tools/uart2Csr.py [deleted file]
miscope/bridges/uart2csr/uart.py [deleted file]
miscope/com/__init__.py [new file with mode: 0644]
miscope/com/uart2csr/__init__.py [new file with mode: 0644]
miscope/com/uart2csr/host/__init__.py [new file with mode: 0644]
miscope/com/uart2csr/host/uart2csr.py [new file with mode: 0644]
miscope/com/uart2csr/uart.py [new file with mode: 0644]
miscope/miio.py
miscope/mila.py
miscope/recorder.py [deleted file]
miscope/recording/__init__.py [new file with mode: 0644]
miscope/std/__init__.py [new file with mode: 0644]
miscope/std/cif.py [new file with mode: 0644]
miscope/std/conv.py [new file with mode: 0644]
miscope/std/misc.py [new file with mode: 0644]
miscope/std/truthtable.py [new file with mode: 0644]
miscope/std/vcd.py [new file with mode: 0644]
miscope/tools/__init__.py [deleted file]
miscope/tools/conv.py [deleted file]
miscope/tools/misc.py [deleted file]
miscope/tools/truthtable.py [deleted file]
miscope/tools/vcd.py [deleted file]
miscope/trigger.py [deleted file]
miscope/triggering/__init__.py [new file with mode: 0644]
sim/tb_RecorderCsr.py [deleted file]
sim/tb_TriggerCsr.py [deleted file]
sim/tb_miscope.py [deleted file]
sim/tb_recorder_csr.py [new file with mode: 0644]
sim/tb_spi2csr.py [deleted file]
sim/tb_trigger_csr.py [new file with mode: 0644]

index 00a53a89b8dff5a71487fbcd76ce6a4571ca9ae2..53b90086c9a61063eb561ed44ccd2e25ba578d21 100644 (file)
@@ -1,11 +1,10 @@
-all: build/top.sta
+all: build/soc-de0nano.sta
 
-build/top.sta:
-       ./build.py
+build/soc-de0nano.sta:
+       ./make.py
 
 load:
-       cd build && quartus_pgm -m jtag -c USB-Blaster[USB-0] -o "p;top.sof"
-
+       cd build && quartus_pgm -m jtag -c USB-Blaster[USB-0] -o "p;soc-de0nano.sof"
 
 clean:
        rm -rf build/*
diff --git a/examples/de0_nano/build.py b/examples/de0_nano/build.py
deleted file mode 100644 (file)
index 9fb0a24..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-from mibuild.platforms import de0nano
-import top
-
-def main():
-       platform = de0nano.Platform()
-       soc = top.SoC(platform)
-       
-       
-       # set extra constraints
-       platform.add_platform_command("""
-set_global_assignment -name FAMILY "Cyclone IV E"
-set_global_assignment -name TOP_LEVEL_ENTITY "top"
-set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
-""")
-
-       platform.build_cmdline(soc)
-
-if __name__ == "__main__":
-       main()
\ No newline at end of file
index 747e48d9ce7cca4b1ab115f9fb723ddb41fb4dd5..529f86acfef88f571c27d4b34d804159c00d6d1b 100644 (file)
@@ -1,23 +1,31 @@
 from miscope import miio
-from miscope.bridges.uart2csr.tools.uart2Csr import *
+from miscope.com.uart2csr.host.uart2csr import *
+
+from csr import *
 
 #==============================================================================
 #      P A R A M E T E R S
 #==============================================================================
 
-csr = Uart2Csr(3,115200)
+uart = Uart2Csr(3, 115200)
+
+class MiIoCtrl():
+       def __init__(self, bus):
+               self.bus = bus
+       
+       def write(self, value):
+               miio_o_write(self.bus, value)
 
-# Csr Addr
-MIIO_ADDR  = 0x00
+       def read(self):
+               return miio_i_read(self.bus)
 
-# Miscope Configuration
-miio = miio.MiIo(MIIO_ADDR, 8, "IO", csr)
+miio = MiIoCtrl(uart)
 
 def led_anim0():
        for i in range(10):
-               miio.set(0xA5)
+               miio.write(0xA5)
                time.sleep(0.1)
-               miio.set(0x5A)
+               miio.write(0x5A)
                time.sleep(0.1)
 
 def led_anim1():
@@ -25,18 +33,18 @@ def led_anim1():
                #Led <<
                ledData = 1
                for i in range(8):
-                       miio.set(ledData)
+                       miio.write(ledData)
                        time.sleep(i*i*0.0020)
                        ledData = (ledData<<1)
                #Led >>
                ledData = 128
                for i in range(8): 
-                       miio.set(ledData)
+                       miio.write(ledData)
                        time.sleep(i*i*0.0020)
                        ledData = (ledData>>1)
 
 #==============================================================================
-#                  T E S T  M I I O 
+#                  T E S T  M I I O 
 #==============================================================================
 
 print("- Led Animation...")
@@ -46,4 +54,4 @@ led_anim1()
 time.sleep(1)
 
 print("- Read Switch: ",end=' ')
-print("%02X" %miio.get())
+print("%02X" %miio.read())
index 8976870971d783194e17e5d63f5a91dc11cc9219..86775388bd81115a161ea35ca6929f0d2e1681ee 100644 (file)
@@ -1,61 +1,79 @@
-from miscope import trigger, recorder, miio, mila
-from miscope.tools.truthtable import *
-from miscope.tools.vcd import *
-from miscope.bridges.uart2csr.tools.uart2Csr import *
+from miscope import mila
+from miscope.std.truthtable import *
+from miscope.std.vcd import *
+from miscope.com.uart2csr.host.uart2csr import *
+from csr import *
 
 #==============================================================================
 #      P A R A M E T E R S
 #==============================================================================
-# Csr Addr
-MILA_ADDR      = 0x01
 
-csr = Uart2Csr(3, 115200, debug=False)
+uart = Uart2Csr(3, 115200)
+
+class MiLaCtrl():
+       def __init__(self, bus):
+               self.bus = bus
+
+       def prog_term(self, trigger, mask):
+               mila_trigger_port0_trig_write(self.bus, trigger)
+               mila_trigger_port0_mask_write(self.bus, mask)
+
+       def prog_sum(self, datas):
+               for adr, dat in enumerate(datas):
+                       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 is_done(self):
+               return mila_recorder_done_read(self.bus)
+
+       def trigger(self, offset, length):
+               mila_recorder_offset_write(self.bus, offset)
+               mila_recorder_length_write(self.bus, length)
+               mila_recorder_trigger_write(self.bus, 1)
+
+       def read(self):
+               r = []
+               empty = mila_recorder_read_empty_read(self.bus)
+               while(not empty):
+                       r.append(mila_recorder_read_dat_read(self.bus))
+                       empty = mila_recorder_read_empty_read(self.bus)
+                       mila_recorder_read_en_write(self.bus, 1)
+               return r
 
 # Mila Param
 trig_w         = 16
 dat_w          = 16
-rec_size       = 512
-rec_offset     = 32
-enable_rle  = True
-
-# Miscope Configuration
-# MiLa
-term = trigger.Term(trig_w)
-trigger = trigger.Trigger(trig_w, [term])
-recorder = recorder.Recorder(dat_w, rec_size)
-mila = mila.MiLa(MILA_ADDR, trigger, recorder, csr)
-
+rec_length     = 512
+rec_offset     = 0
        
 #==============================================================================
-#                  T E S T  M I L A 
+#                  T E S T  M I L A 
 #==============================================================================
 dat_vcd = VcdDat(dat_w)
 
-def capture(size):
+mila = MiLaCtrl(uart)
+
+def capture():
        global dat_vcd
        sum_tt = gen_truth_table("term")
-       mila.trigger.sum.set(sum_tt)
-       mila.recorder.reset()
-       if enable_rle:
-               mila.recorder.enable_rle()
-       recorder.set_size(rec_size)     
-       mila.recorder.set_offset(rec_offset)
-       mila.recorder.arm()
-       print("-Recorder [Armed]")
+       mila.prog_sum(sum_tt)
+       mila.trigger(rec_offset, rec_length)
+       print("-Recorder [Triggered]")
        print("-Waiting Trigger...", end=' ')
-       while(not mila.recorder.is_done()):
+       while(not mila.is_done()):
                time.sleep(0.1)
        print("[Done]")
        
        print("-Receiving Data...", end=' ')
        sys.stdout.flush()
-       dat_vcd += mila.recorder.pull(rec_size)
+       dat_vcd += mila.read()
        print("[Done]")
 
 print("Capturing ...")
 print("----------------------")
-term.set(0x0000, 0xFFFF)
-capture(rec_size)
+mila.prog_term(0x0000, 0xFFFF)
+capture()
 
 mila_layout = [
        ("freqgen", 1),
@@ -64,9 +82,6 @@ mila_layout = [
        ("cnt", 8),
        ]
 
-if enable_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/make.py b/examples/de0_nano/make.py
new file mode 100644 (file)
index 0000000..e0e5c01
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+
+import argparse, os, subprocess, struct, shutil
+
+from mibuild.tools import write_to_file
+import mibuild.platforms.de0nano as de0nano
+
+from miscope.std import cif
+
+import top
+
+def build(build_bitstream, build_header):
+       platform = de0nano.Platform()
+       soc = top.SoC(platform)
+
+       platform.add_platform_command("""
+set_global_assignment -name FAMILY "Cyclone IV E"
+set_global_assignment -name TOP_LEVEL_ENTITY "top"
+set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
+""")
+
+       if build_bitstream:
+               build_name = "soc-de0nano"
+               platform.build(soc, build_name=build_name)
+       else:
+               soc.finalize()
+       if build_header:
+
+               csr_py_header = cif.get_py_csr_header(soc.csr_base, soc.csrbankarray)
+               write_to_file(os.path.join("client", "csr.py"), csr_py_header)
+
+
+def main():
+       parser = argparse.ArgumentParser(description="miscope")
+       parser.add_argument("-B", "--no-bitstream", default=False, action="store_true", help="do not build bitstream file")
+       parser.add_argument("-H", "--no-header", default=False, action="store_true", help="do not build C header file with CSR defs")
+       args = parser.parse_args()
+
+       build(not args.no_bitstream, not args.no_header)
+
+if __name__ == "__main__":
+       main()
diff --git a/examples/de0_nano/misc.py b/examples/de0_nano/misc.py
deleted file mode 100644 (file)
index 1067a5c..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-class RisingEdge(Module):
-       def __init__(self, i=None, o=None, domain="sys"):
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-       ####
-               i_d = Signal()
-               sync =[i_d.eq(self.i)]
-               self.comb +=[self.o.eq(self.i & ~i_d)]
-               self._fragment += Fragment(sync={domain : sync})
-
-class FallingEdge(Module):
-       def __init__(self, i=None, o=None, domain="sys"):
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-       ####
-               i_d = Signal()
-               sync =[i_d.eq(self.i)]
-               self.comb +=[self.o.eq(~self.i & i_d)]
-               self._fragment += Fragment(sync={domain : sync})
-
-class FreqGen(Module):
-       def __init__(self, clk_freq, freq, o=None):
-               cnt_max = int(clk_freq/freq/2)
-               width = bits_for(cnt_max)
-               
-               self.o = ifthenelse(o, o, Signal())
-       ####
-               cnt = Signal(width)
-               self.sync += [
-                       If(cnt >= cnt_max,
-                               cnt.eq(0),
-                               self.o.eq(~self.o)
-                       ).Else(
-                               cnt.eq(cnt+1)
-                               )
-                       ]
-
-RISING_EDGE  = 1
-FALLING_EDGE = 0
-
-class EventGen(Module):
-       def __init__(self, i=None, level=1, clk_freq=0, length=1, o=None):
-               
-               cnt_max = int(length*clk_freq)
-               width = bits_for(cnt_max)
-               
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-       ###
-               cnt = Signal(width)
-               i_edge = Signal()
-               
-               if level == RISING_EDGE:
-                       self.submodules += RisingEdge(self.i, i_edge)
-               elif level == FALLING_EDGE:
-                       self.submodules += FallingEdge(self.i, i_edge)
-               
-               self.sync += [
-                       If(i_edge == 1,
-                               cnt.eq(0),
-                               self.o.eq(1)
-                       ).Elif(cnt >= cnt_max,
-                               self.o.eq(0)
-                       ).Else(
-                               cnt.eq(cnt+1)
-                       ),
-                       ]
-               
-class PwmGen(Module):
-       def __init__(self, width, o=None):
-               self.ratio = Signal(width)
-               self.o     = ifthenelse(o, o, Signal())
-       ###
-               cnt = Signal(width)
-               self.sync += [
-                       If(cnt == 0,
-                               self.o.eq(1)
-                       ).Elif(cnt >= self.ratio,
-                               self.o.eq(0)
-                       ),
-                       cnt.eq(cnt+1)
-                       ]
-               
-class Cascade(Module):
-       def __init__(self, i=None, elements=None, o=None):
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-               self.comb +=[elements[0].i.eq(self.i)]
-               self.comb +=[elements[i+1].i.eq(elements[i].o) for i in range(len(elements)-1)]
-               self.comb +=[self.o.eq(elements[len(elements)-1].o)]
-
-class PwrOnRst(Module):
-       def __init__(self, width, rst=None, simulation=False):
-               self.rst = ifthenelse(rst, rst, Signal())
-       ###
-               cnt = Signal(width)
-               sync_no_reset = [If(self.rst, cnt.eq(cnt+1))]
-               if not simulation:
-                       self.comb +=[
-                               If(cnt >= (2**width-1),
-                                       self.rst.eq(0)
-                               ).Else(
-                                       self.rst.eq(1)
-                               )
-                       ]
-               else:
-                       self.comb += self.rst.eq(0)
-               self._fragment += Fragment(sync={"sys_no_reset" : sync_no_reset})
\ No newline at end of file
index cc363f263e4be4ac39572c8143c4d97fefdfe7af..94622eafc9e71437b850dc21d428690a7f01e274 100644 (file)
 #==============================================================================
 #      I M P O R T 
 #==============================================================================
-from migen.fhdl.structure import *
-from migen.fhdl.module import *
+from migen.fhdl.std import *
 from migen.bus import csr
+from migen.bank import csrgen
+from miscope.std.misc import *
 
-from miscope import trigger, recorder, miio, mila
-from miscope.bridges import uart2csr
-from miscope.tools.misc import *
+from miscope.triggering import *
+from miscope.recording import *
+from miscope import miio, mila
+
+from miscope.com import uart2csr
 
 from timings import *
 
@@ -31,10 +34,6 @@ from timings import *
 # Timings Param
 clk_freq       = 50*MHz
 
-# Csr Addr
-MIIO_ADDR      = 0x00
-MILA_ADDR      = 0x01
-
 # Mila Param
 trig_w         = 16
 dat_w          = 16
@@ -44,16 +43,23 @@ rec_size    = 4096
 #   M I S C O P E    E X A M P L E
 #==============================================================================
 class SoC(Module):
+       csr_base = 0xe0000000
+       csr_map = {
+               "miio":                                 1,
+               "mila":                                 2,
+       }
+
+
        def __init__(self, platform):
                # MiIo
-               self.submodules.miio = miio.MiIo(MIIO_ADDR, 8, "IO")
+               self.submodules.miio = miio.MiIo(8)
 
                # MiLa
-               self.submodules.term = trigger.Term(trig_w)
-               self.submodules.trigger = trigger.Trigger(trig_w, [self.term])
-               self.submodules.recorder = recorder.Recorder(dat_w, rec_size)
+               term = Term(trig_w)
+               trigger = Trigger(trig_w, [term])
+               recorder = Recorder(dat_w, rec_size)
 
-               self.submodules.mila = mila.MiLa(MILA_ADDR, self.trigger, self.recorder, trig_is_dat=True)
+               self.submodules.mila = mila.MiLa(trigger, recorder)
        
                # Uart2Csr
                self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200)
@@ -62,15 +68,12 @@ class SoC(Module):
                self.comb += self.uart2csr.rx.eq(uart_pads.rx)
        
                # Csr Interconnect
-               self.submodules.csrcon = csr.Interconnect(self.uart2csr.csr,
-                               [
-                                       self.miio.bank.bus,
-                                       self.trigger.bank.bus,
-                                       self.recorder.bank.bus
-                               ])
+               self.submodules.csrbankarray = csrgen.BankArray(self,
+                       lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override])
+               self.submodules.csrcon = csr.Interconnect(self.uart2csr.csr, self.csrbankarray.get_buses())
                
                # Led
-               self.led = platform.request("user_led", 0, 8)
+               self.led = Cat(*[platform.request("user_led", i) for i in range(8)])
 
                # Misc
                self.cnt = Signal(9)
@@ -94,7 +97,8 @@ class SoC(Module):
                # Mila
                #
                self.comb +=[
-                       self.mila.trig.eq(Cat(
+                       self.mila.sink.stb.eq(1),
+                       self.mila.sink.payload.d.eq(Cat(
                                self.freqgen.o,
                                self.eventgen_rising.o,
                                self.eventgen_falling.o,
diff --git a/miscope/bridges/__init__.py b/miscope/bridges/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/miscope/bridges/spi2csr/__init__.py b/miscope/bridges/spi2csr/__init__.py
deleted file mode 100644 (file)
index 2416cb6..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-from migen.fhdl.structure import *
-from migen.genlib.misc import *
-from migen.genlib.cdc import *
-from migen.bus import csr
-
-class Spi2Csr(Module):
-       def __init__(self, burst_length=8):
-               self.a_w = 14
-               self.d_w = 8
-               self.burst_length = 8
-               
-               # Csr interface
-               self.csr = csr.Interface()
-               
-               # Spi interface
-               self.spi_clk = Signal()
-               self.spi_cs_n = Signal(reset=1)
-               self.spi_mosi = Signal()
-               self.spi_miso = Signal()
-               
-       ###
-               
-               # Resychronisation
-               clk_synchro = Synchronizer(i=self.spi_clk)
-               cs_n_synchro = Synchronizer(i=self.spi_cs_n)
-               mosi_synchro = Synchronizer(i=self.spi_mosi)
-
-               self.specials += {clk_synchro, cs_n_synchro, mosi_synchro}
-
-               # Decode
-               spi_clk_rising = Signal()
-               spi_clk_falling = Signal()
-               spi_cs_n_active = Signal()
-               spi_mosi_dat = Signal()
-               
-               self.specials += RisingEdge(i=clk_synchro.o, o=spi_clk_rising)
-               self.specials += FallingEdge(i=clk_synchro.o, o=spi_clk_falling)
-
-               self.sync +=[
-                       spi_cs_n_active.eq(~cs_n_synchro.o),
-                       spi_mosi_dat.eq(~mosi_synchro.o),
-               ]
-               
-               #
-               # Spi --> Csr
-               #
-               spi_cnt = Signal(bits_for(self.a_w + self.burst_length*self.d_w))
-               spi_addr = Signal(self.a_w)
-               spi_w_dat = Signal(self.d_w)
-               spi_r_dat = Signal(self.d_w)
-               spi_we = Signal()
-               spi_re = Signal()
-               spi_we_re_done = Signal(reset=1)
-               spi_miso_dat = Signal()
-               
-               # Re/We Signals Decoding
-               first_b = Signal()
-               last_b = Signal()
-               
-               self.comb +=[
-                       first_b.eq(spi_cnt[0:bits_for(self.d_w)-1] == 0),
-                       last_b.eq(spi_cnt[0:bits_for(self.d_w)-1] == 2**(bits_for(self.d_w-1))-1)
-               ]
-               self.sync +=[
-                       If((spi_cnt >= (self.a_w + self.d_w)) & first_b,
-                               spi_we.eq(spi_addr[self.a_w-1] & ~spi_we_re_done),
-                               spi_re.eq(~spi_addr[self.a_w-1] & ~spi_we_re_done),
-                               spi_we_re_done.eq(1)
-                       ).Elif((spi_cnt >= self.a_w) & first_b,
-                               spi_re.eq(~spi_addr[self.a_w-1] & ~spi_we_re_done),
-                               spi_we_re_done.eq(1)
-                       ).Else(
-                               spi_we.eq(0),
-                               spi_re.eq(0),
-                               spi_we_re_done.eq(0)
-                       )
-               ]
-               
-               # Spi Addr / Data Decoding
-               self.sync +=[
-                       If(~spi_cs_n_active,
-                               spi_cnt.eq(0),
-                       ).Elif(spi_clk_rising,
-                               # addr
-                               If(spi_cnt < self.a_w,
-                                       spi_addr.eq(Cat(spi_mosi_dat,spi_addr[:self.a_w-1]))
-                               ).Elif((spi_cnt >= (self.a_w+self.d_w)) & last_b,
-                                       spi_addr.eq(spi_addr+1)
-                               ).Elif((spi_cnt >= self.a_w) & last_b & (spi_addr[self.a_w-1] == 0),
-                                       spi_addr.eq(spi_addr+1)
-                               ),
-                               # dat
-                               If(spi_cnt >= self.a_w,
-                                       spi_w_dat.eq(Cat(spi_mosi_dat,spi_w_dat[:self.d_w-1]))
-                               ),
-                               
-                               # spi_cnt
-                               spi_cnt.eq(spi_cnt+1)
-                       )
-               ]
-               
-               #
-               # Csr --> Spi
-               #
-               spi_r_dat_shift = Signal(self.d_w)
-               self.sync +=[
-                       If(spi_re,
-                               spi_r_dat_shift.eq(spi_r_dat)
-                       ),
-                       
-                       If(~spi_cs_n_active,
-                               spi_miso_dat.eq(0)
-                       ).Elif(spi_clk_falling,
-                               spi_miso_dat.eq(spi_r_dat_shift[self.d_w-1]),
-                               spi_r_dat_shift.eq(Cat(0,spi_r_dat_shift[:self.d_w-1]))
-                       )
-               ]
-                       
-               
-               #
-               # Csr Interface
-               #
-               self.comb += [
-                       self.csr.adr.eq(spi_addr),
-                       self.csr.dat_w.eq(spi_w_dat),
-                       self.csr.we.eq(spi_we)
-               ]
-               
-               #
-               # Spi Interface
-               #
-               self.comb += [
-                       spi_r_dat.eq(self.csr.dat_r),
-                       self.spi_miso.eq(spi_miso_dat)
-               ]
\ No newline at end of file
diff --git a/miscope/bridges/spi2csr/tools/__init__.py b/miscope/bridges/spi2csr/tools/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/miscope/bridges/spi2csr/tools/arduino/spiFpga.cpp b/miscope/bridges/spi2csr/tools/arduino/spiFpga.cpp
deleted file mode 100644 (file)
index 0787072..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * spiFpga
- * Copyright (C) 2012 by Florent Kermarrec <florent@enjoy-digital.fr>
- * Copyright (C) 2011 by James Bowman <jamesb@excamera.com> 
- *
- */
-#include "WProgram.h"
-#include <avr/pgmspace.h>
-#include <SPI.h>
-#include <spiFpga.h>
-
-SFClass SF;
-
-void SFClass::begin()
-{
-       pinMode(SS_PIN, OUTPUT);
-       SPI.begin();
-       SPI.setClockDivider(SPI_CLOCK_DIV2);
-       SPI.setBitOrder(MSBFIRST);
-       SPI.setDataMode(SPI_MODE0);
-       SPSR = (1 << SPI2X);
-       digitalWrite(SS_PIN, HIGH);
-}
-
-void SFClass::end() {
-}
-
-void SFClass::__start(unsigned int addr)
-{
-       digitalWrite(SS_PIN, LOW);
-       SPI.transfer(highByte(addr));
-       SPI.transfer(lowByte(addr));  
-}
-
-void SFClass::__wstart(unsigned int addr)
-{
-       __start(0x8000|addr);
-}
-
-void SFClass::__end()
-{
-       digitalWrite(SS_PIN, HIGH);
-}
-
-char SFClass::rd(unsigned int addr)
-{
-       __start(addr);
-       char r = SPI.transfer(0);
-       __end();
-       return r;
-}
-
-void SFClass::wr(unsigned int addr, char v)
-{
-       __wstart(addr);
-       SPI.transfer(v);
-       __end();
-}
\ No newline at end of file
diff --git a/miscope/bridges/spi2csr/tools/arduino/spiFpga.h b/miscope/bridges/spi2csr/tools/arduino/spiFpga.h
deleted file mode 100644 (file)
index c28837b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * spiFpga
- * Copyright (C) 2012 by Florent Kermarrec <florent@enjoy-digital.fr>
- * Copyright (C) 2011 by James Bowman <jamesb@excamera.com> 
- *
- */
-
-#ifndef _SF_H_INCLUDED
-#define _SF_H_INCLUDED
-
-#ifndef SS_PIN
-#define SS_PIN 10
-#endif
-
-class SFClass {
-public:
-  static void begin();
-  static void end();
-  static void __start(unsigned int addr);
-  static void __wstart(unsigned int addr);
-  static void __end(void);
-  static char rd(unsigned int addr);
-  static void wr(unsigned int addr, char v);
-};
-
-extern SFClass SF;
-
-#endif
diff --git a/miscope/bridges/spi2csr/tools/arduino/uart2Spi.pde b/miscope/bridges/spi2csr/tools/arduino/uart2Spi.pde
deleted file mode 100644 (file)
index df049bf..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-  Uart2Spi
-  Copyright 2012 - Florent Kermarrec - florent@enjoy-digital.fr
-  
-  Protocol:
-  -Write : 0x01 + 16b Addr + 8b Data
-  -Read  : 0x02 + 16b Addr + 8b Don't Care
-
-  Todo:
-  Support Spi Burst Mode
-  
- */
-#include <SPI.h>
-#include <spiFpga.h>
-
-void setup() {
-  SF.begin();
-  SPI.setClockDivider(8);
-  Serial.begin(115200);
-}
-
-int  cmd = 0;
-
-void loop()
-{
- if (Serial.available() == 4)
- {
-   cmd = Serial.read();
-   //Write Cmd
-   if (cmd == 0x01)
-   {
-     char addrMsb = Serial.read();
-     char addrLsb = Serial.read();
-     char data = Serial.read();
-     SF.wr(addrMsb<<8|addrLsb, data);
-   }
-   //Read Cmd
-   if (cmd == 0x02)
-   {
-     char addrMsb = Serial.read();
-     char addrLsb = Serial.read();
-     Serial.read();
-     char data;
-     data = SF.rd(addrMsb<<8|addrLsb);
-     Serial.print(data);
-   }
-   else {
-     Serial.flush();
-   }
- }
-}
\ No newline at end of file
diff --git a/miscope/bridges/spi2csr/tools/uart2Spi.py b/miscope/bridges/spi2csr/tools/uart2Spi.py
deleted file mode 100644 (file)
index c7326c7..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-import string
-import time
-import serial
-from struct import *
-from migen.fhdl.structure import *
-
-def write_b(uart, data):
-       uart.write(pack('B',data))
-
-class Uart2Spi:
-       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 read(self, addr):
-               write_b(self.uart, 0x02)
-               write_b(self.uart, (addr>>8)&0xFF)
-               write_b(self.uart, (addr&0xFF))
-               write_b(self.uart, 0x00)
-               read = self.uart.read()
-               if self.debug:
-                       print("RD @ %04X" %addr)
-               return int(read[0])
-       
-       def read_n(self, addr, n, endianess = "LE"):
-               r = 0
-               words = int(2**bits_for(n-1)/8)
-               for i in range(words):
-                       if endianess == "BE":
-                               r += self.read(addr+i)<<(8*i)
-                       elif endianess == "LE":
-                               r += self.read(addr+words-1-i)<<(8*i)
-               if self.debug:
-                       print("RD @ %04X" %addr)
-               return r
-               
-       
-       def write(self, addr, data):
-               write_b(self.uart, 0x01)
-               write_b(self.uart, (addr>>8)&0xFF)
-               write_b(self.uart, (addr&0xFF))
-               write_b(self.uart, data)
-               if self.debug:
-                       print("WR %02X @ %04X" %(data, addr))
-               
-       def write_n(self, addr, data, n, endianess = "LE"):
-               words = int(2**bits_for(n-1)/8)
-               for i in range(words):
-                       if endianess == "BE":
-                               self.write(addr+i, (data>>(8*i)) & 0xFF)
-                       elif endianess == "LE":
-                               self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
-               if self.debug:
-                       print("WR %08X @ %04X" %(data, addr))
\ No newline at end of file
diff --git a/miscope/bridges/uart2csr/__init__.py b/miscope/bridges/uart2csr/__init__.py
deleted file mode 100644 (file)
index a9c20fa..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.module import *
-from migen.bus import csr
-from migen.genlib.fsm import *
-
-from miscope.bridges.uart2csr.uart import *
-
-WRITE_CMD = 0x01
-READ_CMD = 0x02
-CLOSE_CMD = 0x03
-
-class Uart2Csr(Module):
-       def __init__(self, clk_freq, baud):
-               # Uart interface
-               self.rx = Signal()
-               self.tx = Signal()
-               
-               # Csr interface
-               self.csr = csr.Interface()
-               
-       ###
-               
-               self.submodules.uart = UART(clk_freq, baud)
-               uart = self.uart
-
-               #
-               # In/Out
-               #
-               self.comb +=[
-                       uart.rx.eq(self.rx),
-                       self.tx.eq(uart.tx)
-               ]
-
-               cmd = Signal(8)
-               cnt = Signal(3)
-               sr = Signal(32)
-               burst_cnt = Signal(8)
-               addr = Signal(32)
-               data = Signal(8)
-
-               # FSM
-               self.submodules.fsm = FSM("IDLE", 
-                                                                 "GET_BL", "GET_ADDR", 
-                                                                 "GET_DATA", "WRITE_CSR",
-                                                                 "READ_CSR0", "READ_CSR1", "SEND_DATA")
-
-               fsm = self.fsm
-
-               #
-               # Global
-               #
-               self.sync +=[
-                       If(fsm.ongoing(fsm.IDLE), cnt.eq(0)
-                       ).Elif(uart.rx_ev, cnt.eq(cnt + 1)),
-
-                       If(uart.rx_ev, sr.eq(Cat(uart.rx_dat, sr[0:24])))
-               ]
-
-               # State done signals
-               get_bl_done = Signal()
-               get_addr_done = Signal()
-               get_addr_done_d = Signal()
-               get_data_done = Signal()
-               send_data_done = Signal()
-
-               #
-               # Idle
-               #
-               fsm.act(fsm.IDLE,
-                       If(uart.rx_ev & ((uart.rx_dat == WRITE_CMD) | (uart.rx_dat == READ_CMD)),
-                               fsm.next_state(fsm.GET_BL)
-                       )
-               )
-
-               self.sync += If(fsm.ongoing(fsm.IDLE) & uart.rx_ev, cmd.eq(uart.rx_dat))
-
-               #
-               # Get burst length
-               #
-               fsm.act(fsm.GET_BL,
-                       If(get_bl_done,
-                               fsm.next_state(fsm.GET_ADDR)
-                       )
-               )
-
-               self.comb += get_bl_done.eq(uart.rx_ev & fsm.ongoing(fsm.GET_BL))
-
-               self.sync += If(get_bl_done, burst_cnt.eq(uart.rx_dat))
-
-               #
-               # Get address
-               #
-               fsm.act(fsm.GET_ADDR,
-                       If(get_addr_done & (cmd == WRITE_CMD),
-                               fsm.next_state(fsm.GET_DATA)
-                       ).Elif(get_addr_done & (cmd == READ_CMD),
-                               fsm.next_state(fsm.READ_CSR0)
-                       )       
-               )
-
-               self.comb += get_addr_done.eq(uart.rx_ev & (cnt == 4) & fsm.ongoing(fsm.GET_ADDR))
-               self.sync += get_addr_done_d.eq(get_addr_done)
-               
-               self.sync += [
-                       If(get_addr_done_d,
-                               addr.eq(sr)
-                       ).Elif(fsm.leaving(fsm.WRITE_CSR) | send_data_done,
-                               addr.eq(addr + 1)
-                       )
-               ]
-
-               #
-               # Get data
-               #
-               fsm.act(fsm.GET_DATA,
-                       If(get_data_done,
-                               fsm.next_state(fsm.WRITE_CSR)
-                       )
-               )
-
-               self.comb += get_data_done.eq(uart.rx_ev & fsm.ongoing(fsm.GET_DATA))   
-               self.sync += [
-                       If(get_data_done,
-                               burst_cnt.eq(burst_cnt-1),
-                               data.eq(uart.rx_dat)
-                       )
-               ]
-
-               #
-               # Write Csr
-               #
-               fsm.act(fsm.WRITE_CSR,
-                       If((burst_cnt==0), 
-                               fsm.next_state(fsm.IDLE)
-                       ).Else(fsm.next_state(fsm.GET_DATA))
-               )
-
-
-               #
-               # Read Csr0
-               #
-               fsm.act(fsm.READ_CSR0,
-                       fsm.next_state(fsm.READ_CSR1)
-               )
-
-               self.sync += If(fsm.entering(fsm.READ_CSR0), burst_cnt.eq(burst_cnt-1))
-
-               #
-               # Read Csr1
-               #
-               fsm.act(fsm.READ_CSR1,
-                       fsm.next_state(fsm.SEND_DATA)
-               )
-
-
-               #
-               # Send Data
-               #
-               fsm.act(fsm.SEND_DATA,
-                       If(send_data_done & (burst_cnt==0),
-                               fsm.next_state(fsm.IDLE)
-                       ).Elif(send_data_done,
-                               fsm.next_state(fsm.READ_CSR0)
-                       )
-               )
-
-               self.comb += send_data_done.eq(fsm.ongoing(fsm.SEND_DATA) & uart.tx_ev)
-
-               self.sync += [
-                               uart.tx_dat.eq(self.csr.dat_r),
-                               uart.tx_we.eq(fsm.entering(fsm.SEND_DATA)),
-               ]
-
-
-               #
-               # Csr access
-               #
-               self.comb += self.csr.adr.eq(addr) 
-               self.sync +=[
-                       self.csr.dat_w.eq(data),
-                       If(fsm.ongoing(fsm.WRITE_CSR),
-                               self.csr.we.eq(1)
-                       ).Else(
-                               self.csr.we.eq(0)       
-                       )
-               ]
\ No newline at end of file
diff --git a/miscope/bridges/uart2csr/tools/__init__.py b/miscope/bridges/uart2csr/tools/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/miscope/bridges/uart2csr/tools/uart2Csr.py b/miscope/bridges/uart2csr/tools/uart2Csr.py
deleted file mode 100644 (file)
index 1e58d94..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-import string
-import time
-import serial
-from struct import *
-import time
-from migen.fhdl.structure import *
-
-WRITE_CMD  = 0x01
-READ_CMD   = 0x02
-CLOSE_CMD  = 0x03
-
-def write_b(uart, data):
-       uart.write(pack('B',data))
-
-class Uart2Csr:
-       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 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(1)
-                       val = int(read[0])
-                       if self.debug:
-                               print("RD %02X @ %08X" %(val, addr + 4*i))
-                       values.append(val)
-               if burst_length == 1:
-                       return values[0]
-               else:
-                       return values
-
-       def read_n(self, addr, n, endianess = "LE"):
-               r = 0
-               words = int(2**bits_for(n-1)/8)
-               for i in range(words):
-                       if endianess == "BE":
-                               r += self.read(addr+i)<<(8*i)
-                       elif endianess == "LE":
-                               r += self.read(addr+words-1-i)<<(8*i)
-               if self.debug:
-                       print("RD @ %04X" %addr)
-               return r                
-               
-       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)):
-                               write_b(self.uart, data[i])
-                               if self.debug:
-                                       print("WR %02X @ %08X" %(data[i], addr + 4*i))
-               else:
-                       write_b(self.uart, data)
-                       if self.debug:
-                               print("WR %02X @ %08X" %(data, addr))
-
-       def write_n(self, addr, data, n, endianess = "LE"):
-               words = int(2**bits_for(n-1)/8)
-               for i in range(words):
-                       if endianess == "BE":
-                               self.write(addr+i, (data>>(8*i)) & 0xFF)
-                       elif endianess == "LE":
-                               self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
-               if self.debug:
-                       print("WR %08X @ %04X" %(data, addr))
\ No newline at end of file
diff --git a/miscope/bridges/uart2csr/uart.py b/miscope/bridges/uart2csr/uart.py
deleted file mode 100644 (file)
index fe2e9e0..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-from migen.bank.eventmanager import *
-
-class UART(Module):
-       def __init__(self, clk_freq, baud=115200):
-               
-               self.rx_ev = Signal()
-               self.rx_dat = Signal(8)
-               
-               self.tx_we = Signal()
-               self.tx_ev = Signal()
-               self.tx_dat = Signal(8)
-               
-               self.divisor = Signal(16, reset=int(clk_freq/baud/16))
-
-               self.tx = Signal(reset=1)
-               self.rx = Signal()
-
-       
-               ###
-
-               enable16 = Signal()
-               enable16_counter = Signal(16)
-               self.comb += enable16.eq(enable16_counter == 0)
-               self.sync += [
-                       enable16_counter.eq(enable16_counter - 1),
-                       If(enable16,
-                               enable16_counter.eq(self.divisor - 1))
-               ]
-               
-               # TX
-               tx_reg = Signal(8)
-               tx_bitcount = Signal(4)
-               tx_count16 = Signal(4)
-               tx_done = self.tx_ev
-               tx_busy = Signal()
-               self.sync += [
-                       tx_done.eq(0),
-                       If(self.tx_we,
-                               tx_reg.eq(self.tx_dat),
-                               tx_bitcount.eq(0),
-                               tx_count16.eq(1),
-                               tx_busy.eq(1),
-                               self.tx.eq(0)
-                       ).Elif(enable16 & tx_busy,
-                               tx_count16.eq(tx_count16 + 1),
-                               If(tx_count16 == 0,
-                                       tx_bitcount.eq(tx_bitcount + 1),
-                                       If(tx_bitcount == 8,
-                                               self.tx.eq(1)
-                                       ).Elif(tx_bitcount == 9,
-                                               self.tx.eq(1),
-                                               tx_busy.eq(0),
-                                               tx_done.eq(1)
-                                       ).Else(
-                                               self.tx.eq(tx_reg[0]),
-                                               tx_reg.eq(Cat(tx_reg[1:], 0))
-                                       )
-                               )
-                       )
-               ]
-               
-               # RX
-               rx = Signal()
-               self.specials += MultiReg(self.rx, rx, "sys")
-               rx_r = Signal()
-               rx_reg = Signal(8)
-               rx_bitcount = Signal(4)
-               rx_count16 = Signal(4)
-               rx_busy = Signal()
-               rx_done = self.rx_ev
-               rx_data = self.rx_dat
-               self.sync += [
-                       rx_done.eq(0),
-                       If(enable16,
-                               rx_r.eq(rx),
-                               If(~rx_busy,
-                                       If(~rx & rx_r, # look for start bit
-                                               rx_busy.eq(1),
-                                               rx_count16.eq(7),
-                                               rx_bitcount.eq(0)
-                                       )
-                               ).Else(
-                                       rx_count16.eq(rx_count16 + 1),
-                                       If(rx_count16 == 0,
-                                               rx_bitcount.eq(rx_bitcount + 1),
-
-                                               If(rx_bitcount == 0,
-                                                       If(rx, # verify start bit
-                                                               rx_busy.eq(0)
-                                                       )
-                                               ).Elif(rx_bitcount == 9,
-                                                       rx_busy.eq(0),
-                                                       If(rx, # verify stop bit
-                                                               rx_data.eq(rx_reg),
-                                                               rx_done.eq(1)
-                                                       )
-                                               ).Else(
-                                                       rx_reg.eq(Cat(rx_reg[1:], rx))
-                                               )
-                                       )
-                               )
-                       )
-               ]
diff --git a/miscope/com/__init__.py b/miscope/com/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/miscope/com/uart2csr/__init__.py b/miscope/com/uart2csr/__init__.py
new file mode 100644 (file)
index 0000000..e8e569c
--- /dev/null
@@ -0,0 +1,183 @@
+from migen.fhdl.structure import *
+from migen.fhdl.module import *
+from migen.bus import csr
+from migen.genlib.fsm import FSM, NextState
+
+from miscope.com.uart2csr.uart import *
+
+WRITE_CMD = 0x01
+READ_CMD = 0x02
+CLOSE_CMD = 0x03
+
+class Uart2Csr(Module):
+       def __init__(self, clk_freq, baud):
+               # Uart interface
+               self.rx = Signal()
+               self.tx = Signal()
+               
+               # Csr interface
+               self.csr = csr.Interface()
+               
+       ###
+               
+               self.submodules.uart = UART(clk_freq, baud)
+               uart = self.uart
+
+               #
+               # In/Out
+               #
+               self.comb +=[
+                       uart.rx.eq(self.rx),
+                       self.tx.eq(uart.tx)
+               ]
+
+               cmd = Signal(8)
+               cnt = Signal(3)
+               sr = Signal(32)
+               burst_cnt = Signal(8)
+               addr = Signal(32)
+               data = Signal(8)
+
+               # FSM
+               self.submodules.fsm = FSM(reset_state="IDLE")
+
+               fsm = self.fsm
+
+               #
+               # Global
+               #
+               self.sync +=[
+                       If(fsm.ongoing("IDLE"), cnt.eq(0)
+                       ).Elif(uart.rx_ev, cnt.eq(cnt + 1)),
+
+                       If(uart.rx_ev, sr.eq(Cat(uart.rx_dat, sr[0:24])))
+               ]
+
+               # State done signals
+               get_bl_done = Signal()
+               get_addr_done = Signal()
+               get_addr_done_d = Signal()
+               get_data_done = Signal()
+               send_data_done = Signal()
+
+               #
+               # Idle
+               #
+               fsm.act("IDLE",
+                       If(uart.rx_ev & ((uart.rx_dat == WRITE_CMD) | (uart.rx_dat == READ_CMD)),
+                               NextState("GET_BL")
+                       )
+               )
+
+               self.sync += If(fsm.ongoing("IDLE") & uart.rx_ev, cmd.eq(uart.rx_dat))
+
+               #
+               # Get burst length
+               #
+               fsm.act("GET_BL",
+                       If(get_bl_done,
+                               NextState("GET_ADDR")
+                       )
+               )
+
+               self.comb += get_bl_done.eq(uart.rx_ev & fsm.ongoing("GET_BL"))
+
+               self.sync += If(get_bl_done, burst_cnt.eq(uart.rx_dat))
+
+               #
+               # Get address
+               #
+               fsm.act("GET_ADDR",
+                       If(get_addr_done & (cmd == WRITE_CMD),
+                               NextState("GET_DATA")
+                       ).Elif(get_addr_done & (cmd == READ_CMD),
+                               NextState("READ_CSR0")
+                       )       
+               )
+
+               self.comb += get_addr_done.eq(uart.rx_ev & (cnt == 4) & fsm.ongoing("GET_ADDR"))
+               self.sync += get_addr_done_d.eq(get_addr_done)
+               
+               self.sync += [
+                       If(get_addr_done_d,
+                               addr.eq(sr)
+                       ).Elif(fsm.leaving("WRITE_CSR") | send_data_done,
+                               addr.eq(addr + 1)
+                       )
+               ]
+
+               #
+               # Get data
+               #
+               fsm.act("GET_DATA",
+                       If(get_data_done,
+                               NextState("WRITE_CSR")
+                       )
+               )
+
+               self.comb += get_data_done.eq(uart.rx_ev & fsm.ongoing("GET_DATA"))     
+               self.sync += [
+                       If(get_data_done,
+                               burst_cnt.eq(burst_cnt-1),
+                               data.eq(uart.rx_dat)
+                       )
+               ]
+
+               #
+               # Write Csr
+               #
+               fsm.act("WRITE_CSR",
+                       If((burst_cnt==0), 
+                               NextState("IDLE")
+                       ).Else(NextState("GET_DATA"))
+               )
+
+
+               #
+               # Read Csr0
+               #
+               fsm.act("READ_CSR0",
+                       NextState("READ_CSR1")
+               )
+
+               self.sync += If(fsm.entering("READ_CSR0"), burst_cnt.eq(burst_cnt-1))
+
+               #
+               # Read Csr1
+               #
+               fsm.act("READ_CSR1",
+                       NextState("SEND_DATA")
+               )
+
+
+               #
+               # Send Data
+               #
+               fsm.act("SEND_DATA",
+                       If(send_data_done & (burst_cnt==0),
+                               NextState("IDLE")
+                       ).Elif(send_data_done,
+                               NextState("READ_CSR0")
+                       )
+               )
+
+               self.comb += send_data_done.eq(fsm.ongoing("SEND_DATA") & uart.tx_ev)
+
+               self.sync += [
+                               uart.tx_dat.eq(self.csr.dat_r),
+                               uart.tx_we.eq(fsm.entering("SEND_DATA")),
+               ]
+
+
+               #
+               # Csr access
+               #
+               self.comb += self.csr.adr.eq(addr) 
+               self.sync +=[
+                       self.csr.dat_w.eq(data),
+                       If(fsm.ongoing("WRITE_CSR"),
+                               self.csr.we.eq(1)
+                       ).Else(
+                               self.csr.we.eq(0)       
+                       )
+               ]
\ No newline at end of file
diff --git a/miscope/com/uart2csr/host/__init__.py b/miscope/com/uart2csr/host/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/miscope/com/uart2csr/host/uart2csr.py b/miscope/com/uart2csr/host/uart2csr.py
new file mode 100644 (file)
index 0000000..c1ce7d0
--- /dev/null
@@ -0,0 +1,91 @@
+import string
+import time
+import serial
+from struct import *
+import time
+from migen.fhdl.structure import *
+
+WRITE_CMD  = 0x01
+READ_CMD   = 0x02
+CLOSE_CMD  = 0x03
+
+def write_b(uart, data):
+       uart.write(pack('B',data))
+
+class Uart2Csr:
+       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.close()
+               self.uart.open()
+               
+       def close(self):
+               self.uart.close()
+
+       def read_csr(self, addr, burst_length=1):
+               write_b(self.uart, READ_CMD)
+               write_b(self.uart, burst_length)
+               addr = addr//4
+               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(1)
+                       val = int(read[0])
+                       if self.debug:
+                               print("RD %02X @ %08X" %(val, addr + 4*i))
+                       values.append(val)
+               if burst_length == 1:
+                       return values[0]
+               else:
+                       return values
+
+       def read_n(self, addr, n, endianess = "LE"):
+               r = 0
+               words = int(2**bits_for(n-1)/8)
+               for i in range(words):
+                       if endianess == "BE":
+                               r += self.read(addr+i)<<(8*i)
+                       elif endianess == "LE":
+                               r += self.read(addr+words-1-i)<<(8*i)
+               if self.debug:
+                       print("RD @ %04X" %addr)
+               return r                
+               
+       def write_csr(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)
+               addr = addr//4
+               self.uart.write([(addr & 0xff000000) >> 24,
+                                               (addr & 0x00ff0000) >> 16,
+                                               (addr & 0x0000ff00) >> 8,
+                                               (addr & 0x000000ff)])
+               if isinstance(data, list):
+                       for i in range(len(data)):
+                               write_b(self.uart, data[i])
+                               if self.debug:
+                                       print("WR %02X @ %08X" %(data[i], addr + 4*i))
+               else:
+                       write_b(self.uart, data)
+                       if self.debug:
+                               print("WR %02X @ %08X" %(data, addr))
+
+       def write_n(self, addr, data, n, endianess = "LE"):
+               words = int(2**bits_for(n-1)/8)
+               for i in range(words):
+                       if endianess == "BE":
+                               self.write(addr+i, (data>>(8*i)) & 0xFF)
+                       elif endianess == "LE":
+                               self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
+               if self.debug:
+                       print("WR %08X @ %04X" %(data, addr))
\ No newline at end of file
diff --git a/miscope/com/uart2csr/uart.py b/miscope/com/uart2csr/uart.py
new file mode 100644 (file)
index 0000000..fe2e9e0
--- /dev/null
@@ -0,0 +1,107 @@
+from migen.fhdl.structure import *
+from migen.fhdl.module import Module
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+
+class UART(Module):
+       def __init__(self, clk_freq, baud=115200):
+               
+               self.rx_ev = Signal()
+               self.rx_dat = Signal(8)
+               
+               self.tx_we = Signal()
+               self.tx_ev = Signal()
+               self.tx_dat = Signal(8)
+               
+               self.divisor = Signal(16, reset=int(clk_freq/baud/16))
+
+               self.tx = Signal(reset=1)
+               self.rx = Signal()
+
+       
+               ###
+
+               enable16 = Signal()
+               enable16_counter = Signal(16)
+               self.comb += enable16.eq(enable16_counter == 0)
+               self.sync += [
+                       enable16_counter.eq(enable16_counter - 1),
+                       If(enable16,
+                               enable16_counter.eq(self.divisor - 1))
+               ]
+               
+               # TX
+               tx_reg = Signal(8)
+               tx_bitcount = Signal(4)
+               tx_count16 = Signal(4)
+               tx_done = self.tx_ev
+               tx_busy = Signal()
+               self.sync += [
+                       tx_done.eq(0),
+                       If(self.tx_we,
+                               tx_reg.eq(self.tx_dat),
+                               tx_bitcount.eq(0),
+                               tx_count16.eq(1),
+                               tx_busy.eq(1),
+                               self.tx.eq(0)
+                       ).Elif(enable16 & tx_busy,
+                               tx_count16.eq(tx_count16 + 1),
+                               If(tx_count16 == 0,
+                                       tx_bitcount.eq(tx_bitcount + 1),
+                                       If(tx_bitcount == 8,
+                                               self.tx.eq(1)
+                                       ).Elif(tx_bitcount == 9,
+                                               self.tx.eq(1),
+                                               tx_busy.eq(0),
+                                               tx_done.eq(1)
+                                       ).Else(
+                                               self.tx.eq(tx_reg[0]),
+                                               tx_reg.eq(Cat(tx_reg[1:], 0))
+                                       )
+                               )
+                       )
+               ]
+               
+               # RX
+               rx = Signal()
+               self.specials += MultiReg(self.rx, rx, "sys")
+               rx_r = Signal()
+               rx_reg = Signal(8)
+               rx_bitcount = Signal(4)
+               rx_count16 = Signal(4)
+               rx_busy = Signal()
+               rx_done = self.rx_ev
+               rx_data = self.rx_dat
+               self.sync += [
+                       rx_done.eq(0),
+                       If(enable16,
+                               rx_r.eq(rx),
+                               If(~rx_busy,
+                                       If(~rx & rx_r, # look for start bit
+                                               rx_busy.eq(1),
+                                               rx_count16.eq(7),
+                                               rx_bitcount.eq(0)
+                                       )
+                               ).Else(
+                                       rx_count16.eq(rx_count16 + 1),
+                                       If(rx_count16 == 0,
+                                               rx_bitcount.eq(rx_bitcount + 1),
+
+                                               If(rx_bitcount == 0,
+                                                       If(rx, # verify start bit
+                                                               rx_busy.eq(0)
+                                                       )
+                                               ).Elif(rx_bitcount == 9,
+                                                       rx_busy.eq(0),
+                                                       If(rx, # verify stop bit
+                                                               rx_data.eq(rx_reg),
+                                                               rx_done.eq(1)
+                                                       )
+                                               ).Else(
+                                                       rx_reg.eq(Cat(rx_reg[1:], rx))
+                                               )
+                                       )
+                               )
+                       )
+               ]
index b2512cb52da47aaff9201b39e5ddbf3677c432af..d4bd1bd997ee2352cd41f22fd2822ce1653d0718 100644 (file)
@@ -3,44 +3,17 @@ from migen.bus import csr
 from migen.bank import csrgen
 from migen.bank.description import *
 
-from miscope.tools.misc import *
-
-class MiIo:
-       # 
-       # Definition
-       #
-       def __init__(self, address, width, mode="IO", interface=None):
-               self.address = address
+class MiIo(Module, AutoCSR):
+       def __init__(self, width):
                self.width = width
-               self.mode = mode.upper()
-               self.interface = interface
-               self.words = int((2**bits_for(width-1))/8)
-               
-               if "I" in self.mode:
-                       self.i = Signal(self.width)
-                       self._r_i = CSRStatus(self.width)
-                       
-               if "O" in self.mode:
-                       self.o = Signal(self.width)
-                       self._r_o = CSRStorage(self.width)
-                       
-               self.bank = csrgen.Bank([self._r_o, self._r_i], address=self.address)
-               
-       def get_fragment(self):
-               comb = []
-               
-               if "I" in self.mode:
-                       comb += [self._r_i.status.eq(self.i)]
-                       
-               if "O" in self.mode:
-                       comb += [self.o.eq(self._r_o.storage)]
-                       
-               return Fragment(comb) + self.bank.get_fragment()
-       #
-       # Driver
-       #
-       def set(self, data):
-                       self.interface.write(get_csr_base(self.bank), data)
-                       
-       def get(self):
-               return self.interface.read(get_csr_base(self.bank) + self.words)
\ No newline at end of file
+
+               self.i = Signal(self.width)
+               self.o = Signal(self.width)
+
+               self._r_i = CSRStatus(self.width)
+               self._r_o = CSRStorage(self.width)
+
+               self.sync +=[
+                       self._r_i.status.eq(self.i),
+                       self.o.eq(self._r_o.storage)
+               ]
\ No newline at end of file
index 341b135a52de8601255d0f3fcc72d991fd7f525d..b0aa15aae0f9980d922a5b0798443d8271ee475d 100644 (file)
@@ -1,48 +1,27 @@
 from migen.fhdl.structure import *
+from migen.flow.actor import *
+from migen.flow.network import *
 from migen.bus import csr
 from migen.bank import description, csrgen
 from migen.bank.description import *
 
-from miscope import trigger, recorder
-from miscope.tools.misc import *
-
-class MiLa:
-       def __init__(self, address, trigger, recorder, interface=None, trig_is_dat=False):
-
+class MiLa(Module, AutoCSR):
+       def __init__(self, trigger, recorder):
                self.trigger = trigger
                self.recorder = recorder
-               self.interface = interface
-               self.trig_is_dat = trig_is_dat
-               
-               self.stb = Signal(reset=1)
-               self.trig = Signal(self.trigger.width)
-               self.dat  = Signal(self.recorder.width)
-               
-               self.set_address(address)
-               self.set_interface(interface)
 
-       def set_address(self, address):
-               self.address = address
-               self.trigger.set_address(self.address)
-               self.recorder.set_address(self.address + 0x01)
+               self.sink = trigger.sink
+               self.submodules += trigger, recorder
 
-       def set_interface(self, interface):
-               self.interface = interface
-               self.trigger.set_interface(interface)
-               self.recorder.set_interface(interface)
-               
-       def get_fragment(self):
-               comb =[
-                       self.recorder.stb.eq(self.stb),
-                       self.trigger.trig.eq(self.trig),
+               self.comb +=[
+                       recorder.sink.stb.eq(trigger.source.stb),
                        
-                       self.recorder.hit.eq(self.trigger.hit)
+                       recorder.sink.payload.hit.eq(trigger.source.payload.hit),
+                       trigger.source.ack.eq(recorder.sink.ack)
                ]
-               if self.trig_is_dat:
-                       comb +=[
-                       self.recorder.dat.eq(self.trig),
-                       ]
-               else:
-                       self.recorder.dat.eq(self.dat),
-               
-               return Fragment(comb)
\ No newline at end of file
+
+               # Todo; Insert configurable delay to support pipelined
+               # triggers elements
+               self.comb +=[
+                       recorder.sink.payload.d.eq(self.sink.payload.d),
+               ]
\ No newline at end of file
diff --git a/miscope/recorder.py b/miscope/recorder.py
deleted file mode 100644 (file)
index 87b7bf3..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Memory
-from migen.bus import csr
-from migen.bank import description, csrgen
-from migen.bank.description import *
-from migen.genlib.misc import optree
-from migen.genlib.fsm import *
-
-from miscope.tools.misc import *
-
-class Storage:
-       # 
-       # Definition
-       #
-       def __init__(self, width, depth):
-               self.width = width
-               self.depth = depth
-               self.depth_width = bits_for(self.depth)
-               
-               # Control
-               self.rst = Signal()
-               self.start = Signal()
-               self.offset = Signal(self.depth_width)
-               self.size = Signal(self.depth_width)
-               self.done = Signal()
-               
-               # Push Path
-               self.push_stb = Signal()
-               self.push_dat = Signal(self.width)
-               self._push_ptr = Signal(self.depth_width)
-               self._push_ptr_stop = Signal(self.depth_width)
-               
-               # Pull Path
-               self.pull_stb = Signal()
-               self.pull_dat = Signal(self.width)
-               self._pull_ptr = Signal(self.depth_width)
-               
-               # Memory
-               self._mem = Memory(self.width, self.depth)
-               self._push_port = self._mem.get_port(write_capable=True)
-               self._pull_port = self._mem.get_port(has_re=True)
-               
-       def get_fragment(self):
-               comb = [
-                                       self._push_port.adr.eq(self._push_ptr),
-                                       self._push_port.we.eq(self.push_stb),
-                                       self._push_port.dat_w.eq(self.push_dat),
-               
-                                       self._pull_port.adr.eq(self._pull_ptr),
-                                       self._pull_port.re.eq(self.pull_stb),
-                                       self.pull_dat.eq(self._pull_port.dat_r)
-               ]
-               
-               # FSM
-               fsm = FSM("IDLE", "ACTIVE")
-               
-               # Idle
-               fsm.act(fsm.IDLE, 
-                       If(self.start, 
-                               fsm.next_state(fsm.ACTIVE),
-                       )
-               )
-               
-               # Active
-               fsm.act(fsm.ACTIVE,
-                       If(self.done | self.rst,
-                               fsm.next_state(fsm.IDLE),
-                       )
-               )
-               
-               sync =[ 
-                       If(fsm.entering(fsm.ACTIVE),
-                               self._push_ptr_stop.eq(self._push_ptr + self.size - self.offset),
-                               self._pull_ptr.eq(self._push_ptr - self.offset - 1)     
-                       ).Else(
-                               If(self.pull_stb, self._pull_ptr.eq(self._pull_ptr + 1))
-                       ),
-                       If(self.push_stb, self._push_ptr.eq(self._push_ptr + 1)),
-               ]
-               comb +=[self.done.eq((self._push_ptr == self._push_ptr_stop) & fsm.ongoing(fsm.ACTIVE))]
-               
-               return Fragment(comb, sync, specials={self._mem}) + fsm.get_fragment()
-
-class RLE:
-
-       # 
-       # Definition
-       #
-       def __init__(self, width, length):
-               self.width = width
-               self.length = length
-
-               # Control
-               self.enable = Signal()
-
-               # Input
-               self.stb_i = Signal()
-               self.dat_i = Signal(width)
-
-               # Output
-               self.stb_o = Signal()
-               self.dat_o = Signal(width)
-               
-       def get_fragment(self):
-
-               # Register Input
-               stb_i_d = Signal()
-               dat_i_d = Signal(self.width)
-
-               sync =[dat_i_d.eq(self.dat_i)]
-               sync +=[stb_i_d.eq(self.stb_i)]
-               
-               # Detect diff
-               diff = Signal()
-               comb = [diff.eq(self.stb_i & (~self.enable | (dat_i_d != self.dat_i)))]
-
-               diff_rising = RisingEdge(diff)
-               diff_d = Signal()
-               sync +=[diff_d.eq(diff)]
-
-               # Generate RLE word
-               rle_cnt  = Signal(max=self.length)
-               rle_max  = Signal()
-
-               comb +=[If(rle_cnt == self.length, rle_max.eq(self.enable))]
-
-               sync +=[
-                       If(diff | rle_max,
-                               rle_cnt.eq(0)
-                       ).Else(
-                               rle_cnt.eq(rle_cnt + 1)
-                       )
-               ]
-
-               # Mux RLE word and data
-               comb +=[
-                       If(diff_rising.o & (~rle_max),
-                               self.stb_o.eq(1),
-                               self.dat_o[self.width-1].eq(1),
-                               self.dat_o[:flen(rle_cnt)].eq(rle_cnt)
-                       ).Elif(diff_d | rle_max,
-                               self.stb_o.eq(stb_i_d),
-                               self.dat_o.eq(dat_i_d)
-                       ).Else(
-                               self.stb_o.eq(0),
-                       )
-               ]
-
-               return Fragment(comb, sync) + diff_rising.get_fragment()
-
-class Sequencer:
-       # 
-       # Definition
-       #
-       def __init__(self):
-               
-               # Control
-               self.rst = Signal()
-               self.arm = Signal()
-               
-               # Trigger
-               self.hit  = Signal()
-               
-               # Recorder
-               self.start = Signal()
-               self.done = Signal()
-               
-               # Internal
-               self.enable = Signal()
-               
-       def get_fragment(self):
-               
-               # FSM
-               fsm = FSM("IDLE", "ACTIVE")
-               
-               # Idle
-               fsm.act(fsm.IDLE, 
-                       If(self.arm, 
-                               fsm.next_state(fsm.ACTIVE),
-                       )
-               )
-               
-               # Active
-               fsm.act(fsm.ACTIVE,
-                       If(self.done | self.rst,
-                               fsm.next_state(fsm.IDLE),
-                       ),
-                       self.enable.eq(1)
-               )
-               
-               # Start
-               hit_rising = RisingEdge(self.hit)
-               comb =[self.start.eq(self.enable & hit_rising.o)]
-
-               return Fragment(comb) + fsm.get_fragment() + hit_rising.get_fragment()
-
-
-REC_RST_BASE           = 0x00
-REC_RLE_BASE        = 0x01
-REC_ARM_BASE           = 0x02
-REC_DONE_BASE          = 0x03
-REC_SIZE_BASE          = 0x04
-REC_OFFSET_BASE                = 0x06
-REC_READ_BASE          = 0x08
-REC_READ_DATA_BASE     = 0x09
-
-class Recorder:
-       # 
-       # Definition
-       #
-       def __init__(self, width, depth, address=0x0000, interface=None):
-               self.width = width
-               self.depth = depth
-               self.depth_width = bits_for(self.depth-1)
-               
-               self.storage = Storage(self.width, self.depth)
-               self.sequencer = Sequencer()
-               self.rle = RLE(self.width, (2**(width-2)))
-               
-               # csr interface
-               self._r_rst = CSRStorage(reset=1)
-               self._r_rle = CSRStorage(reset=0)
-               self._r_arm = CSRStorage(reset=0)
-               self._r_done = CSRStatus()
-               
-               self._r_size = CSRStorage(self.depth_width, reset=1)
-               self._r_offset = CSRStorage(self.depth_width, reset=1)
-               
-               self._r_pull_stb = CSRStorage(reset=0)
-               self._r_pull_dat = CSRStatus(self.width)
-               
-               self.regs = [self._r_rst, self._r_rle, self._r_arm, self._r_done, self._r_size, self._r_offset,
-                                       self._r_pull_stb, self._r_pull_dat]
-               
-               # set address / interface
-               self.set_address(address)
-               self.set_interface(interface)
-               
-               # trigger Interface
-               self.hit = Signal()
-               self.stb = Signal()
-               self.dat = Signal(self.width)
-       
-       def set_address(self, address):
-               self.address = address
-               self.bank = csrgen.Bank(self.regs, address=self.address)
-                       
-       def set_interface(self, interface):
-               self.interface = interface
-               
-       def get_fragment(self):
-
-               _pull_stb_rising = RisingEdge(self._r_pull_stb.storage)
-
-               # Bank <--> Storage / Sequencer
-               comb = [
-                       self.sequencer.rst.eq(self._r_rst.storage),
-                       self.storage.rst.eq(self._r_rst.storage),
-                       
-                       self.rle.enable.eq(self._r_rle.storage),
-                       self.sequencer.arm.eq(self._r_arm.storage),
-                       self.storage.offset.eq(self._r_offset.storage),
-                       self.storage.size.eq(self._r_size.storage),
-
-                       self._r_done.status.eq(~self.sequencer.enable),
-                       
-                       self.storage.pull_stb.eq(_pull_stb_rising.o),
-                       self._r_pull_dat.status.eq(self.storage.pull_dat)
-                       ]
-               
-               # Storage <--> Sequencer <--> Trigger
-               comb += [
-                       self.storage.start.eq(self.sequencer.start),
-                       self.sequencer.done.eq(self.storage.done),
-                       self.sequencer.hit.eq(self.hit),
-                       
-                       self.rle.stb_i.eq(self.stb),
-                       self.rle.dat_i.eq(self.dat),
-
-                       self.storage.push_stb.eq(self.sequencer.enable & self.rle.stb_o),
-                       self.storage.push_dat.eq(self.rle.dat_o)
-                       ]
-               
-               return self.bank.get_fragment() + Fragment(comb) +\
-                       self.storage.get_fragment() + self.sequencer.get_fragment() +\
-                       _pull_stb_rising.get_fragment() + self.rle.get_fragment()
-
-                       
-                       
-       #
-       # Driver
-       #
-       def reset(self):
-               self.interface.write(get_csr_base(self.bank) + REC_RST_BASE, 1)
-               self.interface.write(get_csr_base(self.bank) + REC_RST_BASE, 0)
-
-       def enable_rle(self):
-               self.interface.write(get_csr_base(self.bank) + REC_RLE_BASE, 1)
-
-       def disable_rle(self):
-               self.interface.write(get_csr_base(self.bank) + REC_RLE_BASE, 0)
-
-       def arm(self):
-               self.interface.write(get_csr_base(self.bank) + REC_ARM_BASE, 1)
-               self.interface.write(get_csr_base(self.bank) + REC_ARM_BASE, 0)
-       
-       def is_done(self):
-               return self.interface.read(get_csr_base(self.bank) + REC_DONE_BASE) == 1
-               
-       def set_size(self, dat):
-               self.interface.write_n(get_csr_base(self.bank) + REC_SIZE_BASE, dat, 16)
-               
-       def set_offset(self, dat):
-               self.interface.write_n(get_csr_base(self.bank) + REC_OFFSET_BASE, dat, 16)
-               
-       def pull(self, size):
-               r = []
-               for i in range(size):
-                       self.interface.write(get_csr_base(self.bank) + REC_READ_BASE, 1)
-                       self.interface.write(get_csr_base(self.bank) + REC_READ_BASE, 0)
-                       r.append(self.interface.read_n(get_csr_base(self.bank) + REC_READ_DATA_BASE, self.width))
-                       if i%128 == 0:
-                               print(i)
-               return r
diff --git a/miscope/recording/__init__.py b/miscope/recording/__init__.py
new file mode 100644 (file)
index 0000000..064991c
--- /dev/null
@@ -0,0 +1,86 @@
+from migen.fhdl.std import *
+from migen.flow.actor import *
+from migen.flow.network import *
+from migen.fhdl.specials import Memory
+from migen.bus import csr
+from migen.bank import description, csrgen
+from migen.bank.description import *
+from migen.actorlib.fifo import SyncFIFO
+
+class Recorder(Module, AutoCSR):
+       def __init__(self, width, depth):
+               self.width = width
+
+               self.sink = Sink([("hit", 1), ("d", width)])
+
+               self._r_trigger = CSR()
+               self._r_length = CSRStorage(bits_for(depth))
+               self._r_offset = CSRStorage(bits_for(depth))
+               self._r_done = CSRStatus()
+
+               self._r_read_en = CSR()
+               self._r_read_empty = CSRStatus()
+               self._r_read_dat = CSRStatus(width)
+
+               ###
+
+               length = self._r_length.storage
+               offset = self._r_offset.storage
+               done = Signal(reset=1)
+               ongoing = Signal()
+
+               cnt = Signal(max=depth)
+
+               fifo = SyncFIFO([("d", width)], depth)
+               self.submodules += fifo
+       
+               # Write fifo is done only when done = 0
+               # Fifo must always be pulled by software between
+               # acquisition (Todo: add a flush funtionnality)
+               self.comb +=[
+                       fifo.sink.stb.eq(self.sink.stb & ~done),
+                       fifo.sink.payload.d.eq(self.sink.payload.d),
+                       self.sink.ack.eq(1)
+               ]
+
+               # Done, Ongoing:
+               # 0, 0 : Storage triggered but hit was not yet seen
+               #        Data are recorded to fifo, if "offset" datas 
+               #        in the fifo, ack is set on fifo.source to
+               #        store only "offset" datas.
+               #
+               # 0, 1 : Hit was seen, ack is no longer set on fifo.source
+               #        we are storing "length"-"offset" data in this
+               #        phase
+               #
+               # 1, 0 : We have stored "length" datas in fifo. Write to
+               #        fifo is disabled.
+               #        Software must now read data from the fifo until
+               #        it is empty
+               
+               # done & ongoing
+               self.sync += [
+                       If(self._r_trigger.re & self._r_trigger.r, done.eq(0)
+                       ).Elif(cnt==length, done.eq(1)),
+                       
+                       If(self.sink.stb & self.sink.payload.hit & ~done, ongoing.eq(1)
+                       ).Elif(done, ongoing.eq(0)),
+               ]
+
+               # fifo ack & csr connection
+               self.comb += [
+                       If(~done & ~ongoing & (cnt >= offset), fifo.source.ack.eq(1)
+                       ).Else(fifo.source.ack.eq(self._r_read_en.re & self._r_read_en.r)),
+                       self._r_read_empty.status.eq(~fifo.source.stb),
+                       self._r_read_dat.status.eq(fifo.source.payload.d),
+                       self._r_done.status.eq(done)
+               ]
+
+               # cnt
+               self.sync += [
+                       If(done == 1,
+                               cnt.eq(0)
+                       ).Elif(fifo.sink.stb & fifo.sink.ack & ~(fifo.source.stb & fifo.source.ack),
+                               cnt.eq(cnt+1), 
+                       )
+               ]
\ No newline at end of file
diff --git a/miscope/std/__init__.py b/miscope/std/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/miscope/std/cif.py b/miscope/std/cif.py
new file mode 100644 (file)
index 0000000..5300908
--- /dev/null
@@ -0,0 +1,94 @@
+from operator import itemgetter
+import re
+
+from migen.fhdl.std import *
+from migen.bank.description import CSRStatus
+
+def get_macros(filename):
+       f = open(filename, "r")
+       r = {}
+       for line in f:
+               match = re.match("\w*#define\s+(\w+)\s+(.*)", line, re.IGNORECASE)
+               if match:
+                       r[match.group(1)] = match.group(2)
+       return r
+
+def _get_rw_functions(reg_name, reg_base, size, read_only):
+       r = ""
+       if size > 8:
+               raise NotImplementedError("Register too large")
+       elif size > 4:
+               ctype = "unsigned long long int"
+       elif size > 2:
+               ctype = "unsigned int"
+       elif size > 1:
+               ctype = "unsigned short int"
+       else:
+               ctype = "unsigned char"
+
+       r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
+       if size > 1:
+               r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
+               for byte in range(1, size):
+                       r += "\tr <<= 8;\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
+               r += "\treturn r;\n}\n"
+       else:
+               r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
+
+       if not read_only:
+               r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
+               for byte in range(size):
+                       shift = (size-byte-1)*8
+                       if shift:
+                               value_shifted = "value >> "+str(shift)
+                       else:
+                               value_shifted = "value"
+                       r += "\tMMPTR("+hex(reg_base+4*byte)+") = "+value_shifted+";\n"
+               r += "}\n"
+       return r
+
+def get_csr_header(csr_base, bank_array):
+       r = "#ifndef __HW_CSR_H\n#define __HW_CSR_H\n#include <hw/common.h>\n"
+       for name, csrs, mapaddr, rmap in bank_array.banks:
+               r += "\n/* "+name+" */\n"
+               reg_base = csr_base + 0x800*mapaddr
+               r += "#define "+name.upper()+"_BASE "+hex(reg_base)+"\n"
+               for csr in csrs:
+                       nr = (csr.size + 7)//8
+                       r += _get_rw_functions(name + "_" + csr.name, reg_base, nr, isinstance(csr, CSRStatus))
+                       reg_base += 4*nr
+       r += "\n#endif\n"
+       return r
+
+def _get_py_rw_functions(reg_name, reg_base, size):
+       r = ""
+       
+       r += "def "+reg_name+"_read(bus):\n"
+       r += "\tr = bus.read_csr("+hex(reg_base)+")\n"
+       for byte in range(1, size):
+               r += "\tr <<= 8\n\tr |= bus.read_csr("+hex(reg_base+4*byte)+")\n"
+       r += "\treturn r\n\n"
+
+       
+       r += "def "+reg_name+"_write(bus, value):\n"
+       for byte in range(size):
+               shift = (size-byte-1)*8
+               if shift:
+                       value_shifted = "value >> "+str(shift)
+               else:
+                       value_shifted = "value"
+               r += "\tbus.write_csr("+hex(reg_base+4*byte)+", ("+value_shifted+")&0xff)\n"
+       r += "\n"
+       return r
+
+def get_py_csr_header(csr_base, bank_array):
+       r = ""
+       for name, csrs, mapaddr, rmap in bank_array.banks:
+               r += "\n# "+name+"\n"
+               reg_base = csr_base + 0x800*mapaddr
+               r += name.upper()+"_BASE ="+hex(reg_base)+"\n"
+               for csr in csrs:
+                       nr = (csr.size + 7)//8
+                       r += _get_py_rw_functions(name + "_" + csr.name, reg_base, nr)
+                       reg_base += 4*nr
+       return r
\ No newline at end of file
diff --git a/miscope/std/conv.py b/miscope/std/conv.py
new file mode 100644 (file)
index 0000000..66b88db
--- /dev/null
@@ -0,0 +1,11 @@
+def dec2bin(d, nb=0):
+       if d=="x":
+               return "x"*nb
+       elif d==0:
+               b="0"
+       else:
+               b=""
+               while d!=0:
+                       b="01"[d&1]+b
+                       d=d>>1
+       return b.zfill(nb)
diff --git a/miscope/std/misc.py b/miscope/std/misc.py
new file mode 100644 (file)
index 0000000..359f8f5
--- /dev/null
@@ -0,0 +1,114 @@
+from migen.fhdl.std import *
+
+def ifthenelse(cond, r1, r2):
+       if cond != False and cond is not None:
+               return r1
+       else:
+               return r2
+
+class RisingEdge(Module):
+       def __init__(self, i=None, o=None):
+               self.i = ifthenelse(i, i, Signal())
+               self.o = ifthenelse(o, o, Signal())
+       ####
+               i_d = Signal()
+               self.sync += i_d.eq(self.i)
+               self.comb += self.o.eq(self.i & ~i_d)
+
+class FallingEdge(Module):
+       def __init__(self, i=None, o=None, domain="sys"):
+               self.i = ifthenelse(i, i, Signal())
+               self.o = ifthenelse(o, o, Signal())
+       ####
+               i_d = Signal()
+               self.sync += i_d.eq(self.i)
+               self.comb += self.o.eq(~self.i & i_d)
+
+class FreqGen(Module):
+       def __init__(self, clk_freq, freq, o=None):
+               cnt_max = int(clk_freq/freq/2)
+               width = bits_for(cnt_max)
+               
+               self.o = ifthenelse(o, o, Signal())
+       ####
+               cnt = Signal(width)
+               self.sync += [
+                       If(cnt >= cnt_max,
+                               cnt.eq(0),
+                               self.o.eq(~self.o)
+                       ).Else(
+                               cnt.eq(cnt+1)
+                               )
+                       ]
+
+RISING_EDGE  = 1
+FALLING_EDGE = 0
+
+class EventGen(Module):
+       def __init__(self, i=None, level=1, clk_freq=0, length=1, o=None):
+               
+               cnt_max = int(length*clk_freq)
+               width = bits_for(cnt_max)
+               
+               self.i = ifthenelse(i, i, Signal())
+               self.o = ifthenelse(o, o, Signal())
+       ###
+               cnt = Signal(width)
+               i_edge = Signal()
+               
+               if level == RISING_EDGE:
+                       self.submodules += RisingEdge(self.i, i_edge)
+               elif level == FALLING_EDGE:
+                       self.submodules += FallingEdge(self.i, i_edge)
+               
+               self.sync += [
+                       If(i_edge == 1,
+                               cnt.eq(0),
+                               self.o.eq(1)
+                       ).Elif(cnt >= cnt_max,
+                               self.o.eq(0)
+                       ).Else(
+                               cnt.eq(cnt+1)
+                       ),
+                       ]
+               
+class PwmGen(Module):
+       def __init__(self, width, o=None):
+               self.ratio = Signal(width)
+               self.o     = ifthenelse(o, o, Signal())
+       ###
+               cnt = Signal(width)
+               self.sync += [
+                       If(cnt == 0,
+                               self.o.eq(1)
+                       ).Elif(cnt >= self.ratio,
+                               self.o.eq(0)
+                       ),
+                       cnt.eq(cnt+1)
+                       ]
+               
+class Cascade(Module):
+       def __init__(self, i=None, elements=None, o=None):
+               self.i = ifthenelse(i, i, Signal())
+               self.o = ifthenelse(o, o, Signal())
+               self.comb +=[elements[0].i.eq(self.i)]
+               self.comb +=[elements[i+1].i.eq(elements[i].o) for i in range(len(elements)-1)]
+               self.comb +=[self.o.eq(elements[len(elements)-1].o)]
+
+class PwrOnRst(Module):
+       def __init__(self, width, rst=None, simulation=False):
+               self.rst = ifthenelse(rst, rst, Signal())
+       ###
+               cnt = Signal(width)
+               sync_no_reset = [If(self.rst, cnt.eq(cnt+1))]
+               if not simulation:
+                       self.comb +=[
+                               If(cnt >= (2**width-1),
+                                       self.rst.eq(0)
+                               ).Else(
+                                       self.rst.eq(1)
+                               )
+                       ]
+               else:
+                       self.comb += self.rst.eq(0)
+               self._fragment += Fragment(sync={"sys_no_reset" : sync_no_reset})
\ No newline at end of file
diff --git a/miscope/std/truthtable.py b/miscope/std/truthtable.py
new file mode 100644 (file)
index 0000000..14ce796
--- /dev/null
@@ -0,0 +1,47 @@
+import os
+import re 
+import sys
+
+def is_number(x):
+    try:
+        _ = float(x)
+    except ValueError:
+        return False
+    return True
+
+def remove_numbers(seq):
+       return [ x for x in seq if not is_number(x)]
+
+def remove_duplicates(seq):
+       seen = set()
+       seen_add = seen.add
+       return [ x for x in seq if x not in seen and not seen_add(x)]
+
+def get_operands(s):
+       operands = re.findall("[A-z0-9_]+", s)
+       operands = remove_duplicates(operands)
+       operands = remove_numbers(operands)
+       return sorted(operands)
+
+def gen_truth_table(s):
+       operands = get_operands(s)
+       width = len(operands)
+       stim = []
+       for i in range(width):
+               stim_op = []
+               for j in range(2**width):
+                       stim_op.append((int(j/(2**i)))%2)
+               stim.append(stim_op)
+       
+       truth_table = []
+       for i in range(2**width):
+               for j in range(width):
+                       exec("%s = stim[j][i]" %operands[j])
+               truth_table.append(eval(s) != 0)
+       return truth_table
+
+def main():
+       print(gen_truth_table("(A&B&C)|D"))
+       
+if __name__ == '__main__':
+       main()
diff --git a/miscope/std/vcd.py b/miscope/std/vcd.py
new file mode 100644 (file)
index 0000000..481a123
--- /dev/null
@@ -0,0 +1,234 @@
+import sys
+import datetime
+
+from miscope.tools.conv import *
+
+def get_bits(values, width, low, high=None):
+       r = []
+       for val in values:
+               t = dec2bin(val, width)[::-1]
+               if high == None:
+                       t = t[low]
+               else:
+                       t = t[low:high]
+               t = t[::1]
+               t = int(t,2)
+               r.append(t)
+       return r
+
+class VcdDat(list):
+       def __init__(self, width):
+               self.width = width
+
+       def __getitem__(self, key):
+               if isinstance(key, int):
+                       return get_bits(self, self.width, key)
+               elif isinstance(key, slice):
+                       if key.start != None:
+                               start = key.start
+                       else:
+                               start = 0
+                       if key.stop != None:
+                               stop = key.stop
+                       else:
+                               stop = self.width
+                       if stop > self.width:
+                               stop = self.width
+                       if key.step != None:
+                               raise KeyError
+                       return get_bits(self, self.width, start, stop)
+               else:
+                       raise KeyError
+
+       def decode_rle(self):
+               rle_bit = self[-1]
+               rle_dat = self[:self.width-1]
+
+               dat = VcdDat(self.width)
+               i=0
+               last = 0
+               for d in self:
+                       if rle_bit[i]:
+                               if len(dat) >= 1:
+                                       # FIX ME... why is rle_dat in reverse orderd...
+                                       for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
+                                               dat.append(last)
+                       else:
+                               dat.append(d)
+                               last = d
+                       i +=1
+               return dat 
+
+class Var:
+       def __init__(self, name, width, values=[], type="wire", default="x"):
+               self.type = type
+               self.width = width
+               self.name = name
+               self.val = default
+               self.values = values
+               self.vcd_id = None
+               
+       def set_vcd_id(self, s):
+               self.vcd_id = s
+       
+       def __len__(self):
+               return len(self.values)
+
+       def change(self, cnt):
+               r = ""
+               try : 
+                       if self.values[cnt+1] != self.val:
+                               r += "b"
+                               r += dec2bin(self.values[cnt+1], self.width)[::-1]
+                               r += " "
+                               r += self.vcd_id
+                               r += "\n"
+                               return r
+               except :
+                       return r
+               return r
+
+class Vcd:
+       def __init__(self, timescale="1ps", comment=""):
+               self.timescale = timescale
+               self.comment = comment
+               self.vars = []
+               self.vcd_id = "!"
+               self.cnt = -1
+               
+       def add(self, var):
+               var.set_vcd_id(self.vcd_id)
+               self.vcd_id = chr(ord(self.vcd_id)+1)
+               self.vars.append(var)
+
+       def add_from_layout(self, layout, var):
+               i=0
+               for s, n in layout:
+                       self.add(Var(s, n, var[i:i+n]))
+                       i += n
+       
+       def __len__(self):
+               l = 0
+               for var in self.vars:
+                       l = max(len(var),l)
+               return l
+       
+       def change(self):
+               r = ""
+               c = ""
+               for var in self.vars:
+                       c += var.change(self.cnt)
+               if c != "":
+                       r += "#"
+                       r += str(self.cnt+1)
+                       r += "\n"
+                       r += c
+               return r
+
+       def p_date(self):
+               now = datetime.datetime.now()
+               r = "$date\n"
+               r += "\t"
+               r += now.strftime("%Y-%m-%d %H:%M")
+               r += "\n"
+               r += "$end\n"
+               return r
+               
+       def p_version(self):
+               r  = "$version\n"
+               r += "\tmiscope VCD dump\n"
+               r += "$end\n"
+               return r
+               
+       def p_comment(self):
+               r  = "$comment\n"
+               r += self.comment
+               r += "\n$end\n"
+               return r
+               
+       def p_timescale(self):
+               r  = "$timescale "
+               r += self.timescale
+               r += " $end\n"
+               return r
+               
+       def p_scope(self):
+               r  = "$scope "
+               r += self.timescale
+               r += " $end\n"
+               return r
+
+       def  p_vars(self):
+               r = ""
+               for var in self.vars:
+                       r += "$var "
+                       r += var.type
+                       r += " "
+                       r += str(var.width)
+                       r += " "
+                       r += var.vcd_id
+                       r += " "
+                       r += var.name
+                       r += " $end\n"
+               return r
+               
+       def p_unscope(self):
+               r  = "$unscope "
+               r += " $end\n"
+               return r
+       
+       def p_enddefinitions(self):
+               r  = "$enddefinitions "
+               r += " $end\n"
+               return r
+       
+       def p_dumpvars(self):
+               r  = "$dumpvars\n"
+               for var in self.vars:
+                       r += "b"
+                       r += dec2bin(var.val, var.width)
+                       r += " "
+                       r += var.vcd_id
+                       r+= "\n"
+               r += "$end\n"
+               return r
+               
+       def p_valuechange(self):
+               r = ""
+               for i in range(len(self)):
+                       r += self.change()
+                       self.cnt += 1
+               return r
+
+       def __repr__(self):
+               r = ""
+               r += self.p_date()
+               r += self.p_version()
+               r += self.p_comment()
+               r += self.p_timescale()
+               r += self.p_scope()
+               r += self.p_vars()
+               r += self.p_unscope()
+               r += self.p_enddefinitions()
+               r += self.p_dumpvars()
+               r += self.p_valuechange()
+               return r
+               
+       def write(self, filename):
+               f = open(filename, "w")
+               f.write(str(self))
+               f.close()
+
+def main():
+       myvcd = Vcd()
+       myvcd.add(Var(1, "foo1", [0,1,0,1,0,1]))
+       myvcd.add(Var(2, "foo2", [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
+       myvcd.add(Var(3, "foo3"))
+       myvcd.add(Var(4, "foo4"))
+       ramp = [i%128 for i in range(1024)]
+       myvcd.add(Var(16, "ramp", ramp))
+       print(myvcd)
+       
+if __name__ == '__main__':
+  main()
+
diff --git a/miscope/tools/__init__.py b/miscope/tools/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/miscope/tools/conv.py b/miscope/tools/conv.py
deleted file mode 100644 (file)
index 66b88db..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-def dec2bin(d, nb=0):
-       if d=="x":
-               return "x"*nb
-       elif d==0:
-               b="0"
-       else:
-               b=""
-               while d!=0:
-                       b="01"[d&1]+b
-                       d=d>>1
-       return b.zfill(nb)
diff --git a/miscope/tools/misc.py b/miscope/tools/misc.py
deleted file mode 100644 (file)
index 5e780a7..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-class RisingEdge(Module):
-       def __init__(self, i=None, o=None, domain="sys"):
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-       ####
-               i_d = Signal()
-               sync =[i_d.eq(self.i)]
-               self.comb +=[self.o.eq(self.i & ~i_d)]
-               self._fragment += Fragment(sync={domain : sync})
-
-class FallingEdge(Module):
-       def __init__(self, i=None, o=None, domain="sys"):
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-       ####
-               i_d = Signal()
-               sync =[i_d.eq(self.i)]
-               self.comb +=[self.o.eq(~self.i & i_d)]
-               self._fragment += Fragment(sync={domain : sync})
-
-class FreqGen(Module):
-       def __init__(self, clk_freq, freq, o=None):
-               cnt_max = int(clk_freq/freq/2)
-               width = bits_for(cnt_max)
-               
-               self.o = ifthenelse(o, o, Signal())
-       ####
-               cnt = Signal(width)
-               self.sync += [
-                       If(cnt >= cnt_max,
-                               cnt.eq(0),
-                               self.o.eq(~self.o)
-                       ).Else(
-                               cnt.eq(cnt+1)
-                               )
-                       ]
-
-RISING_EDGE  = 1
-FALLING_EDGE = 0
-
-class EventGen(Module):
-       def __init__(self, i=None, level=1, clk_freq=0, length=1, o=None):
-               
-               cnt_max = int(length*clk_freq)
-               width = bits_for(cnt_max)
-               
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-       ###
-               cnt = Signal(width)
-               i_edge = Signal()
-               
-               if level == RISING_EDGE:
-                       self.submodules += RisingEdge(self.i, i_edge)
-               elif level == FALLING_EDGE:
-                       self.submodules += FallingEdge(self.i, i_edge)
-               
-               self.sync += [
-                       If(i_edge == 1,
-                               cnt.eq(0),
-                               self.o.eq(1)
-                       ).Elif(cnt >= cnt_max,
-                               self.o.eq(0)
-                       ).Else(
-                               cnt.eq(cnt+1)
-                       ),
-                       ]
-               
-class PwmGen(Module):
-       def __init__(self, width, o=None):
-               self.ratio = Signal(width)
-               self.o     = ifthenelse(o, o, Signal())
-       ###
-               cnt = Signal(width)
-               self.sync += [
-                       If(cnt == 0,
-                               self.o.eq(1)
-                       ).Elif(cnt >= self.ratio,
-                               self.o.eq(0)
-                       ),
-                       cnt.eq(cnt+1)
-                       ]
-               
-class Cascade(Module):
-       def __init__(self, i=None, elements=None, o=None):
-               self.i = ifthenelse(i, i, Signal())
-               self.o = ifthenelse(o, o, Signal())
-               self.comb +=[elements[0].i.eq(self.i)]
-               self.comb +=[elements[i+1].i.eq(elements[i].o) for i in range(len(elements)-1)]
-               self.comb +=[self.o.eq(elements[len(elements)-1].o)]
-
-class PwrOnRst(Module):
-       def __init__(self, width, rst=None, simulation=False):
-               self.rst = ifthenelse(rst, rst, Signal())
-       ###
-               cnt = Signal(width)
-               sync_no_reset = [If(self.rst, cnt.eq(cnt+1))]
-               if not simulation:
-                       self.comb +=[
-                               If(cnt >= (2**width-1),
-                                       self.rst.eq(0)
-                               ).Else(
-                                       self.rst.eq(1)
-                               )
-                       ]
-               else:
-                       self.comb += self.rst.eq(0)
-               self._fragment += Fragment(sync={"sys_no_reset" : sync_no_reset})
-               
-def get_csr_base(bank, name=None):
-       base = 0
-       if name != None:
-               base = None
-               for i, c in enumerate(bank.simple_csrs):
-                       if name in c.name:
-                               if base == None:
-                                       base = i
-                               elif base >= i:
-                                       base = i
-       return (bank.address<<9) + base
\ No newline at end of file
diff --git a/miscope/tools/truthtable.py b/miscope/tools/truthtable.py
deleted file mode 100644 (file)
index 14ce796..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-import os
-import re 
-import sys
-
-def is_number(x):
-    try:
-        _ = float(x)
-    except ValueError:
-        return False
-    return True
-
-def remove_numbers(seq):
-       return [ x for x in seq if not is_number(x)]
-
-def remove_duplicates(seq):
-       seen = set()
-       seen_add = seen.add
-       return [ x for x in seq if x not in seen and not seen_add(x)]
-
-def get_operands(s):
-       operands = re.findall("[A-z0-9_]+", s)
-       operands = remove_duplicates(operands)
-       operands = remove_numbers(operands)
-       return sorted(operands)
-
-def gen_truth_table(s):
-       operands = get_operands(s)
-       width = len(operands)
-       stim = []
-       for i in range(width):
-               stim_op = []
-               for j in range(2**width):
-                       stim_op.append((int(j/(2**i)))%2)
-               stim.append(stim_op)
-       
-       truth_table = []
-       for i in range(2**width):
-               for j in range(width):
-                       exec("%s = stim[j][i]" %operands[j])
-               truth_table.append(eval(s) != 0)
-       return truth_table
-
-def main():
-       print(gen_truth_table("(A&B&C)|D"))
-       
-if __name__ == '__main__':
-       main()
diff --git a/miscope/tools/vcd.py b/miscope/tools/vcd.py
deleted file mode 100644 (file)
index 481a123..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-import sys
-import datetime
-
-from miscope.tools.conv import *
-
-def get_bits(values, width, low, high=None):
-       r = []
-       for val in values:
-               t = dec2bin(val, width)[::-1]
-               if high == None:
-                       t = t[low]
-               else:
-                       t = t[low:high]
-               t = t[::1]
-               t = int(t,2)
-               r.append(t)
-       return r
-
-class VcdDat(list):
-       def __init__(self, width):
-               self.width = width
-
-       def __getitem__(self, key):
-               if isinstance(key, int):
-                       return get_bits(self, self.width, key)
-               elif isinstance(key, slice):
-                       if key.start != None:
-                               start = key.start
-                       else:
-                               start = 0
-                       if key.stop != None:
-                               stop = key.stop
-                       else:
-                               stop = self.width
-                       if stop > self.width:
-                               stop = self.width
-                       if key.step != None:
-                               raise KeyError
-                       return get_bits(self, self.width, start, stop)
-               else:
-                       raise KeyError
-
-       def decode_rle(self):
-               rle_bit = self[-1]
-               rle_dat = self[:self.width-1]
-
-               dat = VcdDat(self.width)
-               i=0
-               last = 0
-               for d in self:
-                       if rle_bit[i]:
-                               if len(dat) >= 1:
-                                       # FIX ME... why is rle_dat in reverse orderd...
-                                       for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
-                                               dat.append(last)
-                       else:
-                               dat.append(d)
-                               last = d
-                       i +=1
-               return dat 
-
-class Var:
-       def __init__(self, name, width, values=[], type="wire", default="x"):
-               self.type = type
-               self.width = width
-               self.name = name
-               self.val = default
-               self.values = values
-               self.vcd_id = None
-               
-       def set_vcd_id(self, s):
-               self.vcd_id = s
-       
-       def __len__(self):
-               return len(self.values)
-
-       def change(self, cnt):
-               r = ""
-               try : 
-                       if self.values[cnt+1] != self.val:
-                               r += "b"
-                               r += dec2bin(self.values[cnt+1], self.width)[::-1]
-                               r += " "
-                               r += self.vcd_id
-                               r += "\n"
-                               return r
-               except :
-                       return r
-               return r
-
-class Vcd:
-       def __init__(self, timescale="1ps", comment=""):
-               self.timescale = timescale
-               self.comment = comment
-               self.vars = []
-               self.vcd_id = "!"
-               self.cnt = -1
-               
-       def add(self, var):
-               var.set_vcd_id(self.vcd_id)
-               self.vcd_id = chr(ord(self.vcd_id)+1)
-               self.vars.append(var)
-
-       def add_from_layout(self, layout, var):
-               i=0
-               for s, n in layout:
-                       self.add(Var(s, n, var[i:i+n]))
-                       i += n
-       
-       def __len__(self):
-               l = 0
-               for var in self.vars:
-                       l = max(len(var),l)
-               return l
-       
-       def change(self):
-               r = ""
-               c = ""
-               for var in self.vars:
-                       c += var.change(self.cnt)
-               if c != "":
-                       r += "#"
-                       r += str(self.cnt+1)
-                       r += "\n"
-                       r += c
-               return r
-
-       def p_date(self):
-               now = datetime.datetime.now()
-               r = "$date\n"
-               r += "\t"
-               r += now.strftime("%Y-%m-%d %H:%M")
-               r += "\n"
-               r += "$end\n"
-               return r
-               
-       def p_version(self):
-               r  = "$version\n"
-               r += "\tmiscope VCD dump\n"
-               r += "$end\n"
-               return r
-               
-       def p_comment(self):
-               r  = "$comment\n"
-               r += self.comment
-               r += "\n$end\n"
-               return r
-               
-       def p_timescale(self):
-               r  = "$timescale "
-               r += self.timescale
-               r += " $end\n"
-               return r
-               
-       def p_scope(self):
-               r  = "$scope "
-               r += self.timescale
-               r += " $end\n"
-               return r
-
-       def  p_vars(self):
-               r = ""
-               for var in self.vars:
-                       r += "$var "
-                       r += var.type
-                       r += " "
-                       r += str(var.width)
-                       r += " "
-                       r += var.vcd_id
-                       r += " "
-                       r += var.name
-                       r += " $end\n"
-               return r
-               
-       def p_unscope(self):
-               r  = "$unscope "
-               r += " $end\n"
-               return r
-       
-       def p_enddefinitions(self):
-               r  = "$enddefinitions "
-               r += " $end\n"
-               return r
-       
-       def p_dumpvars(self):
-               r  = "$dumpvars\n"
-               for var in self.vars:
-                       r += "b"
-                       r += dec2bin(var.val, var.width)
-                       r += " "
-                       r += var.vcd_id
-                       r+= "\n"
-               r += "$end\n"
-               return r
-               
-       def p_valuechange(self):
-               r = ""
-               for i in range(len(self)):
-                       r += self.change()
-                       self.cnt += 1
-               return r
-
-       def __repr__(self):
-               r = ""
-               r += self.p_date()
-               r += self.p_version()
-               r += self.p_comment()
-               r += self.p_timescale()
-               r += self.p_scope()
-               r += self.p_vars()
-               r += self.p_unscope()
-               r += self.p_enddefinitions()
-               r += self.p_dumpvars()
-               r += self.p_valuechange()
-               return r
-               
-       def write(self, filename):
-               f = open(filename, "w")
-               f.write(str(self))
-               f.close()
-
-def main():
-       myvcd = Vcd()
-       myvcd.add(Var(1, "foo1", [0,1,0,1,0,1]))
-       myvcd.add(Var(2, "foo2", [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
-       myvcd.add(Var(3, "foo3"))
-       myvcd.add(Var(4, "foo4"))
-       ramp = [i%128 for i in range(1024)]
-       myvcd.add(Var(16, "ramp", ramp))
-       print(myvcd)
-       
-if __name__ == '__main__':
-  main()
-
diff --git a/miscope/trigger.py b/miscope/trigger.py
deleted file mode 100644 (file)
index 61a9a8d..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Memory
-from migen.bus import csr
-from migen.bank import description, csrgen
-from migen.bank.description import *
-from migen.genlib.misc import optree
-
-from miscope.tools.misc import *
-
-class RegParams:
-       def __init__(self, name, base, width, nb):
-               self.name = name
-               self.base = base
-               self.width = width
-               self.nb = nb
-               
-               self.size = nb*width
-               self.words = int(2**bits_for(self.width-1)/8)
-
-def list_regs(objects):
-               r = []
-               for object in objects:
-                       if "_reg" in object:
-                               r.append(objects[object])
-               return r
-
-class Term:
-       #
-       # Definition
-       #
-       def __init__(self, width):
-               self.width = width
-               self.interface = None
-               
-               self.i = Signal(width)
-               self.t = Signal(width)
-               self.m = Signal(width)
-               self.o = Signal()
-               
-               self.reg_p = RegParams("term_reg", 0, width, 2)
-               self.reg = None
-       
-       def get_registers_comb(self):
-               comb = [self.t.eq(self.reg.storage[0*self.width:1*self.width])]
-               comb += [self.m.eq(self.reg.storage[1*self.width:2*self.width])]
-               return comb
-       
-       def get_fragment(self):
-               comb = [self.o.eq((self.m & self.i) == self.t)]
-               comb += self.get_registers_comb()
-               return Fragment(comb)
-       
-       #
-       # Driver
-       #
-       def set(self, dat, mask=None):
-               if mask is None:
-                       mask = (2**self.width)-1
-               self.interface.write_n(self.reg_p.base, mask, self.width)       
-               self.interface.write_n(self.reg_p.base + self.reg_p.words, dat, self.width)
-               
-class RangeDetector:
-       # 
-       # Definition
-       #
-       def __init__(self, width):
-               self.width = width
-               self.pipe = pipe
-               self.interface = None
-               
-               self.reg_p = RegParams("range_reg", 0, width, 2)
-               self.reg = None
-               
-               self.i = Signal(width)
-               self.low = Signal(width)
-               self.high = Signal(width)
-               self.o = Signal()
-               
-       def get_registers_comb(self):
-               comb = [self.low.eq(self.reg.storage[0*self.width:1*self.width])]
-               comb += [self.low.eq(self.reg.storage[1*self.width:2*self.width])]
-               return comb
-               
-       def get_fragment(self):
-               comb = [self.o.eq((self.i >= self.low) & (self.i <= self.high))]
-               comb += self.get_registers_comb()
-               return Fragment(comb)
-       #
-       # Driver
-       #
-       def set_low(self, dat):
-               self.interface.write_n(self.reg_p.base, dat ,self.width)
-       
-       def set_high(self, dat):
-               self.interface.write_n(self.reg_p.base + self.reg_p.words, dat ,self.width)
-
-class EdgeDetector:
-       # 
-       # Definition
-       #
-       def __init__(self, width, mode="RFB"):
-               self.width = width
-               self.mode = mode
-               self.interface = None
-               
-               self.reg_p = RegParams("edge_reg", 0, width, len(self.mode))
-               self.reg = None
-               
-               self.i = Signal(self.width)
-               self.i_d = Signal(self.width)
-               if "R" in self.mode:
-                       self.r_mask = Signal(self.width)
-                       self.ro = Signal()
-               if "F" in self.mode:
-                       self.f_mask = Signal(self.width)
-                       self.fo = Signal()
-               if "B" in self.mode:
-                       self.b_mask = Signal(self.width)
-                       self.bo = Signal()
-               self.o = Signal()
-       
-       def get_registers_comb(self):
-               comb = []
-               i = 0
-               if "R" in self.mode:
-                       comb += [self.r_mask.eq(self.reg.storage[i*self.width:(i+1)*self.width])]
-                       i += 1
-               if "F" in self.mode:
-                       comb += [self.f_mask.eq(self.reg.storage[i*self.width:(i+1)*self.width])]
-                       i += 1
-               if "B" in self.mode:
-                       comb += [self.b_mask.eq(self.reg.storage[i*self.width:(i+1)*self.width])]
-                       i += 1
-               return comb
-       
-       def get_fragment(self):
-               comb = []
-               sync = [self.i_d.eq(self.i)]
-               
-               # Rising Edge
-               if "R" in self.mode:
-                       comb += [self.ro.eq(self.r_mask & self.i & (~self.i_d))]
-               else:
-                       comb += [self.ro.eq(0)]
-                       
-               # Falling Edge
-               if "F" in self.mode:
-                       comb += [self.fo.eq(self.f_mask & (~self.i) & self.i_d)]
-               else:
-                       comb += [self.fo.eq(0)]
-                       
-               # Both
-               if "B" in self.mode:
-                       comb += [self.bo.eq((self.b_mask & self.i) != self.i_d)]
-               else:
-                       comb += [self.bo.eq(0)]
-                       
-               # Output
-               comb += [self.o.eq(self.ro | self.fo | self.bo)]
-               
-               # Registers
-               comb += self.get_registers_comb()
-               
-               return Fragment(comb, sync)
-               
-       #
-       # Driver
-       #
-       def get_offset(self, type):
-               if type == "R":
-                       r = 0
-                       r = r + self.words if "F" in self.mode else r
-                       r = r + self.words if "B" in self.mode else r
-                       return r
-               elif type == "F":
-                       r = 0
-                       r = r + self.words if "B" in self.mode else r
-                       return r
-               elif type == "B":
-                       r = 0
-                       return r
-               return 0
-                       
-       def set_r(self, dat):
-               self.interface.write_n(self.reg_p.base + self.get_offset("R"), dat ,self.width)
-       
-       def set_f(self, dat):
-               self.interface.write_n(self.reg_p.base + self.get_offset("F"), dat ,self.width)
-               
-       def set_b(self, dat):
-               self.interface.write_n(self.reg_p.base + self.get_offset("B"), dat ,self.width)
-
-class Sum:
-       #
-       # Definition
-       #
-       def __init__(self, width=4):
-               self.width = width
-               self.interface = None
-               
-               self.i = Signal(self.width)
-               self.o = Signal()
-               
-               self.reg_p = RegParams("sum_reg", 0, 8, 4)
-               self.reg = None
-               
-               self.prog_stb = Signal()
-               self.prog_adr = Signal(width)
-               self.prog_dat = Signal()
-               
-               self._mem = Memory(1, 2**self.width)
-               self._lut_port = self._mem.get_port()
-               self._prog_port = self._mem.get_port(write_capable=True)
-       
-       def get_registers_comb(self):
-               comb = [
-                       self.prog_adr.eq(self.reg.storage[0:16]),
-                       self.prog_dat.eq(self.reg.storage[16]),
-                       self.prog_stb.eq(self.reg.storage[17])
-                       ]
-               return comb
-       
-       def get_fragment(self):
-               comb = [
-                               self._lut_port.adr.eq(self.i),
-                               
-                               self._prog_port.adr.eq(self.prog_adr),
-                               self._prog_port.we.eq(self.prog_stb),
-                               self._prog_port.dat_w.eq(self.prog_dat),
-
-                               self.o.eq(self._lut_port.dat_r),
-               ]
-               comb += self.get_registers_comb()
-               return Fragment(comb, specials={self._mem})
-       
-       #
-       # Driver
-       #
-       def set(self, truth_table):
-               for i in range(len(truth_table)):
-                       val = truth_table[i]
-                       we = 1<<17
-                       dat = val<<16
-                       addr = i
-                       self.interface.write_n(self.reg_p.base, we + dat + addr, self.reg_p.size)
-                       self.interface.write_n(self.reg_p.base, dat + addr, self.reg_p.size)
-               
-class Trigger:
-       # 
-       # Definition
-       #
-       def __init__(self, width, ports, address=0x0000, interface=None):
-               self.width = width
-               self.ports = ports
-               
-               self.sum = Sum(len(ports))
-               self.trig = Signal(self.width)
-               self.hit = Signal()
-               
-               # insert port number in port reg name
-               for i in range(len(self.ports)):
-                       self.ports[i].reg_p.name += "_%d"%i
-               
-               # generate ports csr registers fields
-               for port in self.ports:
-                       rf = CSRStorage(port.reg_p.size, reset=0, name=port.reg_p.name)
-                       setattr(self, port.reg_p.name, rf)
-               
-               # generate sum csr registers fields
-               self.sum_reg = CSRStorage(self.sum.reg_p.size, reset=0, name=self.sum.reg_p.name)
-
-               # generate registers
-               self.regs = list_regs(self.__dict__)
-               self.bank = csrgen.Bank(self.regs, address=address)
-               
-               # update base addr & interface
-               self.set_address(address)
-               self.set_interface(interface)
-               self.set_registers()
-               
-       def set_address(self, address):
-               self.address = address
-               self.bank = csrgen.Bank(self.regs, address=self.address)
-               for port in self.ports:
-                       port.reg_p.base = get_csr_base(self.bank, port.reg_p.name)
-               self.sum.reg_p.base = get_csr_base(self.bank, self.sum.reg_p.name)
-
-       def set_interface(self, interface):
-               self.interface = interface
-               for port in self.ports:
-                       port.interface = self.interface
-               self.sum.interface = self.interface
-       
-       def set_registers(self):
-               self.sum.reg=self.sum_reg
-               for port in self.ports:
-                       port.reg=getattr(self, port.reg_p.name)
-               
-       def get_fragment(self):
-               # connect trig to input of each trig element
-               comb = [port.i.eq(self.trig) for port in self.ports]
-               
-               # connect output of trig elements to sum
-               comb += [self.sum.i[j].eq(self.ports[j].o) for j in range(len(self.ports))]
-               
-               # connect sum ouput to hit
-               comb += [self.hit.eq(self.sum.o)]
-               
-               # add ports & sum to frag
-               frag = self.bank.get_fragment()
-               frag += self.sum.get_fragment()
-               for port in self.ports:
-                       frag += port.get_fragment()
-                       
-               return frag + Fragment(comb)
diff --git a/miscope/triggering/__init__.py b/miscope/triggering/__init__.py
new file mode 100644 (file)
index 0000000..3a328ae
--- /dev/null
@@ -0,0 +1,95 @@
+from migen.fhdl.std import *
+from migen.flow.actor import *
+from migen.flow.network import *
+from migen.fhdl.specials import Memory
+from migen.bus import csr
+from migen.bank import description, csrgen
+from migen.bank.description import *
+
+class Term(Module, AutoCSR):
+       def __init__(self, width):
+               self.width = width
+
+               self.sink = Sink([("d", width)])
+               self.source = Source([("hit", 1)])
+
+               self.busy = Signal()
+
+               self._r_trig = CSRStorage(width)
+               self._r_mask = CSRStorage(width)
+
+               ###
+
+               trig = self._r_trig.storage
+               mask = self._r_mask.storage
+
+               hit = Signal()
+
+               self.comb +=[
+                       hit.eq((self.sink.payload.d & mask) == trig),
+                       self.source.stb.eq(self.sink.stb),
+                       self.sink.ack.eq(self.sink.ack),
+                       self.source.payload.hit.eq(hit)
+               ]
+
+class Sum(Module, AutoCSR):
+       def __init__(self, ports=4):
+               
+               self.sinks = [Sink([("hit", 1)]) for p in range(ports)]
+               self.source = Source([("hit", 1)])
+               
+               self._r_prog_we = CSRStorage()
+               self._r_prog_adr = CSRStorage(ports) #FIXME
+               self._r_prog_dat = CSRStorage()
+
+               mem = Memory(1, 2**ports)
+               lut_port = mem.get_port()
+               prog_port = mem.get_port(write_capable=True)
+
+               self.specials += mem, lut_port, prog_port
+
+               ###
+
+               # Lut prog
+               self.comb +=[
+                       prog_port.we.eq(self._r_prog_we.storage),
+                       prog_port.adr.eq(self._r_prog_adr.storage),
+                       prog_port.dat_w.eq(self._r_prog_dat.storage)
+               ]
+
+               # Lut read
+               for i, sink in enumerate(self.sinks):
+                       self.comb += lut_port.adr[i].eq(sink.payload.hit)
+
+               # Drive source
+               self.comb +=[
+                       self.source.stb.eq(optree("&", [sink.stb for sink in self.sinks])),
+                       self.source.payload.hit.eq(lut_port.dat_r),
+                       [sink.ack.eq(self.source.ack) for sink in self.sinks]
+               ]
+
+
+class Trigger(Module, AutoCSR):
+       def __init__(self, width, ports):
+               self.width = width
+               self.ports = ports
+               
+               self.submodules.sum = Sum(len(ports))
+
+               # FIXME : when self.submodules +=  is used, 
+               # get_csrs() is not called
+               for i, port in enumerate(ports):
+                       tmp = "self.submodules.port"+str(i)+" = port"
+                       exec(tmp)
+
+               self.sink   = Sink([("d", width)])
+               self.source = self.sum.source
+               self.busy = Signal()
+
+               ###
+               for i, port in enumerate(ports):
+                       self.comb +=[
+                               port.sink.stb.eq(self.sink.stb),
+                               port.sink.payload.d.eq(self.sink.payload.d),
+                               port.source.connect(self.sum.sinks[i])
+                       ]
\ No newline at end of file
diff --git a/sim/tb_RecorderCsr.py b/sim/tb_RecorderCsr.py
deleted file mode 100644 (file)
index 9aaf3d0..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl import verilog
-from migen.bus import csr
-from migen.sim.generic import Simulator, PureSimulable, TopLevel
-from migen.sim.icarus import Runner
-from migen.bus.transactions import *
-
-from miscope.recorder import *
-
-arm_done = False
-dat = 0
-
-rec_done = False
-
-dat_rdy = False
-
-rec_size = 128
-
-def csr_transactions():
-
-       # Reset
-       yield TWrite(REC_RST_BASE, 1)
-       yield TWrite(REC_RST_BASE, 0)
-
-       # RLE
-       yield TWrite(REC_RLE_BASE, 1)
-       
-       # Size
-       yield TWrite(REC_SIZE_BASE + 0, 0)
-       yield TWrite(REC_SIZE_BASE + 1, rec_size)
-       
-       # Offset
-       yield TWrite(REC_OFFSET_BASE + 0, 0)
-       yield TWrite(REC_OFFSET_BASE + 1, 0)
-       
-       # Arm
-       yield TWrite(REC_ARM_BASE, 1)
-       yield TWrite(REC_ARM_BASE, 0)
-       
-       for t in range(10):
-               yield None
-               
-       global arm_done
-       arm_done = True
-       
-       global rec_done
-       while not rec_done:
-               yield None
-
-       global dat_rdy
-       for t in range(rec_size):
-               yield TWrite(REC_READ_BASE, 1)
-               dat_rdy = False
-               yield TWrite(REC_READ_BASE, 0)
-               yield TRead(REC_READ_DATA_BASE + 0)
-               yield TRead(REC_READ_DATA_BASE + 1)
-               yield TRead(REC_READ_DATA_BASE + 2)
-               yield TRead(REC_READ_DATA_BASE + 3)
-               dat_rdy = True
-
-       dat_rdy = False
-
-       for t in range(100):
-               yield None
-
-def main():
-       # Csr Master
-       csr_master0 = csr.Initiator(csr_transactions())
-
-       # Recorder
-       recorder0 = Recorder(32, 1024)
-       
-       # Csr Interconnect
-       csrcon0 = csr.Interconnect(csr_master0.bus,
-                       [
-                               recorder0.bank.bus
-                       ])
-
-       # Recorder Data
-       def recorder_data(s):
-               global arm_done
-               if arm_done:
-                       s.wr(recorder0.hit, 1)
-                       arm_done = False
-
-               global dat
-               s.wr(recorder0.dat, dat//5)
-               dat += 1
-                       
-               global rec_done
-               if s.rd(recorder0.sequencer.enable) == 0:
-                       rec_done = True
-               
-               if dat_rdy:
-                       print("%08X" %s.rd(recorder0._pull_dat.field.w))
-
-       # Simulation
-       def end_simulation(s):
-               s.interrupt = csr_master0.done
-
-       fragment = csr_master0.get_fragment()
-       fragment += recorder0.get_fragment()
-       fragment += csrcon0.get_fragment()
-       fragment += Fragment(sim=[end_simulation])
-       fragment += Fragment(sim=[recorder_data])
-       sim = Simulator(fragment, TopLevel("tb_RecorderCsr.vcd"))
-       sim.run(10000)
-
-main()
-print("Sim Done")
-input()
\ No newline at end of file
diff --git a/sim/tb_TriggerCsr.py b/sim/tb_TriggerCsr.py
deleted file mode 100644 (file)
index 9262872..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl import verilog
-from migen.bus import csr
-from migen.sim.generic import Simulator, PureSimulable, TopLevel
-from migen.sim.icarus import Runner
-from migen.bus.transactions import *
-
-from miscope import trigger
-from miscope.tools.truthtable import *
-
-def term_prog(off, dat):
-       for i in range(4):
-               yield TWrite(off+3-i, (dat>>(8*i))&0xFF)
-
-def sum_prog(off, addr, dat):
-       we = 2
-       yield TWrite(off+3, addr%0xFF)
-       yield TWrite(off+2, (addr>>8)%0xFF)
-       yield TWrite(off+1, we+dat)
-       yield TWrite(off+0, 0)
-       for i in range(4):
-               yield TWrite(off+i,0)
-
-
-csr_done = False
-
-def csr_transactions():
-
-       term_trans = []
-       term_trans += [term_prog(0x04+0  ,0xFFFFFFFF)]
-       term_trans += [term_prog(0x04+4  ,0xDEADBEEF)]
-       term_trans += [term_prog(0x04+8  ,0xFFFFFFFF)]
-       term_trans += [term_prog(0x04+12 ,0xCAFEFADE)]
-       term_trans += [term_prog(0x04+16 ,0xFFFFFFFF)]
-       term_trans += [term_prog(0x04+20 ,0xDEADBEEF)]
-       term_trans += [term_prog(0x04+24 ,0xFFFFFFFF)]
-       term_trans += [term_prog(0x04+28 ,0xCAFEFADE)]
-       for t in term_trans:
-               for r in t:
-                       yield r
-       
-       sum_trans = []
-       sum_trans += [sum_prog(0x00, i, 1) for i in range(8)]
-       sum_trans += [sum_prog(0x00, i, 0) for i in range(8)]
-       for t in sum_trans:
-               for r in t:
-                       yield r
-       
-       sum_tt = gen_truth_table("i1 & i2 & i3 & i4")
-       sum_trans = []
-       for i in range(len(sum_tt)):
-               sum_trans.append(sum_prog(0x00, i, sum_tt[i]))
-       print(sum_tt)
-       for t in sum_trans:
-               for r in t:
-                       yield r
-       
-       global csr_done
-       csr_done = True
-       
-       for t in range(100):
-               yield None
-
-
-def main():
-       # Csr Master
-       csr_master0 = csr.Initiator(csr_transactions())
-       
-       # Trigger
-       term0 = trigger.Term(32)
-       term1 = trigger.Term(32)
-       term2 = trigger.Term(32)
-       term3 = trigger.Term(32)
-       trigger0 = trigger.Trigger(32, [term0, term1, term2, term3])
-       
-       # Csr Interconnect
-       csrcon0 = csr.Interconnect(csr_master0.bus, 
-                       [
-                               trigger0.bank.bus
-                       ])
-       
-       # Term Test
-       def term_stimuli(s):
-               if csr_done:
-                       s.wr(term0.i, 0xDEADBEEF)
-                       s.wr(term1.i ,0xCAFEFADE)
-                       s.wr(term2.i, 0xDEADBEEF)
-                       s.wr(term3.i, 0xCAFEFADE)
-       
-       
-       # Simulation
-       def end_simulation(s):
-               s.interrupt = csr_master0.done
-       
-       fragment = csr_master0.get_fragment()
-       fragment += term0.get_fragment()
-       fragment += term1.get_fragment()
-       fragment += term2.get_fragment()
-       fragment += term3.get_fragment()
-       fragment += trigger0.get_fragment()
-       fragment += csrcon0.get_fragment()
-       fragment += Fragment(sim=[end_simulation])
-       fragment += Fragment(sim=[term_stimuli])
-       sim = Simulator(fragment, TopLevel("tb_TriggerCsr.vcd"))
-       sim.run(2000)
-
-main()
-print("Sim Done")
-input()
-
-
-
-
-
diff --git a/sim/tb_miscope.py b/sim/tb_miscope.py
deleted file mode 100644 (file)
index 5b2107d..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl import verilog
-from migen.bus import csr
-from migen.sim.generic import Simulator, PureSimulable, TopLevel
-from migen.sim.icarus import Runner
-from migen.bus.transactions import *
-
-from miscope.trigger import *
-from miscope.recorder import *
-from miscope.tools.truthtable import *
-from miscope.tools.vcd import *
-
-TRIGGER_ADDR  = 0x0000
-RECORDER_ADDR = 0x0200
-
-rec_done = False
-dat_rdy  = False
-
-dat_vcd = VcdDat(32)
-rec_size = 64
-
-def term_prog(off, dat):
-       for i in range(4):
-               yield TWrite(off+3-i, (dat>>(8*i))&0xFF)
-
-
-def sum_prog(off, addr, dat):
-       we = 2
-       yield TWrite(off+3, addr%0xFF)
-       yield TWrite(off+2, (addr>>8)%0xFF)
-       yield TWrite(off+1, we+dat)
-       yield TWrite(off+0, 0)
-       for i in range(4):
-               yield TWrite(off+i,0)
-
-def csr_transactions(trigger0, recorder0):
-
-       # Trigger Prog
-       ##############################
-
-       # Term Prog
-       term_trans = []
-       term_trans += [term_prog(trigger0.ports[0].reg_p.base+0, 0xFFFFFFFF)]
-       term_trans += [term_prog(trigger0.ports[0].reg_p.base+4, 0x00000000)]
-       term_trans += [term_prog(trigger0.ports[1].reg_p.base+0, 0xFFFFFFFF)]
-       term_trans += [term_prog(trigger0.ports[1].reg_p.base+4, 0x00000004)]
-       term_trans += [term_prog(trigger0.ports[2].reg_p.base+0, 0xFFFFFFFF)]   
-       term_trans += [term_prog(trigger0.ports[2].reg_p.base+4, 0x00000008)]
-       term_trans += [term_prog(trigger0.ports[3].reg_p.base+0, 0xFFFFFFFF)]   
-       term_trans += [term_prog(trigger0.ports[3].reg_p.base+4, 0x0000000C)]
-       for t in term_trans:
-               for r in t:
-                       yield r
-       
-       # Sum Prog
-       sum_tt = gen_truth_table("term0 | term1 | term2 | term3")
-       sum_trans = []
-       for i in range(len(sum_tt)):
-               sum_trans.append(sum_prog(trigger0.sum.reg_p.base, i, sum_tt[i]))
-       for t in sum_trans:
-               for r in t:
-                       yield r
-       
-       # Recorder Prog
-       ##############################
-       #Reset
-       yield TWrite(recorder0.address + REC_RST_BASE,  1)
-       yield TWrite(recorder0.address + REC_RST_BASE,  0)
-
-       # RLE
-       yield TWrite(REC_RLE_BASE, 0)
-       
-       #Size
-       yield TWrite(recorder0.address + REC_SIZE_BASE + 0,  0)
-       yield TWrite(recorder0.address + REC_OFFSET_BASE + 1, rec_size)
-       
-       #Offset
-       yield TWrite(recorder0.address + REC_OFFSET_BASE + 0,   0)
-       yield TWrite(recorder0.address + REC_OFFSET_BASE + 1,  16)
-
-       #Arm
-       yield TWrite(recorder0.address + REC_ARM_BASE,  1)
-       yield TWrite(recorder0.address + REC_ARM_BASE,  0)
-
-       # Wait Record to be done
-       ##############################
-       global rec_done
-       while not rec_done:
-               yield None
-
-       # Read recorded data
-       ##############################
-       global dat_rdy  
-       for t in range(rec_size):
-               yield TWrite(recorder0.address + REC_READ_BASE, 1)
-               dat_rdy = False
-               yield TWrite(recorder0.address + REC_READ_BASE, 0)
-               yield TRead(recorder0.address + REC_READ_DATA_BASE + 0)
-               yield TRead(recorder0.address + REC_READ_DATA_BASE + 1)
-               yield TRead(recorder0.address + REC_READ_DATA_BASE + 2)
-               yield TRead(recorder0.address + REC_READ_DATA_BASE + 3)
-               dat_rdy = True
-
-       dat_rdy = False
-
-       for t in range(512):
-               yield None
-
-
-trig_sig_val = 0
-
-
-def main():
-
-       # Trigger
-       term0 = Term(32)
-       term1 = Term(32)
-       term2 = Term(32)
-       term3 = Term(32)
-       trigger0 = Trigger(32, [term0, term1, term2, term3], address=TRIGGER_ADDR)
-       
-       # Recorder
-       recorder0 = Recorder(32, 1024, address=RECORDER_ADDR)
-       
-       # Csr Master
-       csr_master0 = csr.Initiator(csr_transactions(trigger0, recorder0))
-
-       # Csr Interconnect
-       csrcon0 = csr.Interconnect(csr_master0.bus, 
-                       [
-                               trigger0.bank.bus,
-                               recorder0.bank.bus
-                       ])
-
-       trig_sig = Signal(32)
-       comb =[
-               trigger0.trig.eq(trig_sig)
-       ]
-       
-       comb += [
-               recorder0.dat.eq(trig_sig),
-               recorder0.hit.eq(trigger0.hit)
-       ]
-       # Term Test
-       def term_stimuli(s):
-               global trig_sig_val
-               s.wr(trig_sig,trig_sig_val)
-               trig_sig_val += 1
-               trig_sig_val = trig_sig_val % 256
-
-       # Recorder Data
-       def recorder_data(s):
-               global rec_done
-               if s.rd(recorder0.sequencer.done) == 1:
-                       rec_done = True
-               
-               global dat_rdy
-               if dat_rdy:
-                       print("%08X" %s.rd(recorder0._pull_dat.field.w))
-                       global dat_vcd
-                       dat_vcd.append(s.rd(recorder0._pull_dat.field.w))
-
-       
-       # Simulation
-       def end_simulation(s):
-               s.interrupt = csr_master0.done
-               myvcd = Vcd()
-               myvcd.add(Var("trig_dat", 32, dat_vcd))
-               f = open("tb_miscope_out.vcd", "w")
-               f.write(str(myvcd))
-               f.close()
-       
-       fragment = term0.get_fragment()
-       fragment += term1.get_fragment()
-       fragment += term2.get_fragment()
-       fragment += term3.get_fragment()
-       fragment += trigger0.get_fragment()
-       fragment += recorder0.get_fragment()
-       fragment += csr_master0.get_fragment()
-       fragment += csrcon0.get_fragment()
-
-       fragment += Fragment(comb=comb)
-       fragment += Fragment(sim=[term_stimuli])
-       fragment += Fragment(sim=[recorder_data])
-       fragment += Fragment(sim=[end_simulation])
-
-       sim = Simulator(fragment, TopLevel("tb_miscope.vcd"))
-       sim.run(2000)
-
-main()
-print("Sim Done")
-input()
diff --git a/sim/tb_recorder_csr.py b/sim/tb_recorder_csr.py
new file mode 100644 (file)
index 0000000..a14eba0
--- /dev/null
@@ -0,0 +1,142 @@
+from migen.fhdl.std import *
+from migen.fhdl import verilog
+from migen.bus import csr
+from migen.sim.generic import Simulator, TopLevel
+from migen.sim.icarus import Runner
+from migen.bus.transactions import *
+
+from miscope.recording import *
+from miscope.std.truthtable import *
+
+from miscope.std import cif
+
+from mibuild.tools import write_to_file
+
+try:
+       from csr_header import *
+       print("csr_header imported")
+except:
+       print("csr_header not found")
+
+class Csr2Trans():
+       def __init__(self):
+               self.t = []
+
+       def write_csr(self, adr, value):
+               self.t.append(TWrite(adr//4, value))
+
+       def read_csr(self, adr):
+               self.t.append(TRead(adr//4))
+               return 0
+
+
+triggered = False
+dat = 0
+
+rec_done = False
+
+dat_rdy = False
+
+rec_length = 128
+
+def csr_configure():
+       bus = Csr2Trans()
+
+       # Length
+       recorder_length_write(bus, rec_length)
+
+       # Offset
+       recorder_offset_write(bus, 0)
+       
+       # Trigger
+       recorder_trigger_write(bus, 1)
+
+       return bus.t
+
+def csr_read_data():
+       bus = Csr2Trans()
+
+       for i in range(rec_length+100):
+               recorder_read_dat_read(bus)
+               recorder_read_en_write(bus, 1)
+       return bus.t
+
+def csr_transactions():
+       for t in csr_configure():
+               yield t
+
+       for t in range(100):
+               yield None
+       
+       global triggered
+       triggered = True
+
+       for t in range(512):
+               yield None
+
+       for t in csr_read_data():
+               yield t
+
+       for t in range(100):
+               yield None
+
+
+class TB(Module):
+       csr_base = 0
+       csr_map = {
+               "recorder": 1,
+       }
+       def __init__(self, first_run=False):
+               self.csr_base = 0
+
+               # Csr Master
+               if not first_run:
+                       self.submodules.master = csr.Initiator(csr_transactions())
+       
+               # Recorder
+               self.submodules.recorder = Recorder(32, 1024)
+       
+               # Csr
+               self.submodules.csrbankarray = csrgen.BankArray(self, 
+                       lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override])
+               if not first_run:
+                       self.submodules.csrcon = csr.Interconnect(self.master.bus,      self.csrbankarray.get_buses())
+
+       # Recorder Data
+       def recorder_data(self, s):
+               s.wr(self.recorder.sink.stb, 1)
+               if not hasattr(self, "cnt"):
+                       self.cnt = 0
+               self.cnt += 1   
+
+               s.wr(self.recorder.sink.payload.d, self.cnt)
+
+               global triggered
+               if triggered:
+                       s.wr(self.recorder.sink.payload.hit, 1)
+                       triggered = False
+               else:
+                       s.wr(self.recorder.sink.payload.hit, 0)
+
+       # Simulation
+       def end_simulation(self, s):
+               s.interrupt = self.master.done
+
+
+       def do_simulation(self, s):
+               self.recorder_data(s)
+               self.end_simulation(s)
+
+
+def main():
+       tb = TB(first_run=True)
+       csr_py_header = cif.get_py_csr_header(tb.csr_base, tb.csrbankarray)
+       write_to_file("csr_header.py", csr_py_header)
+
+       tb = TB()
+       sim = Simulator(tb, TopLevel("tb_recorder_csr.vcd"))
+       sim.run(2000)
+       print("Sim Done")
+       input()
+
+main()
\ No newline at end of file
diff --git a/sim/tb_spi2csr.py b/sim/tb_spi2csr.py
deleted file mode 100644 (file)
index ecc58e4..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-from migen.fhdl.structure import *
-from migen.fhdl import verilog, autofragment
-from migen.bus import csr
-from migen.sim.generic import Simulator, PureSimulable, TopLevel
-from migen.sim.icarus import Runner
-from migen.bus.transactions import *
-from migen.bank import description, csrgen
-from migen.bank.description import *
-
-import miscope.bridges.spi2csr
-
-def get_bit(dat, bit):
-       return int(dat & (1<<bit) != 0)
-
-def set_bit(dat, bit):
-       return dat | (1<<bit)   
-
-def spi_transactions():
-       yield TWrite(0x0000, 0x5A)
-       yield TWrite(0x0001, 0xA5)
-       yield TWrite(0x0002, 0x5A)
-       yield TWrite(0x0003, 0xA5)
-       
-       for i in range(10):
-               yield None 
-       
-       yield TRead(0x0000)
-       yield TRead(0x0001)
-       yield TRead(0x0002)
-       yield TRead(0x0003)
-       
-       for i in range(100):
-               yield None 
-
-class SpiMaster(PureSimulable):
-       def __init__(self, spi, clk_ratio, generator):
-               self.spi = spi
-               self.clk_ratio = clk_ratio
-               self.generator = generator
-               self.transaction_start = 0
-               self.transaction = None
-               self.done = False
-               self.r_dat = 0
-       
-       def do_simulation(self, s):
-               a_w = self.spi.a_width
-               d_w = self.spi.d_width
-               
-               if not self.done:
-                       if self.transaction is None:
-                               try:
-                                       self.transaction = next(self.generator)
-                               except StopIteration:
-                                       self.done = True
-                                       self.transaction = None
-                               if self.transaction is not None:
-                                       self.transaction_cnt = 0
-                                       self.r_dat = 0
-                                       print(self.transaction)
-                       elif isinstance(self.transaction, TWrite):
-                       
-                                       # Clk
-                                       if (int(self.transaction_cnt/(self.clk_ratio/2)))%2:
-                                               s.wr(self.spi.spi_clk, 1)
-                                       else:
-                                               s.wr(self.spi.spi_clk, 0)
-                                       
-                                       # Mosi Addr
-                                       if self.transaction_cnt < a_w*self.clk_ratio:
-                                               bit = a_w-1-int((self.transaction_cnt)/self.clk_ratio)
-                                               if int(self.transaction_cnt/self.clk_ratio) == 0:
-                                                       data = 1
-                                               else:
-                                                       data = get_bit(self.transaction.address, bit)
-                                               s.wr(self.spi.spi_mosi, data)
-                                       # Mosi Data
-                                       elif self.transaction_cnt >= a_w*self.clk_ratio and self.transaction_cnt < (a_w + d_w)*self.clk_ratio:
-                                               bit = d_w-1-int((self.transaction_cnt-a_w*self.clk_ratio)/self.clk_ratio)
-                                               data = get_bit(self.transaction.data,bit)
-                                               s.wr(self.spi.spi_mosi, data)
-                                       else:
-                                               s.wr(self.spi.spi_mosi, 0)
-                                       
-                                       # Cs_n
-                                       if self.transaction_cnt < (a_w + d_w)*self.clk_ratio:
-                                               s.wr(self.spi.spi_cs_n,0)
-                                       else:
-                                               s.wr(self.spi.spi_cs_n, 1)
-                                               s.wr(self.spi.spi_clk, 0)
-                                               s.wr(self.spi.spi_mosi, 0)
-                                               self.transaction = None
-                                       
-                                       # Incr transaction_cnt
-                                       self.transaction_cnt +=1
-                       
-                       elif isinstance(self.transaction, TRead):       
-                       
-                                       # Clk
-                                       if (int(self.transaction_cnt/(self.clk_ratio/2)))%2:
-                                               s.wr(self.spi.spi_clk, 1)
-                                       else:
-                                               s.wr(self.spi.spi_clk, 0)
-                                       
-                                       # Mosi Addr
-                                       if self.transaction_cnt < a_w*self.clk_ratio:
-                                               bit = a_w-1-int((self.transaction_cnt)/self.clk_ratio)
-                                               if int(self.transaction_cnt/self.clk_ratio) == 0:
-                                                       data = 0
-                                               else:
-                                                       data = get_bit(self.transaction.address, bit)
-                                               s.wr(self.spi.spi_mosi, data)
-                                       else:
-                                               s.wr(self.spi.spi_mosi, 0)
-                                       
-                                       # Miso Data
-                                       if self.transaction_cnt >= a_w*self.clk_ratio and self.transaction_cnt%self.clk_ratio==self.clk_ratio/2:
-                                               bit = d_w-1-int((self.transaction_cnt-a_w*self.clk_ratio)/self.clk_ratio)
-                                               if s.rd(self.spi.spi_miso):
-                                                       self.r_dat = set_bit(self.r_dat, bit)
-                                       
-                                       # Cs_n
-                                       if self.transaction_cnt < (a_w + d_w)*self.clk_ratio:
-                                               s.wr(self.spi.spi_cs_n,0)
-                                       else:
-                                               s.wr(self.spi.spi_cs_n, 1)
-                                               s.wr(self.spi.spi_clk, 0)
-                                               s.wr(self.spi.spi_mosi, 0)
-                                               self.transaction = None
-                                               print("%02X" %self.r_dat)
-                                       
-                                       # Incr transaction_cnt
-                                       self.transaction_cnt +=1
-
-
-def main():
-       # Csr Slave
-       scratch_reg0 = RegisterField("scratch_reg0", 32, reset=0, access_dev=READ_ONLY)
-       scratch_reg1 = RegisterField("scratch_reg1", 32, reset=0, access_dev=READ_ONLY)
-       scratch_reg2 = RegisterField("scratch_reg3", 32, reset=0, access_dev=READ_ONLY)
-       scratch_reg3 = RegisterField("scratch_reg4", 32, reset=0, access_dev=READ_ONLY)
-       regs = [scratch_reg0, scratch_reg1, scratch_reg2, scratch_reg3]
-       bank0 = csrgen.Bank(regs,address=0x0000)
-       
-       # Spi2Csr
-       spi2csr0 = spi2csr.Spi2Csr(16,8)
-       
-       
-       # Csr Interconnect
-       csrcon0 = csr.Interconnect(spi2csr0.csr, 
-                       [
-                               bank0.interface
-                       ])
-       
-       # Spi Master
-       spi_master0 = SpiMaster(spi2csr0, 8, spi_transactions())
-       
-       # Simulation
-       def end_simulation(s):
-               s.interrupt = spi_master0.done
-       
-       
-       fragment = autofragment.from_local()
-       fragment += Fragment(sim=[end_simulation])
-       sim = Simulator(fragment, Runner(),TopLevel("tb_spi2Csr.vcd"))
-       sim.run(10000)
-
-main()
-input()        
diff --git a/sim/tb_trigger_csr.py b/sim/tb_trigger_csr.py
new file mode 100644 (file)
index 0000000..d2be921
--- /dev/null
@@ -0,0 +1,109 @@
+from migen.fhdl.std import *
+from migen.fhdl import verilog
+from migen.bus import csr
+from migen.sim.generic import Simulator, TopLevel
+from migen.sim.icarus import Runner
+from migen.bus.transactions import *
+
+from miscope.triggering import *
+from miscope.std.truthtable import *
+
+from miscope.std import cif
+
+from mibuild.tools import write_to_file
+
+try:
+       from csr_header import *
+       print("csr_header imported")
+except:
+       print("csr_header not found")
+
+class Csr2Trans():
+       def __init__(self):
+               self.t = []
+
+       def write_csr(self, adr, value):
+               self.t.append(TWrite(adr//4, value))
+
+       def read_csr(self, adr):
+               self.t.append(TRead(adr//4))
+       
+def csr_prog_mila():
+       bus = Csr2Trans()
+       trigger_port0_mask_write(bus, 0xFFFFFFFF)
+       trigger_port0_trig_write(bus, 0xDEADBEEF)
+       trigger_port1_mask_write(bus, 0xFFFFFFFF)
+       trigger_port1_trig_write(bus, 0xDEADBEEF)
+       trigger_port1_mask_write(bus, 0xFFFFFFFF)
+       trigger_port1_mask_write(bus, 0xFFFFFFFF)
+       trigger_port1_trig_write(bus, 0xDEADBEEF)
+
+       sum_tt = gen_truth_table("i1 & i2 & i3 & i4")
+       sum_trans = []
+       for i in range(len(sum_tt)):
+               trigger_sum_prog_adr_write(bus, i)
+               trigger_sum_prog_dat_write(bus, sum_tt[i])
+               trigger_sum_prog_we_write(bus, 1)
+
+       return bus.t
+
+
+csr_done = False
+
+def csr_transactions():
+       for t in csr_prog_mila():
+               yield t
+       global csr_done
+       csr_done = True
+       for t in range(100):
+               yield None
+
+class TB(Module):
+       csr_base = 0
+       csr_map = {
+               "trigger": 1,
+       }
+       def __init__(self, first_run=False):
+               
+
+               # Csr Master
+               if not first_run:
+                       self.submodules.master = csr.Initiator(csr_transactions())
+       
+               # Trigger
+               term0 = Term(32)
+               term1 = Term(32)
+               term2 = Term(32)
+               term3 = Term(32)
+               self.submodules.trigger = Trigger(32, [term0, term1, term2, term3])
+       
+               # Csr
+               self.submodules.csrbankarray = csrgen.BankArray(self, 
+                       lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override])
+               if not first_run:
+                       self.submodules.csrcon = csr.Interconnect(self.master.bus,      self.csrbankarray.get_buses())
+       
+               self.terms = [term0, term1, term2, term3]
+
+       def do_simulation(self, s):
+               for term in self.terms:
+                       s.wr(term.sink.stb, 1)
+               if csr_done:
+                       s.wr(self.terms[0].sink.payload.d, 0xDEADBEEF)
+                       s.wr(self.terms[1].sink.payload.d ,0xCAFEFADE)
+                       s.wr(self.terms[2].sink.payload.d, 0xDEADBEEF)
+                       s.wr(self.terms[3].sink.payload.d, 0xCAFEFADE)
+               s.interrupt = self.master.done
+
+def main():
+       tb = TB(first_run=True)
+       csr_py_header = cif.get_py_csr_header(tb.csr_base, tb.csrbankarray)
+       write_to_file("csr_header.py", csr_py_header)
+
+       tb = TB()
+       sim = Simulator(tb, TopLevel("tb_trigger_csr.vcd"))
+       sim.run(2000)
+       print("Sim Done")
+       input()
+
+main()