use mibuild for de1 example
This commit is contained in:
parent
58a6acba27
commit
80e9db7e61
|
@ -1,29 +1,14 @@
|
||||||
PYTHON=c:\Python32\python
|
PYTHON=C:\Python32\python
|
||||||
|
|
||||||
all: build/de1.sta
|
all: build/top.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:
|
build/top.sta:
|
||||||
|
cp top.sdc build/top.sdc
|
||||||
$(PYTHON) build.py
|
$(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:
|
load:
|
||||||
cd build && quartus_pgm.exe -m jtag -c USB-Blaster[USB-0] -o "p;de1.sof"
|
cd build && quartus_pgm.exe -m jtag -c USB-Blaster[USB-0] -o "p;top.sof"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf build/*
|
rm -rf build/*
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,34 @@
|
||||||
import os
|
import os
|
||||||
|
from mibuild.platforms import de1
|
||||||
|
from mibuild.altera_quartus import _add_period_constraint
|
||||||
import top
|
import top
|
||||||
|
|
||||||
# list Verilog sources before changing directory
|
def main():
|
||||||
verilog_sources = []
|
plat = de1.Platform()
|
||||||
def add_core_dir(d):
|
soc = top.SoC()
|
||||||
root = os.path.join("verilog", d, "rtl")
|
|
||||||
files = os.listdir(root)
|
# set pin constraints
|
||||||
for f in files:
|
plat.request("clk50", obj=soc.clk50)
|
||||||
if f[-2:] == ".v":
|
plat.request("key", obj=soc.key)
|
||||||
verilog_sources.append(os.path.join(root, f))
|
plat.request("ledg", obj=soc.led)
|
||||||
def add_core_files(d, files):
|
plat.request("gpio_0", obj=soc.gpio_0)
|
||||||
for f in files:
|
|
||||||
verilog_sources.append(os.path.join("verilog", d, f))
|
# 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():
|
_add_period_constraint(plat, "sys_clk", 20.0)
|
||||||
r = ""
|
cd = dict()
|
||||||
for s in verilog_sources:
|
cd["sys"] = soc.cd_sys
|
||||||
r += "set_global_assignment -name VERILOG_FILE " + s + "\n"
|
plat.build_cmdline(soc.get_fragment(), clock_domains=cd)
|
||||||
return r
|
|
||||||
|
|
||||||
os.chdir("build")
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
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)
|
|
|
@ -1,62 +0,0 @@
|
||||||
class Constraints:
|
|
||||||
def __init__(self, in_rst_n, cd_in, spi2csr0, led0, sw0):
|
|
||||||
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, "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"])
|
|
||||||
# sw0
|
|
||||||
add_vec(sw0, ["L22", "L21", "M22", "V12",
|
|
||||||
"W12" , "U12" , "U11" , "M2"])
|
|
||||||
|
|
||||||
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
|
|
|
@ -1,3 +0,0 @@
|
||||||
# Revisions
|
|
||||||
|
|
||||||
PROJECT_REVISION = "de1"
|
|
|
@ -1,4 +0,0 @@
|
||||||
#
|
|
||||||
# Clocks
|
|
||||||
#
|
|
||||||
create_clock -period 50MHz [get_ports in_clk]
|
|
|
@ -43,7 +43,6 @@ from miscope import trigger, recorder, miio, mila
|
||||||
from miscope.bridges import spi2csr
|
from miscope.bridges import spi2csr
|
||||||
|
|
||||||
from timings import *
|
from timings import *
|
||||||
from constraints import Constraints
|
|
||||||
|
|
||||||
from math import sin
|
from math import sin
|
||||||
|
|
||||||
|
@ -74,128 +73,128 @@ MILA1_ADDR = 0x0600
|
||||||
#==============================================================================
|
#==============================================================================
|
||||||
# M I S C O P E E X A M P L E
|
# 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_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])
|
||||||
|
]
|
||||||
|
|
||||||
# migIo0
|
frag = autofragment.from_attributes(self)
|
||||||
miIo0 = miio.MiIo(MIIO0_ADDR, 8, "IO")
|
frag += Fragment(comb, sync)
|
||||||
|
return frag
|
||||||
# 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])]
|
|
||||||
|
|
||||||
#Switch
|
|
||||||
sw0 = Signal(8)
|
|
||||||
comb += [miIo0.i.eq(sw0)]
|
|
||||||
|
|
||||||
# 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, sw0)
|
|
||||||
src_verilog, vns = verilog.convert(frag,
|
|
||||||
cst.get_ios(),
|
|
||||||
name="de1",
|
|
||||||
clock_domains={
|
|
||||||
"sys": cd_in
|
|
||||||
},
|
|
||||||
return_ns=True)
|
|
||||||
src_qsf = cst.get_qsf(vns)
|
|
||||||
return (src_verilog, src_qsf)
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#
|
||||||
|
# Clocks
|
||||||
|
#
|
||||||
|
create_clock -period 50MHz [get_ports clk50]
|
Loading…
Reference in New Issue