+++ /dev/null
-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
+++ /dev/null
-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())
+++ /dev/null
-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")
\ No newline at end of file
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse, os, subprocess, struct, shutil
-
-from mibuild.tools import write_to_file
-import mibuild.platforms.de0nano as de0nano
-
-from miscope.std import cif
-
-import top
-
-def build(build_bitstream, build_header):
- platform = de0nano.Platform()
- soc = top.SoC(platform)
-
- platform.add_platform_command("""
-set_global_assignment -name FAMILY "Cyclone IV E"
-set_global_assignment -name TOP_LEVEL_ENTITY "top"
-set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
-""")
-
- if build_bitstream:
- build_name = "soc-de0nano"
- platform.build(soc, build_name=build_name)
- else:
- soc.finalize()
- if build_header:
-
- csr_py_header = cif.get_py_csr_header(soc.csr_base, soc.csrbankarray)
- write_to_file(os.path.join("client", "csr.py"), csr_py_header)
-
-
-def main():
- parser = argparse.ArgumentParser(description="miscope")
- parser.add_argument("-B", "--no-bitstream", default=False, action="store_true", help="do not build bitstream file")
- parser.add_argument("-H", "--no-header", default=False, action="store_true", help="do not build C header file with CSR defs")
- args = parser.parse_args()
-
- build(not args.no_bitstream, not args.no_header)
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-from 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)
\ No newline at end of file
+++ /dev/null
-################################################################################
-# _____ _ ____ _ _ _ _
-# | __|___ |_|___ _ _ | \|_|___|_| |_ ___| |
-# | __| | | | . | | | | | | | . | | _| .'| |
-# |_____|_|_|_| |___|_ | |____/|_|_ |_|_| |__,|_|
-# |___| |___| |___|
-#
-# 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)
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import *
-from migen.bus import csr
-from migen.genlib.fsm import FSM, NextState
-
-from miscope.com.uart2csr.uart import *
-
-WRITE_CMD = 0x01
-READ_CMD = 0x02
-CLOSE_CMD = 0x03
-
-class Uart2Csr(Module):
- def __init__(self, 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)
- )
- ]
\ No newline at end of file
+++ /dev/null
-import string
-import time
-import serial
-from struct import *
-import time
-from migen.fhdl.structure import *
-
-WRITE_CMD = 0x01
-READ_CMD = 0x02
-CLOSE_CMD = 0x03
-
-def write_b(uart, data):
- uart.write(pack('B',data))
-
-class Uart2Csr:
- def __init__(self, port, baudrate, debug=False):
- self.port = port
- self.baudrate = baudrate
- self.debug = debug
- self.uart = serial.Serial(port, baudrate, timeout=0.25)
-
- def open(self):
- self.uart.close()
- self.uart.open()
-
- def close(self):
- self.uart.close()
-
- def read_csr(self, addr, burst_length=1):
- write_b(self.uart, READ_CMD)
- write_b(self.uart, burst_length)
- addr = addr//4
- write_b(self.uart, (addr & 0xff000000) >> 24)
- write_b(self.uart, (addr & 0x00ff0000) >> 16)
- write_b(self.uart, (addr & 0x0000ff00) >> 8)
- write_b(self.uart, (addr & 0x000000ff))
- values = []
- for i in range(burst_length):
- read = self.uart.read(1)
- val = int(read[0])
- if self.debug:
- print("RD %02X @ %08X" %(val, addr + 4*i))
- values.append(val)
- if burst_length == 1:
- return values[0]
- else:
- return values
-
- def read_n(self, addr, n, endianess = "LE"):
- r = 0
- words = int(2**bits_for(n-1)/8)
- for i in range(words):
- if endianess == "BE":
- r += self.read(addr+i)<<(8*i)
- elif endianess == "LE":
- r += self.read(addr+words-1-i)<<(8*i)
- if self.debug:
- print("RD @ %04X" %addr)
- return r
-
- def write_csr(self, addr, data):
- if isinstance(data, list):
- burst_length = len(data)
- else:
- burst_length = 1
- write_b(self.uart, WRITE_CMD)
- write_b(self.uart, burst_length)
- addr = addr//4
- self.uart.write([(addr & 0xff000000) >> 24,
- (addr & 0x00ff0000) >> 16,
- (addr & 0x0000ff00) >> 8,
- (addr & 0x000000ff)])
- if isinstance(data, list):
- for i in range(len(data)):
- write_b(self.uart, data[i])
- if self.debug:
- print("WR %02X @ %08X" %(data[i], addr + 4*i))
- else:
- write_b(self.uart, data)
- if self.debug:
- print("WR %02X @ %08X" %(data, addr))
-
- def write_n(self, addr, data, n, endianess = "LE"):
- words = int(2**bits_for(n-1)/8)
- for i in range(words):
- if endianess == "BE":
- self.write(addr+i, (data>>(8*i)) & 0xFF)
- elif endianess == "LE":
- self.write(addr+words-1-i, (data>>(8*i)) & 0xFF)
- if self.debug:
- print("WR %08X @ %04X" %(data, addr))
\ No newline at end of file
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-from migen.bank.eventmanager import *
-
-class UART(Module):
- def __init__(self, clk_freq, baud=115200):
-
- self.rx_ev = Signal()
- self.rx_dat = Signal(8)
-
- self.tx_we = Signal()
- self.tx_ev = Signal()
- self.tx_dat = Signal(8)
-
- self.divisor = Signal(16, reset=int(clk_freq/baud/16))
-
- self.tx = Signal(reset=1)
- self.rx = Signal()
-
-
- ###
-
- enable16 = Signal()
- enable16_counter = Signal(16)
- self.comb += enable16.eq(enable16_counter == 0)
- self.sync += [
- enable16_counter.eq(enable16_counter - 1),
- If(enable16,
- enable16_counter.eq(self.divisor - 1))
- ]
-
- # TX
- tx_reg = Signal(8)
- tx_bitcount = Signal(4)
- tx_count16 = Signal(4)
- tx_done = self.tx_ev
- tx_busy = Signal()
- self.sync += [
- tx_done.eq(0),
- If(self.tx_we,
- tx_reg.eq(self.tx_dat),
- tx_bitcount.eq(0),
- tx_count16.eq(1),
- tx_busy.eq(1),
- self.tx.eq(0)
- ).Elif(enable16 & tx_busy,
- tx_count16.eq(tx_count16 + 1),
- If(tx_count16 == 0,
- tx_bitcount.eq(tx_bitcount + 1),
- If(tx_bitcount == 8,
- self.tx.eq(1)
- ).Elif(tx_bitcount == 9,
- self.tx.eq(1),
- tx_busy.eq(0),
- tx_done.eq(1)
- ).Else(
- self.tx.eq(tx_reg[0]),
- tx_reg.eq(Cat(tx_reg[1:], 0))
- )
- )
- )
- ]
-
- # RX
- rx = Signal()
- self.specials += MultiReg(self.rx, rx, "sys")
- rx_r = Signal()
- rx_reg = Signal(8)
- rx_bitcount = Signal(4)
- rx_count16 = Signal(4)
- rx_busy = Signal()
- rx_done = self.rx_ev
- rx_data = self.rx_dat
- self.sync += [
- rx_done.eq(0),
- If(enable16,
- rx_r.eq(rx),
- If(~rx_busy,
- If(~rx & rx_r, # look for start bit
- rx_busy.eq(1),
- rx_count16.eq(7),
- rx_bitcount.eq(0)
- )
- ).Else(
- rx_count16.eq(rx_count16 + 1),
- If(rx_count16 == 0,
- rx_bitcount.eq(rx_bitcount + 1),
-
- If(rx_bitcount == 0,
- If(rx, # verify start bit
- rx_busy.eq(0)
- )
- ).Elif(rx_bitcount == 9,
- rx_busy.eq(0),
- If(rx, # verify stop bit
- rx_data.eq(rx_reg),
- rx_done.eq(1)
- )
- ).Else(
- rx_reg.eq(Cat(rx_reg[1:], rx))
- )
- )
- )
- )
- ]
+++ /dev/null
-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)
\ No newline at end of file
+++ /dev/null
-// 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]);
- }
- }
- }
-}
--- /dev/null
+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
--- /dev/null
+
+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
\ No newline at end of file
--- /dev/null
+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)
\ No newline at end of file
--- /dev/null
+import os
+import re
+import sys
+
+def is_number(x):
+ try:
+ _ = float(x)
+ except ValueError:
+ return False
+ return True
+
+def remove_numbers(seq):
+ return [ x for x in seq if not is_number(x)]
+
+def remove_duplicates(seq):
+ seen = set()
+ seen_add = seen.add
+ return [ x for x in seq if x not in seen and not seen_add(x)]
+
+def get_operands(s):
+ operands = re.findall("[A-z0-9_]+", s)
+ operands = remove_duplicates(operands)
+ operands = remove_numbers(operands)
+ return sorted(operands)
+
+def gen_truth_table(s):
+ operands = get_operands(s)
+ width = len(operands)
+ stim = []
+ for i in range(width):
+ stim_op = []
+ for j in range(2**width):
+ stim_op.append((int(j/(2**i)))%2)
+ stim.append(stim_op)
+
+ truth_table = []
+ for i in range(2**width):
+ for j in range(width):
+ exec("%s = stim[j][i]" %operands[j])
+ truth_table.append(eval(s) != 0)
+ return truth_table
+
+def main():
+ print(gen_truth_table("(A&B&C)|D"))
+
+if __name__ == '__main__':
+ main()
--- /dev/null
+import 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)))
--- /dev/null
+import sys
+import datetime
+
+from miscope.std.misc import *
+
+def get_bits(values, width, low, high=None):
+ r = []
+ for val in values:
+ t = dec2bin(val, width)[::-1]
+ if high == None:
+ t = t[low]
+ else:
+ t = t[low:high]
+ t = t[::1]
+ t = int(t,2)
+ r.append(t)
+ return r
+
+class VcdDat(list):
+ def __init__(self, width):
+ self.width = width
+
+ def __getitem__(self, key):
+ if isinstance(key, int):
+ return get_bits(self, self.width, key)
+ elif isinstance(key, slice):
+ if key.start != None:
+ start = key.start
+ else:
+ start = 0
+ if key.stop != None:
+ stop = key.stop
+ else:
+ stop = self.width
+ if stop > self.width:
+ stop = self.width
+ if key.step != None:
+ raise KeyError
+ return get_bits(self, self.width, start, stop)
+ else:
+ raise KeyError
+
+ def decode_rle(self):
+ rle_bit = self[-1]
+ rle_dat = self[:self.width-1]
+
+ dat = VcdDat(self.width)
+ i=0
+ last = 0
+ for d in self:
+ if rle_bit[i]:
+ if len(dat) >= 1:
+ # FIX ME... why is rle_dat in reverse order...
+ for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
+ dat.append(last)
+ else:
+ dat.append(d)
+ last = d
+ i +=1
+ return dat
+
+class Var:
+ def __init__(self, name, width, values=[], type="wire", default="x"):
+ self.type = type
+ self.width = width
+ self.name = name
+ self.val = default
+ self.values = values
+ self.vcd_id = None
+
+ def set_vcd_id(self, s):
+ self.vcd_id = s
+
+ def __len__(self):
+ return len(self.values)
+
+ def change(self, cnt):
+ r = ""
+ try :
+ if self.values[cnt+1] != self.val:
+ r += "b"
+ r += dec2bin(self.values[cnt+1], self.width)[::-1]
+ r += " "
+ r += self.vcd_id
+ r += "\n"
+ return r
+ except :
+ return r
+ return r
+
+class Vcd:
+ def __init__(self, timescale="1ps", comment=""):
+ self.timescale = timescale
+ self.comment = comment
+ self.vars = []
+ self.vcd_id = "!"
+ self.cnt = -1
+
+ def add(self, var):
+ var.set_vcd_id(self.vcd_id)
+ self.vcd_id = chr(ord(self.vcd_id)+1)
+ self.vars.append(var)
+
+ def add_from_layout(self, layout, var):
+ i=0
+ for s, n in layout:
+ self.add(Var(s, n, var[i:i+n]))
+ i += n
+
+ def __len__(self):
+ l = 0
+ for var in self.vars:
+ l = max(len(var),l)
+ return l
+
+ def change(self):
+ r = ""
+ c = ""
+ for var in self.vars:
+ c += var.change(self.cnt)
+ if c != "":
+ r += "#"
+ r += str(self.cnt+1)
+ r += "\n"
+ r += c
+ return r
+
+ def p_date(self):
+ now = datetime.datetime.now()
+ r = "$date\n"
+ r += "\t"
+ r += now.strftime("%Y-%m-%d %H:%M")
+ r += "\n"
+ r += "$end\n"
+ return r
+
+ def p_version(self):
+ r = "$version\n"
+ r += "\tmiscope VCD dump\n"
+ r += "$end\n"
+ return r
+
+ def p_comment(self):
+ r = "$comment\n"
+ r += self.comment
+ r += "\n$end\n"
+ return r
+
+ def p_timescale(self):
+ r = "$timescale "
+ r += self.timescale
+ r += " $end\n"
+ return r
+
+ def p_scope(self):
+ r = "$scope "
+ r += self.timescale
+ r += " $end\n"
+ return r
+
+ def p_vars(self):
+ r = ""
+ for var in self.vars:
+ r += "$var "
+ r += var.type
+ r += " "
+ r += str(var.width)
+ r += " "
+ r += var.vcd_id
+ r += " "
+ r += var.name
+ r += " $end\n"
+ return r
+
+ def p_unscope(self):
+ r = "$unscope "
+ r += " $end\n"
+ return r
+
+ def p_enddefinitions(self):
+ r = "$enddefinitions "
+ r += " $end\n"
+ return r
+
+ def p_dumpvars(self):
+ r = "$dumpvars\n"
+ for var in self.vars:
+ r += "b"
+ r += dec2bin(var.val, var.width)
+ r += " "
+ r += var.vcd_id
+ r+= "\n"
+ r += "$end\n"
+ return r
+
+ def p_valuechange(self):
+ r = ""
+ for i in range(len(self)):
+ r += self.change()
+ self.cnt += 1
+ return r
+
+ def __repr__(self):
+ r = ""
+ r += self.p_date()
+ r += self.p_version()
+ r += self.p_comment()
+ r += self.p_timescale()
+ r += self.p_scope()
+ r += self.p_vars()
+ r += self.p_unscope()
+ r += self.p_enddefinitions()
+ r += self.p_dumpvars()
+ r += self.p_valuechange()
+ return r
+
+ def write(self, filename):
+ f = open(filename, "w")
+ f.write(str(self))
+ f.close()
+
+def main():
+ myvcd = Vcd()
+ myvcd.add(Var(1, "foo1", [0,1,0,1,0,1]))
+ myvcd.add(Var(2, "foo2", [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
+ myvcd.add(Var(3, "foo3"))
+ myvcd.add(Var(4, "foo4"))
+ ramp = [i%128 for i in range(1024)]
+ myvcd.add(Var(16, "ramp", ramp))
+ print(myvcd)
+
+if __name__ == '__main__':
+ main()
+
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):
--- /dev/null
+from migen.genlib.record import *
+
+def rec_dat(width):
+ layout = [
+ ("stb", 1, DIR_M_TO_S),
+ ("ack", 1, DIR_S_TO_M),
+ ("dat", width, DIR_M_TO_S)
+ ]
+ return Record(layout)
+
+def rec_hit():
+ layout = [
+ ("stb", 1, DIR_M_TO_S),
+ ("ack", 1, DIR_S_TO_M),
+ ("hit", 1, DIR_M_TO_S)
+ ]
+ return Record(layout)
+
+def rec_dat_hit(width):
+ layout = [
+ ("stb", 1, DIR_M_TO_S),
+ ("ack", 1, DIR_S_TO_M),
+ ("hit", 1, DIR_M_TO_S),
+ ("dat", width, DIR_M_TO_S)
+ ]
+ return Record(layout)
\ No newline at end of file
+++ /dev/null
-from migen.genlib.record import *
-
-def rec_dat(width):
- layout = [
- ("stb", 1, DIR_M_TO_S),
- ("ack", 1, DIR_S_TO_M),
- ("dat", width, DIR_M_TO_S)
- ]
- return Record(layout)
-
-def rec_hit():
- layout = [
- ("stb", 1, DIR_M_TO_S),
- ("ack", 1, DIR_S_TO_M),
- ("hit", 1, DIR_M_TO_S)
- ]
- return Record(layout)
-
-def rec_dat_hit(width):
- layout = [
- ("stb", 1, DIR_M_TO_S),
- ("ack", 1, DIR_S_TO_M),
- ("hit", 1, DIR_M_TO_S),
- ("dat", width, DIR_M_TO_S)
- ]
- return Record(layout)
\ No newline at end of file
+++ /dev/null
-from operator import itemgetter
-import re
-
-from migen.fhdl.std import *
-from migen.bank.description import CSRStatus
-
-def get_macros(filename):
- f = open(filename, "r")
- r = {}
- for line in f:
- match = re.match("\w*#define\s+(\w+)\s+(.*)", line, re.IGNORECASE)
- if match:
- r[match.group(1)] = match.group(2)
- return r
-
-def _get_rw_functions(reg_name, reg_base, size, read_only):
- r = ""
- if size > 8:
- raise NotImplementedError("Register too large")
- elif size > 4:
- ctype = "unsigned long long int"
- elif size > 2:
- ctype = "unsigned int"
- elif size > 1:
- ctype = "unsigned short int"
- else:
- ctype = "unsigned char"
-
- r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
- if size > 1:
- r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
- for byte in range(1, size):
- r += "\tr <<= 8;\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
- r += "\treturn r;\n}\n"
- else:
- r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
-
- if not read_only:
- r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
- for byte in range(size):
- shift = (size-byte-1)*8
- if shift:
- value_shifted = "value >> "+str(shift)
- else:
- value_shifted = "value"
- r += "\tMMPTR("+hex(reg_base+4*byte)+") = "+value_shifted+";\n"
- r += "}\n"
- return r
-
-def get_csr_header(csr_base, bank_array):
- r = "#ifndef __HW_CSR_H\n#define __HW_CSR_H\n#include <hw/common.h>\n"
- for name, csrs, mapaddr, rmap in bank_array.banks:
- r += "\n/* "+name+" */\n"
- reg_base = csr_base + 0x800*mapaddr
- r += "#define "+name.upper()+"_BASE "+hex(reg_base)+"\n"
- for csr in csrs:
- nr = (csr.size + 7)//8
- r += _get_rw_functions(name + "_" + csr.name, reg_base, nr, isinstance(csr, CSRStatus))
- reg_base += 4*nr
- r += "\n#endif\n"
- return r
-
-def _get_py_rw_functions(reg_name, reg_base, size):
- r = ""
-
- r += "def "+reg_name+"_read(bus):\n"
- r += "\tr = bus.read_csr("+hex(reg_base)+")\n"
- for byte in range(1, size):
- r += "\tr <<= 8\n\tr |= bus.read_csr("+hex(reg_base+4*byte)+")\n"
- r += "\treturn r\n\n"
-
-
- r += "def "+reg_name+"_write(bus, value):\n"
- for byte in range(size):
- shift = (size-byte-1)*8
- if shift:
- value_shifted = "value >> "+str(shift)
- else:
- value_shifted = "value"
- r += "\tbus.write_csr("+hex(reg_base+4*byte)+", ("+value_shifted+")&0xff)\n"
- r += "\n"
- return r
-
-def get_py_csr_header(csr_base, bank_array):
- r = ""
- for name, csrs, mapaddr, rmap in bank_array.banks:
- r += "\n# "+name+"\n"
- reg_base = csr_base + 0x800*mapaddr
- r += name.upper()+"_BASE ="+hex(reg_base)+"\n"
- for csr in csrs:
- nr = (csr.size + 7)//8
- r += _get_py_rw_functions(name + "_" + csr.name, reg_base, nr)
- reg_base += 4*nr
- return r
\ No newline at end of file
+++ /dev/null
-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)
- ]
\ No newline at end of file
+++ /dev/null
-import os
-import re
-import sys
-
-def is_number(x):
- try:
- _ = float(x)
- except ValueError:
- return False
- return True
-
-def remove_numbers(seq):
- return [ x for x in seq if not is_number(x)]
-
-def remove_duplicates(seq):
- seen = set()
- seen_add = seen.add
- return [ x for x in seq if x not in seen and not seen_add(x)]
-
-def get_operands(s):
- operands = re.findall("[A-z0-9_]+", s)
- operands = remove_duplicates(operands)
- operands = remove_numbers(operands)
- return sorted(operands)
-
-def gen_truth_table(s):
- operands = get_operands(s)
- width = len(operands)
- stim = []
- for i in range(width):
- stim_op = []
- for j in range(2**width):
- stim_op.append((int(j/(2**i)))%2)
- stim.append(stim_op)
-
- truth_table = []
- for i in range(2**width):
- for j in range(width):
- exec("%s = stim[j][i]" %operands[j])
- truth_table.append(eval(s) != 0)
- return truth_table
-
-def main():
- print(gen_truth_table("(A&B&C)|D"))
-
-if __name__ == '__main__':
- main()
+++ /dev/null
-import sys
-import datetime
-
-from miscope.std.misc import *
-
-def get_bits(values, width, low, high=None):
- r = []
- for val in values:
- t = dec2bin(val, width)[::-1]
- if high == None:
- t = t[low]
- else:
- t = t[low:high]
- t = t[::1]
- t = int(t,2)
- r.append(t)
- return r
-
-class VcdDat(list):
- def __init__(self, width):
- self.width = width
-
- def __getitem__(self, key):
- if isinstance(key, int):
- return get_bits(self, self.width, key)
- elif isinstance(key, slice):
- if key.start != None:
- start = key.start
- else:
- start = 0
- if key.stop != None:
- stop = key.stop
- else:
- stop = self.width
- if stop > self.width:
- stop = self.width
- if key.step != None:
- raise KeyError
- return get_bits(self, self.width, start, stop)
- else:
- raise KeyError
-
- def decode_rle(self):
- rle_bit = self[-1]
- rle_dat = self[:self.width-1]
-
- dat = VcdDat(self.width)
- i=0
- last = 0
- for d in self:
- if rle_bit[i]:
- if len(dat) >= 1:
- # FIX ME... why is rle_dat in reverse order...
- for j in range(int(dec2bin(rle_dat[i])[::-1],2)):
- dat.append(last)
- else:
- dat.append(d)
- last = d
- i +=1
- return dat
-
-class Var:
- def __init__(self, name, width, values=[], type="wire", default="x"):
- self.type = type
- self.width = width
- self.name = name
- self.val = default
- self.values = values
- self.vcd_id = None
-
- def set_vcd_id(self, s):
- self.vcd_id = s
-
- def __len__(self):
- return len(self.values)
-
- def change(self, cnt):
- r = ""
- try :
- if self.values[cnt+1] != self.val:
- r += "b"
- r += dec2bin(self.values[cnt+1], self.width)[::-1]
- r += " "
- r += self.vcd_id
- r += "\n"
- return r
- except :
- return r
- return r
-
-class Vcd:
- def __init__(self, timescale="1ps", comment=""):
- self.timescale = timescale
- self.comment = comment
- self.vars = []
- self.vcd_id = "!"
- self.cnt = -1
-
- def add(self, var):
- var.set_vcd_id(self.vcd_id)
- self.vcd_id = chr(ord(self.vcd_id)+1)
- self.vars.append(var)
-
- def add_from_layout(self, layout, var):
- i=0
- for s, n in layout:
- self.add(Var(s, n, var[i:i+n]))
- i += n
-
- def __len__(self):
- l = 0
- for var in self.vars:
- l = max(len(var),l)
- return l
-
- def change(self):
- r = ""
- c = ""
- for var in self.vars:
- c += var.change(self.cnt)
- if c != "":
- r += "#"
- r += str(self.cnt+1)
- r += "\n"
- r += c
- return r
-
- def p_date(self):
- now = datetime.datetime.now()
- r = "$date\n"
- r += "\t"
- r += now.strftime("%Y-%m-%d %H:%M")
- r += "\n"
- r += "$end\n"
- return r
-
- def p_version(self):
- r = "$version\n"
- r += "\tmiscope VCD dump\n"
- r += "$end\n"
- return r
-
- def p_comment(self):
- r = "$comment\n"
- r += self.comment
- r += "\n$end\n"
- return r
-
- def p_timescale(self):
- r = "$timescale "
- r += self.timescale
- r += " $end\n"
- return r
-
- def p_scope(self):
- r = "$scope "
- r += self.timescale
- r += " $end\n"
- return r
-
- def p_vars(self):
- r = ""
- for var in self.vars:
- r += "$var "
- r += var.type
- r += " "
- r += str(var.width)
- r += " "
- r += var.vcd_id
- r += " "
- r += var.name
- r += " $end\n"
- return r
-
- def p_unscope(self):
- r = "$unscope "
- r += " $end\n"
- return r
-
- def p_enddefinitions(self):
- r = "$enddefinitions "
- r += " $end\n"
- return r
-
- def p_dumpvars(self):
- r = "$dumpvars\n"
- for var in self.vars:
- r += "b"
- r += dec2bin(var.val, var.width)
- r += " "
- r += var.vcd_id
- r+= "\n"
- r += "$end\n"
- return r
-
- def p_valuechange(self):
- r = ""
- for i in range(len(self)):
- r += self.change()
- self.cnt += 1
- return r
-
- def __repr__(self):
- r = ""
- r += self.p_date()
- r += self.p_version()
- r += self.p_comment()
- r += self.p_timescale()
- r += self.p_scope()
- r += self.p_vars()
- r += self.p_unscope()
- r += self.p_enddefinitions()
- r += self.p_dumpvars()
- r += self.p_valuechange()
- return r
-
- def write(self, filename):
- f = open(filename, "w")
- f.write(str(self))
- f.close()
-
-def main():
- myvcd = Vcd()
- myvcd.add(Var(1, "foo1", [0,1,0,1,0,1]))
- myvcd.add(Var(2, "foo2", [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0]))
- myvcd.add(Var(3, "foo3"))
- myvcd.add(Var(4, "foo4"))
- ramp = [i%128 for i in range(1024)]
- myvcd.add(Var(16, "ramp", ramp))
- print(myvcd)
-
-if __name__ == '__main__':
- main()
-
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.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)
+ )
+
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))))
--- /dev/null
+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
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):
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):
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):
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()
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,
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()
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):
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
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)
# 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()