mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
clean up/fixes
This commit is contained in:
parent
db1ceccca1
commit
b1cbfe2326
16 changed files with 452 additions and 185 deletions
35
README
35
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
|
||||
|
|
|
@ -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)
|
||||
|
|
68
examples/de0_nano/client/test_mila.py
Normal file
68
examples/de0_nano/client/test_mila.py
Normal file
|
@ -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")
|
|
@ -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)
|
||||
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)
|
||||
|
|
|
@ -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()
|
||||
print("WR %08X @ %04X" %(data, addr))
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
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))
|
|
@ -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)
|
||||
return self.interface.read(self.bank.get_base() + self.words)
|
|
@ -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 =[
|
||||
|
|
|
@ -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
|
||||
|
|
111
miscope/tools/misc.py
Normal file
111
miscope/tools/misc.py
Normal file
|
@ -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})
|
|
@ -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__':
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue