refactor code

This commit is contained in:
Florent Kermarrec 2014-04-18 10:33:05 +02:00
parent b766af0d99
commit 7a489b3135
32 changed files with 601 additions and 1158 deletions

View file

View file

@ -1,12 +0,0 @@
all: build/soc-de0nano.sta
build/soc-de0nano.sta:
./make.py
load:
cd build && quartus_pgm -m jtag -c USB-Blaster[USB-0] -o "p;soc-de0nano.sof"
clean:
rm -rf build/*
.PHONY: load clean

View file

@ -1,57 +0,0 @@
from miscope import miio
from miscope.com.uart2csr.host.uart2csr import *
from csr import *
#==============================================================================
# P A R A M E T E R S
#==============================================================================
uart = Uart2Csr(3, 115200)
class MiIoCtrl():
def __init__(self, bus):
self.bus = bus
def write(self, value):
miio_o_write(self.bus, value)
def read(self):
return miio_i_read(self.bus)
miio = MiIoCtrl(uart)
def led_anim0():
for i in range(10):
miio.write(0xA5)
time.sleep(0.1)
miio.write(0x5A)
time.sleep(0.1)
def led_anim1():
for j in range(4):
#Led <<
ledData = 1
for i in range(8):
miio.write(ledData)
time.sleep(i*i*0.0020)
ledData = (ledData<<1)
#Led >>
ledData = 128
for i in range(8):
miio.write(ledData)
time.sleep(i*i*0.0020)
ledData = (ledData>>1)
#==============================================================================
# T E S T M I I O
#==============================================================================
print("- Led Animation...")
led_anim0()
time.sleep(1)
led_anim1()
time.sleep(1)
print("- Read Switch: ",end=' ')
print("%02X" %miio.read())

View file

@ -1,99 +0,0 @@
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
#==============================================================================
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 enable_rle(self):
mila_rle_enable_write(self.bus, 1)
def disable_rle(self):
mila_rle_enable_write(self.bus, 0)
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_length = 512
rec_offset = 0
rle = True
#==============================================================================
# T E S T M I L A
#==============================================================================
dat_vcd = VcdDat(dat_w)
mila = MiLaCtrl(uart)
def capture():
global dat_vcd
sum_tt = gen_truth_table("term")
mila.prog_sum(sum_tt)
mila.trigger(rec_offset, rec_length)
print("-Recorder [Triggered]")
print("-Waiting Trigger...", end=' ')
while(not mila.is_done()):
time.sleep(0.1)
print("[Done]")
print("-Receiving Data...", end=' ')
sys.stdout.flush()
dat_vcd += mila.read()
print("[Done]")
print("Capturing ...")
print("----------------------")
if rle:
mila.enable_rle()
mila.prog_term(0x0000, 0xFFFF)
capture()
mila_layout = [
("freqgen", 1),
("event_rising", 1),
("event_falling", 1),
("cnt", 8),
]
if rle:
dat_vcd = dat_vcd.decode_rle()
myvcd = Vcd()
myvcd.add_from_layout(mila_layout, dat_vcd)
myvcd.write("test_mila.vcd")

View file

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

@ -1,29 +0,0 @@
from math import ceil
Hz = 1
KHz = 10**3
MHz = 10**6
GHz = 10**9
s = 1
ms = 1/KHz
us = 1/MHz
ns = 1/GHz
class t2n:
def __init__(self, clk_period_ns):
self.clk_period_ns = clk_period_ns
self.clk_period_us = clk_period_ns*(MHz/GHz)
self.clk_period_ms = clk_period_ns*(KHz/GHz)
def ns(self,t,margin=True):
if margin:
t += self.clk_period_ns/2
return ceil(t/self.clk_period_ns)
def us(self,t,margin=True):
if margin:
t += self.clk_period_us/2
return ceil(t/self.clk_period_us)
def ms(self,t,margin=True):
if margin:
t += self.clk_period_ms/2
return ceil(t/self.clk_period_ms)

View file

@ -1,106 +0,0 @@
################################################################################
# _____ _ ____ _ _ _ _
# | __|___ |_|___ _ _ | \|_|___|_| |_ ___| |
# | __| | | | . | | | | | | | . | | _| .'| |
# |_____|_|_|_| |___|_ | |____/|_|_ |_|_| |__,|_|
# |___| |___| |___|
#
# Copyright 2013 / Florent Kermarrec / florent@enjoy-digital.fr
#
# miscope example on De0 Nano
# --------------------------------
################################################################################
#==============================================================================
# I M P O R T
#==============================================================================
from migen.fhdl.std import *
from migen.bus import csr
from migen.bank import csrgen
from miscope.std.misc import *
from miscope.trigger import Term
from miscope.miio import MiIo
from miscope.mila import MiLa
from miscope.com import uart2csr
from timings import *
#==============================================================================
# P A R A M E T E R S
#==============================================================================
# Timings Param
clk_freq = 50*MHz
# Mila Param
mila_width = 16
mila_depth = 4096
#==============================================================================
# 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(8)
# MiLa
term = Term(mila_width)
self.submodules.mila = MiLa(mila_width, mila_depth, [term], rle=True)
# Uart2Csr
self.submodules.uart2csr = uart2csr.Uart2Csr(platform.request("serial"), clk_freq, 115200)
# Csr Interconnect
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 = Cat(*[platform.request("user_led", i) for i in range(8)])
# Misc
self.cnt = Signal(16)
self.submodules.freqgen = FreqGen(clk_freq, 500*KHz)
self.submodules.eventgen_rising = EventGen(RISING_EDGE, clk_freq, 100*ns)
self.submodules.eventgen_falling = EventGen(FALLING_EDGE, clk_freq, 100*ns)
self.comb += [
self.eventgen_rising.i.eq(self.freqgen.o),
self.eventgen_falling.i.eq(self.freqgen.o)
]
###
#
# Miio
#
# Output
self.comb += self.led.eq(self.miio.o)
# Input
self.comb += self.miio.i.eq(self.miio.o)
#
# Mila
#
self.comb +=[
self.mila.sink.stb.eq(1),
self.mila.sink.dat.eq(Cat(
self.freqgen.o,
self.eventgen_rising.o,
self.eventgen_falling.o,
self.cnt[8:12])
)
]
self.sync += self.cnt.eq(self.cnt+1)

View file

@ -1,180 +0,0 @@
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, pads, clk_freq, baud):
# Csr interface
self.csr = csr.Interface()
###
self.submodules.uart = UART(clk_freq, baud)
uart = self.uart
#
# In/Out
#
self.comb +=[
uart.rx.eq(pads.rx),
pads.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)
)
]

View file

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

View file

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

View file

@ -1,89 +0,0 @@
import string
import time
import serial
from struct import *
import time
WRITE_CMD = 0x01
READ_CMD = 0x02
CLOSE_CMD = 0x03
def write_b(uart, data):
uart.write(pack('B',data))
class Uart2Wb:
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.write("\nuart2wb\n".encode('ascii'))
self.uart.flush()
time.sleep(0.1)
self.uart.close()
self.uart.open()
def close(self):
for i in range(16):
write_b(self.uart, CLOSE_CMD)
self.uart.close()
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(4)
val = (int(read[0]) << 24) | (int(read[1]) << 16) | (int(read[2]) << 8) | int(read[3])
if self.debug:
print("RD %08X @ %08X" %(val, addr + 4*i))
values.append(val)
if burst_length == 1:
return values[0]
else:
return values
def read_csr(self, addr, burst_length=1):
values = self.read(addr, burst_length)
if isinstance(values, list):
for i in range(len(values)):
values[i] = values[i]&0xff
else:
values = values & 0xff
return values
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)):
self.uart.write([(data[i] & 0xff000000) >> 24,
(data[i] & 0x00ff0000) >> 16,
(data[i] & 0x0000ff00) >> 8,
(data[i] & 0x000000ff)])
if self.debug:
print("WR %08X @ %08X" %(elt, addr + 4*i))
else:
self.uart.write([(data & 0xff000000) >> 24,
(data & 0x00ff0000) >> 16,
(data & 0x0000ff00) >> 8,
(data & 0x000000ff)])
if self.debug:
print("WR %08X @ %08X" %(data, addr))
def write_csr(self, addr, data):
self.write(addr, data)

View file

@ -1,53 +0,0 @@
// Use this code in your LM32 code to control CSR
// over uart
#define WRITE_CMD 0x01
#define READ_CMD 0x02
#define CLOSE_CMD 0x03
#define MMPTR(x) (*((volatile unsigned int *)(x)))
static void uart2wb(void)
{
unsigned char cmd;
unsigned char burst_length;
unsigned char adr_t[4];
unsigned int adr;
char data_t[4];
unsigned int data;
unsigned char i;
unsigned char j;
while(cmd != CLOSE_CMD)
{
cmd = readchar();
if (cmd == WRITE_CMD)
{
burst_length = readchar();
for(i=0;i<4;i++) adr_t[i] = readchar();
adr = adr_t[0]<<24 | adr_t[1]<<16 | adr_t[2]<<8 | adr_t[3];
for(i=0;i<burst_length;i++)
{
for(j=0;j<4;j++) data_t[j] = readchar();
data = data_t[0]<<24 | data_t[1]<<16 | data_t[2]<<8 | data_t[3];
MMPTR(adr+4*i) = data;
}
}
if (cmd == READ_CMD)
{
burst_length = readchar();
for(i=0;i<4;i++) adr_t[i] = readchar();
adr = adr_t[0]<<24 | adr_t[1]<<16 | adr_t[2]<<8 | adr_t[3];
for(i=0;i<burst_length;i++)
{
data = MMPTR(adr+4*i);
data_t[0] = (data & 0xff000000)>>24;
data_t[1] = (data & 0x00ff0000)>>16;
data_t[2] = (data & 0x0000ff00)>>8;
data_t[3] = (data & 0x000000ff);
for(j=0;j<4;j++) putchar(data_t[j]);
}
}
}
}

11
miscope/host/cpuif.py Normal file
View file

@ -0,0 +1,11 @@
from migen.bank.description import CSRStatus
def get_csr_csv(csr_base, bank_array):
r = ""
for name, csrs, mapaddr, rmap in bank_array.banks:
reg_base = csr_base + 0x800*mapaddr
for csr in csrs:
nr = (csr.size + 7)//8
r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, reg_base, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
reg_base += 4*nr
return r

63
miscope/host/drivers.py Normal file
View file

@ -0,0 +1,63 @@
class MiIoDriver():
def __init__(self, regs, name):
self.regs = regs
self.name = name
self.build_miio()
def build_miio(self):
for key, value in self.regs.d.items():
if self.name in key:
key.replace(self.name, "miio")
setattr(self, key, value)
def write(self, value):
self.miio_o.write(value)
def read(self):
return self.miio_i.read()
class MiLaDriver():
def __init__(self, regs, name):
self.regs = regs
self.name = name
self.build_mila()
def build_mila(self):
for key, value in self.regs.d.items():
if self.name in key:
key.replace(self.name, "mila")
setattr(self, key, value)
def prog_term(self, trigger, mask):
self.mila_trigger_port0_trig.write(trigger)
self.mila_trigger_port0_mask.write(mask)
def prog_sum(self, datas):
for adr, dat in enumerate(datas):
self.mila_trigger_sum_prog_adr.write(adr)
self.mila_trigger_sum_prog_dat.write(dat)
self.mila_trigger_sum_prog_we.write(1)
def enable_rle(self):
self.mila_rle_enable.write(1)
def disable_rle(self):
self.mila_rle_enable.write(0)
def is_done(self):
return self.mila_recorder_done.read()
def trigger(self, offset, length):
self.mila_recorder_offset.write(offset)
self.mila_recorder_length.write(length)
self.mila_recorder_trigger.write(1)
def read(self):
r = []
empty = self.mila_recorder_read_empty.read()
while(not empty):
r.append(self.mila_recorder_read_dat.read())
empty = self.mila_recorder_read_empty.read()
self.mila_recorder_read_en.write(1)
return r

48
miscope/host/regs.py Normal file
View file

@ -0,0 +1,48 @@
import csv
class MappedReg:
def __init__(self, readfn, writefn, name, addr, length, mode):
self.readfn = readfn
self.writefn = writefn
self.addr = addr
self.length = length
self.mode = mode
def read(self):
if self.mode not in ["rw", "ro"]:
raise KeyError(name + "register not readable")
r = 0
for i in range(self.length):
r |= self.readfn(self.addr + 4*i)
if i != (self.length-1):
r <<= 8
return r
def write(self, value):
if self.mode not in ["rw", "wo"]:
raise KeyError(name + "register not writable")
for i in range(self.length):
dat = (value >> ((self.length-1-i)*8)) & 0xff
self.writefn(self.addr + 4*i, dat)
class MappedRegs:
def __init__(self, d):
self.d = d
def __getattr__(self, attr):
try:
return self.__dict__['d'][attr]
except KeyError:
pass
raise KeyError("No such register " + attr)
def build_map(addrmap, readfn, writefn):
csv_reader = csv.reader(open(addrmap), delimiter=',', quotechar='#')
d = {}
for item in csv_reader:
name, addr, length, mode = item
addr = int(addr.replace("0x", ""), 16)
length = int(length)
d[name] = MappedReg(readfn, writefn, name, addr, length, mode)
return MappedRegs(d)

View file

@ -0,0 +1,78 @@
import string
import serial
from struct import *
from migen.fhdl.structure import *
from miscope.host.regs import *
def write_b(uart, data):
uart.write(pack('B',data))
class Uart2Wishbone:
WRITE_CMD = 0x01
READ_CMD = 0x02
def __init__(self, port, baudrate, addrmap=None, debug=False):
self.port = port
self.baudrate = baudrate
self.debug = debug
self.uart = serial.Serial(port, baudrate, timeout=0.25)
self.regs = build_map(addrmap, self.read, self.write)
def open(self):
self.uart.flushOutput()
self.uart.close()
self.uart.open()
self.uart.flushInput()
def close(self):
self.uart.close()
def read(self, addr, burst_length=1):
self.uart.flushInput()
write_b(self.uart, self.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):
val = 0
for j in range(4):
val = val << 8
val |= ord(self.uart.read())
if self.debug:
print("RD %08X @ %08X" %(val, (addr+i)*4))
values.append(val)
if burst_length == 1:
return values[0]
else:
return values
def write(self, addr, data):
if isinstance(data, list):
burst_length = len(data)
else:
burst_length = 1
write_b(self.uart, self.WRITE_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))
if isinstance(data, list):
for i in range(len(data)):
dat = data[i]
for j in range(4):
write_b(self.uart, (dat & 0xff000000) >> 24)
dat = dat << 8
if self.debug:
print("WR %08X @ %08X" %(data[i], (addr + i)*4))
else:
dat = data
for j in range(4):
write_b(self.uart, (dat & 0xff000000) >> 24)
dat = dat << 8
if self.debug:
print("WR %08X @ %08X" %(data, (addr * 4)))

View file

@ -7,7 +7,7 @@ from migen.bank.description import *
from miscope.std import *
from miscope.trigger import Trigger
from miscope.storage import RunLengthEncoder, Recorder
from miscope.storage import Recorder, RunLengthEncoder
class MiLa(Module, AutoCSR):
def __init__(self, width, depth, ports, rle=False):

View file

@ -1,94 +0,0 @@
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,89 +0,0 @@
from migen.fhdl.std import *
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)
class RisingEdge(Module):
def __init__(self):
self.i = Signal()
self.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):
self.i = Signal()
self.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):
cnt_max = int(clk_freq/freq/2)
self.o = Signal()
####
cnt = Signal(max=cnt_max)
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, level=RISING_EDGE, clk_freq=0, length=1):
cnt_max = int(length*clk_freq)
self.o = Signal()
###
cnt = Signal(max=cnt_max)
if level == RISING_EDGE:
self.submodules.edge_detect = RisingEdge()
elif level == FALLING_EDGE:
self.submodules.edge_detect = FallingEdge()
self.i = self.edge_detect.i
self.sync += [
If(self.edge_detect.o == 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):
self.ratio = Signal(width)
self.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)
]

297
miscope/uart2wishbone.py Normal file
View file

@ -0,0 +1,297 @@
from migen.fhdl.structure import *
from migen.fhdl.module import *
from migen.genlib.record import *
from migen.genlib.cdc import MultiReg
from migen.genlib.fsm import FSM, NextState
from migen.genlib.misc import split, displacer, chooser
from migen.bank.description import *
from migen.bus import wishbone
# Todo
# ----
# - implement timeout in fsm to prevent deadlocks
def rec_rx():
layout = [
("stb", 1, DIR_M_TO_S),
("dat", 8, DIR_M_TO_S)
]
return Record(layout)
def rec_tx():
layout = [
("stb", 1, DIR_M_TO_S),
("ack", 1, DIR_S_TO_M),
("dat", 8, DIR_M_TO_S)
]
return Record(layout)
class UART(Module):
def __init__(self, pads, clk_freq, baud=115200):
self.rx = rec_rx()
self.tx = rec_tx()
self.divisor = Signal(16, reset=int(clk_freq/baud/16))
pads.tx.reset = 1
###
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.ack
tx_busy = Signal()
tx_stb_d = Signal()
self.sync += [
tx_stb_d.eq(self.tx.stb & ~tx_done),
tx_done.eq(0),
If(self.tx.stb & ~tx_stb_d,
tx_reg.eq(self.tx.dat),
tx_bitcount.eq(0),
tx_count16.eq(1),
tx_busy.eq(1),
pads.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,
pads.tx.eq(1)
).Elif(tx_bitcount == 9,
pads.tx.eq(1),
tx_busy.eq(0),
tx_done.eq(1)
).Else(
pads.tx.eq(tx_reg[0]),
tx_reg.eq(Cat(tx_reg[1:], 0))
)
)
)
]
# RX
rx = Signal()
self.specials += MultiReg(pads.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.stb
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))
)
)
)
)
]
class Counter(Module):
def __init__(self, width):
self.value = Signal(width)
self.clr = Signal()
self.inc = Signal()
self.sync += [
If(self.clr,
self.value.eq(0)
).Elif(self.inc,
self.value.eq(self.value+1)
)
]
class UARTPads:
def __init__(self):
self.rx = Signal()
self.tx = Signal()
class UARTMux(Module):
def __init__(self, pads, nb):
self.sel = Signal(max=nb)
self.pads = [UARTPads() for i in range(nb)]
###
# Route Rx pad to all modules
for i in range(nb):
self.comb += self.pads[i].rx.eq(pads.rx)
# Route only selected module to Tx pad
pads_tx = [self.pads[i].tx for i in range(nb)]
self.comb += chooser(Cat(pads_tx), self.sel, pads.tx, n=nb)
class UART2Wishbone(Module, AutoCSR):
WRITE_CMD = 0x01
READ_CMD = 0x02
def __init__(self, pads, clk_freq, baud, share_uart=False):
# Wishbone interface
self.wishbone = wishbone.Interface()
if share_uart:
self._sel = CSRStorage()
###
if share_uart:
self.submodules.uart_mux = UARTMux(pads, 2)
self.submodules.uart = UART(self.uart_mux.pads[1], clk_freq, baud)
self.shared_pads = self.uart_mux.pads[0]
self.comb += self.uart_mux.sel.eq(self._sel.storage)
else:
self.submodules.uart = UART(pads, clk_freq, baud)
uart = self.uart
fsm = FSM()
self.submodules += fsm
word_cnt = Counter(3)
burst_cnt = Counter(8)
self.submodules += word_cnt, burst_cnt
###
cmd = Signal(8)
fsm.act("WAIT_CMD",
If(uart.rx.stb,
If( (uart.rx.dat == self.WRITE_CMD) |
(uart.rx.dat == self.READ_CMD),
NextState("RECEIVE_BURST_LENGTH")
),
word_cnt.clr.eq(1),
burst_cnt.clr.eq(1)
)
)
self.sync += If(fsm.ongoing("WAIT_CMD") & uart.rx.stb, cmd.eq(uart.rx.dat))
####
burst_length = Signal(8)
fsm.act("RECEIVE_BURST_LENGTH",
word_cnt.inc.eq(uart.rx.stb),
If(word_cnt.value == 1,
word_cnt.clr.eq(1),
NextState("RECEIVE_ADDRESS")
)
)
self.sync += \
If(fsm.ongoing("RECEIVE_BURST_LENGTH") & uart.rx.stb, burst_length.eq(uart.rx.dat))
####
address = Signal(32)
fsm.act("RECEIVE_ADDRESS",
word_cnt.inc.eq(uart.rx.stb),
If(word_cnt.value == 4,
word_cnt.clr.eq(1),
If(cmd == self.WRITE_CMD,
NextState("RECEIVE_DATA")
).Elif(cmd == self.READ_CMD,
NextState("READ_DATA")
)
)
)
self.sync += \
If(fsm.ongoing("RECEIVE_ADDRESS") & uart.rx.stb,
address.eq(Cat(uart.rx.dat, address[0:24]))
)
###
data = Signal(32)
###
fsm.act("RECEIVE_DATA",
word_cnt.inc.eq(uart.rx.stb),
If(word_cnt.value == 4,
word_cnt.clr.eq(1),
NextState("WRITE_DATA")
)
)
fsm.act("WRITE_DATA",
self.wishbone.adr.eq(address + burst_cnt.value),
self.wishbone.dat_w.eq(data),
self.wishbone.sel.eq(2**flen(self.wishbone.sel)-1),
self.wishbone.stb.eq(1),
self.wishbone.we.eq(1),
self.wishbone.cyc.eq(1),
If(self.wishbone.ack,
burst_cnt.inc.eq(1),
If(burst_cnt.value == (burst_length-1),
NextState("WAIT_CMD")
).Else(
word_cnt.clr.eq(1),
NextState("RECEIVE_DATA")
)
)
)
###
fsm.act("READ_DATA",
self.wishbone.adr.eq(address + burst_cnt.value),
self.wishbone.sel.eq(2**flen(self.wishbone.sel)-1),
self.wishbone.stb.eq(1),
self.wishbone.we.eq(0),
self.wishbone.cyc.eq(1),
If(self.wishbone.stb & self.wishbone.ack,
word_cnt.clr.eq(1),
NextState("SEND_DATA")
)
)
fsm.act("SEND_DATA",
word_cnt.inc.eq(uart.tx.ack),
If(word_cnt.value == 4,
burst_cnt.inc.eq(1),
If(burst_cnt.value == (burst_length-1),
NextState("WAIT_CMD")
).Else(
NextState("READ_DATA")
)
),
uart.tx.stb.eq(1),
chooser(data, word_cnt.value, uart.tx.dat, n=4, reverse=True)
)
###
self.sync += \
If(fsm.ongoing("RECEIVE_DATA") & uart.rx.stb,
data.eq(Cat(uart.rx.dat, data[0:24]))
).Elif(fsm.ongoing("READ_DATA") & self.wishbone.stb & self.wishbone.ack,
data.eq(self.wishbone.dat_r)
)

View file

@ -7,7 +7,7 @@ from setuptools import find_packages
here = os.path.abspath(os.path.dirname(__file__))
README = open(os.path.join(here, "README")).read()
required_version = (3, 1)
required_version = (3, 3)
if sys.version_info < required_version:
raise SystemExit("Migscope requires python {0} or greater".format(
".".join(map(str, required_version))))

11
sim/cpuif.py Normal file
View file

@ -0,0 +1,11 @@
from migen.bank.description import CSRStatus
def get_csr_csv(csr_base, bank_array):
r = ""
for name, csrs, mapaddr, rmap in bank_array.banks:
reg_base = csr_base + 0x800*mapaddr
for csr in csrs:
nr = (csr.size + 7)//8
r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, reg_base, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
reg_base += 4*nr
return r

View file

@ -1,21 +1,17 @@
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.sim.generic import run_simulation
from migen.bus.transactions import *
from miscope.std import cif
from miscope.std.truthtable import *
from miscope.std import *
from miscope.storage import *
from mibuild.tools import write_to_file
from miscope.tools.regs import *
from miscope.tools.truthtable import *
try:
from csr_header import *
print("csr_header imported")
except:
print("csr_header not found")
from cpuif import *
class Csr2Trans():
def __init__(self):
@ -38,30 +34,26 @@ dat_rdy = False
rec_length = 128
def csr_configure():
bus = Csr2Trans()
def csr_configure(bus, regs):
# Length
recorder_length_write(bus, rec_length)
regs.recorder_length.write(rec_length)
# Offset
recorder_offset_write(bus, 0)
regs.recorder_offset.write(0)
# Trigger
recorder_trigger_write(bus, 1)
regs.recorder_trigger.write(1)
return bus.t
def csr_read_data():
bus = Csr2Trans()
def csr_read_data(bus, regs):
for i in range(rec_length+100):
recorder_read_dat_read(bus)
recorder_read_en_write(bus, 1)
regs.recorder_read_dat.read()
regs.recorder_read_en.write(1)
return bus.t
def csr_transactions():
for t in csr_configure():
def csr_transactions(bus, regs):
for t in csr_configure(bus, regs):
yield t
for t in range(100):
@ -73,7 +65,7 @@ def csr_transactions():
for t in range(512):
yield None
for t in csr_read_data():
for t in csr_read_data(bus, regs):
yield t
for t in range(100):
@ -85,56 +77,57 @@ class TB(Module):
csr_map = {
"recorder": 1,
}
def __init__(self, first_run=False):
def __init__(self, addrmap=None):
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())
# Csr Master
csr_header = get_csr_csv(self.csr_base, self.csrbankarray)
write_to_file("csr.csv", csr_header)
bus = Csr2Trans()
regs = build_map(addrmap, bus.read_csr, bus.write_csr)
self.submodules.master = csr.Initiator(csr_transactions(bus, regs))
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)
def recorder_data(self, selfp):
selfp.recorder.dat_sink.stb = 1
if not hasattr(self, "cnt"):
self.cnt = 0
self.cnt += 1
s.wr(self.recorder.sink.payload.d, self.cnt)
selfp.recorder.dat_sink.dat = self.cnt
global triggered
if triggered:
s.wr(self.recorder.sink.payload.hit, 1)
selfp.recorder.trig_sink.stb = 1
selfp.recorder.trig_sink.hit = 1
triggered = False
else:
s.wr(self.recorder.sink.payload.hit, 0)
selfp.recorder.trig_sink.stb = 0
selfp.recorder.trig_sink.hit = 0
# Simulation
def end_simulation(self, s):
s.interrupt = self.master.done
def end_simulation(self, selfp):
if self.master.done:
raise StopSimulation
def do_simulation(self, s):
self.recorder_data(s)
self.end_simulation(s)
def do_simulation(self, selfp):
self.recorder_data(selfp)
self.end_simulation(selfp)
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)
tb = TB(addrmap="csr.csv")
run_simulation(tb, ncycles=2000, vcd_name="tb_recorder_csr.vcd")
print("Sim Done")
input()

View file

@ -1,10 +1,7 @@
from migen.fhdl.std import *
from migen.fhdl import verilog
from migen.sim.generic import Simulator, TopLevel
from migen.sim.icarus import Runner
from miscope.storage import RunLengthEncoder
from migen.sim.generic import run_simulation
from miscope import storage
rle_test_seq = iter(
[ 0x00AA,
@ -29,20 +26,19 @@ class TB(Module):
def __init__(self):
# Rle
self.submodules.rle = RunLengthEncoder(16, 32)
self.submodules.rle = storage.RunLengthEncoder(16, 32)
def do_simulation(self, s):
s.wr(self.rle._r_enable.storage, 1)
s.wr(self.rle.sink.stb, 1)
def do_simulation(self, selfp):
selfp.rle._r_enable.storage = 1
selfp.rle.sink.stb = 1
try:
s.wr(self.rle.sink.dat, next(rle_test_seq))
selfp.rle.sink.dat = next(rle_test_seq)
except:
pass
def main():
tb = TB()
sim = Simulator(tb, TopLevel("tb_rle.vcd"))
sim.run(2000)
run_simulation(tb, ncycles=8000, vcd_name="tb_rle.vcd")
print("Sim Done")
input()

View file

@ -1,21 +1,17 @@
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.sim.generic import run_simulation
from migen.bus.transactions import *
from miscope.std import cif
from miscope.std.truthtable import *
from miscope.std import *
from miscope.trigger import *
from mibuild.tools import write_to_file
from miscope.tools.regs import *
from miscope.tools.truthtable import *
try:
from csr_header import *
print("csr_header imported")
except:
print("csr_header not found")
from cpuif import *
class Csr2Trans():
def __init__(self):
@ -27,30 +23,29 @@ class Csr2Trans():
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)
def csr_prog_mila(bus, regs):
regs.trigger_port0_mask.write(0xFFFFFFFF)
regs.trigger_port0_trig.write(0xDEADBEEF)
regs.trigger_port1_mask.write(0xFFFFFFFF)
regs.trigger_port1_trig.write(0xDEADBEEF)
regs.trigger_port1_mask.write(0xFFFFFFFF)
regs.trigger_port1_mask.write(0xFFFFFFFF)
regs.trigger_port1_trig.write(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)
regs.trigger_sum_prog_adr.write(i)
regs.trigger_sum_prog_dat.write(sum_tt[i])
regs.trigger_sum_prog_we.write(1)
return bus.t
csr_done = False
def csr_transactions():
for t in csr_prog_mila():
def csr_transactions(bus, regs):
for t in csr_prog_mila(bus, regs):
yield t
global csr_done
csr_done = True
@ -62,13 +57,9 @@ class TB(Module):
csr_map = {
"trigger": 1,
}
def __init__(self, first_run=False):
# Csr Master
if not first_run:
self.submodules.master = csr.Initiator(csr_transactions())
def __init__(self, addrmap=None):
self.csr_base = 0
# Trigger
term0 = Term(32)
term1 = Term(32)
@ -79,29 +70,32 @@ class TB(Module):
# 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())
# Csr Master
csr_header = get_csr_csv(self.csr_base, self.csrbankarray)
write_to_file("csr.csv", csr_header)
bus = Csr2Trans()
regs = build_map(addrmap, bus.read_csr, bus.write_csr)
self.submodules.master = csr.Initiator(csr_transactions(bus, regs))
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)
def do_simulation(self, selfp):
for term in selfp.terms:
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
selfp.terms[0].sink.dat = 0xDEADBEEF
selfp.terms[1].sink.dat = 0xCAFEFADE
selfp.terms[2].sink.dat = 0xDEADBEEF
selfp.terms[3].sink.dat = 0xCAFEFADE
raise StopSimulation
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)
tb = TB(addrmap="csr.csv")
run_simulation(tb, ncycles=2000, vcd_name="tb_trigger_csr.vcd")
print("Sim Done")
input()