import os
+from mibuild.platforms import de0nano
+from mibuild.altera_quartus import _add_period_constraint
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 main():
+ plat = de0nano.Platform()
+ soc = top.SoC()
+
+ # set pin constraints
+ plat.request("clk50", obj=soc.clk50)
+ plat.request("key", obj=soc.key)
+ plat.request("led", obj=soc.led)
+ plat.request("gpio_2", obj=soc.gpio_2)
+
+ # set extra constraints
+ plat.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
+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"
+""")
-def get_qsf_prj():
- r = ""
- for s in verilog_sources:
- r += "set_global_assignment -name VERILOG_FILE " + s + "\n"
- return r
+ _add_period_constraint(plat, "sys_clk", 20.0)
+ cd = dict()
+ cd["sys"] = soc.cd_sys
+ plat.build_cmdline(soc.get_fragment(), clock_domains=cd)
-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("de0_nano.v", src_verilog)
-verilog_sources.append("build/de0_nano.v")
-
-# generate Quartus project file
-qsf_prj = get_qsf_prj()
-str2file("de0_nano.qsf", qsf_prj + qsf_cst)
\ No newline at end of file
+if __name__ == "__main__":
+ main()
\ No newline at end of file
+++ /dev/null
-class Constraints:
- def __init__(self, in_rst_n, cd_in, 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.nbits == 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(cd_in.clk, "R8") # CLOCK_50
-
- # sys_rst
- add(in_rst_n, "J15") # KEY[0]
-
- # spi2csr0
- add(spi2csr0.spi_clk, "A14") #GPIO_2[0]
- add(spi2csr0.spi_cs_n, "B16") #GPIO_2[1]
- add(spi2csr0.spi_mosi, "C14") #GPIO_2[2]
- add(spi2csr0.spi_miso, "C16") #GPIO_2[3]
-
- # led0
- add_vec(led0, ["A15", "A13", "B13", "A11",
- "D1" , "F3" , "B1" , "L3"])
-
-
- 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 IV E"
-set_global_assignment -name DEVICE EP4CE22F17C6
-set_global_assignment -name TOP_LEVEL_ENTITY "de0_nano"
-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
#
# Copyright 2012 / Florent Kermarrec / florent@enjoy-digital.fr
#
-# miscope Example on De0 Nano Board
+# miscope example on De0 Nano Board
# ----------------------------------
################################################################################
#
from miscope.bridges import spi2csr
from timings import *
-from constraints import Constraints
from math import sin
#==============================================================================
# M I S C O P E E X A M P L E
#==============================================================================
-def get():
+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_2 = Signal(13)
+ self.key = Signal(2)
+ 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_2[0]
+ self.spi2csr0.spi_cs_n = self.gpio_2[1]
+ self.spi2csr0.spi_mosi = self.gpio_2[2]
+ self.spi2csr0.spi_miso = self.gpio_2[3]
+
+ #
+ # Clocking / Reset
+ #
+ comb += [
+ self.cd_sys.clk.eq(self.clk50),
+ self.cd_sys.rst.eq(~self.key[0])
+ ]
- # migIo0
- miIo0 = miio.MiIo(MIIO0_ADDR, 8, "IO")
-
- # migLa0
- term0 = trigger.Term(trig0_width)
- trigger0 = trigger.Trigger(trig0_width, [term0])
- recorder0 = recorder.Recorder(dat0_width, record_size)
-
- miLa0 = mila.MiLa(MILA0_ADDR, trigger0, recorder0)
-
- # migLa1
- term1 = trigger.Term(trig1_width)
- trigger1 = trigger.Trigger(trig1_width, [term1])
- recorder1 = recorder.Recorder(dat1_width, record_size)
-
- miLa1 = mila.MiLa(MILA1_ADDR, trigger1, recorder1)
-
- # Spi2Csr
- spi2csr0 = spi2csr.Spi2Csr(16,8)
-
- # Csr Interconnect
- csrcon0 = csr.Interconnect(spi2csr0.csr,
- [
- miIo0.bank.bus,
- miLa0.trigger.bank.bus,
- miLa0.recorder.bank.bus,
- miLa1.trigger.bank.bus,
- miLa1.recorder.bank.bus,
-
- ])
- 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(miIo0.o == 0,
- sig_gen.eq(cnt_gen)
- ).Elif(miIo0.o == 1,
- sig_gen.eq(square_gen)
- ).Elif(miIo0.o == 2,
- sig_gen.eq(sinus_gen)
- ).Else(
- sig_gen.eq(0)
- )
- ]
-
- # Led
- led0 = Signal(8)
- comb += [led0.eq(miIo0.o[:8])]
-
-
- # MigLa0 input
- comb += [
- miLa0.trig.eq(sig_gen),
- miLa0.dat.eq(sig_gen)
- ]
-
- # MigLa1 input
- comb += [
- miLa1.trig[:8].eq(spi2csr0.csr.dat_w),
- miLa1.trig[8:24].eq(spi2csr0.csr.adr),
- miLa1.trig[24].eq(spi2csr0.csr.we),
- miLa1.dat[:8].eq(spi2csr0.csr.dat_w),
- miLa1.dat[8:24].eq(spi2csr0.csr.adr),
- miLa1.dat[24].eq(spi2csr0.csr.we)
- ]
-
-
- # HouseKeeping
- cd_in = ClockDomain("in")
- in_rst_n = Signal()
- comb += [
- cd_in.rst.eq(~in_rst_n)
- ]
-
- frag = autofragment.from_local()
- frag += Fragment(sync=sync,comb=comb,memories=[sinus_mem])
- cst = Constraints(in_rst_n, cd_in, spi2csr0, led0)
- src_verilog, vns = verilog.convert(frag,
- cst.get_ios(),
- name="de0_nano",
- clock_domains={
- "sys": cd_in
- },
- return_ns=True)
- src_qsf = cst.get_qsf(vns)
- return (src_verilog, src_qsf)
\ No newline at end of file
+ frag = autofragment.from_attributes(self)
+ frag += Fragment(comb, sync)
+ return frag
\ No newline at end of file