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
|
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
|
While free vendor toolchains are generally used by beginners or for prototyping
|
||||||
(situations where having a logic analyser in the design is generally very
|
(situations where having a logic analyser in the design is generally helpful)
|
||||||
helpful) free toolchains are always provided without the proprietary logic
|
free toolchains are always provided without the proprietary logic analyzer
|
||||||
analyzer solution... :(
|
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!
|
alternative to vendor's solutions!
|
||||||
|
|
||||||
[> Specification:
|
[> Specification:
|
||||||
|
|
||||||
miscope provides Migen cores to be embedded in the design and Python drivers to
|
Miscope provides Migen cores to embed in the design and Python drivers to control
|
||||||
control the logic analyzer from the Host. miscope automatically interconnects
|
the logic analyzer from the Host. Miscope automatically interconnects all cores
|
||||||
all cores to the CSR bus. When using Python on the Host, no needs to worry about
|
to a CSR bus. When using Python on the Host, no needs to worry aboutcores register
|
||||||
cores register mapping, importing miscope project gives you direct access to
|
mapping, importing miscope project gives you direct access to all the cores!
|
||||||
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:
|
[> Status:
|
||||||
Refactoring in progress...
|
Miio & Mila working on board with standard term.
|
||||||
|
RangeDetector and EdgeDector terms not tested.
|
||||||
|
|
||||||
[> Examples:
|
[> Examples:
|
||||||
test_MigIo : Led & Switch Test controlled by Python Host.
|
test_Miio : Led & Switch Test controlled by Python Host.
|
||||||
test_MigLa : Logic Analyzer controlled by Python Host.
|
test_Miia : Logic Analyzer controlled by Python Host.
|
||||||
|
|
||||||
[> Contact
|
[> Contact
|
||||||
E-mail: florent@enjoy-digital.fr
|
E-mail: florent@enjoy-digital.fr
|
||||||
|
|
|
@ -8,7 +8,7 @@ from miscope.bridges.uart2csr.tools.uart2Csr import *
|
||||||
csr = Uart2Csr(3,115200)
|
csr = Uart2Csr(3,115200)
|
||||||
|
|
||||||
# Csr Addr
|
# Csr Addr
|
||||||
MIIO_ADDR = 0x0000
|
MIIO_ADDR = 0x00
|
||||||
|
|
||||||
# Miscope Configuration
|
# Miscope Configuration
|
||||||
miio = miio.MiIo(MIIO_ADDR, 8, "IO", csr)
|
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
|
# 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.fhdl.module import *
|
||||||
from migen.bus import csr
|
from migen.bus import csr
|
||||||
|
|
||||||
from miscope import miio
|
from miscope import trigger, recorder, miio, mila
|
||||||
from miscope.bridges import uart2csr
|
from miscope.bridges import uart2csr
|
||||||
|
from miscope.tools.misc import *
|
||||||
|
|
||||||
from timings import *
|
from timings import *
|
||||||
|
|
||||||
|
@ -31,7 +32,13 @@ from timings import *
|
||||||
clk_freq = 50*MHz
|
clk_freq = 50*MHz
|
||||||
|
|
||||||
# Csr Addr
|
# 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
|
# M I S C O P E E X A M P L E
|
||||||
|
@ -39,7 +46,14 @@ MIIO0_ADDR = 0x0000
|
||||||
class SoC(Module):
|
class SoC(Module):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# MiIo
|
# 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
|
# Uart2Csr
|
||||||
self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200)
|
self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200)
|
||||||
|
@ -47,15 +61,43 @@ class SoC(Module):
|
||||||
# Csr Interconnect
|
# Csr Interconnect
|
||||||
self.submodules.csrcon = csr.Interconnect(self.uart2csr.csr,
|
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
|
# Led
|
||||||
self.led = Signal(8)
|
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
|
# Output
|
||||||
self.comb += self.led.eq(self.miio.o)
|
self.comb += self.led.eq(self.miio.o)
|
||||||
|
|
||||||
# Input
|
# 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)
|
||||||
|
|
|
@ -54,12 +54,3 @@ class Uart2Spi:
|
||||||
self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
|
self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print("WR %08X @ %04X" %(data, addr))
|
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()
|
|
|
@ -3,6 +3,7 @@ import time
|
||||||
import serial
|
import serial
|
||||||
from struct import *
|
from struct import *
|
||||||
import time
|
import time
|
||||||
|
from migen.fhdl.structure import *
|
||||||
|
|
||||||
WRITE_CMD = 0x01
|
WRITE_CMD = 0x01
|
||||||
READ_CMD = 0x02
|
READ_CMD = 0x02
|
||||||
|
@ -37,6 +38,18 @@ class Uart2Csr:
|
||||||
else:
|
else:
|
||||||
return values
|
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):
|
def write(self, addr, data):
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
burst_length = len(data)
|
burst_length = len(data)
|
||||||
|
@ -57,3 +70,13 @@ class Uart2Csr:
|
||||||
write_b(self.uart, data)
|
write_b(self.uart, data)
|
||||||
if self.debug:
|
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
|
#Driver
|
||||||
#
|
#
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
self.interface.write(self.address, data)
|
self.interface.write(self.bank.get_base(), data)
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
return self.interface.read(self.address + self.words)
|
return self.interface.read(self.bank.get_base() + self.words)
|
|
@ -18,15 +18,17 @@ class MiLa:
|
||||||
self.set_address(address)
|
self.set_address(address)
|
||||||
self.set_interface(interface)
|
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):
|
def set_interface(self, interface):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
self.trigger.set_interface(interface)
|
self.trigger.set_interface(interface)
|
||||||
self.recorder.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):
|
def get_fragment(self):
|
||||||
comb =[
|
comb =[
|
||||||
|
|
|
@ -6,6 +6,8 @@ from migen.bank.description import *
|
||||||
from migen.genlib.misc import optree
|
from migen.genlib.misc import optree
|
||||||
from migen.genlib.fsm import *
|
from migen.genlib.fsm import *
|
||||||
|
|
||||||
|
from miscope.tools.misc import RisingEdge
|
||||||
|
|
||||||
class Storage:
|
class Storage:
|
||||||
#
|
#
|
||||||
# Definition
|
# Definition
|
||||||
|
@ -49,14 +51,6 @@ class Storage:
|
||||||
self.pull_dat.eq(self._pull_port.dat_r)
|
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 = FSM("IDLE", "ACTIVE")
|
fsm = FSM("IDLE", "ACTIVE")
|
||||||
|
|
||||||
|
@ -64,32 +58,28 @@ class Storage:
|
||||||
fsm.act(fsm.IDLE,
|
fsm.act(fsm.IDLE,
|
||||||
If(self.start,
|
If(self.start,
|
||||||
fsm.next_state(fsm.ACTIVE),
|
fsm.next_state(fsm.ACTIVE),
|
||||||
active_rising.eq(1)
|
)
|
||||||
),
|
|
||||||
idle_ongoing.eq(1)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Active
|
# Active
|
||||||
fsm.act(fsm.ACTIVE,
|
fsm.act(fsm.ACTIVE,
|
||||||
If(self.done | self.rst,
|
If(self.done | self.rst,
|
||||||
fsm.next_state(fsm.IDLE),
|
fsm.next_state(fsm.IDLE),
|
||||||
idle_rising.eq(1)
|
)
|
||||||
),
|
|
||||||
active_ongoing.eq(1)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
sync =[
|
sync =[
|
||||||
If(active_rising,
|
If(fsm.entering(fsm.ACTIVE),
|
||||||
self._push_ptr_stop.eq(self._push_ptr + self.size - self.offset),
|
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(
|
).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:
|
class Sequencer:
|
||||||
#
|
#
|
||||||
|
@ -121,11 +111,6 @@ class Sequencer:
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
|
|
||||||
idle_rising = Signal()
|
|
||||||
idle_ongoing = Signal()
|
|
||||||
active_rising = Signal()
|
|
||||||
active_ongoing = Signal()
|
|
||||||
|
|
||||||
# FSM
|
# FSM
|
||||||
fsm = FSM("IDLE", "ACTIVE")
|
fsm = FSM("IDLE", "ACTIVE")
|
||||||
|
|
||||||
|
@ -133,35 +118,28 @@ class Sequencer:
|
||||||
fsm.act(fsm.IDLE,
|
fsm.act(fsm.IDLE,
|
||||||
If(self.ctl_arm,
|
If(self.ctl_arm,
|
||||||
fsm.next_state(fsm.ACTIVE),
|
fsm.next_state(fsm.ACTIVE),
|
||||||
active_rising.eq(1)
|
)
|
||||||
),
|
|
||||||
idle_ongoing.eq(1)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Active
|
# Active
|
||||||
fsm.act(fsm.ACTIVE,
|
fsm.act(fsm.ACTIVE,
|
||||||
If(self.rec_done,
|
If(self.rec_done | self.ctl_rst,
|
||||||
fsm.next_state(fsm.IDLE),
|
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
|
# trig_hit rising_edge
|
||||||
_hit_d = Signal()
|
hit_rising = RisingEdge(self.hit)
|
||||||
_hit_rising = Signal()
|
|
||||||
sync =[_hit_d.eq(self.hit)]
|
|
||||||
comb +=[_hit_rising.eq(self.hit & ~_hit_d)]
|
|
||||||
|
|
||||||
# connexion
|
# connexion
|
||||||
comb = [
|
comb = [
|
||||||
self.rec_offset.eq(self.ctl_offset),
|
self.rec_offset.eq(self.ctl_offset),
|
||||||
self.rec_size.eq(self.ctl_size),
|
self.rec_size.eq(self.ctl_size),
|
||||||
self.rec_start.eq(self.enable & _hit_rising),
|
self.rec_start.eq(self.enable & hit_rising.o),
|
||||||
self.ctl_done.eq(~self.enable)
|
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_RST_BASE = 0x00
|
||||||
|
@ -170,16 +148,16 @@ REC_DONE_BASE = 0x02
|
||||||
REC_SIZE_BASE = 0x03
|
REC_SIZE_BASE = 0x03
|
||||||
REC_OFFSET_BASE = 0x05
|
REC_OFFSET_BASE = 0x05
|
||||||
REC_READ_BASE = 0x07
|
REC_READ_BASE = 0x07
|
||||||
REC_READ_DATA_BASE = 0x09
|
REC_READ_DATA_BASE = 0x08
|
||||||
|
|
||||||
class Recorder:
|
class Recorder:
|
||||||
#
|
#
|
||||||
# Definition
|
# Definition
|
||||||
#
|
#
|
||||||
def __init__(self, width, depth, address = 0x0000, interface = None):
|
def __init__(self, width, depth, address=0x0000, interface=None):
|
||||||
self.width = width
|
self.width = width
|
||||||
self.depth = depth
|
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.storage = Storage(self.width, self.depth)
|
||||||
self.sequencer = Sequencer(self.depth)
|
self.sequencer = Sequencer(self.depth)
|
||||||
|
@ -200,8 +178,6 @@ class Recorder:
|
||||||
self.regs = [self._rst, self._arm, self._done, self._size, self._offset,
|
self.regs = [self._rst, self._arm, self._done, self._size, self._offset,
|
||||||
self._pull_stb, self._pull_dat]
|
self._pull_stb, self._pull_dat]
|
||||||
|
|
||||||
self.bank = csrgen.Bank(self.regs, address=address)
|
|
||||||
|
|
||||||
# set address / interface
|
# set address / interface
|
||||||
self.set_address(address)
|
self.set_address(address)
|
||||||
self.set_interface(interface)
|
self.set_interface(interface)
|
||||||
|
@ -212,19 +188,14 @@ class Recorder:
|
||||||
|
|
||||||
def set_address(self, address):
|
def set_address(self, address):
|
||||||
self.address = 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):
|
def set_interface(self, interface):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
|
|
||||||
def get_fragment(self):
|
def get_fragment(self):
|
||||||
_pull_stb_d = Signal()
|
|
||||||
_pull_stb_rising = Signal()
|
|
||||||
|
|
||||||
sync = [
|
_pull_stb_rising = RisingEdge(self._pull_stb.field.r)
|
||||||
_pull_stb_d.eq(self._pull_stb.field.r),
|
|
||||||
_pull_stb_rising.eq(self._pull_stb.field.r & ~_pull_stb_d)
|
|
||||||
]
|
|
||||||
|
|
||||||
# Bank <--> Storage / Sequencer
|
# Bank <--> Storage / Sequencer
|
||||||
comb = [
|
comb = [
|
||||||
|
@ -237,7 +208,7 @@ class Recorder:
|
||||||
|
|
||||||
self._done.field.w.eq(self.sequencer.ctl_done),
|
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._pull_dat.field.w.eq(self.storage.pull_dat)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -254,33 +225,34 @@ class Recorder:
|
||||||
self.storage.push_dat.eq(self.dat)
|
self.storage.push_dat.eq(self.dat)
|
||||||
]
|
]
|
||||||
|
|
||||||
return self.bank.get_fragment() + Fragment(comb, sync) +\
|
return self.bank.get_fragment() + Fragment(comb) +\
|
||||||
self.storage.get_fragment() + self.sequencer.get_fragment()
|
self.storage.get_fragment() + self.sequencer.get_fragment() +\
|
||||||
|
_pull_stb_rising.get_fragment()
|
||||||
|
|
||||||
#
|
#
|
||||||
#Driver
|
#Driver
|
||||||
#
|
#
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.interface.write(self.address + REC_RST_BASE, 1)
|
self.interface.write(self.bank.get_base() + REC_RST_BASE, 1)
|
||||||
self.interface.write(self.address + REC_RST_BASE, 0)
|
self.interface.write(self.bank.get_base() + REC_RST_BASE, 0)
|
||||||
|
|
||||||
def arm(self):
|
def arm(self):
|
||||||
self.interface.write(self.address + REC_ARM_BASE, 1)
|
self.interface.write(self.bank.get_base() + REC_ARM_BASE, 1)
|
||||||
self.interface.write(self.address + REC_ARM_BASE, 0)
|
self.interface.write(self.bank.get_base() + REC_ARM_BASE, 0)
|
||||||
|
|
||||||
def is_done(self):
|
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):
|
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):
|
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):
|
def read(self, size):
|
||||||
r = []
|
r = []
|
||||||
for i in range(size):
|
for i in range(size):
|
||||||
self.interface.write(self.address + REC_READ_BASE, 1)
|
self.interface.write(self.bank.get_base() + REC_READ_BASE, 1)
|
||||||
self.interface.write(self.address + REC_READ_BASE, 0)
|
self.interface.write(self.bank.get_base() + REC_READ_BASE, 0)
|
||||||
r.append(self.interface.read_n(self.address + REC_READ_DATA_BASE, self.width))
|
r.append(self.interface.read_n(self.bank.get_base() + REC_READ_DATA_BASE, self.width))
|
||||||
return r
|
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 *
|
from miscope.tools.conv import *
|
||||||
|
|
||||||
def get_bits(values, width, low, high =None):
|
def get_bits(values, width, low, high=None):
|
||||||
r = []
|
r = []
|
||||||
for val in values:
|
for val in values:
|
||||||
t = dec2bin(val,width)[::-1]
|
t = dec2bin(val, width)[::-1]
|
||||||
if high == None:
|
if high == None:
|
||||||
t = t[low]
|
t = t[low]
|
||||||
else:
|
else:
|
||||||
|
@ -16,8 +16,32 @@ def get_bits(values, width, low, high =None):
|
||||||
r.append(t)
|
r.append(t)
|
||||||
return r
|
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:
|
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.type = type
|
||||||
self.width = width
|
self.width = width
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -36,7 +60,7 @@ class Var:
|
||||||
try :
|
try :
|
||||||
if self.values[cnt+1] != self.val:
|
if self.values[cnt+1] != self.val:
|
||||||
r += "b"
|
r += "b"
|
||||||
r += dec2bin(self.values[cnt+1], self.width)
|
r += dec2bin(self.values[cnt+1], self.width)[::-1]
|
||||||
r += " "
|
r += " "
|
||||||
r += self.vcd_id
|
r += self.vcd_id
|
||||||
r += "\n"
|
r += "\n"
|
||||||
|
@ -45,9 +69,8 @@ class Var:
|
||||||
return r
|
return r
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
class Vcd:
|
class Vcd:
|
||||||
def __init__(self,timescale = "1ps", comment = ""):
|
def __init__(self, timescale="1ps", comment=""):
|
||||||
self.timescale = timescale
|
self.timescale = timescale
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
self.vars = []
|
self.vars = []
|
||||||
|
@ -59,6 +82,12 @@ class Vcd:
|
||||||
self.vcd_id = chr(ord(self.vcd_id)+1)
|
self.vcd_id = chr(ord(self.vcd_id)+1)
|
||||||
self.vars.append(var)
|
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):
|
def __len__(self):
|
||||||
l = 0
|
l = 0
|
||||||
for var in self.vars:
|
for var in self.vars:
|
||||||
|
@ -77,7 +106,6 @@ class Vcd:
|
||||||
r += c
|
r += c
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
def p_date(self):
|
def p_date(self):
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
r = "$date\n"
|
r = "$date\n"
|
||||||
|
@ -110,6 +138,7 @@ class Vcd:
|
||||||
r += self.timescale
|
r += self.timescale
|
||||||
r += " $end\n"
|
r += " $end\n"
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def p_vars(self):
|
def p_vars(self):
|
||||||
r = ""
|
r = ""
|
||||||
for var in self.vars:
|
for var in self.vars:
|
||||||
|
@ -152,7 +181,6 @@ class Vcd:
|
||||||
self.cnt += 1
|
self.cnt += 1
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
r = ""
|
r = ""
|
||||||
r += self.p_date()
|
r += self.p_date()
|
||||||
|
@ -174,12 +202,12 @@ class Vcd:
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
myvcd = Vcd()
|
myvcd = Vcd()
|
||||||
myvcd.add(Var("wire", 1, "foo1", [0,1,0,1,0,1]))
|
myvcd.add(Var(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(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(3, "foo3"))
|
||||||
myvcd.add(Var("wire", 4, "foo4"))
|
myvcd.add(Var(4, "foo4"))
|
||||||
ramp = [i%128 for i in range(1024)]
|
ramp = [i%128 for i in range(1024)]
|
||||||
myvcd.add(Var("wire", 16, "ramp", ramp))
|
myvcd.add(Var(16, "ramp", ramp))
|
||||||
print(myvcd)
|
print(myvcd)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -55,8 +55,8 @@ class Term:
|
||||||
def write(self, dat, mask=None):
|
def write(self, dat, mask=None):
|
||||||
if mask is None:
|
if mask is None:
|
||||||
mask = (2**self.width)-1
|
mask = (2**self.width)-1
|
||||||
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)
|
self.interface.write_n(self.reg_p.base, mask, self.width)
|
||||||
|
self.interface.write_n(self.reg_p.base + self.reg_p.words, dat, self.width)
|
||||||
|
|
||||||
class RangeDetector:
|
class RangeDetector:
|
||||||
#
|
#
|
||||||
|
@ -144,13 +144,13 @@ class EdgeDetector:
|
||||||
|
|
||||||
# Falling Edge
|
# Falling Edge
|
||||||
if "F" in self.mode:
|
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:
|
else:
|
||||||
comb += [self.fo.eq(0)]
|
comb += [self.fo.eq(0)]
|
||||||
|
|
||||||
# Both
|
# Both
|
||||||
if "B" in self.mode:
|
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:
|
else:
|
||||||
comb += [self.bo.eq(0)]
|
comb += [self.bo.eq(0)]
|
||||||
|
|
||||||
|
@ -243,8 +243,8 @@ class Sum:
|
||||||
we = 1<<17
|
we = 1<<17
|
||||||
dat = val<<16
|
dat = val<<16
|
||||||
addr = i
|
addr = i
|
||||||
self.interface.write_n(self.reg_p.base, we + 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_size)
|
self.interface.write_n(self.reg_p.base, dat + addr, self.reg_p.size)
|
||||||
|
|
||||||
class Trigger:
|
class Trigger:
|
||||||
#
|
#
|
||||||
|
@ -283,7 +283,7 @@ class Trigger:
|
||||||
|
|
||||||
def set_address(self, address):
|
def set_address(self, address):
|
||||||
self.address = 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:
|
for port in self.ports:
|
||||||
port.reg_p.base = self.bank.get_base(port.reg_p.name)
|
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)
|
self.sum.reg_p.base = self.bank.get_base(self.sum.reg_p.name)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
from migen.fhdl import verilog, autofragment
|
from migen.fhdl import verilog
|
||||||
from migen.bus import csr
|
from migen.bus import csr
|
||||||
from migen.sim.generic import Simulator, PureSimulable, TopLevel
|
from migen.sim.generic import Simulator, PureSimulable, TopLevel
|
||||||
from migen.sim.icarus import Runner
|
from migen.sim.icarus import Runner
|
||||||
|
@ -8,7 +8,7 @@ from migen.bus.transactions import *
|
||||||
from miscope import recorder
|
from miscope import recorder
|
||||||
|
|
||||||
arm_done = False
|
arm_done = False
|
||||||
trig_dat = 0
|
dat = 0
|
||||||
|
|
||||||
rec_done = False
|
rec_done = False
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ def csr_transactions():
|
||||||
|
|
||||||
#Arm
|
#Arm
|
||||||
yield TWrite(1, 1)
|
yield TWrite(1, 1)
|
||||||
|
yield TWrite(1, 0)
|
||||||
|
|
||||||
for t in range(10):
|
for t in range(10):
|
||||||
yield None
|
yield None
|
||||||
|
@ -62,42 +63,45 @@ def main():
|
||||||
csr_master0 = csr.Initiator(csr_transactions())
|
csr_master0 = csr.Initiator(csr_transactions())
|
||||||
|
|
||||||
# Recorder
|
# Recorder
|
||||||
recorder0 = recorder.Recorder(0, 32, 1024)
|
recorder0 = recorder.Recorder(32, 1024)
|
||||||
|
|
||||||
# Csr Interconnect
|
# Csr Interconnect
|
||||||
csrcon0 = csr.Interconnect(csr_master0.bus,
|
csrcon0 = csr.Interconnect(csr_master0.bus,
|
||||||
[
|
[
|
||||||
recorder0.bank.interface
|
recorder0.bank.bus
|
||||||
])
|
])
|
||||||
|
|
||||||
# Recorder Data
|
# Recorder Data
|
||||||
def recorder_data(s):
|
def recorder_data(s):
|
||||||
global arm_done
|
global arm_done
|
||||||
if arm_done:
|
if arm_done:
|
||||||
s.wr(recorder0.trig_hit, 1)
|
s.wr(recorder0.hit, 1)
|
||||||
arm_done = False
|
arm_done = False
|
||||||
|
|
||||||
global trig_dat
|
global dat
|
||||||
s.wr(recorder0.trig_dat,trig_dat)
|
s.wr(recorder0.dat,dat)
|
||||||
trig_dat += 1
|
dat += 1
|
||||||
|
|
||||||
global rec_done
|
global rec_done
|
||||||
if s.rd(recorder0.sequencer.rec_done) == 1:
|
if s.rd(recorder0.sequencer.rec_done) == 1:
|
||||||
rec_done = True
|
rec_done = True
|
||||||
|
|
||||||
if dat_rdy:
|
if dat_rdy:
|
||||||
print("%08X" %s.rd(recorder0._get_dat.field.w))
|
print("%08X" %s.rd(recorder0._pull_dat.field.w))
|
||||||
|
|
||||||
|
|
||||||
# Simulation
|
# Simulation
|
||||||
def end_simulation(s):
|
def end_simulation(s):
|
||||||
s.interrupt = csr_master0.done
|
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=[end_simulation])
|
||||||
fragment += Fragment(sim=[recorder_data])
|
fragment += Fragment(sim=[recorder_data])
|
||||||
sim = Simulator(fragment, Runner(), TopLevel("tb_RecorderCsr.vcd"))
|
sim = Simulator(fragment, TopLevel("tb_RecorderCsr.vcd"))
|
||||||
sim.run(10000)
|
sim.run(10000)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
print("Sim Done")
|
||||||
input()
|
input()
|
|
@ -1,5 +1,5 @@
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
from migen.fhdl import verilog, autofragment
|
from migen.fhdl import verilog
|
||||||
from migen.bus import csr
|
from migen.bus import csr
|
||||||
from migen.sim.generic import Simulator, PureSimulable, TopLevel
|
from migen.sim.generic import Simulator, PureSimulable, TopLevel
|
||||||
from migen.sim.icarus import Runner
|
from migen.sim.icarus import Runner
|
||||||
|
@ -27,10 +27,14 @@ csr_done = False
|
||||||
def csr_transactions():
|
def csr_transactions():
|
||||||
|
|
||||||
term_trans = []
|
term_trans = []
|
||||||
term_trans += [term_prog(0x04 ,0xDEADBEEF)]
|
term_trans += [term_prog(0x04+0 ,0xFFFFFFFF)]
|
||||||
term_trans += [term_prog(0x08 ,0xCAFEFADE)]
|
term_trans += [term_prog(0x04+4 ,0xDEADBEEF)]
|
||||||
term_trans += [term_prog(0x0C ,0xDEADBEEF)]
|
term_trans += [term_prog(0x04+8 ,0xFFFFFFFF)]
|
||||||
term_trans += [term_prog(0x10 ,0xCAFEFADE)]
|
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 t in term_trans:
|
||||||
for r in t:
|
for r in t:
|
||||||
yield r
|
yield r
|
||||||
|
@ -67,12 +71,12 @@ def main():
|
||||||
term1 = trigger.Term(32)
|
term1 = trigger.Term(32)
|
||||||
term2 = trigger.Term(32)
|
term2 = trigger.Term(32)
|
||||||
term3 = 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
|
# Csr Interconnect
|
||||||
csrcon0 = csr.Interconnect(csr_master0.bus,
|
csrcon0 = csr.Interconnect(csr_master0.bus,
|
||||||
[
|
[
|
||||||
trigger0.bank.interface
|
trigger0.bank.bus
|
||||||
])
|
])
|
||||||
|
|
||||||
# Term Test
|
# Term Test
|
||||||
|
@ -88,13 +92,20 @@ def main():
|
||||||
def end_simulation(s):
|
def end_simulation(s):
|
||||||
s.interrupt = csr_master0.done
|
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=[end_simulation])
|
||||||
fragment += Fragment(sim=[term_stimuli])
|
fragment += Fragment(sim=[term_stimuli])
|
||||||
sim = Simulator(fragment, Runner(), TopLevel("tb_TriggerCsr.vcd"))
|
sim = Simulator(fragment, TopLevel("tb_TriggerCsr.vcd"))
|
||||||
sim.run(2000)
|
sim.run(2000)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
print("Sim Done")
|
||||||
input()
|
input()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from migen.fhdl.structure import *
|
from migen.fhdl.structure import *
|
||||||
from migen.fhdl import verilog, autofragment
|
from migen.fhdl import verilog
|
||||||
from migen.bus import csr
|
from migen.bus import csr
|
||||||
from migen.sim.generic import Simulator, PureSimulable, TopLevel
|
from migen.sim.generic import Simulator, PureSimulable, TopLevel
|
||||||
from migen.sim.icarus import Runner
|
from migen.sim.icarus import Runner
|
||||||
|
@ -38,10 +38,14 @@ def csr_transactions(trigger0, recorder0):
|
||||||
|
|
||||||
# Term Prog
|
# Term Prog
|
||||||
term_trans = []
|
term_trans = []
|
||||||
term_trans += [term_prog(trigger0.ports[0].reg_base, 0x00000000)]
|
term_trans += [term_prog(trigger0.ports[0].reg_p.base+0, 0xFFFFFFFF)]
|
||||||
term_trans += [term_prog(trigger0.ports[1].reg_base, 0x00000004)]
|
term_trans += [term_prog(trigger0.ports[0].reg_p.base+4, 0x00000000)]
|
||||||
term_trans += [term_prog(trigger0.ports[2].reg_base, 0x00000008)]
|
term_trans += [term_prog(trigger0.ports[1].reg_p.base+0, 0xFFFFFFFF)]
|
||||||
term_trans += [term_prog(trigger0.ports[3].reg_base, 0x0000000C)]
|
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 t in term_trans:
|
||||||
for r in t:
|
for r in t:
|
||||||
yield r
|
yield r
|
||||||
|
@ -50,7 +54,7 @@ def csr_transactions(trigger0, recorder0):
|
||||||
sum_tt = gen_truth_table("term0 | term1 | term2 | term3")
|
sum_tt = gen_truth_table("term0 | term1 | term2 | term3")
|
||||||
sum_trans = []
|
sum_trans = []
|
||||||
for i in range(len(sum_tt)):
|
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 t in sum_trans:
|
||||||
for r in t:
|
for r in t:
|
||||||
yield r
|
yield r
|
||||||
|
@ -71,6 +75,7 @@ def csr_transactions(trigger0, recorder0):
|
||||||
|
|
||||||
#Arm
|
#Arm
|
||||||
yield TWrite(recorder0.address + 1, 1)
|
yield TWrite(recorder0.address + 1, 1)
|
||||||
|
yield TWrite(recorder0.address + 1, 0)
|
||||||
|
|
||||||
# Wait Record to be done
|
# Wait Record to be done
|
||||||
##############################
|
##############################
|
||||||
|
@ -107,10 +112,10 @@ def main():
|
||||||
term1 = trigger.Term(32)
|
term1 = trigger.Term(32)
|
||||||
term2 = trigger.Term(32)
|
term2 = trigger.Term(32)
|
||||||
term3 = 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
|
# Recorder
|
||||||
recorder0 = recorder.Recorder(RECORDER_ADDR, 32, 1024)
|
recorder0 = recorder.Recorder(32, 1024, address=RECORDER_ADDR)
|
||||||
|
|
||||||
# Csr Master
|
# Csr Master
|
||||||
csr_master0 = csr.Initiator(csr_transactions(trigger0, recorder0))
|
csr_master0 = csr.Initiator(csr_transactions(trigger0, recorder0))
|
||||||
|
@ -118,19 +123,18 @@ def main():
|
||||||
# Csr Interconnect
|
# Csr Interconnect
|
||||||
csrcon0 = csr.Interconnect(csr_master0.bus,
|
csrcon0 = csr.Interconnect(csr_master0.bus,
|
||||||
[
|
[
|
||||||
trigger0.bank.interface,
|
trigger0.bank.bus,
|
||||||
recorder0.bank.interface
|
recorder0.bank.bus
|
||||||
])
|
])
|
||||||
|
|
||||||
trig_sig = Signal(32)
|
trig_sig = Signal(32)
|
||||||
comb = []
|
comb =[
|
||||||
comb +=[
|
trigger0.trig.eq(trig_sig)
|
||||||
trigger0.in_trig.eq(trig_sig)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
comb += [
|
comb += [
|
||||||
recorder0.trig_dat.eq(trig_sig),
|
recorder0.dat.eq(trig_sig),
|
||||||
recorder0.trig_hit.eq(trigger0.hit)
|
recorder0.hit.eq(trigger0.hit)
|
||||||
]
|
]
|
||||||
# Term Test
|
# Term Test
|
||||||
def term_stimuli(s):
|
def term_stimuli(s):
|
||||||
|
@ -147,9 +151,9 @@ def main():
|
||||||
|
|
||||||
global dat_rdy
|
global dat_rdy
|
||||||
if 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
|
global dat_vcd
|
||||||
dat_vcd.append(s.rd(recorder0._get_dat.field.w))
|
dat_vcd.append(s.rd(recorder0._pull_dat.field.w))
|
||||||
|
|
||||||
|
|
||||||
# Simulation
|
# Simulation
|
||||||
|
@ -157,19 +161,27 @@ def main():
|
||||||
s.interrupt = csr_master0.done
|
s.interrupt = csr_master0.done
|
||||||
myvcd = Vcd()
|
myvcd = Vcd()
|
||||||
myvcd.add(Var("wire", 32, "trig_dat", dat_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.write(str(myvcd))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
fragment = term0.get_fragment()
|
||||||
|
fragment += term1.get_fragment()
|
||||||
|
fragment += term2.get_fragment()
|
||||||
|
fragment += term3.get_fragment()
|
||||||
|
fragment += trigger0.get_fragment()
|
||||||
|
fragment += recorder0.get_fragment()
|
||||||
|
fragment += csr_master0.get_fragment()
|
||||||
|
fragment += csrcon0.get_fragment()
|
||||||
|
|
||||||
fragment = autofragment.from_local()
|
|
||||||
fragment += Fragment(comb=comb)
|
fragment += Fragment(comb=comb)
|
||||||
fragment += Fragment(sim=[term_stimuli])
|
fragment += Fragment(sim=[term_stimuli])
|
||||||
fragment += Fragment(sim=[recorder_data])
|
fragment += Fragment(sim=[recorder_data])
|
||||||
fragment += Fragment(sim=[end_simulation])
|
fragment += Fragment(sim=[end_simulation])
|
||||||
|
|
||||||
sim = Simulator(fragment, Runner(),TopLevel("tb_MigScope.vcd"))
|
sim = Simulator(fragment, TopLevel("tb_miscope.vcd"))
|
||||||
sim.run(2000)
|
sim.run(2000)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
print("Sim Done")
|
||||||
input()
|
input()
|
||||||
|
|
Loading…
Reference in a new issue