72e82a90aa50f123f57ef32b0982e9e3ea428209
5 from migen
.fhdl
.structure
import _Fragment
6 from migen
.build
.generic_platform
import *
7 from migen
.build
import tools
8 from migen
.build
.xilinx
import common
11 def _format_constraint(c
):
12 if isinstance(c
, Pins
):
13 return "LOC=" + c
.identifiers
[0]
14 elif isinstance(c
, IOStandard
):
15 return "IOSTANDARD=" + c
.name
16 elif isinstance(c
, Drive
):
17 return "DRIVE=" + str(c
.strength
)
18 elif isinstance(c
, Misc
):
22 def _format_ucf(signame
, pin
, others
, resname
):
24 for c
in [Pins(pin
)] + others
:
25 fc
= _format_constraint(c
)
28 fmt_r
= resname
[0] + ":" + str(resname
[1])
29 if resname
[2] is not None:
30 fmt_r
+= "." + resname
[2]
31 return "NET \"" + signame
+ "\" " + " | ".join(fmt_c
) + "; # " + fmt_r
+ "\n"
34 def _build_ucf(named_sc
, named_pc
):
36 for sig
, pins
, others
, resname
in named_sc
:
38 for i
, p
in enumerate(pins
):
39 r
+= _format_ucf(sig
+ "(" + str(i
) + ")", p
, others
, resname
)
41 r
+= _format_ucf(sig
, pins
[0], others
, resname
)
43 r
+= "\n" + "\n\n".join(named_pc
)
47 def _build_xst_files(device
, sources
, vincpaths
, build_name
, xst_opt
):
49 for filename
, language
, library
in sources
:
50 prj_contents
+= language
+ " " + library
+ " " + filename
+ "\n"
51 tools
.write_to_file(build_name
+ ".prj", prj_contents
)
59 """.format(build_name
=build_name
, xst_opt
=xst_opt
, device
=device
)
60 for path
in vincpaths
:
61 xst_contents
+= "-vlgincdir " + path
+ "\n"
62 tools
.write_to_file(build_name
+ ".xst", xst_contents
)
65 def _run_yosys(device
, sources
, vincpaths
, build_name
):
68 for path
in vincpaths
:
69 incflags
+= " -I" + path
70 for filename
, language
, library
in sources
:
71 ys_contents
+= "read_{}{} {}\n".format(language
, incflags
, filename
)
73 ys_contents
+= """hierarchy -check -top top
74 proc; memory; opt; fsm; opt
75 synth_xilinx -top top -edif {build_name}.edif""".format(build_name
=build_name
)
77 ys_name
= build_name
+ ".ys"
78 tools
.write_to_file(ys_name
, ys_contents
)
79 r
= subprocess
.call(["yosys", ys_name
])
81 raise OSError("Subprocess failed")
84 def _run_ise(build_name
, ise_path
, source
, mode
, ngdbuild_opt
,
85 bitgen_opt
, ise_commands
, map_opt
, par_opt
, ver
=None):
86 if sys
.platform
== "win32" or sys
.platform
== "cygwin":
90 build_script_contents
= "@echo off\nrem Autogenerated by Migen\n"
92 source_cmd
= "source "
95 build_script_contents
= "# Autogenerated by Migen\nset -e\n"
97 settings
= common
.settings(ise_path
, ver
, "ISE_DS")
98 build_script_contents
+= source_cmd
+ settings
+ "\n"
103 build_script_contents
+= """
104 xst -ifn {build_name}.xst
107 build_script_contents
+= """
108 ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd
109 map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf
110 par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf
111 bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit
113 build_script_contents
= build_script_contents
.format(build_name
=build_name
,
114 ngdbuild_opt
=ngdbuild_opt
, bitgen_opt
=bitgen_opt
, ext
=ext
,
115 par_opt
=par_opt
, map_opt
=map_opt
)
116 build_script_contents
+= ise_commands
.format(build_name
=build_name
)
117 build_script_file
= "build_" + build_name
+ script_ext
118 tools
.write_to_file(build_script_file
, build_script_contents
, force_unix
=False)
119 command
= shell
+ [build_script_file
]
120 r
= subprocess
.call(command
)
122 raise OSError("Subprocess failed")
125 class XilinxISEToolchain
:
127 self
.xst_opt
= """-ifmt MIXED
130 -register_balancing yes"""
131 self
.map_opt
= "-ol high -w"
132 self
.par_opt
= "-ol high -w"
133 self
.ngdbuild_opt
= ""
134 self
.bitgen_opt
= "-g Binary:Yes -w"
135 self
.ise_commands
= ""
137 def build(self
, platform
, fragment
, build_dir
="build", build_name
="top",
138 toolchain_path
=None, source
=None, run
=True, mode
="xst"):
139 if not isinstance(fragment
, _Fragment
):
140 fragment
= fragment
.get_fragment()
141 if toolchain_path
is None:
142 if sys
.platform
== "win32":
143 toolchain_path
= "C:\\Xilinx"
144 elif sys
.platform
== "cygwin":
145 toolchain_path
= "/cygdrive/c/Xilinx"
147 toolchain_path
= "/opt/Xilinx"
149 source
= sys
.platform
!= "win32"
151 platform
.finalize(fragment
)
152 ngdbuild_opt
= self
.ngdbuild_opt
155 tools
.mkdir_noerror(build_dir
)
159 if mode
== "xst" or mode
== "yosys":
160 v_output
= platform
.get_verilog(fragment
)
162 named_sc
, named_pc
= platform
.resolve_signals(vns
)
163 v_file
= build_name
+ ".v"
164 v_output
.write(v_file
)
165 sources
= platform
.sources |
{(v_file
, "verilog", "work")}
167 _build_xst_files(platform
.device
, sources
, platform
.verilog_include_paths
, build_name
, self
.xst_opt
)
170 _run_yosys(platform
.device
, sources
, platform
.verilog_include_paths
, build_name
)
172 ngdbuild_opt
+= "-p " + platform
.device
175 from mist
import synthesize
176 synthesize(fragment
, platform
.constraint_manager
.get_io_signals())
178 if mode
== "edif" or mode
== "mist":
179 e_output
= platform
.get_edif(fragment
)
181 named_sc
, named_pc
= platform
.resolve_signals(vns
)
182 e_file
= build_name
+ ".edif"
183 e_output
.write(e_file
)
186 tools
.write_to_file(build_name
+ ".ucf", _build_ucf(named_sc
, named_pc
))
188 _run_ise(build_name
, toolchain_path
, source
, isemode
,
189 ngdbuild_opt
, self
.bitgen_opt
, self
.ise_commands
,
190 self
.map_opt
, self
.par_opt
)
196 def add_period_constraint(self
, platform
, clk
, period
):
197 platform
.add_platform_command("""NET "{clk}" TNM_NET = "GRP{clk}";
198 TIMESPEC "TS{clk}" = PERIOD "GRP{clk}" """+str(period
)+""" ns HIGH 50%;""", clk
=clk
)