refactoring

This commit is contained in:
Florent Kermarrec 2013-09-21 13:04:07 +02:00
parent 89a8d8daf3
commit ce9bff21e9
36 changed files with 753 additions and 1896 deletions

View file

@ -1,11 +1,10 @@
all: build/top.sta all: build/soc-de0nano.sta
build/top.sta: build/soc-de0nano.sta:
./build.py ./make.py
load: 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: clean:
rm -rf build/* rm -rf build/*

View file

@ -1,22 +0,0 @@
#!/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()

View file

@ -1,23 +1,31 @@
from miscope import miio 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 # P A R A M E T E R S
#============================================================================== #==============================================================================
csr = Uart2Csr(3,115200) uart = Uart2Csr(3, 115200)
# Csr Addr class MiIoCtrl():
MIIO_ADDR = 0x00 def __init__(self, bus):
self.bus = bus
def write(self, value):
miio_o_write(self.bus, value)
# Miscope Configuration def read(self):
miio = miio.MiIo(MIIO_ADDR, 8, "IO", csr) return miio_i_read(self.bus)
miio = MiIoCtrl(uart)
def led_anim0(): def led_anim0():
for i in range(10): for i in range(10):
miio.set(0xA5) miio.write(0xA5)
time.sleep(0.1) time.sleep(0.1)
miio.set(0x5A) miio.write(0x5A)
time.sleep(0.1) time.sleep(0.1)
def led_anim1(): def led_anim1():
@ -25,18 +33,18 @@ def led_anim1():
#Led << #Led <<
ledData = 1 ledData = 1
for i in range(8): for i in range(8):
miio.set(ledData) miio.write(ledData)
time.sleep(i*i*0.0020) time.sleep(i*i*0.0020)
ledData = (ledData<<1) ledData = (ledData<<1)
#Led >> #Led >>
ledData = 128 ledData = 128
for i in range(8): for i in range(8):
miio.set(ledData) miio.write(ledData)
time.sleep(i*i*0.0020) time.sleep(i*i*0.0020)
ledData = (ledData>>1) ledData = (ledData>>1)
#============================================================================== #==============================================================================
# T E S T M I G I O # T E S T M I I O
#============================================================================== #==============================================================================
print("- Led Animation...") print("- Led Animation...")
@ -46,4 +54,4 @@ led_anim1()
time.sleep(1) time.sleep(1)
print("- Read Switch: ",end=' ') print("- Read Switch: ",end=' ')
print("%02X" %miio.get()) print("%02X" %miio.read())

View file

@ -1,61 +1,79 @@
from miscope import trigger, recorder, miio, mila from miscope import mila
from miscope.tools.truthtable import * from miscope.std.truthtable import *
from miscope.tools.vcd import * from miscope.std.vcd import *
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 # 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 # Mila Param
trig_w = 16 trig_w = 16
dat_w = 16 dat_w = 16
rec_size = 512 rec_length = 512
rec_offset = 32 rec_offset = 0
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)
#============================================================================== #==============================================================================
# T E S T M I G L A # T E S T M I L A
#============================================================================== #==============================================================================
dat_vcd = VcdDat(dat_w) dat_vcd = VcdDat(dat_w)
def capture(size): mila = MiLaCtrl(uart)
def capture():
global dat_vcd global dat_vcd
sum_tt = gen_truth_table("term") sum_tt = gen_truth_table("term")
mila.trigger.sum.set(sum_tt) mila.prog_sum(sum_tt)
mila.recorder.reset() mila.trigger(rec_offset, rec_length)
if enable_rle: print("-Recorder [Triggered]")
mila.recorder.enable_rle()
recorder.set_size(rec_size)
mila.recorder.set_offset(rec_offset)
mila.recorder.arm()
print("-Recorder [Armed]")
print("-Waiting Trigger...", end=' ') print("-Waiting Trigger...", end=' ')
while(not mila.recorder.is_done()): while(not mila.is_done()):
time.sleep(0.1) time.sleep(0.1)
print("[Done]") print("[Done]")
print("-Receiving Data...", end=' ') print("-Receiving Data...", end=' ')
sys.stdout.flush() sys.stdout.flush()
dat_vcd += mila.recorder.pull(rec_size) dat_vcd += mila.read()
print("[Done]") print("[Done]")
print("Capturing ...") print("Capturing ...")
print("----------------------") print("----------------------")
term.set(0x0000, 0xFFFF) mila.prog_term(0x0000, 0xFFFF)
capture(rec_size) capture()
mila_layout = [ mila_layout = [
("freqgen", 1), ("freqgen", 1),
@ -64,9 +82,6 @@ mila_layout = [
("cnt", 8), ("cnt", 8),
] ]
if enable_rle:
dat_vcd = dat_vcd.decode_rle()
myvcd = Vcd() myvcd = Vcd()
myvcd.add_from_layout(mila_layout, dat_vcd) myvcd.add_from_layout(mila_layout, dat_vcd)
myvcd.write("test_mila.vcd") myvcd.write("test_mila.vcd")

42
examples/de0_nano/make.py Normal file
View file

@ -0,0 +1,42 @@
#!/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()

View file

@ -14,13 +14,16 @@
#============================================================================== #==============================================================================
# I M P O R T # I M P O R T
#============================================================================== #==============================================================================
from migen.fhdl.structure import * from migen.fhdl.std import *
from migen.fhdl.module import *
from migen.bus import csr from migen.bus import csr
from migen.bank import csrgen
from miscope.std.misc import *
from miscope import trigger, recorder, miio, mila from miscope.triggering import *
from miscope.bridges import uart2csr from miscope.recording import *
from miscope.tools.misc import * from miscope import miio, mila
from miscope.com import uart2csr
from timings import * from timings import *
@ -31,10 +34,6 @@ from timings import *
# Timings Param # Timings Param
clk_freq = 50*MHz clk_freq = 50*MHz
# Csr Addr
MIIO_ADDR = 0x00
MILA_ADDR = 0x01
# Mila Param # Mila Param
trig_w = 16 trig_w = 16
dat_w = 16 dat_w = 16
@ -44,16 +43,23 @@ rec_size = 4096
# M I S C O P E E X A M P L E # M I S C O P E E X A M P L E
#============================================================================== #==============================================================================
class SoC(Module): class SoC(Module):
csr_base = 0xe0000000
csr_map = {
"miio": 1,
"mila": 2,
}
def __init__(self, platform): def __init__(self, platform):
# MiIo # MiIo
self.submodules.miio = miio.MiIo(MIIO_ADDR, 8, "IO") self.submodules.miio = miio.MiIo(8)
# MiLa # MiLa
self.submodules.term = trigger.Term(trig_w) term = Term(trig_w)
self.submodules.trigger = trigger.Trigger(trig_w, [self.term]) trigger = Trigger(trig_w, [term])
self.submodules.recorder = recorder.Recorder(dat_w, rec_size) 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 # Uart2Csr
self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200) self.submodules.uart2csr = uart2csr.Uart2Csr(clk_freq, 115200)
@ -62,15 +68,12 @@ class SoC(Module):
self.comb += self.uart2csr.rx.eq(uart_pads.rx) self.comb += self.uart2csr.rx.eq(uart_pads.rx)
# Csr Interconnect # Csr Interconnect
self.submodules.csrcon = csr.Interconnect(self.uart2csr.csr, self.submodules.csrbankarray = csrgen.BankArray(self,
[ lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override])
self.miio.bank.bus, self.submodules.csrcon = csr.Interconnect(self.uart2csr.csr, self.csrbankarray.get_buses())
self.trigger.bank.bus,
self.recorder.bank.bus
])
# Led # Led
self.led = platform.request("user_led", 0, 8) self.led = Cat(*[platform.request("user_led", i) for i in range(8)])
# Misc # Misc
self.cnt = Signal(9) self.cnt = Signal(9)
@ -94,7 +97,8 @@ class SoC(Module):
# Mila # Mila
# #
self.comb +=[ self.comb +=[
self.mila.trig.eq(Cat( self.mila.sink.stb.eq(1),
self.mila.sink.payload.d.eq(Cat(
self.freqgen.o, self.freqgen.o,
self.eventgen_rising.o, self.eventgen_rising.o,
self.eventgen_falling.o, self.eventgen_falling.o,

View file

@ -1,135 +0,0 @@
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)
]

View file

@ -1,59 +0,0 @@
/*
* 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();
}

View file

@ -1,28 +0,0 @@
/*
* 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

View file

@ -1,51 +0,0 @@
/*
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();
}
}
}

View file

@ -1,56 +0,0 @@
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))

View file

@ -1,9 +1,9 @@
from migen.fhdl.structure import * from migen.fhdl.structure import *
from migen.fhdl.module import * from migen.fhdl.module import *
from migen.bus import csr from migen.bus import csr
from migen.genlib.fsm import * from migen.genlib.fsm import FSM, NextState
from miscope.bridges.uart2csr.uart import * from miscope.com.uart2csr.uart import *
WRITE_CMD = 0x01 WRITE_CMD = 0x01
READ_CMD = 0x02 READ_CMD = 0x02
@ -39,10 +39,7 @@ class Uart2Csr(Module):
data = Signal(8) data = Signal(8)
# FSM # FSM
self.submodules.fsm = FSM("IDLE", self.submodules.fsm = FSM(reset_state="IDLE")
"GET_BL", "GET_ADDR",
"GET_DATA", "WRITE_CSR",
"READ_CSR0", "READ_CSR1", "SEND_DATA")
fsm = self.fsm fsm = self.fsm
@ -50,7 +47,7 @@ class Uart2Csr(Module):
# Global # Global
# #
self.sync +=[ self.sync +=[
If(fsm.ongoing(fsm.IDLE), cnt.eq(0) If(fsm.ongoing("IDLE"), cnt.eq(0)
).Elif(uart.rx_ev, cnt.eq(cnt + 1)), ).Elif(uart.rx_ev, cnt.eq(cnt + 1)),
If(uart.rx_ev, sr.eq(Cat(uart.rx_dat, sr[0:24]))) If(uart.rx_ev, sr.eq(Cat(uart.rx_dat, sr[0:24])))
@ -66,45 +63,45 @@ class Uart2Csr(Module):
# #
# Idle # Idle
# #
fsm.act(fsm.IDLE, fsm.act("IDLE",
If(uart.rx_ev & ((uart.rx_dat == WRITE_CMD) | (uart.rx_dat == READ_CMD)), If(uart.rx_ev & ((uart.rx_dat == WRITE_CMD) | (uart.rx_dat == READ_CMD)),
fsm.next_state(fsm.GET_BL) NextState("GET_BL")
) )
) )
self.sync += If(fsm.ongoing(fsm.IDLE) & uart.rx_ev, cmd.eq(uart.rx_dat)) self.sync += If(fsm.ongoing("IDLE") & uart.rx_ev, cmd.eq(uart.rx_dat))
# #
# Get burst length # Get burst length
# #
fsm.act(fsm.GET_BL, fsm.act("GET_BL",
If(get_bl_done, If(get_bl_done,
fsm.next_state(fsm.GET_ADDR) NextState("GET_ADDR")
) )
) )
self.comb += get_bl_done.eq(uart.rx_ev & fsm.ongoing(fsm.GET_BL)) 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)) self.sync += If(get_bl_done, burst_cnt.eq(uart.rx_dat))
# #
# Get address # Get address
# #
fsm.act(fsm.GET_ADDR, fsm.act("GET_ADDR",
If(get_addr_done & (cmd == WRITE_CMD), If(get_addr_done & (cmd == WRITE_CMD),
fsm.next_state(fsm.GET_DATA) NextState("GET_DATA")
).Elif(get_addr_done & (cmd == READ_CMD), ).Elif(get_addr_done & (cmd == READ_CMD),
fsm.next_state(fsm.READ_CSR0) NextState("READ_CSR0")
) )
) )
self.comb += get_addr_done.eq(uart.rx_ev & (cnt == 4) & fsm.ongoing(fsm.GET_ADDR)) 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 += get_addr_done_d.eq(get_addr_done)
self.sync += [ self.sync += [
If(get_addr_done_d, If(get_addr_done_d,
addr.eq(sr) addr.eq(sr)
).Elif(fsm.leaving(fsm.WRITE_CSR) | send_data_done, ).Elif(fsm.leaving("WRITE_CSR") | send_data_done,
addr.eq(addr + 1) addr.eq(addr + 1)
) )
] ]
@ -112,13 +109,13 @@ class Uart2Csr(Module):
# #
# Get data # Get data
# #
fsm.act(fsm.GET_DATA, fsm.act("GET_DATA",
If(get_data_done, If(get_data_done,
fsm.next_state(fsm.WRITE_CSR) NextState("WRITE_CSR")
) )
) )
self.comb += get_data_done.eq(uart.rx_ev & fsm.ongoing(fsm.GET_DATA)) self.comb += get_data_done.eq(uart.rx_ev & fsm.ongoing("GET_DATA"))
self.sync += [ self.sync += [
If(get_data_done, If(get_data_done,
burst_cnt.eq(burst_cnt-1), burst_cnt.eq(burst_cnt-1),
@ -129,46 +126,46 @@ class Uart2Csr(Module):
# #
# Write Csr # Write Csr
# #
fsm.act(fsm.WRITE_CSR, fsm.act("WRITE_CSR",
If((burst_cnt==0), If((burst_cnt==0),
fsm.next_state(fsm.IDLE) NextState("IDLE")
).Else(fsm.next_state(fsm.GET_DATA)) ).Else(NextState("GET_DATA"))
) )
# #
# Read Csr0 # Read Csr0
# #
fsm.act(fsm.READ_CSR0, fsm.act("READ_CSR0",
fsm.next_state(fsm.READ_CSR1) NextState("READ_CSR1")
) )
self.sync += If(fsm.entering(fsm.READ_CSR0), burst_cnt.eq(burst_cnt-1)) self.sync += If(fsm.entering("READ_CSR0"), burst_cnt.eq(burst_cnt-1))
# #
# Read Csr1 # Read Csr1
# #
fsm.act(fsm.READ_CSR1, fsm.act("READ_CSR1",
fsm.next_state(fsm.SEND_DATA) NextState("SEND_DATA")
) )
# #
# Send Data # Send Data
# #
fsm.act(fsm.SEND_DATA, fsm.act("SEND_DATA",
If(send_data_done & (burst_cnt==0), If(send_data_done & (burst_cnt==0),
fsm.next_state(fsm.IDLE) NextState("IDLE")
).Elif(send_data_done, ).Elif(send_data_done,
fsm.next_state(fsm.READ_CSR0) NextState("READ_CSR0")
) )
) )
self.comb += send_data_done.eq(fsm.ongoing(fsm.SEND_DATA) & uart.tx_ev) self.comb += send_data_done.eq(fsm.ongoing("SEND_DATA") & uart.tx_ev)
self.sync += [ self.sync += [
uart.tx_dat.eq(self.csr.dat_r), uart.tx_dat.eq(self.csr.dat_r),
uart.tx_we.eq(fsm.entering(fsm.SEND_DATA)), uart.tx_we.eq(fsm.entering("SEND_DATA")),
] ]
@ -178,7 +175,7 @@ class Uart2Csr(Module):
self.comb += self.csr.adr.eq(addr) self.comb += self.csr.adr.eq(addr)
self.sync +=[ self.sync +=[
self.csr.dat_w.eq(data), self.csr.dat_w.eq(data),
If(fsm.ongoing(fsm.WRITE_CSR), If(fsm.ongoing("WRITE_CSR"),
self.csr.we.eq(1) self.csr.we.eq(1)
).Else( ).Else(
self.csr.we.eq(0) self.csr.we.eq(0)

View file

@ -18,10 +18,18 @@ class Uart2Csr:
self.baudrate = baudrate self.baudrate = baudrate
self.debug = debug self.debug = debug
self.uart = serial.Serial(port, baudrate, timeout=0.25) self.uart = serial.Serial(port, baudrate, timeout=0.25)
def read(self, addr, burst_length=1): 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, READ_CMD)
write_b(self.uart, burst_length) write_b(self.uart, burst_length)
addr = addr//4
write_b(self.uart, (addr & 0xff000000) >> 24) write_b(self.uart, (addr & 0xff000000) >> 24)
write_b(self.uart, (addr & 0x00ff0000) >> 16) write_b(self.uart, (addr & 0x00ff0000) >> 16)
write_b(self.uart, (addr & 0x0000ff00) >> 8) write_b(self.uart, (addr & 0x0000ff00) >> 8)
@ -50,13 +58,14 @@ class Uart2Csr:
print("RD @ %04X" %addr) print("RD @ %04X" %addr)
return r return r
def write(self, addr, data): def write_csr(self, addr, data):
if isinstance(data, list): if isinstance(data, list):
burst_length = len(data) burst_length = len(data)
else: else:
burst_length = 1 burst_length = 1
write_b(self.uart, WRITE_CMD) write_b(self.uart, WRITE_CMD)
write_b(self.uart, burst_length) write_b(self.uart, burst_length)
addr = addr//4
self.uart.write([(addr & 0xff000000) >> 24, self.uart.write([(addr & 0xff000000) >> 24,
(addr & 0x00ff0000) >> 16, (addr & 0x00ff0000) >> 16,
(addr & 0x0000ff00) >> 8, (addr & 0x0000ff00) >> 8,

View file

@ -3,44 +3,17 @@ from migen.bus import csr
from migen.bank import csrgen from migen.bank import csrgen
from migen.bank.description import * from migen.bank.description import *
from miscope.tools.misc import * class MiIo(Module, AutoCSR):
def __init__(self, width):
class MiIo:
#
# Definition
#
def __init__(self, address, width, mode="IO", interface=None):
self.address = address
self.width = width self.width = width
self.mode = mode.upper()
self.interface = interface self.i = Signal(self.width)
self.words = int((2**bits_for(width-1))/8) self.o = Signal(self.width)
if "I" in self.mode: self._r_i = CSRStatus(self.width)
self.i = Signal(self.width) self._r_o = CSRStorage(self.width)
self._r_i = CSRStatus(self.width)
self.sync +=[
if "O" in self.mode: self._r_i.status.eq(self.i),
self.o = Signal(self.width) self.o.eq(self._r_o.storage)
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)

View file

@ -1,48 +1,27 @@
from migen.fhdl.structure import * from migen.fhdl.structure import *
from migen.flow.actor import *
from migen.flow.network import *
from migen.bus import csr from migen.bus import csr
from migen.bank import description, csrgen from migen.bank import description, csrgen
from migen.bank.description import * from migen.bank.description import *
from miscope import trigger, recorder class MiLa(Module, AutoCSR):
from miscope.tools.misc import * def __init__(self, trigger, recorder):
class MiLa:
def __init__(self, address, trigger, recorder, interface=None, trig_is_dat=False):
self.trigger = trigger self.trigger = trigger
self.recorder = recorder 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.sink = trigger.sink
self.address = address self.submodules += trigger, recorder
self.trigger.set_address(self.address)
self.recorder.set_address(self.address + 0x01)
def set_interface(self, interface): self.comb +=[
self.interface = interface recorder.sink.stb.eq(trigger.source.stb),
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.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 +=[ # Todo; Insert configurable delay to support pipelined
self.recorder.dat.eq(self.trig), # triggers elements
] self.comb +=[
else: recorder.sink.payload.d.eq(self.sink.payload.d),
self.recorder.dat.eq(self.dat), ]
return Fragment(comb)

View file

@ -1,324 +0,0 @@
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

View file

@ -0,0 +1,86 @@
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),
)
]

94
miscope/std/cif.py Normal file
View file

@ -0,0 +1,94 @@
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

View file

@ -1,15 +1,19 @@
from migen.fhdl.structure import * from migen.fhdl.std import *
from migen.fhdl.module import Module
def ifthenelse(cond, r1, r2):
if cond != False and cond is not None:
return r1
else:
return r2
class RisingEdge(Module): class RisingEdge(Module):
def __init__(self, i=None, o=None, domain="sys"): def __init__(self, i=None, o=None):
self.i = ifthenelse(i, i, Signal()) self.i = ifthenelse(i, i, Signal())
self.o = ifthenelse(o, o, Signal()) self.o = ifthenelse(o, o, Signal())
#### ####
i_d = Signal() i_d = Signal()
sync =[i_d.eq(self.i)] self.sync += i_d.eq(self.i)
self.comb +=[self.o.eq(self.i & ~i_d)] self.comb += self.o.eq(self.i & ~i_d)
self._fragment += Fragment(sync={domain : sync})
class FallingEdge(Module): class FallingEdge(Module):
def __init__(self, i=None, o=None, domain="sys"): def __init__(self, i=None, o=None, domain="sys"):
@ -17,9 +21,8 @@ class FallingEdge(Module):
self.o = ifthenelse(o, o, Signal()) self.o = ifthenelse(o, o, Signal())
#### ####
i_d = Signal() i_d = Signal()
sync =[i_d.eq(self.i)] self.sync += i_d.eq(self.i)
self.comb +=[self.o.eq(~self.i & i_d)] self.comb += self.o.eq(~self.i & i_d)
self._fragment += Fragment(sync={domain : sync})
class FreqGen(Module): class FreqGen(Module):
def __init__(self, clk_freq, freq, o=None): def __init__(self, clk_freq, freq, o=None):

View file

@ -1,123 +0,0 @@
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

View file

@ -1,315 +0,0 @@
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)

View file

@ -0,0 +1,95 @@
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])
]

View file

@ -1,111 +0,0 @@
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()

View file

@ -1,114 +0,0 @@
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()

View file

@ -1,192 +0,0 @@
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()

142
sim/tb_recorder_csr.py Normal file
View file

@ -0,0 +1,142 @@
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()

View file

@ -1,168 +0,0 @@
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()

109
sim/tb_trigger_csr.py Normal file
View file

@ -0,0 +1,109 @@
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()