diff --git a/examples/de0_nano/Makefile b/examples/de0_nano/Makefile index 11ded926c..157f69b99 100644 --- a/examples/de0_nano/Makefile +++ b/examples/de0_nano/Makefile @@ -9,8 +9,8 @@ build/soc.qsf: $(PYTHON) build.py build/soc.map: build/soc.qsf - cp soc.qpf build/soc.qpf - cd build && quartus_map soc.qpf + cp soc.qpf build/de0_nano.qpf + cd build && quartus_map de0_nano.qpf clean: rm -rf build/* diff --git a/examples/de0_nano/build.py b/examples/de0_nano/build.py index 29510eea1..78618ee84 100644 --- a/examples/de0_nano/build.py +++ b/examples/de0_nano/build.py @@ -19,15 +19,6 @@ def get_qsf_prj(): r += "set_global_assignment -name VERILOG_FILE " + s + "\n" return r -add_core_dir("generic") -add_core_dir("lm32") -add_core_dir("hpdmc_sdr16") -add_core_dir("fmlbrg") -add_core_dir("uart") -add_core_dir("rc5") -add_core_dir("gpio") -add_core_dir("spi_master") - os.chdir("build") def str2file(filename, contents): @@ -37,8 +28,8 @@ def str2file(filename, contents): # generate top (src_verilog, qsf_cst) = top.get() -str2file("soc.v", src_verilog) -verilog_sources.append("build/soc.v") +str2file("de0_nano.v", src_verilog) +verilog_sources.append("build/de0_nano.v") # generate Quartus project file qsf_prj = get_qsf_prj() diff --git a/examples/de0_nano/client/.keep_me b/examples/de0_nano/client/.keep_me new file mode 100644 index 000000000..e69de29bb diff --git a/examples/de0_nano/constraints.py b/examples/de0_nano/constraints.py index 4c46bc5e1..97a8e87db 100644 --- a/examples/de0_nano/constraints.py +++ b/examples/de0_nano/constraints.py @@ -1,5 +1,5 @@ class Constraints: - def __init__(self, uart0, rc50, gpio0, led0, sw0, spi_master0, hpdmc0): + def __init__(self): self.constraints = [] def add(signal, pin, vec=-1, iostandard="3.3-V LVTTL", extra="", sch=""): self.constraints.append((signal, vec, pin, iostandard, extra,sch)) @@ -9,51 +9,7 @@ class Constraints: for p in pins: add(signal, p, i, iostandard, extra) i += 1 - - # uart0 - #add(uart0.tx, "TBD") - #add(uart0.rx, "TBD") - - # rc50 - #add(rc50.rx, "TBD") - - # gpio0 - #add_vec(gpio0.inputs, ["TBD","TBD","TBD","TBD", - # "TBD","TBD","TBD","TBD"]) - #add_vec(gpio0.outputs, ["TBD","TBD","TBD","TBD", - # "TBD","TBD","TBD","TBD"]) - - # led0 - add_vec(led0.outputs, ["A15", "A13", "B13", "A11", - "D1" , "F3" , "B1" , "L3"]) - - # sw0 - add_vec(sw0.inputs, ["M1", "T8", "B9", "M15"]) - - # spi_master0 - add(spi_master0.cs, "TBD") - add(spi_master0.sck, "TBD") - add(spi_master0.mosi, "TBD") - add(spi_master0.miso, "TBD") - - # hpdmc0 - add(hpdmc0.sdram_clk, "R4") - add(hpdmc0.sdram_cke, "L7") - add(hpdmc0.sdram_cs_n, "P6") - add(hpdmc0.sdram_we_n, "C2") - add(hpdmc0.sdram_cas_n, "L1") - add(hpdmc0.sdram_ras_n, "L2") - add_vec(hpdmc0.sdram_addr, ["P2","N5","N6","M8", - "P8","T7","N8","T6", - "R1","P1","N2","N1", - "L4",]) - add_vec(hpdmc0.sdram_ba, ["M7","M6"]) - add_vec(hpdmc0.sdram_dqm, ["R6","T5"]) - add_vec(hpdmc0.sdram_dq, ["G2", "G1", "L8", "K5", - "K2", "J2", "J1", "R7", - "T4", "T2", "T3", "R3", - "R5", "P3", "N3", "K1"]) - + def get_ios(self): return set([c[0] for c in self.constraints]) diff --git a/examples/de0_nano/top.py b/examples/de0_nano/top.py index 033143a63..02a65238a 100644 --- a/examples/de0_nano/top.py +++ b/examples/de0_nano/top.py @@ -1,24 +1,50 @@ -# De0Nano-System On Chip / Generic Base for a Custom SOC -# - Lm32 SoftCore -# - 32MB Sdram -# - 2KB Eeprom (TBD) -# - G Sensor & AD Converter (TBD) -# - Up to 72 GPIO (8 in/ 8 out) -# - Uart -# - Spi Slave & Master (Only Master) +################################################################################ +# _____ _ ____ _ _ _ _ +# | __|___ |_|___ _ _ | \|_|___|_| |_ ___| | +# | __| | | | . | | | | | | | . | | _| .'| | +# |_____|_|_|_| |___|_ | |____/|_|_ |_|_| |__,|_| +# |___| |___| |___| +# +# Copyright 2012 / Florent Kermarrec / florent@enjoy-digital.fr +# +# migScope Example on De0 Nano Board +# ---------------------------------- +################################################################################ +# +# In this example, signals are generated inside generated inside the FPGA. +# We will use migScope to record those signals it and visualize them. +# +# Example architecture: +# ---------------------- +# migScope Config <-- Python Client (Host) --> Vcd Output +# | +# Arduino (Uart<-->Spi Bridge) +# | +# De0 Nano +# | +# +--------------------+-----------------------+ +# migIo Signal Generator migLa +# Control of Signal Ramp, Sinus, Logic Analyzer +# generator Square, ... +############################################################################### + #============================================================================== # I M P O R T #============================================================================== -from fractions import Fraction -from math import ceil - from migen.fhdl.structure import * from migen.fhdl import verilog, autofragment -from migen.bus import wishbone, csr, wishbone2csr, fml +from migen.bus import csr +from migen.bus.transactions import * +from migen.bank import description, csrgen +from migen.bank.description import * + +import sys +sys.path.append("../../") + +from migScope import trigger, recorder +import spi2Csr -from soc import lm32, uart, rc5, gpio, spi_master, identifier, fmlbrg, hpdmc_sdr16 -from cmacros import get_macros from timings import * from constraints import Constraints @@ -31,93 +57,74 @@ clk_freq = 50*MHz clk_period_ns = clk_freq*ns n = t2n(clk_period_ns) +# Bus Width +trig_width = 16 +dat_width = 16 + +# Record Size +record_size = 1024 + +# Csr Addr +CONTROL_ADDR = 0x0000 +TRIGGER_ADDR = 0x0200 +RECORDER_ADDR = 0x0400 + #============================================================================== -# S O C +# M I S C O P E E X A M P L E #============================================================================== - -# -# Configuration -#=============================================================================== - -# Csr -csr_macros = get_macros("common/csrbase.h") -def csr_offset(name): - base = int(csr_macros[name + "_BASE"], 0) - assert((base >= 0xe0000000) and (base <= 0xe0010000)) - return (base - 0xe0000000)//0x800 - -# Interrupt -interrupt_macros = get_macros("common/interrupt.h") -def interrupt_n(name): - return int(interrupt_macros[name + "_INTERRUPT"], 0) - -# Version -version = get_macros("common/version.h")["VERSION"][1:-1] - def get(): - - # - # Wishbone - #=============================================================================== - cpu0 = lm32.LM32() - wishbone2csr0 = wishbone2csr.WB2CSR() - fmlbrg0 = fmlbrg.FMLBRG(16) - hpdmc0 = hpdmc_sdr16.HPDMC_SDR16(13) - # CSR 0x00000000 (shadow @0x80000000) - # FML bridge 0x10000000 (shadow @0x90000000) - wishbonecon = wishbone.InterconnectShared( - [ - cpu0.ibus, - cpu0.dbus - ], [ - (binc("000") , wishbone2csr0.wishbone), - (binc("001") , fmlbrg0.wishbone) - ], - register=True, - offset=1) - # - # Fml - #=============================================================================== - fmlcon0 = fml.Interconnect(fmlbrg0.fml,hpdmc0.fml) + # Control Reg + control_reg0 = RegisterField("control_reg0", 32, reset=0, access_dev=READ_ONLY) + regs = [control_reg0] + bank0 = csrgen.Bank(regs,address=CONTROL_ADDR) + + # Trigger + term0 = trigger.Term(trig_width) + trigger0 = trigger.Trigger(TRIGGER_ADDR, trig_width, dat_width, [term0]) - # - # Csr - #=============================================================================== - uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200) - identifier0 = identifier.Identifier(csr_offset("ID"), 0x1234, version, int(clk_freq)) - rc50 = rc5.RC5(csr_offset("RC5"),clk_freq) - gpio0 = gpio.GPIO(csr_offset("GPIO")) - led0 = gpio.GPIO(csr_offset("LED")) - sw0 = gpio.GPIO(csr_offset("SW"),4) - spi_master0 = spi_master.SPI_MASTER(csr_offset("SPI_MASTER")) - csrcon0 = csr.Interconnect(wishbone2csr0.csr, [ - uart0.csr, - identifier0.bank.interface, - rc50.csr, - gpio0.csr, - led0.csr, - sw0.csr, - spi_master0.csr, - hpdmc0.csr - ]) + # Recorder + recorder0 = recorder.Recorder(RECORDER_ADDR, dat_width, record_size) - # - # Interrupts - #=============================================================================== - interrupts = Fragment([ - cpu0.interrupt[interrupt_n("UART")].eq(uart0.irq), - cpu0.interrupt[interrupt_n("RC5")].eq(rc50.irq), - cpu0.interrupt[interrupt_n("GPIO")].eq(gpio0.irq) - ]) - # + # Spi2Csr + spi2csr0 = spi2Csr.Spi2Csr(16,8) + + # Csr Interconnect + csrcon0 = csr.Interconnect(spi2csr0.csr, + [ + bank0.interface, + trigger0.bank.interface, + recorder0.bank.interface + ]) + comb = [] + sync = [] + + # Signal Generator + sig_gen = Signal(BV(trig_width)) + sync += [ + sig_gen.eq(sig_gen+1) + ] + + # Dat / Trig Bus + comb += [ + trigger0.in_trig.eq(sig_gen), + trigger0.in_dat.eq(sig_gen) + ] + + # Trigger --> Recorder + comb += [ + recorder0.trig_dat.eq(trigger0.dat), + recorder0.trig_hit.eq(trigger0.hit) + ] + + # HouseKeeping - #=============================================================================== - frag = autofragment.from_local() + interrupts - cst = Constraints(uart0, rc50, gpio0, led0, sw0, spi_master0, hpdmc0) + frag = autofragment.from_local() + frag += Fragment(sync=sync,comb=comb) + cst = Constraints() src_verilog, vns = verilog.convert(frag, cst.get_ios(), - name="soc", + name="de0_nano", return_ns=True) src_qsf = cst.get_qsf(vns) return (src_verilog, src_qsf) \ No newline at end of file diff --git a/spi2Csr/__init__.py b/spi2Csr/__init__.py index 72e1ad0d2..68550603a 100644 --- a/spi2Csr/__init__.py +++ b/spi2Csr/__init__.py @@ -110,7 +110,7 @@ class Spi2Csr : spi_addr.eq(Cat(spi_mosi_dat,spi_addr[:self.a_width-1])) ).Elif((spi_cnt >= (self.a_width+self.d_width)) & last_b, spi_addr.eq(spi_addr+1) - ).Elif((spi_cnt >= self.a_width) & last_b & (spi_cnt[self.a_width-1] == 0), + ).Elif((spi_cnt >= self.a_width) & last_b & (spi_addr[self.a_width-1] == 0), spi_addr.eq(spi_addr+1) ), # dat