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