1 from abc
import abstractproperty
4 from ..lib
.cdc
import ResetSynchronizer
8 __all__
= ["QuicklogicPlatform"]
11 class QuicklogicPlatform(TemplatedPlatform
):
21 * ``symbiflow_write_fasm``
22 * ``symbiflow_write_bitstream``
24 The environment is populated by running the script specified in the environment variable
25 ``NMIGEN_ENV_QLSymbiflow``, if present.
28 * ``add_constraints``: inserts commands in XDC file.
31 device
= abstractproperty()
32 package
= abstractproperty()
34 # Since the QuickLogic version of SymbiFlow toolchain is not upstreamed yet
35 # we should distinguish the QuickLogic version from mainline one.
36 # QuickLogic toolchain: https://github.com/QuickLogic-Corp/quicklogic-fpga-toolchain/releases
37 toolchain
= "QLSymbiflow"
44 "symbiflow_write_fasm",
45 "symbiflow_write_bitstream",
46 "symbiflow_write_openocd",
49 **TemplatedPlatform
.build_script_templates
,
51 /* {{autogenerated}} */
54 "{{name}}.debug.v": r
"""
55 /* {{autogenerated}} */
56 {{emit_debug_verilog()}}
60 {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
61 set_io {{port_name}} {{pin_name}}
66 {% for port_name, pin_name, attrs in platform.iter_port_constraints_bits() -%}
67 {% for attr_name, attr_value in attrs.items() -%}
68 set_property {{attr_name}} {{attr_value}} [get_ports {{port_name|tcl_escape}} }]
71 {{get_override("add_constraints")|default("# (add_constraints placeholder)")}}
75 {% for net_signal, port_signal, frequency in platform.iter_clock_constraints() -%}
76 {% if port_signal is not none -%}
77 create_clock -period {{100000000/frequency}} {{port_signal.name|ascii_escape}}
84 {{invoke_tool("symbiflow_synth")}}
86 -v {% for file in platform.iter_files(".v", ".sv", ".vhd", ".vhdl") -%} {{file}} {% endfor %} {{name}}.v
87 -d {{platform.device}}
89 -P {{platform.package}}
93 {{invoke_tool("symbiflow_pack")}}
95 -d {{platform.device}}
99 {{invoke_tool("symbiflow_place")}}
101 -d {{platform.device}}
104 -P {{platform.package}}
108 {{invoke_tool("symbiflow_route")}}
110 -d {{platform.device}}
114 {{invoke_tool("symbiflow_write_fasm")}}
116 -d {{platform.device}}
120 {{invoke_tool("symbiflow_write_bitstream")}}
122 -d {{platform.device}}
123 -P {{platform.package}}
126 # This should be `invoke_tool("symbiflow_write_openocd")`, but isn't because of a bug in
127 # the QLSymbiflow v1.3.0 toolchain release.
129 python3 -m quicklogic_fasm.bitstream_to_openocd
137 def add_clock_constraint(self
, clock
, frequency
):
138 super().add_clock_constraint(clock
, frequency
)
139 clock
.attrs
["keep"] = "TRUE"
141 def create_missing_domain(self
, name
):
142 if name
== "sync" and self
.default_clk
is not None:
144 if self
.default_clk
== "sys_clk0":
147 m
.submodules
+= Instance("qlal4s3b_cell_macro",
149 m
.submodules
+= Instance("gclkbuff",
153 clk_i
= self
.request(self
.default_clk
).i
155 if self
.default_rst
is not None:
156 rst_i
= self
.request(self
.default_rst
).i
160 m
.domains
+= ClockDomain("sync")
161 m
.d
.comb
+= ClockSignal("sync").eq(clk_i
)
162 m
.submodules
.reset_sync
= ResetSynchronizer(rst_i
, domain
="sync")