From fb624fddc4ce40941684025462704268d1bf61fe Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 12 Sep 2012 17:56:36 +0200 Subject: [PATCH] initialize de1 example --- examples/de0_nano/de0_nano.sdc | 5 ++ examples/de1/Makefile | 30 +++++++ examples/de1/build.py | 36 ++++++++ examples/de1/build/.keep_me | 0 examples/de1/client/.keep_me | 0 examples/de1/constraints.py | 59 ++++++++++++++ examples/de1/de1.qpf | 30 +++++++ examples/de1/de1.sdc | 5 ++ examples/de1/timings.py | 29 +++++++ examples/de1/top.py | 145 +++++++++++++++++++++++++++++++++ 10 files changed, 339 insertions(+) create mode 100644 examples/de0_nano/de0_nano.sdc create mode 100644 examples/de1/Makefile create mode 100644 examples/de1/build.py create mode 100644 examples/de1/build/.keep_me create mode 100644 examples/de1/client/.keep_me create mode 100644 examples/de1/constraints.py create mode 100644 examples/de1/de1.qpf create mode 100644 examples/de1/de1.sdc create mode 100644 examples/de1/timings.py create mode 100644 examples/de1/top.py diff --git a/examples/de0_nano/de0_nano.sdc b/examples/de0_nano/de0_nano.sdc new file mode 100644 index 00000000..4687410a --- /dev/null +++ b/examples/de0_nano/de0_nano.sdc @@ -0,0 +1,5 @@ +# Synopsys, Inc. constraint file +# +# Clocks +# +create_clock -period 50MHz [get_ports in_clk] \ No newline at end of file diff --git a/examples/de1/Makefile b/examples/de1/Makefile new file mode 100644 index 00000000..87c35b31 --- /dev/null +++ b/examples/de1/Makefile @@ -0,0 +1,30 @@ +PYTHON=c:\Python32\python + +all: build/de1.sta +# We need to change to the build directory because the Quartus tools +# tend to dump a mess of various files in the current directory. + +build/de1.qsf: + $(PYTHON) build.py + +build/de1.map: build/de1.qsf + cp de1.qpf build/de1.qpf + cp de1.sdc build/de1.sdc + cd build && quartus_map de1.qpf + +build/de1.fit: build/de1.map + cd build && quartus_fit de1.qpf + +build/de1.asm: build/de1.fit + cd build && quartus_asm de1.qpf + +build/de1.sta: build/de1.asm + cd build && quartus_sta de1.qpf + +load: + cd build && quartus_pgm.exe -m jtag -c USB-Blaster[USB-0] -o "p;de1.sof" + +clean: + rm -rf build/* + +.PHONY: load clean diff --git a/examples/de1/build.py b/examples/de1/build.py new file mode 100644 index 00000000..b1c25b31 --- /dev/null +++ b/examples/de1/build.py @@ -0,0 +1,36 @@ +import os +import top + +# list Verilog sources before changing directory +verilog_sources = [] +def add_core_dir(d): + root = os.path.join("verilog", d, "rtl") + files = os.listdir(root) + for f in files: + if f[-2:] == ".v": + verilog_sources.append(os.path.join(root, f)) +def add_core_files(d, files): + for f in files: + verilog_sources.append(os.path.join("verilog", d, f)) + +def get_qsf_prj(): + r = "" + for s in verilog_sources: + r += "set_global_assignment -name VERILOG_FILE " + s + "\n" + return r + +os.chdir("build") + +def str2file(filename, contents): + f = open(filename, "w") + f.write(contents) + f.close() + +# generate top +(src_verilog, qsf_cst) = top.get() +str2file("de1.v", src_verilog) +verilog_sources.append("build/de1.v") + +# generate Quartus project file +qsf_prj = get_qsf_prj() +str2file("de1.qsf", qsf_prj + qsf_cst) \ No newline at end of file diff --git a/examples/de1/build/.keep_me b/examples/de1/build/.keep_me new file mode 100644 index 00000000..e69de29b diff --git a/examples/de1/client/.keep_me b/examples/de1/client/.keep_me new file mode 100644 index 00000000..e69de29b diff --git a/examples/de1/constraints.py b/examples/de1/constraints.py new file mode 100644 index 00000000..8c1f33ee --- /dev/null +++ b/examples/de1/constraints.py @@ -0,0 +1,59 @@ +class Constraints: + def __init__(self, in_clk, in_rst_n, spi2csr0, led0): + self.constraints = [] + def add(signal, pin, vec=-1, iostandard="3.3-V LVTTL", extra="", sch=""): + self.constraints.append((signal, vec, pin, iostandard, extra,sch)) + def add_vec(signal, pins, iostandard="3.3-V LVTTL", extra="", sch=""): + assert(signal.bv.width == len(pins)), "%s size : %d / qsf size : %d" %(signal,signal.bv.width,len(pins)) + i = 0 + for p in pins: + add(signal, p, i, iostandard, extra) + i += 1 + # sys_clk + add(in_clk, "L1") # CLOCK_50 + + # sys_rst + add(in_rst_n, "R22") # KEY[0] + + # spi2csr0 + add(spi2csr0.spi_clk, "F13") #GPIO_1[9] + add(spi2csr0.spi_cs_n, "G15") #GPIO_1[3] + add(spi2csr0.spi_mosi, "E15") #GPIO_1[5] + add(spi2csr0.spi_miso, "G16") #GPIO_1[7] + + # led0 + add_vec(led0, ["U22", "U21", "V22", "V21", + "W22" , "W21" , "Y22" , "Y21"]) + + def get_ios(self): + return set([c[0] for c in self.constraints]) + + def get_qsf(self, ns): + r = "" + for c in self.constraints: + r += "set_location_assignment PIN_"+str(c[2]) + r += " -to " + ns.get_name(c[0]) + if c[1] >= 0: + r += "[" + str(c[1]) + "]" + r += "\n" + + r += "set_instance_assignment -name IO_STANDARD " + r += "\"" + c[3] + "\"" + r += " -to " + ns.get_name(c[0]) + if c[1] >= 0: + r += "[" + str(c[1]) + "]" + r += "\n" + + r += """ +set_global_assignment -name FAMILY "Cyclone II" +set_global_assignment -name DEVICE EP2C20F484C7 +set_global_assignment -name TOP_LEVEL_ENTITY "de1" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name DUTY_CYCLE 50 -section_id in_clk +set_global_assignment -name FMAX_REQUIREMENT "50.0 MHz" -section_id in_clk + """ + return r diff --git a/examples/de1/de1.qpf b/examples/de1/de1.qpf new file mode 100644 index 00000000..82d96c17 --- /dev/null +++ b/examples/de1/de1.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.0 Build 132 02/25/2009 SJ Full Version +# Date created = 11:09:38 March 18, 2009 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "9.0" +DATE = "11:09:38 March 18, 2009" + +# Revisions + +PROJECT_REVISION = "soc" diff --git a/examples/de1/de1.sdc b/examples/de1/de1.sdc new file mode 100644 index 00000000..4687410a --- /dev/null +++ b/examples/de1/de1.sdc @@ -0,0 +1,5 @@ +# Synopsys, Inc. constraint file +# +# Clocks +# +create_clock -period 50MHz [get_ports in_clk] \ No newline at end of file diff --git a/examples/de1/timings.py b/examples/de1/timings.py new file mode 100644 index 00000000..c3fa4b17 --- /dev/null +++ b/examples/de1/timings.py @@ -0,0 +1,29 @@ +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*(GHz/MHz) + self.clk_period_ms = clk_period_ns*(GHz/KHz) + 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 diff --git a/examples/de1/top.py b/examples/de1/top.py new file mode 100644 index 00000000..0f5e39b5 --- /dev/null +++ b/examples/de1/top.py @@ -0,0 +1,145 @@ +################################################################################ +# _____ _ ____ _ _ _ _ +# | __|___ |_|___ _ _ | \|_|___|_| |_ ___| | +# | __| | | | . | | | | | | | . | | _| .'| | +# |_____|_|_|_| |___|_ | |____/|_|_ |_|_| |__,|_| +# |___| |___| |___| +# +# Copyright 2012 / Florent Kermarrec / florent@enjoy-digital.fr +# +# migScope Example on De1 Board +# ---------------------------------- +################################################################################ +# +# In this example signals are generated in the FPGA. +# We will use migScope to record those signals and visualize them. +# +# Example architecture: +# ---------------------- +# migScope Config --> Python Client (Host) --> Vcd Output +# & Trig | +# 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 migen.fhdl.structure import * +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 * + +import sys +sys.path.append("../../") + +from migScope import trigger, recorder +import spi2Csr + +from timings import * +from constraints import Constraints + +#============================================================================== +# 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 +trig_width = 16 +dat_width = 16 + +# Record Size +record_size = 1024 + +# Csr Addr +CONTROL_ADDR = 0x0000 +TRIGGER_ADDR = 0x0200 +RECORDER_ADDR = 0x0400 + +#============================================================================== +# M I S C O P E E X A M P L E +#============================================================================== +def get(): + + # 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]) + + # Recorder + recorder0 = recorder.Recorder(RECORDER_ADDR, dat_width, record_size) + + # 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) + ] + + # Led + led0 = Signal(BV(8)) + comb += [ + led0.eq(control_reg0.field.r[:8]) + ] + + + # 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 + in_clk = Signal() + in_rst_n = Signal() + in_rst = Signal() + comb += [ + in_rst.eq(~in_rst_n) + ] + frag = autofragment.from_local() + frag += Fragment(sync=sync,comb=comb) + cst = Constraints(in_clk, in_rst_n, spi2csr0, led0) + src_verilog, vns = verilog.convert(frag, + cst.get_ios(), + name="de0_nano", + clk_signal = in_clk, + rst_signal = in_rst, + return_ns=True) + src_qsf = cst.get_qsf(vns) + return (src_verilog, src_qsf) \ No newline at end of file -- 2.30.2