clean up/fixes
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 21 Mar 2013 11:23:44 +0000 (12:23 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 22 Mar 2013 10:31:21 +0000 (11:31 +0100)
16 files changed:
README
examples/de0_nano/client/test_miio.py
examples/de0_nano/client/test_mila.py [new file with mode: 0644]
examples/de0_nano/top.py
miscope/bridges/spi2csr/tools/uart2Spi.py
miscope/bridges/uart2csr/__init__.py
miscope/bridges/uart2csr/tools/uart2Csr.py
miscope/miio.py
miscope/mila.py
miscope/recorder.py
miscope/tools/misc.py [new file with mode: 0644]
miscope/tools/vcd.py
miscope/trigger.py
sim/tb_RecorderCsr.py
sim/tb_TriggerCsr.py
sim/tb_miscope.py

diff --git a/README b/README
index dbc997c79b43b887f4d92b97e0443a1f128868b3..cdffe5f61324ebd1bb0de8b3c7cd0bdefbac8b36 100644 (file)
--- a/README
+++ b/README
@@ -6,38 +6,41 @@
  
        Copyright 2012 / Florent Kermarrec / florent@enjoy-digital.fr
  
-                               miscope
+                                 Miscope
 --------------------------------------------------------------------------------
 
-[> miscope
+[> Miscope
 ------------
 
-miscope is a small logic analyzer to be embedded in an FPGA.
+Miscope is a small logic analyzer to embed in an FPGA.
 
 While free vendor toolchains are generally used by beginners or for prototyping 
-(situations where having a logic analyser in the design is generally very 
-helpful) free toolchains are always provided without the proprietary logic 
-analyzer solution... :(
+(situations where having a logic analyser in the design is generally helpful) 
+free toolchains are always provided without the proprietary logic analyzer 
+solution... :(
 
-Based on Migen, miscope aims to provide a free, portable and flexible 
+Based on Migen, Miscope aims to provide a free, portable and flexible 
 alternative to vendor's solutions!
 
 [> Specification:
 
-miscope provides Migen cores to be embedded in the design and Python drivers to 
-control the logic  analyzer  from the Host. miscope automatically interconnects 
-all cores to the CSR bus. When using Python on the Host, no needs to worry about
-cores register mapping, importing miscope project gives you direct access to 
-all the cores!
+Miscope provides Migen cores to embed in the design and Python drivers to control
+the logic analyzer from the Host. Miscope automatically interconnects all cores 
+to a CSR bus. When using Python on the Host, no needs to worry aboutcores register
+mapping, importing miscope project gives you direct access to all the cores!
 
-miscope produces .vcd output files to be analyzed in your favorite waveform viewer.
+Miscope produces .vcd output files to be analyzed in your favorite waveform viewer.
+
+Since Miscope also provides an Uart2Csr bridge, you only need 2 external Rx/Tx pins
+to be ready to debug!
 
 [> Status:
-Refactoring in progress...
+Miio & Mila working on board with standard term.
+RangeDetector and EdgeDector terms not tested.
 
 [> Examples:
-test_MigIo : Led & Switch Test controlled by Python Host.
-test_MigLa : Logic Analyzer controlled by Python Host.
+test_Miio : Led & Switch Test controlled by Python Host.
+test_Miia : Logic Analyzer controlled by Python Host.
 
 [> Contact
 E-mail: florent@enjoy-digital.fr
index 0e0119239fc3e31c8d8f9781300cb7ea0f6fbb10..dea73da9d351b6bc1b3e6dcedb446ee4ec965fd0 100644 (file)
@@ -8,7 +8,7 @@ from miscope.bridges.uart2csr.tools.uart2Csr import *
 csr = Uart2Csr(3,115200)
 
 # Csr Addr
-MIIO_ADDR  = 0x0000
+MIIO_ADDR  = 0x00
 
 # Miscope Configuration
 miio = miio.MiIo(MIIO_ADDR, 8, "IO", csr)
diff --git a/examples/de0_nano/client/test_mila.py b/examples/de0_nano/client/test_mila.py
new file mode 100644 (file)
index 0000000..fcd6a75
--- /dev/null
@@ -0,0 +1,68 @@
+from miscope import trigger, recorder, miio, mila
+from miscope.tools.truthtable import *
+from miscope.tools.vcd import *
+from miscope.bridges.uart2csr.tools.uart2Csr import *
+
+#==============================================================================
+#      P A R A M E T E R S
+#==============================================================================
+# Csr Addr
+MILA_ADDR      = 0x01
+
+csr = Uart2Csr(3, 115200, debug=False)
+
+# Mila Param
+trig_w         = 16
+dat_w          = 16
+rec_size       = 512
+rec_offset     = 32
+
+# 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)
+
+       
+#==============================================================================
+#                  T E S T  M I G L A 
+#==============================================================================
+dat_vcd = VcdDat(dat_w)
+
+def capture(size):
+       global trigger
+       global recorder
+       global dat_vcd
+       sum_tt = gen_truth_table("term")
+       mila.trigger.sum.write(sum_tt)
+       mila.recorder.reset()
+       recorder.size(rec_size) 
+       mila.recorder.offset(rec_offset)
+       mila.recorder.arm()
+       print("-Recorder [Armed]")
+       print("-Waiting Trigger...", end=' ')
+       while(not mila.recorder.is_done()):
+               time.sleep(0.1)
+       print("[Done]")
+       
+       print("-Receiving Data...", end=' ')
+       sys.stdout.flush()
+       dat_vcd += mila.recorder.read(size)
+       print("[Done]")
+
+print("Capturing ...")
+print("----------------------")
+term.write(0x0000, 0xFFFF)
+capture(rec_size)
+
+mila_layout = [
+       ("freqgen", 1),
+       ("event_rising", 1),
+       ("event_falling", 1),
+       ("cnt", 8),
+       ]
+
+myvcd = Vcd()
+myvcd.add_from_layout(mila_layout, dat_vcd)
+myvcd.write("test_mila.vcd")
\ No newline at end of file
index 40bef128844642e55582aa4eacec0677bf202a3f..81592de5423d819f7028229c28a23cfee31e540d 100644 (file)
@@ -7,7 +7,7 @@
 #
 #      Copyright 2013 / Florent Kermarrec / florent@enjoy-digital.fr
 #
-#                        miscope miio example on De0 Nano
+#                           miscope example on De0 Nano
 #                        --------------------------------
 ################################################################################
 
@@ -18,8 +18,9 @@ from migen.fhdl.structure import *
 from migen.fhdl.module import *
 from migen.bus import csr
 
-from miscope import miio
+from miscope import trigger, recorder, miio, mila
 from miscope.bridges import uart2csr
+from miscope.tools.misc import *
 
 from timings import *
 
@@ -31,7 +32,13 @@ from timings import *
 clk_freq       = 50*MHz
 
 # Csr Addr
-MIIO0_ADDR  = 0x0000
+MIIO_ADDR      = 0x00
+MILA_ADDR      = 0x01
+
+# Mila Param
+trig_w         = 16
+dat_w          = 16
+rec_size       = 4096
 
 #==============================================================================
 #   M I S C O P E    E X A M P L E
@@ -39,7 +46,14 @@ MIIO0_ADDR  = 0x0000
 class SoC(Module):
        def __init__(self):
                # MiIo
-               self.submodules.miio = miio.MiIo(MIIO0_ADDR, 8, "IO")
+               self.submodules.miio = miio.MiIo(MIIO_ADDR, 8, "IO")
+
+               # 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)
+
+               self.submodules.mila = mila.MiLa(MILA_ADDR, self.trigger, self.recorder)
        
                # Uart2Csr
                self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200)
@@ -47,15 +61,43 @@ class SoC(Module):
                # Csr Interconnect
                self.submodules.csrcon = csr.Interconnect(self.uart2csr.csr,
                                [
-                                       self.miio.bank.bus
+                                       self.miio.bank.bus,
+                                       self.trigger.bank.bus,
+                                       self.recorder.bank.bus
                                ])
                
                # Led
                self.led = Signal(8)
-               
+
+               # Misc
+               self.cnt = Signal(9)
+               self.submodules.freqgen = FreqGen(clk_freq, 500*KHz)
+               self.submodules.eventgen_rising = EventGen(self.freqgen.o, RISING_EDGE, clk_freq, 100*ns)
+               self.submodules.eventgen_falling = EventGen(self.freqgen.o, FALLING_EDGE, clk_freq, 100*ns)
+
        ###
+
+               #
+               # Miio
+               #
+
                # Output
                self.comb += self.led.eq(self.miio.o)
-
+               
                # Input
-               self.comb += self.miio.i.eq(0x5A)
\ No newline at end of file
+               self.comb += self.miio.i.eq(self.miio.o)
+
+               #
+               # Mila
+               #
+               self.comb +=[
+                       self.mila.trig[0].eq(self.freqgen.o),
+                       self.mila.trig[1].eq(self.eventgen_rising.o),
+                       self.mila.trig[2].eq(self.eventgen_falling.o),
+                       self.mila.trig[3:11].eq(self.cnt),
+                       self.mila.dat[0].eq(self.freqgen.o),
+                       self.mila.dat[1].eq(self.eventgen_rising.o),
+                       self.mila.dat[2].eq(self.eventgen_falling.o),
+                       self.mila.dat[3:11].eq(self.cnt),
+               ]
+               self.sync += self.cnt.eq(self.cnt+1)
index 9f5568df127afe966650d3db311193e25334276d..c7326c7024b51701dc09add6d303354f111578aa 100644 (file)
@@ -53,13 +53,4 @@ class Uart2Spi:
                        elif endianess == "LE":
                                self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
                if self.debug:
-                       print("WR %08X @ %04X" %(data, addr))
-
-def main():
-       csr = Uart2Spi(1,115200)
-       for i in range(100):
-               csr.write(0x0000,i)
-               print(csr.read(0x0000))
-
-if __name__ == '__main__':
-  main()
\ No newline at end of file
+                       print("WR %08X @ %04X" %(data, addr))
\ No newline at end of file
index b10d2dff44beecb6cb752999de918193602fb6bf..9cf0a8b4e0893f7b2bcb7254b65cf737ca2911a5 100644 (file)
@@ -75,8 +75,8 @@ class Uart2Csr(Module):
                self.sync += If(fsm.ongoing(fsm.IDLE) & uart.rx_ev, cmd.eq(uart.rx_dat))
 
                #
-           # Get burst length
-           #
+               # Get burst length
+               #
                fsm.act(fsm.GET_BL,
                        If(get_bl_done,
                                fsm.next_state(fsm.GET_ADDR)
index 0f265eb864f9e94d9d30b17ce19169f9571953f2..27fc288bfa9c1baaf18e33ee36d99363cf9112be 100644 (file)
@@ -3,6 +3,7 @@ import time
 import serial
 from struct import *
 import time
+from migen.fhdl.structure import *
 
 WRITE_CMD  = 0x01
 READ_CMD   = 0x02
@@ -36,7 +37,19 @@ class Uart2Csr:
                        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)
@@ -45,9 +58,9 @@ class Uart2Csr:
                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)])
+                                               (addr & 0x00ff0000) >> 16,
+                                               (addr & 0x0000ff00) >> 8,
+                                               (addr & 0x000000ff)])
                if isinstance(data, list):
                        for i in range(len(data)):
                                write_b(self.uart, data[i])
@@ -56,4 +69,14 @@ class Uart2Csr:
                else:
                        write_b(self.uart, data)
                        if self.debug:
-                               print("WR %02X @ %08X" %(data, addr))
\ No newline at end of file
+                               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
index bad8dbc45e2ad95cc5c9e4d2c6dde9791e2e79f1..0772910335ae2db74ca0671d630dfeca7022f700 100644 (file)
@@ -38,7 +38,7 @@ class MiIo:
        #Driver
        #
        def write(self, data):
-                       self.interface.write(self.address, data)
+                       self.interface.write(self.bank.get_base(), data)
                        
        def read(self):
-               return self.interface.read(self.address + self.words)
\ No newline at end of file
+               return self.interface.read(self.bank.get_base() + self.words)
\ No newline at end of file
index e9104d44f4b3216483d586ac8c9c320127f8636b..177ee583f97007a713d2a909e8f0d0d1b89e946a 100644 (file)
@@ -17,16 +17,18 @@ class MiLa:
                
                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)
+
        def set_interface(self, interface):
                self.interface = interface
                self.trigger.set_interface(interface)
                self.recorder.set_interface(interface)
                
-       def set_address(self, address):
-               self.address = address
-               self.trigger.set_address(self.address)
-               self.recorder.set_address(self.address + 0x0200)
+
        
        def get_fragment(self):
                comb =[
index 04283f2d85d03be613ae726ecbbbe6a949200aaa..caa236741f8268f132826f23789f39bbe4f024fe 100644 (file)
@@ -6,6 +6,8 @@ from migen.bank.description import *
 from migen.genlib.misc import optree
 from migen.genlib.fsm import *
 
+from miscope.tools.misc import RisingEdge
+
 class Storage:
        # 
        # Definition
@@ -49,14 +51,6 @@ class Storage:
                                        self.pull_dat.eq(self._pull_port.dat_r)
                ]
                
-               size_minus_offset = Signal(self.depth_width)
-               comb += [size_minus_offset.eq(self.size-self.offset)]
-               
-               idle_rising = Signal()
-               idle_ongoing = Signal()
-               active_rising = Signal()
-               active_ongoing = Signal()
-               
                # FSM
                fsm = FSM("IDLE", "ACTIVE")
                
@@ -64,32 +58,28 @@ class Storage:
                fsm.act(fsm.IDLE, 
                        If(self.start, 
                                fsm.next_state(fsm.ACTIVE),
-                               active_rising.eq(1)
-                       ),
-                       idle_ongoing.eq(1)
+                       )
                )
                
                # Active
                fsm.act(fsm.ACTIVE,
                        If(self.done | self.rst,
                                fsm.next_state(fsm.IDLE),
-                               idle_rising.eq(1)
-                       ),
-                       active_ongoing.eq(1)
+                       )
                )
                
                sync =[ 
-                       If(active_rising,
+                       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) 
+                               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.pull_stb, self._pull_ptr.eq(self._pull_ptr + 1))
                        ),
-                       If(self.push_stb, self._push_ptr.eq(self._push_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) & active_ongoing)]
+               comb +=[self.done.eq((self._push_ptr == self._push_ptr_stop) & fsm.ongoing(fsm.ACTIVE))]
                
-               return Fragment(comb, sync, specials={self._mem})
+               return Fragment(comb, sync, specials={self._mem}) + fsm.get_fragment()
 
 class Sequencer:
        # 
@@ -120,11 +110,6 @@ class Sequencer:
                self.enable = Signal()
                
        def get_fragment(self):
-       
-               idle_rising = Signal()
-               idle_ongoing = Signal()
-               active_rising = Signal()
-               active_ongoing = Signal()
                
                # FSM
                fsm = FSM("IDLE", "ACTIVE")
@@ -133,53 +118,46 @@ class Sequencer:
                fsm.act(fsm.IDLE, 
                        If(self.ctl_arm, 
                                fsm.next_state(fsm.ACTIVE),
-                               active_rising.eq(1)
-                       ),
-                       idle_ongoing.eq(1)
+                       )
                )
                
                # Active
                fsm.act(fsm.ACTIVE,
-                       If(self.rec_done,
+                       If(self.rec_done | self.ctl_rst,
                                fsm.next_state(fsm.IDLE),
-                               idle_rising.eq(1)
                        ),
-                       active_ongoing.eq(1)
+                       self.enable.eq(1)
                )
-               comb =[self.enable.eq(active_ongoing)]
                
                # trig_hit rising_edge
-               _hit_d = Signal()
-               _hit_rising = Signal()
-               sync =[_hit_d.eq(self.hit)]
-               comb +=[_hit_rising.eq(self.hit & ~_hit_d)]
+               hit_rising = RisingEdge(self.hit)
                
                # connexion
                comb = [
                        self.rec_offset.eq(self.ctl_offset),
                        self.rec_size.eq(self.ctl_size),
-                       self.rec_start.eq(self.enable & _hit_rising),
-                       self.ctl_done.eq(~self.enable)
+                       self.rec_start.eq(self.enable & hit_rising.o),
+                       self.ctl_done.eq(~self.enable),
                        ]
-               return Fragment(comb, sync)
+               return Fragment(comb) + fsm.get_fragment() + hit_rising.get_fragment()
 
 
-REC_RST_BASE                           = 0x00
-REC_ARM_BASE                           = 0x01
-REC_DONE_BASE                  = 0x02
-REC_SIZE_BASE                  = 0x03
-REC_OFFSET_BASE                = 0x05
-REC_READ_BASE                          = 0x07
-REC_READ_DATA_BASE     = 0x09
+REC_RST_BASE           = 0x00
+REC_ARM_BASE           = 0x01
+REC_DONE_BASE          = 0x02
+REC_SIZE_BASE          = 0x03
+REC_OFFSET_BASE                = 0x05
+REC_READ_BASE          = 0x07
+REC_READ_DATA_BASE     = 0x08
 
 class Recorder:
        # 
        # Definition
        #
-       def __init__(self, width, depth, address = 0x0000, interface = None):
+       def __init__(self, width, depth, address=0x0000, interface=None):
                self.width = width
                self.depth = depth
-               self.depth_width = bits_for(self.depth)
+               self.depth_width = bits_for(self.depth-1)
                
                self.storage = Storage(self.width, self.depth)
                self.sequencer = Sequencer(self.depth)
@@ -188,19 +166,17 @@ class Recorder:
                self._rst = RegisterField("rst", reset=1)
                self._arm = RegisterField("arm", reset=0)
                self._done = RegisterField("done", reset=0, access_bus=READ_ONLY, 
-                                                                                                                        access_dev=WRITE_ONLY)
+                                                                       access_dev=WRITE_ONLY)
                
                self._size = RegisterField("size", self.depth_width, reset=1)
                self._offset = RegisterField("offset", self.depth_width, reset=1)
                
                self._pull_stb = RegisterField("pull_stb", reset=0)
                self._pull_dat = RegisterField("pull_dat", self.width, reset=1, 
-                                                                                                                                        access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+                                                                               access_bus=READ_ONLY, access_dev=WRITE_ONLY)
                
                self.regs = [self._rst, self._arm, self._done, self._size, self._offset,
-                                                                self._pull_stb, self._pull_dat]
-                       
-               self.bank = csrgen.Bank(self.regs, address=address)
+                                       self._pull_stb, self._pull_dat]
                
                # set address / interface
                self.set_address(address)
@@ -212,19 +188,14 @@ class Recorder:
        
        def set_address(self, address):
                self.address = address
-               self.bank = csrgen.Bank(self.regs,address=self.address)
+               self.bank = csrgen.Bank(self.regs, address=self.address)
                        
        def set_interface(self, interface):
                self.interface = interface
                
        def get_fragment(self):
-               _pull_stb_d = Signal()
-               _pull_stb_rising = Signal()
-               
-               sync = [
-                       _pull_stb_d.eq(self._pull_stb.field.r),
-                       _pull_stb_rising.eq(self._pull_stb.field.r & ~_pull_stb_d)
-               ]
+
+               _pull_stb_rising = RisingEdge(self._pull_stb.field.r)
 
                # Bank <--> Storage / Sequencer
                comb = [
@@ -237,7 +208,7 @@ class Recorder:
                        
                        self._done.field.w.eq(self.sequencer.ctl_done),
                        
-                       self.storage.pull_stb.eq(_pull_stb_rising),
+                       self.storage.pull_stb.eq(_pull_stb_rising.o),
                        self._pull_dat.field.w.eq(self.storage.pull_dat)
                        ]
                
@@ -254,33 +225,34 @@ class Recorder:
                        self.storage.push_dat.eq(self.dat)
                        ]
                
-               return self.bank.get_fragment() + Fragment(comb, sync) +\
-                       self.storage.get_fragment() + self.sequencer.get_fragment()
+               return self.bank.get_fragment() + Fragment(comb) +\
+                       self.storage.get_fragment() + self.sequencer.get_fragment() +\
+                       _pull_stb_rising.get_fragment()
                        
        #
        #Driver
        #
        def reset(self):
-               self.interface.write(self.address + REC_RST_BASE, 1)
-               self.interface.write(self.address + REC_RST_BASE, 0)
+               self.interface.write(self.bank.get_base() + REC_RST_BASE, 1)
+               self.interface.write(self.bank.get_base() + REC_RST_BASE, 0)
        
        def arm(self):
-               self.interface.write(self.address + REC_ARM_BASE, 1)
-               self.interface.write(self.address + REC_ARM_BASE, 0)
+               self.interface.write(self.bank.get_base() + REC_ARM_BASE, 1)
+               self.interface.write(self.bank.get_base() + REC_ARM_BASE, 0)
        
        def is_done(self):
-               return self.interface.read(self.address + REC_DONE_BASE) == 1
+               return self.interface.read(self.bank.get_base() + REC_DONE_BASE) == 1
                
        def size(self, dat):
-               self.interface.write_n(self.address + REC_SIZE_BASE, dat, 16)
+               self.interface.write_n(self.bank.get_base() + REC_SIZE_BASE, dat, 16)
                
        def offset(self, dat):
-               self.interface.write_n(self.address + REC_OFFSET_BASE, dat, 16)
+               self.interface.write_n(self.bank.get_base() + REC_OFFSET_BASE, dat, 16)
                
        def read(self, size):
                r = []
                for i in range(size):
-                       self.interface.write(self.address + REC_READ_BASE, 1)
-                       self.interface.write(self.address + REC_READ_BASE, 0)
-                       r.append(self.interface.read_n(self.address + REC_READ_DATA_BASE, self.width))
+                       self.interface.write(self.bank.get_base() + REC_READ_BASE, 1)
+                       self.interface.write(self.bank.get_base() + REC_READ_BASE, 0)
+                       r.append(self.interface.read_n(self.bank.get_base() + REC_READ_DATA_BASE, self.width))
                return r
diff --git a/miscope/tools/misc.py b/miscope/tools/misc.py
new file mode 100644 (file)
index 0000000..1067a5c
--- /dev/null
@@ -0,0 +1,111 @@
+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 3a44116ad01872d63dfe3b6664444198a3615833..192ce383c1e37438185cf3ee4d20a9c13b057803 100644 (file)
@@ -3,10 +3,10 @@ import datetime
 
 from miscope.tools.conv import *
 
-def get_bits(values, width, low, high =None):
+def get_bits(values, width, low, high=None):
        r = []
        for val in values:
-               t = dec2bin(val,width)[::-1]
+               t = dec2bin(val, width)[::-1]
                if high == None:
                        t = t[low]
                else:
@@ -16,8 +16,32 @@ def get_bits(values, width, low, high =None):
                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
+
 class Var:
-       def __init__(self,type , width , name, values=[], default="x"):
+       def __init__(self, name, width, values=[], type="wire", default="x"):
                self.type = type
                self.width = width
                self.name = name
@@ -36,7 +60,7 @@ class Var:
                try : 
                        if self.values[cnt+1] != self.val:
                                r += "b"
-                               r += dec2bin(self.values[cnt+1], self.width)
+                               r += dec2bin(self.values[cnt+1], self.width)[::-1]
                                r += " "
                                r += self.vcd_id
                                r += "\n"
@@ -44,10 +68,9 @@ class Var:
                except :
                        return r
                return r
-       
-               
+
 class Vcd:
-       def __init__(self,timescale = "1ps", comment = ""):
+       def __init__(self, timescale="1ps", comment=""):
                self.timescale = timescale
                self.comment = comment
                self.vars = []
@@ -58,6 +81,12 @@ class Vcd:
                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
@@ -77,7 +106,6 @@ class Vcd:
                        r += c
                return r
 
-       
        def p_date(self):
                now = datetime.datetime.now()
                r = "$date\n"
@@ -110,6 +138,7 @@ class Vcd:
                r += self.timescale
                r += " $end\n"
                return r
+
        def  p_vars(self):
                r = ""
                for var in self.vars:
@@ -151,7 +180,6 @@ class Vcd:
                        r += self.change()
                        self.cnt += 1
                return r
-               
 
        def __repr__(self):
                r = ""
@@ -174,12 +202,12 @@ class Vcd:
 
 def main():
        myvcd = Vcd()
-       myvcd.add(Var("wire", 1, "foo1", [0,1,0,1,0,1]))
-       myvcd.add(Var("wire", 2, "foo2", [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
-       myvcd.add(Var("wire", 3, "foo3"))
-       myvcd.add(Var("wire", 4, "foo4"))
+       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("wire", 16, "ramp", ramp))
+       myvcd.add(Var(16, "ramp", ramp))
        print(myvcd)
        
 if __name__ == '__main__':
index 80599b6fbaae226528207ba49c7c1f588c0257fd..8beae52946bba961f55731fee28db164691f9ef9 100644 (file)
@@ -55,8 +55,8 @@ class Term:
        def write(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)
-               self.interface.write_n(self.reg_p.base, mask, self.width)
                
 class RangeDetector:
        # 
@@ -144,13 +144,13 @@ class EdgeDetector:
                        
                # Falling Edge
                if "F" in self.mode:
-                       comb += [self.fo.eq(self.f_mask & (~ self.i) & self.i_d)]
+                       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)]
+                       comb += [self.bo.eq((self.b_mask & self.i) != self.i_d)]
                else:
                        comb += [self.bo.eq(0)]
                        
@@ -243,8 +243,8 @@ class Sum:
                        we = 1<<17
                        dat = val<<16
                        addr = i
-                       self.interface.write_n(self.reg_p.base, we + dat + addr, self.reg_size)
-                       self.interface.write_n(self.reg_p.base, dat + addr, self.reg_size)
+                       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:
        # 
@@ -283,11 +283,11 @@ class Trigger:
                
        def set_address(self, address):
                self.address = address
-               self.bank = csrgen.Bank(self.regs,address=self.address)
+               self.bank = csrgen.Bank(self.regs, address=self.address)
                for port in self.ports:
                        port.reg_p.base = self.bank.get_base(port.reg_p.name)
                self.sum.reg_p.base = self.bank.get_base(self.sum.reg_p.name)
-               
+
        def set_interface(self, interface):
                self.interface = interface
                for port in self.ports:
index 45e2ea08f20e1dc7cf719ee6658a4f584a4d9faf..d9f086f8c79b57b9c4ef01f26e543d7c3d62e6da 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl.structure import *
-from migen.fhdl import verilog, autofragment
+from migen.fhdl import verilog
 from migen.bus import csr
 from migen.sim.generic import Simulator, PureSimulable, TopLevel
 from migen.sim.icarus import Runner
@@ -8,7 +8,7 @@ from migen.bus.transactions import *
 from miscope import recorder
 
 arm_done = False
-trig_dat = 0
+dat = 0
 
 rec_done = False
 
@@ -30,6 +30,7 @@ def csr_transactions():
        
        #Arm
        yield TWrite(1, 1)
+       yield TWrite(1, 0)
        
        for t in range(10):
                yield None
@@ -62,42 +63,45 @@ def main():
        csr_master0 = csr.Initiator(csr_transactions())
 
        # Recorder
-       recorder0 = recorder.Recorder(0, 32, 1024)
+       recorder0 = recorder.Recorder(32, 1024)
        
        # Csr Interconnect
        csrcon0 = csr.Interconnect(csr_master0.bus,
                        [
-                               recorder0.bank.interface
+                               recorder0.bank.bus
                        ])
 
        # Recorder Data
        def recorder_data(s):
                global arm_done
                if arm_done:
-                       s.wr(recorder0.trig_hit, 1)
+                       s.wr(recorder0.hit, 1)
                        arm_done = False
 
-               global trig_dat
-               s.wr(recorder0.trig_dat,trig_dat)
-               trig_dat += 1
+               global dat
+               s.wr(recorder0.dat,dat)
+               dat += 1
                        
                global rec_done
                if s.rd(recorder0.sequencer.rec_done) == 1:
                        rec_done = True
                
                if dat_rdy:
-                       print("%08X" %s.rd(recorder0._get_dat.field.w))
+                       print("%08X" %s.rd(recorder0._pull_dat.field.w))
                
 
        # Simulation
        def end_simulation(s):
                s.interrupt = csr_master0.done
 
-       fragment = autofragment.from_local()
+       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, Runner(), TopLevel("tb_RecorderCsr.vcd"))
+       sim = Simulator(fragment, TopLevel("tb_RecorderCsr.vcd"))
        sim.run(10000)
 
 main()
+print("Sim Done")
 input()
\ No newline at end of file
index f3db1bdaeb529ddda2c7c5f6bbc5c0a59e32f0c0..9262872e7ff6bf9c7f6964a0521d984045b8b82b 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl.structure import *
-from migen.fhdl import verilog, autofragment
+from migen.fhdl import verilog
 from migen.bus import csr
 from migen.sim.generic import Simulator, PureSimulable, TopLevel
 from migen.sim.icarus import Runner
@@ -27,10 +27,14 @@ csr_done = False
 def csr_transactions():
 
        term_trans = []
-       term_trans += [term_prog(0x04  ,0xDEADBEEF)]
-       term_trans += [term_prog(0x08  ,0xCAFEFADE)]
-       term_trans += [term_prog(0x0C  ,0xDEADBEEF)]
-       term_trans += [term_prog(0x10  ,0xCAFEFADE)]
+       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
@@ -67,12 +71,12 @@ def main():
        term1 = trigger.Term(32)
        term2 = trigger.Term(32)
        term3 = trigger.Term(32)
-       trigger0 = trigger.Trigger(0, 32, 64, [term0, term1, term2, term3])
+       trigger0 = trigger.Trigger(32, [term0, term1, term2, term3])
        
        # Csr Interconnect
        csrcon0 = csr.Interconnect(csr_master0.bus, 
                        [
-                               trigger0.bank.interface
+                               trigger0.bank.bus
                        ])
        
        # Term Test
@@ -88,13 +92,20 @@ def main():
        def end_simulation(s):
                s.interrupt = csr_master0.done
        
-       fragment = autofragment.from_local()
+       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, Runner(), TopLevel("tb_TriggerCsr.vcd"))
+       sim = Simulator(fragment, TopLevel("tb_TriggerCsr.vcd"))
        sim.run(2000)
 
 main()
+print("Sim Done")
 input()
 
 
index e44ddc53640996a16c56b81b256a8072369262ca..8ad225e2e40814bdee61ff9a3f53f8854d91fc55 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl.structure import *
-from migen.fhdl import verilog, autofragment
+from migen.fhdl import verilog
 from migen.bus import csr
 from migen.sim.generic import Simulator, PureSimulable, TopLevel
 from migen.sim.icarus import Runner
@@ -38,10 +38,14 @@ def csr_transactions(trigger0, recorder0):
 
        # Term Prog
        term_trans = []
-       term_trans += [term_prog(trigger0.ports[0].reg_base, 0x00000000)]
-       term_trans += [term_prog(trigger0.ports[1].reg_base, 0x00000004)]
-       term_trans += [term_prog(trigger0.ports[2].reg_base, 0x00000008)]
-       term_trans += [term_prog(trigger0.ports[3].reg_base, 0x0000000C)]
+       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
@@ -50,7 +54,7 @@ def csr_transactions(trigger0, recorder0):
        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_base, i, sum_tt[i]))
+               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
@@ -71,6 +75,7 @@ def csr_transactions(trigger0, recorder0):
 
        #Arm
        yield TWrite(recorder0.address + 1,  1)
+       yield TWrite(recorder0.address + 1,  0)
 
        # Wait Record to be done
        ##############################
@@ -107,10 +112,10 @@ def main():
        term1 = trigger.Term(32)
        term2 = trigger.Term(32)
        term3 = trigger.Term(32)
-       trigger0 = trigger.Trigger(TRIGGER_ADDR, 32, 64, [term0, term1, term2, term3])
+       trigger0 = trigger.Trigger(32, [term0, term1, term2, term3], address=TRIGGER_ADDR)
        
        # Recorder
-       recorder0 = recorder.Recorder(RECORDER_ADDR, 32, 1024)
+       recorder0 = recorder.Recorder(32, 1024, address=RECORDER_ADDR)
        
        # Csr Master
        csr_master0 = csr.Initiator(csr_transactions(trigger0, recorder0))
@@ -118,19 +123,18 @@ def main():
        # Csr Interconnect
        csrcon0 = csr.Interconnect(csr_master0.bus, 
                        [
-                               trigger0.bank.interface,
-                               recorder0.bank.interface
+                               trigger0.bank.bus,
+                               recorder0.bank.bus
                        ])
 
        trig_sig = Signal(32)
-       comb = []
-       comb +=[
-               trigger0.in_trig.eq(trig_sig)
+       comb =[
+               trigger0.trig.eq(trig_sig)
        ]
        
        comb += [
-               recorder0.trig_dat.eq(trig_sig),
-               recorder0.trig_hit.eq(trigger0.hit)
+               recorder0.dat.eq(trig_sig),
+               recorder0.hit.eq(trigger0.hit)
        ]
        # Term Test
        def term_stimuli(s):
@@ -147,9 +151,9 @@ def main():
                
                global dat_rdy
                if dat_rdy:
-                       print("%08X" %s.rd(recorder0._get_dat.field.w))
+                       print("%08X" %s.rd(recorder0._pull_dat.field.w))
                        global dat_vcd
-                       dat_vcd.append(s.rd(recorder0._get_dat.field.w))
+                       dat_vcd.append(s.rd(recorder0._pull_dat.field.w))
 
        
        # Simulation
@@ -157,19 +161,27 @@ def main():
                s.interrupt = csr_master0.done
                myvcd = Vcd()
                myvcd.add(Var("wire", 32, "trig_dat", dat_vcd))
-               f = open("tb_Miscope_Out.vcd", "w")
+               f = open("tb_miscope_out.vcd", "w")
                f.write(str(myvcd))
                f.close()
        
-       
-       fragment = autofragment.from_local()
+       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, Runner(),TopLevel("tb_MigScope.vcd"))
+       sim = Simulator(fragment, TopLevel("tb_miscope.vcd"))
        sim.run(2000)
 
 main()
+print("Sim Done")
 input()