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
csr = Uart2Csr(3,115200)
# Csr Addr
-MIIO_ADDR = 0x0000
+MIIO_ADDR = 0x00
# Miscope Configuration
miio = miio.MiIo(MIIO_ADDR, 8, "IO", csr)
--- /dev/null
+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
#
# Copyright 2013 / Florent Kermarrec / florent@enjoy-digital.fr
#
-# miscope miio example on De0 Nano
+# miscope example on De0 Nano
# --------------------------------
################################################################################
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 *
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
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)
# 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)
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
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)
import serial
from struct import *
import time
+from migen.fhdl.structure import *
WRITE_CMD = 0x01
READ_CMD = 0x02
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)
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])
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
#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
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 =[
from migen.genlib.misc import optree
from migen.genlib.fsm import *
+from miscope.tools.misc import RisingEdge
+
class Storage:
#
# Definition
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")
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:
#
self.enable = Signal()
def get_fragment(self):
-
- idle_rising = Signal()
- idle_ongoing = Signal()
- active_rising = Signal()
- active_ongoing = Signal()
# FSM
fsm = FSM("IDLE", "ACTIVE")
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)
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)
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 = [
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)
]
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
--- /dev/null
+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
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:
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
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"
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 = []
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
r += c
return r
-
def p_date(self):
now = datetime.datetime.now()
r = "$date\n"
r += self.timescale
r += " $end\n"
return r
+
def p_vars(self):
r = ""
for var in self.vars:
r += self.change()
self.cnt += 1
return r
-
def __repr__(self):
r = ""
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__':
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:
#
# 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)]
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:
#
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:
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
from miscope import recorder
arm_done = False
-trig_dat = 0
+dat = 0
rec_done = False
#Arm
yield TWrite(1, 1)
+ yield TWrite(1, 0)
for t in range(10):
yield None
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
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
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
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
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()
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
# 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
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
#Arm
yield TWrite(recorder0.address + 1, 1)
+ yield TWrite(recorder0.address + 1, 0)
# Wait Record to be done
##############################
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))
# 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):
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
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()