201 lines
5.3 KiB
Python
201 lines
5.3 KiB
Python
################################################################################
|
|
# _____ _ ____ _ _ _ _
|
|
# | __|___ |_|___ _ _ | \|_|___|_| |_ ___| |
|
|
# | __| | | | . | | | | | | | . | | _| .'| |
|
|
# |_____|_|_|_| |___|_ | |____/|_|_ |_|_| |__,|_|
|
|
# |___| |___| |___|
|
|
#
|
|
# Copyright 2012 / Florent Kermarrec / florent@enjoy-digital.fr
|
|
#
|
|
# miscope Example on De1 Board
|
|
# ----------------------------------
|
|
################################################################################
|
|
#
|
|
# In this example signals are generated in the FPGA.
|
|
# We use miscope to record those signals and visualize them.
|
|
#
|
|
# Example architecture:
|
|
# ----------------------
|
|
# miscope Config --> Python Client (Host) --> Vcd Output
|
|
# & Trig |
|
|
# Arduino (Uart<-->Spi Bridge)
|
|
# |
|
|
# De1
|
|
# |
|
|
# +--------------------+-----------------------+
|
|
# miIo Signal Generator miLa
|
|
# Control of Signal Ramp, Sinus, Logic Analyzer
|
|
# generator Square, ...
|
|
###############################################################################
|
|
|
|
|
|
#==============================================================================
|
|
# I M P O R T
|
|
#==============================================================================
|
|
from migen.fhdl.structure import *
|
|
from migen.fhdl.specials import Memory
|
|
from migen.fhdl import verilog, autofragment
|
|
from migen.bus import csr
|
|
from migen.bus.transactions import *
|
|
from migen.bank import description, csrgen
|
|
from migen.bank.description import *
|
|
|
|
from miscope import trigger, recorder, miio, mila
|
|
from miscope.bridges import spi2csr
|
|
|
|
from timings import *
|
|
|
|
from math import sin
|
|
|
|
#==============================================================================
|
|
# P A R A M E T E R S
|
|
#==============================================================================
|
|
|
|
#Timings Param
|
|
clk_freq = 50*MHz
|
|
clk_period_ns = clk_freq*ns
|
|
n = t2n(clk_period_ns)
|
|
|
|
# Bus Width
|
|
trig0_width = 16
|
|
dat0_width = 16
|
|
|
|
trig1_width = 32
|
|
dat1_width = 32
|
|
|
|
# Record Size
|
|
record_size = 4096
|
|
|
|
# Csr Addr
|
|
MIIO0_ADDR = 0x0000
|
|
MILA0_ADDR = 0x0200
|
|
MILA1_ADDR = 0x0600
|
|
|
|
#==============================================================================
|
|
# M I S C O P E E X A M P L E
|
|
#==============================================================================
|
|
class SoC:
|
|
def __init__(self):
|
|
# migIo0
|
|
self.miIo0 = miio.MiIo(MIIO0_ADDR, 8, "IO")
|
|
|
|
# migLa0
|
|
self.term0 = trigger.Term(trig0_width)
|
|
self.trigger0 = trigger.Trigger(trig0_width, [self.term0])
|
|
self.recorder0 = recorder.Recorder(dat0_width, record_size)
|
|
|
|
self.miLa0 = mila.MiLa(MILA0_ADDR, self.trigger0, self.recorder0)
|
|
|
|
# migLa1
|
|
self.term1 = trigger.Term(trig1_width)
|
|
self.trigger1 = trigger.Trigger(trig1_width, [self.term1])
|
|
self.recorder1 = recorder.Recorder(dat1_width, record_size)
|
|
|
|
self.miLa1 = mila.MiLa(MILA1_ADDR, self.trigger1, self.recorder1)
|
|
|
|
# Spi2Csr
|
|
self.spi2csr0 = spi2csr.Spi2Csr(16,8)
|
|
|
|
# Csr Interconnect
|
|
self.csrcon0 = csr.Interconnect(self.spi2csr0.csr,
|
|
[
|
|
self.miIo0.bank.bus,
|
|
self.miLa0.trigger.bank.bus,
|
|
self.miLa0.recorder.bank.bus,
|
|
self.miLa1.trigger.bank.bus,
|
|
self.miLa1.recorder.bank.bus
|
|
])
|
|
|
|
self.clk50 = Signal()
|
|
self.led = Signal(8)
|
|
self.gpio_0 = Signal(36)
|
|
self.key = Signal(4)
|
|
self.cd_sys = ClockDomain("sys")
|
|
|
|
def get_fragment(self):
|
|
comb = []
|
|
sync = []
|
|
|
|
#
|
|
# Signal Generator
|
|
#
|
|
|
|
# Counter
|
|
cnt_gen = Signal(8)
|
|
sync += [
|
|
cnt_gen.eq(cnt_gen+1)
|
|
]
|
|
|
|
# Square
|
|
square_gen = Signal(8)
|
|
sync += [
|
|
If(cnt_gen[7],
|
|
square_gen.eq(255)
|
|
).Else(
|
|
square_gen.eq(0)
|
|
)
|
|
]
|
|
|
|
sinus = [int(128*sin((2*3.1415)/256*(x+1)))+128 for x in range(256)]
|
|
sinus_re = Signal()
|
|
sinus_gen = Signal(8)
|
|
comb +=[sinus_re.eq(1)]
|
|
sinus_mem = Memory(8, 256, init = sinus)
|
|
sinus_port = sinus_mem.get_port(has_re=True)
|
|
comb += [
|
|
sinus_port.adr.eq(cnt_gen),
|
|
sinus_port.re.eq(sinus_re),
|
|
sinus_gen.eq(sinus_port.dat_r)
|
|
]
|
|
|
|
# Signal Selection
|
|
sig_gen = Signal(8)
|
|
comb += [
|
|
If(self.miIo0.o == 0,
|
|
sig_gen.eq(cnt_gen)
|
|
).Elif(self.miIo0.o == 1,
|
|
sig_gen.eq(square_gen)
|
|
).Elif(self.miIo0.o == 2,
|
|
sig_gen.eq(sinus_gen)
|
|
).Else(
|
|
sig_gen.eq(0)
|
|
)
|
|
]
|
|
|
|
# Led
|
|
comb += [self.led.eq(self.miIo0.o[:8])]
|
|
|
|
|
|
# MigLa0 input
|
|
comb += [
|
|
self.miLa0.trig.eq(sig_gen),
|
|
self.miLa0.dat.eq(sig_gen)
|
|
]
|
|
|
|
# MigLa1 input
|
|
comb += [
|
|
self.miLa1.trig[:8].eq(self.spi2csr0.csr.dat_w),
|
|
self.miLa1.trig[8:24].eq(self.spi2csr0.csr.adr),
|
|
self.miLa1.trig[24].eq(self.spi2csr0.csr.we),
|
|
self.miLa1.dat[:8].eq(self.spi2csr0.csr.dat_w),
|
|
self.miLa1.dat[8:24].eq(self.spi2csr0.csr.adr),
|
|
self.miLa1.dat[24].eq(self.spi2csr0.csr.we)
|
|
]
|
|
|
|
# Spi2Csr
|
|
self.spi2csr0.spi_clk = self.gpio_0[0]
|
|
self.spi2csr0.spi_cs_n = self.gpio_0[1]
|
|
self.spi2csr0.spi_mosi = self.gpio_0[2]
|
|
self.spi2csr0.spi_miso = self.gpio_0[3]
|
|
|
|
#
|
|
# Clocking / Reset
|
|
#
|
|
comb += [
|
|
self.cd_sys.clk.eq(self.clk50),
|
|
self.cd_sys.rst.eq(~self.key[0])
|
|
]
|
|
|
|
frag = autofragment.from_attributes(self)
|
|
frag += Fragment(comb, sync)
|
|
return frag |