initialize de1 example
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 12 Sep 2012 15:56:36 +0000 (17:56 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 12 Sep 2012 15:56:36 +0000 (17:56 +0200)
examples/de0_nano/de0_nano.sdc [new file with mode: 0644]
examples/de1/Makefile [new file with mode: 0644]
examples/de1/build.py [new file with mode: 0644]
examples/de1/build/.keep_me [new file with mode: 0644]
examples/de1/client/.keep_me [new file with mode: 0644]
examples/de1/constraints.py [new file with mode: 0644]
examples/de1/de1.qpf [new file with mode: 0644]
examples/de1/de1.sdc [new file with mode: 0644]
examples/de1/timings.py [new file with mode: 0644]
examples/de1/top.py [new file with mode: 0644]

diff --git a/examples/de0_nano/de0_nano.sdc b/examples/de0_nano/de0_nano.sdc
new file mode 100644 (file)
index 0000000..4687410
--- /dev/null
@@ -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 (file)
index 0000000..87c35b3
--- /dev/null
@@ -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 (file)
index 0000000..b1c25b3
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/examples/de1/client/.keep_me b/examples/de1/client/.keep_me
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/examples/de1/constraints.py b/examples/de1/constraints.py
new file mode 100644 (file)
index 0000000..8c1f33e
--- /dev/null
@@ -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 (file)
index 0000000..82d96c1
--- /dev/null
@@ -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 (file)
index 0000000..4687410
--- /dev/null
@@ -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 (file)
index 0000000..c3fa4b1
--- /dev/null
@@ -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 (file)
index 0000000..0f5e39b
--- /dev/null
@@ -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