siliconcompiler 0.26.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siliconcompiler/__init__.py +24 -0
- siliconcompiler/__main__.py +12 -0
- siliconcompiler/_common.py +49 -0
- siliconcompiler/_metadata.py +36 -0
- siliconcompiler/apps/__init__.py +0 -0
- siliconcompiler/apps/_common.py +76 -0
- siliconcompiler/apps/sc.py +92 -0
- siliconcompiler/apps/sc_dashboard.py +94 -0
- siliconcompiler/apps/sc_issue.py +178 -0
- siliconcompiler/apps/sc_remote.py +199 -0
- siliconcompiler/apps/sc_server.py +39 -0
- siliconcompiler/apps/sc_show.py +142 -0
- siliconcompiler/apps/smake.py +232 -0
- siliconcompiler/checklists/__init__.py +0 -0
- siliconcompiler/checklists/oh_tapeout.py +41 -0
- siliconcompiler/core.py +3221 -0
- siliconcompiler/data/RobotoMono/LICENSE.txt +202 -0
- siliconcompiler/data/RobotoMono/RobotoMono-Regular.ttf +0 -0
- siliconcompiler/data/heartbeat.v +18 -0
- siliconcompiler/data/logo.png +0 -0
- siliconcompiler/flowgraph.py +570 -0
- siliconcompiler/flows/__init__.py +0 -0
- siliconcompiler/flows/_common.py +67 -0
- siliconcompiler/flows/asicflow.py +180 -0
- siliconcompiler/flows/asictopflow.py +38 -0
- siliconcompiler/flows/dvflow.py +86 -0
- siliconcompiler/flows/fpgaflow.py +202 -0
- siliconcompiler/flows/generate_openroad_rcx.py +66 -0
- siliconcompiler/flows/lintflow.py +35 -0
- siliconcompiler/flows/screenshotflow.py +51 -0
- siliconcompiler/flows/showflow.py +59 -0
- siliconcompiler/flows/signoffflow.py +53 -0
- siliconcompiler/flows/synflow.py +128 -0
- siliconcompiler/fpgas/__init__.py +0 -0
- siliconcompiler/fpgas/lattice_ice40.py +42 -0
- siliconcompiler/fpgas/vpr_example.py +109 -0
- siliconcompiler/issue.py +300 -0
- siliconcompiler/libs/__init__.py +0 -0
- siliconcompiler/libs/asap7sc7p5t.py +8 -0
- siliconcompiler/libs/gf180mcu.py +8 -0
- siliconcompiler/libs/nangate45.py +8 -0
- siliconcompiler/libs/sky130hd.py +8 -0
- siliconcompiler/libs/sky130io.py +8 -0
- siliconcompiler/package.py +412 -0
- siliconcompiler/pdks/__init__.py +0 -0
- siliconcompiler/pdks/asap7.py +8 -0
- siliconcompiler/pdks/freepdk45.py +8 -0
- siliconcompiler/pdks/gf180.py +8 -0
- siliconcompiler/pdks/skywater130.py +8 -0
- siliconcompiler/remote/__init__.py +36 -0
- siliconcompiler/remote/client.py +891 -0
- siliconcompiler/remote/schema.py +106 -0
- siliconcompiler/remote/server.py +507 -0
- siliconcompiler/remote/server_schema/requests/cancel_job.json +51 -0
- siliconcompiler/remote/server_schema/requests/check_progress.json +61 -0
- siliconcompiler/remote/server_schema/requests/check_server.json +38 -0
- siliconcompiler/remote/server_schema/requests/delete_job.json +51 -0
- siliconcompiler/remote/server_schema/requests/get_results.json +48 -0
- siliconcompiler/remote/server_schema/requests/remote_run.json +40 -0
- siliconcompiler/remote/server_schema/responses/cancel_job.json +18 -0
- siliconcompiler/remote/server_schema/responses/check_progress.json +30 -0
- siliconcompiler/remote/server_schema/responses/check_server.json +32 -0
- siliconcompiler/remote/server_schema/responses/delete_job.json +18 -0
- siliconcompiler/remote/server_schema/responses/get_results.json +21 -0
- siliconcompiler/remote/server_schema/responses/remote_run.json +25 -0
- siliconcompiler/report/__init__.py +13 -0
- siliconcompiler/report/html_report.py +74 -0
- siliconcompiler/report/report.py +355 -0
- siliconcompiler/report/streamlit_report.py +137 -0
- siliconcompiler/report/streamlit_viewer.py +944 -0
- siliconcompiler/report/summary_image.py +117 -0
- siliconcompiler/report/summary_table.py +105 -0
- siliconcompiler/report/utils.py +163 -0
- siliconcompiler/scheduler/__init__.py +2092 -0
- siliconcompiler/scheduler/docker_runner.py +253 -0
- siliconcompiler/scheduler/run_node.py +138 -0
- siliconcompiler/scheduler/send_messages.py +178 -0
- siliconcompiler/scheduler/slurm.py +208 -0
- siliconcompiler/scheduler/validation/email_credentials.json +54 -0
- siliconcompiler/schema/__init__.py +7 -0
- siliconcompiler/schema/schema_cfg.py +4014 -0
- siliconcompiler/schema/schema_obj.py +1841 -0
- siliconcompiler/schema/utils.py +93 -0
- siliconcompiler/sphinx_ext/__init__.py +0 -0
- siliconcompiler/sphinx_ext/dynamicgen.py +1006 -0
- siliconcompiler/sphinx_ext/schemagen.py +221 -0
- siliconcompiler/sphinx_ext/utils.py +166 -0
- siliconcompiler/targets/__init__.py +0 -0
- siliconcompiler/targets/asap7_demo.py +68 -0
- siliconcompiler/targets/asic_demo.py +38 -0
- siliconcompiler/targets/fpgaflow_demo.py +47 -0
- siliconcompiler/targets/freepdk45_demo.py +59 -0
- siliconcompiler/targets/gf180_demo.py +77 -0
- siliconcompiler/targets/skywater130_demo.py +70 -0
- siliconcompiler/templates/email/general.j2 +66 -0
- siliconcompiler/templates/email/summary.j2 +43 -0
- siliconcompiler/templates/issue/README.txt +26 -0
- siliconcompiler/templates/issue/run.sh +6 -0
- siliconcompiler/templates/report/bootstrap.min.css +7 -0
- siliconcompiler/templates/report/bootstrap.min.js +7 -0
- siliconcompiler/templates/report/bootstrap_LICENSE.md +24 -0
- siliconcompiler/templates/report/sc_report.j2 +427 -0
- siliconcompiler/templates/slurm/run.sh +9 -0
- siliconcompiler/templates/tcl/manifest.tcl.j2 +137 -0
- siliconcompiler/tools/__init__.py +0 -0
- siliconcompiler/tools/_common/__init__.py +432 -0
- siliconcompiler/tools/_common/asic.py +115 -0
- siliconcompiler/tools/_common/sdc/sc_constraints.sdc +76 -0
- siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +63 -0
- siliconcompiler/tools/bambu/bambu.py +32 -0
- siliconcompiler/tools/bambu/convert.py +77 -0
- siliconcompiler/tools/bluespec/bluespec.py +40 -0
- siliconcompiler/tools/bluespec/convert.py +103 -0
- siliconcompiler/tools/builtin/_common.py +155 -0
- siliconcompiler/tools/builtin/builtin.py +26 -0
- siliconcompiler/tools/builtin/concatenate.py +85 -0
- siliconcompiler/tools/builtin/join.py +27 -0
- siliconcompiler/tools/builtin/maximum.py +46 -0
- siliconcompiler/tools/builtin/minimum.py +57 -0
- siliconcompiler/tools/builtin/mux.py +70 -0
- siliconcompiler/tools/builtin/nop.py +38 -0
- siliconcompiler/tools/builtin/verify.py +83 -0
- siliconcompiler/tools/chisel/SCDriver.scala +10 -0
- siliconcompiler/tools/chisel/build.sbt +27 -0
- siliconcompiler/tools/chisel/chisel.py +37 -0
- siliconcompiler/tools/chisel/convert.py +140 -0
- siliconcompiler/tools/execute/exec_input.py +41 -0
- siliconcompiler/tools/execute/execute.py +17 -0
- siliconcompiler/tools/genfasm/bitstream.py +61 -0
- siliconcompiler/tools/genfasm/genfasm.py +40 -0
- siliconcompiler/tools/ghdl/convert.py +87 -0
- siliconcompiler/tools/ghdl/ghdl.py +41 -0
- siliconcompiler/tools/icarus/compile.py +87 -0
- siliconcompiler/tools/icarus/icarus.py +36 -0
- siliconcompiler/tools/icepack/bitstream.py +20 -0
- siliconcompiler/tools/icepack/icepack.py +43 -0
- siliconcompiler/tools/klayout/export.py +117 -0
- siliconcompiler/tools/klayout/klayout.py +119 -0
- siliconcompiler/tools/klayout/klayout_export.py +205 -0
- siliconcompiler/tools/klayout/klayout_operations.py +363 -0
- siliconcompiler/tools/klayout/klayout_show.py +242 -0
- siliconcompiler/tools/klayout/klayout_utils.py +176 -0
- siliconcompiler/tools/klayout/operations.py +194 -0
- siliconcompiler/tools/klayout/screenshot.py +98 -0
- siliconcompiler/tools/klayout/show.py +101 -0
- siliconcompiler/tools/magic/drc.py +49 -0
- siliconcompiler/tools/magic/extspice.py +19 -0
- siliconcompiler/tools/magic/magic.py +85 -0
- siliconcompiler/tools/magic/sc_drc.tcl +96 -0
- siliconcompiler/tools/magic/sc_extspice.tcl +54 -0
- siliconcompiler/tools/magic/sc_magic.tcl +47 -0
- siliconcompiler/tools/montage/montage.py +30 -0
- siliconcompiler/tools/montage/tile.py +66 -0
- siliconcompiler/tools/netgen/count_lvs.py +132 -0
- siliconcompiler/tools/netgen/lvs.py +90 -0
- siliconcompiler/tools/netgen/netgen.py +36 -0
- siliconcompiler/tools/netgen/sc_lvs.tcl +46 -0
- siliconcompiler/tools/nextpnr/apr.py +24 -0
- siliconcompiler/tools/nextpnr/nextpnr.py +59 -0
- siliconcompiler/tools/openfpgaloader/openfpgaloader.py +39 -0
- siliconcompiler/tools/openroad/__init__.py +0 -0
- siliconcompiler/tools/openroad/cts.py +45 -0
- siliconcompiler/tools/openroad/dfm.py +66 -0
- siliconcompiler/tools/openroad/export.py +131 -0
- siliconcompiler/tools/openroad/floorplan.py +70 -0
- siliconcompiler/tools/openroad/openroad.py +977 -0
- siliconcompiler/tools/openroad/physyn.py +27 -0
- siliconcompiler/tools/openroad/place.py +41 -0
- siliconcompiler/tools/openroad/rcx_bench.py +95 -0
- siliconcompiler/tools/openroad/rcx_extract.py +34 -0
- siliconcompiler/tools/openroad/route.py +45 -0
- siliconcompiler/tools/openroad/screenshot.py +60 -0
- siliconcompiler/tools/openroad/scripts/sc_apr.tcl +499 -0
- siliconcompiler/tools/openroad/scripts/sc_cts.tcl +64 -0
- siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/sc_export.tcl +98 -0
- siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +413 -0
- siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +158 -0
- siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +7 -0
- siliconcompiler/tools/openroad/scripts/sc_place.tcl +84 -0
- siliconcompiler/tools/openroad/scripts/sc_procs.tcl +423 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +63 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx_bench.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx_extract.tcl +12 -0
- siliconcompiler/tools/openroad/scripts/sc_route.tcl +133 -0
- siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +21 -0
- siliconcompiler/tools/openroad/scripts/sc_write.tcl +5 -0
- siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +361 -0
- siliconcompiler/tools/openroad/show.py +94 -0
- siliconcompiler/tools/openroad/templates/pex.tcl +8 -0
- siliconcompiler/tools/opensta/__init__.py +101 -0
- siliconcompiler/tools/opensta/report_libraries.py +28 -0
- siliconcompiler/tools/opensta/scripts/sc_procs.tcl +47 -0
- siliconcompiler/tools/opensta/scripts/sc_report_libraries.tcl +74 -0
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +268 -0
- siliconcompiler/tools/opensta/timing.py +214 -0
- siliconcompiler/tools/slang/__init__.py +49 -0
- siliconcompiler/tools/slang/lint.py +101 -0
- siliconcompiler/tools/surelog/__init__.py +123 -0
- siliconcompiler/tools/surelog/parse.py +183 -0
- siliconcompiler/tools/surelog/templates/output.v +7 -0
- siliconcompiler/tools/sv2v/convert.py +46 -0
- siliconcompiler/tools/sv2v/sv2v.py +37 -0
- siliconcompiler/tools/template/template.py +125 -0
- siliconcompiler/tools/verilator/compile.py +139 -0
- siliconcompiler/tools/verilator/lint.py +19 -0
- siliconcompiler/tools/verilator/parse.py +27 -0
- siliconcompiler/tools/verilator/verilator.py +172 -0
- siliconcompiler/tools/vivado/__init__.py +7 -0
- siliconcompiler/tools/vivado/bitstream.py +21 -0
- siliconcompiler/tools/vivado/place.py +21 -0
- siliconcompiler/tools/vivado/route.py +21 -0
- siliconcompiler/tools/vivado/scripts/sc_bitstream.tcl +6 -0
- siliconcompiler/tools/vivado/scripts/sc_place.tcl +2 -0
- siliconcompiler/tools/vivado/scripts/sc_route.tcl +4 -0
- siliconcompiler/tools/vivado/scripts/sc_run.tcl +45 -0
- siliconcompiler/tools/vivado/scripts/sc_syn_fpga.tcl +25 -0
- siliconcompiler/tools/vivado/syn_fpga.py +20 -0
- siliconcompiler/tools/vivado/vivado.py +147 -0
- siliconcompiler/tools/vpr/_json_constraint.py +63 -0
- siliconcompiler/tools/vpr/_xml_constraint.py +109 -0
- siliconcompiler/tools/vpr/place.py +137 -0
- siliconcompiler/tools/vpr/route.py +124 -0
- siliconcompiler/tools/vpr/screenshot.py +54 -0
- siliconcompiler/tools/vpr/show.py +88 -0
- siliconcompiler/tools/vpr/vpr.py +357 -0
- siliconcompiler/tools/xyce/xyce.py +36 -0
- siliconcompiler/tools/yosys/lec.py +56 -0
- siliconcompiler/tools/yosys/prepareLib.py +59 -0
- siliconcompiler/tools/yosys/sc_lec.tcl +84 -0
- siliconcompiler/tools/yosys/sc_syn.tcl +79 -0
- siliconcompiler/tools/yosys/syn_asic.py +565 -0
- siliconcompiler/tools/yosys/syn_asic.tcl +377 -0
- siliconcompiler/tools/yosys/syn_asic_fpga_shared.tcl +31 -0
- siliconcompiler/tools/yosys/syn_fpga.py +146 -0
- siliconcompiler/tools/yosys/syn_fpga.tcl +233 -0
- siliconcompiler/tools/yosys/syn_strategies.tcl +81 -0
- siliconcompiler/tools/yosys/techmaps/lcu_kogge_stone.v +39 -0
- siliconcompiler/tools/yosys/templates/abc.const +2 -0
- siliconcompiler/tools/yosys/yosys.py +147 -0
- siliconcompiler/units.py +259 -0
- siliconcompiler/use.py +177 -0
- siliconcompiler/utils/__init__.py +423 -0
- siliconcompiler/utils/asic.py +158 -0
- siliconcompiler/utils/showtools.py +25 -0
- siliconcompiler-0.26.5.dist-info/LICENSE +190 -0
- siliconcompiler-0.26.5.dist-info/METADATA +195 -0
- siliconcompiler-0.26.5.dist-info/RECORD +251 -0
- siliconcompiler-0.26.5.dist-info/WHEEL +5 -0
- siliconcompiler-0.26.5.dist-info/entry_points.txt +12 -0
- siliconcompiler-0.26.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
|
|
2
|
+
source "$sc_refdir/syn_asic_fpga_shared.tcl"
|
|
3
|
+
|
|
4
|
+
proc legalize_flops { feature_set } {
|
|
5
|
+
|
|
6
|
+
set legalize_flop_types []
|
|
7
|
+
|
|
8
|
+
if { [lsearch -exact $feature_set enable] >= 0 && \
|
|
9
|
+
[lsearch -exact $feature_set async_set] >= 0 && \
|
|
10
|
+
[lsearch -exact $feature_set async_reset] >= 0 } {
|
|
11
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
12
|
+
lappend legalize_flop_types \$_DFF_PN?_
|
|
13
|
+
lappend legalize_flop_types \$_DFFE_PP_
|
|
14
|
+
lappend legalize_flop_types \$_DFFE_PN?P_
|
|
15
|
+
lappend legalize_flop_types \$_DFFSR_PNN_
|
|
16
|
+
lappend legalize_flop_types \$_DFFSRE_PNNP_
|
|
17
|
+
} elseif { [lsearch -exact $feature_set enable] >= 0 && \
|
|
18
|
+
[lsearch -exact $feature_set async_set] >= 0 } {
|
|
19
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
20
|
+
lappend legalize_flop_types \$_DFF_PN1_
|
|
21
|
+
lappend legalize_flop_types \$_DFFE_PP_
|
|
22
|
+
lappend legalize_flop_types \$_DFFE_PN1P_
|
|
23
|
+
} elseif { [lsearch -exact $feature_set enable] >= 0 && \
|
|
24
|
+
[lsearch -exact $feature_set async_reset] >= 0 } {
|
|
25
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
26
|
+
lappend legalize_flop_types \$_DFF_PN0_
|
|
27
|
+
lappend legalize_flop_types \$_DFFE_PP_
|
|
28
|
+
lappend legalize_flop_types \$_DFFE_PN0P_
|
|
29
|
+
} elseif { [lsearch -exact $feature_set enable] >= 0 } {
|
|
30
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
31
|
+
lappend legalize_flop_types \$_DFF_P??_
|
|
32
|
+
lappend legalize_flop_types \$_DFFE_PP_
|
|
33
|
+
lappend legalize_flop_types \$_DFFE_P??P_
|
|
34
|
+
} elseif { [lsearch -exact $feature_set async_set] >= 0 && \
|
|
35
|
+
[lsearch -exact $feature_set async_reset] >= 0 } {
|
|
36
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
37
|
+
lappend legalize_flop_types \$_DFF_PN?_
|
|
38
|
+
lappend legalize_flop_types \$_DFFSR_PNN_
|
|
39
|
+
} elseif { [lsearch -exact $feature_set async_set] >= 0 } {
|
|
40
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
41
|
+
lappend legalize_flop_types \$_DFF_PN1_
|
|
42
|
+
} elseif { [lsearch -exact $feature_set async_reset] >= 0 } {
|
|
43
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
44
|
+
lappend legalize_flop_types \$_DFF_PN0_
|
|
45
|
+
} else {
|
|
46
|
+
# Choose to legalize to async resets even though they
|
|
47
|
+
# won't tech map. Goal is to get the user to fix
|
|
48
|
+
# their code and put in synchronous resets
|
|
49
|
+
lappend legalize_flop_types \$_DFF_P_
|
|
50
|
+
lappend legalize_flop_types \$_DFF_P??_
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
set legalize_list []
|
|
54
|
+
foreach flop_type $legalize_flop_types {
|
|
55
|
+
lappend legalize_list -cell $flop_type 01
|
|
56
|
+
}
|
|
57
|
+
yosys log "Legalize list: $legalize_list"
|
|
58
|
+
yosys dfflegalize {*}$legalize_list
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
proc get_dsp_options { sc_syn_dsp_options } {
|
|
62
|
+
|
|
63
|
+
set option_text [ list ]
|
|
64
|
+
foreach dsp_option $sc_syn_dsp_options {
|
|
65
|
+
lappend option_text -D $dsp_option
|
|
66
|
+
}
|
|
67
|
+
return $option_text
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
set sc_partname [sc_cfg_get fpga partname]
|
|
71
|
+
set build_dir [sc_cfg_get option builddir]
|
|
72
|
+
set job_name [sc_cfg_get option jobname]
|
|
73
|
+
set step [sc_cfg_get arg step]
|
|
74
|
+
set index [sc_cfg_get arg index]
|
|
75
|
+
|
|
76
|
+
set sc_syn_lut_size \
|
|
77
|
+
[sc_cfg_get fpga $sc_partname lutsize]
|
|
78
|
+
|
|
79
|
+
if { [sc_cfg_exists fpga $sc_partname var feature_set] } {
|
|
80
|
+
set sc_syn_feature_set \
|
|
81
|
+
[sc_cfg_get fpga $sc_partname var feature_set]
|
|
82
|
+
} else {
|
|
83
|
+
set sc_syn_feature_set [ list ]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if { [sc_cfg_exists fpga $sc_partname var yosys_dsp_options] } {
|
|
87
|
+
yosys log "Process Yosys DSP techmap options."
|
|
88
|
+
set sc_syn_dsp_options \
|
|
89
|
+
[sc_cfg_get fpga $sc_partname var yosys_dsp_options]
|
|
90
|
+
yosys log "Yosys DSP techmap options = $sc_syn_dsp_options"
|
|
91
|
+
} else {
|
|
92
|
+
set sc_syn_dsp_options [ list ]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# TODO: add logic that remaps yosys built in name based on part number
|
|
96
|
+
|
|
97
|
+
# Run this first to handle module instantiations in generate blocks -- see
|
|
98
|
+
# comment in syn_asic.tcl for longer explanation.
|
|
99
|
+
yosys hierarchy -top $sc_design
|
|
100
|
+
|
|
101
|
+
if { [string match {ice*} $sc_partname] } {
|
|
102
|
+
yosys synth_ice40 -top $sc_design -json "${sc_design}.netlist.json"
|
|
103
|
+
} else {
|
|
104
|
+
|
|
105
|
+
# Pre-processing step: if DSPs instance are hard-coded into
|
|
106
|
+
# the user's design, we can use a blackbox flow for DSP mapping
|
|
107
|
+
# as follows:
|
|
108
|
+
|
|
109
|
+
if { [sc_cfg_exists fpga $sc_partname file yosys_macrolib] } {
|
|
110
|
+
|
|
111
|
+
set sc_syn_macrolibs \
|
|
112
|
+
[sc_cfg_get fpga $sc_partname file yosys_macrolib]
|
|
113
|
+
|
|
114
|
+
foreach macrolib $sc_syn_macrolibs {
|
|
115
|
+
yosys read_verilog -lib $macrolib
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Match VPR reference flow's hierarchy check, including their comments
|
|
120
|
+
|
|
121
|
+
yosys proc
|
|
122
|
+
yosys flatten
|
|
123
|
+
|
|
124
|
+
#Generic optimization passes; this is a fusion of the VTR reference
|
|
125
|
+
#flow and the Yosys synth_ice40 flow
|
|
126
|
+
yosys opt_expr
|
|
127
|
+
yosys opt_clean
|
|
128
|
+
yosys check
|
|
129
|
+
yosys opt -nodffe -nosdff
|
|
130
|
+
yosys fsm
|
|
131
|
+
yosys opt
|
|
132
|
+
yosys wreduce
|
|
133
|
+
yosys peepopt
|
|
134
|
+
yosys opt_clean
|
|
135
|
+
yosys share
|
|
136
|
+
yosys techmap -map +/cmp2lut.v -D LUT_WIDTH=$sc_syn_lut_size
|
|
137
|
+
yosys opt_expr
|
|
138
|
+
yosys opt_clean
|
|
139
|
+
|
|
140
|
+
#Map DSP blocks before doing anything else,
|
|
141
|
+
#so that we don't convert any math blocks
|
|
142
|
+
#into other primitives
|
|
143
|
+
|
|
144
|
+
# Note there are two possibilities for how mapping might be done:
|
|
145
|
+
# using the extract command (to pattern match user RTL against
|
|
146
|
+
# the techmap) or using the techmap command. The latter is better
|
|
147
|
+
# for mapping simple multipliers; the former is better (for now)
|
|
148
|
+
# for mapping more complex DSP blocks (MAC, pipelined blocks, etc).
|
|
149
|
+
# and also more extensible to arbitrary hard macros. Run separate
|
|
150
|
+
# passes of both to get best of both worlds
|
|
151
|
+
|
|
152
|
+
if { [sc_cfg_exists fpga $sc_partname file yosys_extractlib] } {
|
|
153
|
+
set sc_syn_extractlibs \
|
|
154
|
+
[sc_cfg_get fpga $sc_partname file yosys_extractlib]
|
|
155
|
+
|
|
156
|
+
foreach extractlib $sc_syn_extractlibs {
|
|
157
|
+
yosys log "Run extract with $extractlib"
|
|
158
|
+
yosys extract -map $extractlib
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if { [sc_cfg_exists fpga $sc_partname file yosys_dsp_techmap] } {
|
|
163
|
+
set sc_syn_dsp_library \
|
|
164
|
+
[sc_cfg_get fpga $sc_partname file yosys_dsp_techmap]
|
|
165
|
+
|
|
166
|
+
yosys log "Run techmap flow for DSP Blocks"
|
|
167
|
+
set formatted_dsp_options [get_dsp_options $sc_syn_dsp_options]
|
|
168
|
+
yosys techmap -map +/mul2dsp.v -map $sc_syn_dsp_library \
|
|
169
|
+
{*}$formatted_dsp_options
|
|
170
|
+
|
|
171
|
+
post_techmap
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
#Mimic ICE40 flow by running an alumacc and memory -nomap passes
|
|
175
|
+
#after DSP mapping
|
|
176
|
+
yosys alumacc
|
|
177
|
+
yosys opt
|
|
178
|
+
yosys memory -nomap
|
|
179
|
+
yosys opt -full
|
|
180
|
+
|
|
181
|
+
yosys techmap -map +/techmap.v
|
|
182
|
+
|
|
183
|
+
set sc_syn_memory_libmap ""
|
|
184
|
+
if { [sc_cfg_exists fpga $sc_partname file yosys_memory_libmap] } {
|
|
185
|
+
set sc_syn_memory_libmap \
|
|
186
|
+
[sc_cfg_get fpga $sc_partname file yosys_memory_libmap]
|
|
187
|
+
}
|
|
188
|
+
set sc_do_rom_map [expr { [lsearch -exact $sc_syn_feature_set mem_init] < 0 }]
|
|
189
|
+
set sc_syn_memory_library ""
|
|
190
|
+
if { [sc_cfg_exists fpga $sc_partname file yosys_memory_techmap] } {
|
|
191
|
+
set sc_syn_memory_library \
|
|
192
|
+
[sc_cfg_get fpga $sc_partname file yosys_memory_techmap]
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if { [sc_map_memory $sc_syn_memory_libmap $sc_syn_memory_library $sc_do_rom_map] } {
|
|
196
|
+
post_techmap
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
#After doing memory mapping, turn any remaining
|
|
200
|
+
#$mem_v2 instances into flop arrays
|
|
201
|
+
yosys memory_map
|
|
202
|
+
yosys demuxmap
|
|
203
|
+
yosys simplemap
|
|
204
|
+
|
|
205
|
+
legalize_flops $sc_syn_feature_set
|
|
206
|
+
|
|
207
|
+
if { [sc_cfg_exists fpga $sc_partname file yosys_flop_techmap] } {
|
|
208
|
+
set sc_syn_flop_library \
|
|
209
|
+
[sc_cfg_get fpga $sc_partname file yosys_flop_techmap]
|
|
210
|
+
yosys techmap -map $sc_syn_flop_library
|
|
211
|
+
|
|
212
|
+
post_techmap
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
#Perform preliminary buffer insertion before passing to ABC to help reduce
|
|
216
|
+
#the overhead of final buffer insertion downstream
|
|
217
|
+
yosys insbuf
|
|
218
|
+
|
|
219
|
+
yosys abc -lut $sc_syn_lut_size
|
|
220
|
+
|
|
221
|
+
yosys setundef -zero
|
|
222
|
+
yosys clean -purge
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
yosys echo off
|
|
226
|
+
yosys tee -o ./reports/stat.json stat -json -top $sc_design
|
|
227
|
+
yosys echo on
|
|
228
|
+
|
|
229
|
+
########################################################
|
|
230
|
+
# Write Netlist
|
|
231
|
+
########################################################
|
|
232
|
+
yosys write_blif "outputs/${sc_design}.blif"
|
|
233
|
+
yosys write_json "outputs/${sc_design}.netlist.json"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# ABC scripts
|
|
2
|
+
# Adapted from:
|
|
3
|
+
# https://github.com/The-OpenROAD-Project/OpenLane/blob/23b9177502c19ef749836aef8f4ee06416961a18/scripts/synth.tcl
|
|
4
|
+
|
|
5
|
+
# OpenLANE defaults
|
|
6
|
+
# TODO: we can introduce a flag to allow the user to choose between these "fine
|
|
7
|
+
# tuning" variations
|
|
8
|
+
set buffering 1
|
|
9
|
+
set sizing 0
|
|
10
|
+
|
|
11
|
+
set abc_rs_K "resub,-K,"
|
|
12
|
+
set abc_rs "resub"
|
|
13
|
+
set abc_rsz "resub,-z"
|
|
14
|
+
set abc_rw_K "rewrite,-K,"
|
|
15
|
+
set abc_rw "rewrite"
|
|
16
|
+
set abc_rwz "rewrite,-z"
|
|
17
|
+
set abc_rf "refactor"
|
|
18
|
+
set abc_rfz "refactor,-z"
|
|
19
|
+
set abc_b "balance"
|
|
20
|
+
|
|
21
|
+
set abc_resyn2 "${abc_b}; ${abc_rw}; ${abc_rf}; ${abc_b}; ${abc_rw}; ${abc_rwz}; ${abc_b}; ${abc_rfz}; ${abc_rwz}; ${abc_b}"
|
|
22
|
+
set abc_share "strash; multi,-m; ${abc_resyn2}"
|
|
23
|
+
set abc_resyn2a "${abc_b};${abc_rw};${abc_b};${abc_rw};${abc_rwz};${abc_b};${abc_rwz};${abc_b}"
|
|
24
|
+
set abc_resyn3 "balance;resub;resub,-K,6;balance;resub,-z;resub,-z,-K,6;balance;resub,-z,-K,5;balance"
|
|
25
|
+
set abc_resyn2rs "${abc_b};${abc_rs_K},6;${abc_rw};${abc_rs_K},6,-N,2;${abc_rf};${abc_rs_K},8;${abc_rw};${abc_rs_K},10;${abc_rwz};${abc_rs_K},10,-N,2;${abc_b},${abc_rs_K},12;${abc_rfz};${abc_rs_K},12,-N,2;${abc_rwz};${abc_b}"
|
|
26
|
+
|
|
27
|
+
set abc_choice "fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
|
|
28
|
+
set abc_choice2 "fraig_store; balance; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
|
|
29
|
+
|
|
30
|
+
set abc_map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0"
|
|
31
|
+
set abc_map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0"
|
|
32
|
+
set abc_retime_area "retime,-D,{D},-M,5"
|
|
33
|
+
set abc_retime_dly "retime,-D,{D},-M,6"
|
|
34
|
+
set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
|
|
35
|
+
|
|
36
|
+
set abc_area_recovery_1 "${abc_choice}; map;"
|
|
37
|
+
set abc_area_recovery_2 "${abc_choice2}; map;"
|
|
38
|
+
|
|
39
|
+
set map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0"
|
|
40
|
+
set map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0"
|
|
41
|
+
set abc_retime_area "retime,-D,{D},-M,5"
|
|
42
|
+
set abc_retime_dly "retime,-D,{D},-M,6"
|
|
43
|
+
set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
|
|
44
|
+
|
|
45
|
+
if {$buffering==1} {
|
|
46
|
+
# TODO: reintroduce the arguments to buffer: max_FO is a
|
|
47
|
+
# synthesis-specific max fanout argument, while max_Tran defaults to
|
|
48
|
+
# 0.1x the clock period. However, since the Yosys default script uses the default
|
|
49
|
+
# arguments to buffer, this should be safe to skip for now.
|
|
50
|
+
|
|
51
|
+
# set abc_fine_tune "buffer,-N,${max_FO},-S,${max_Tran};upsize,{D};dnsize,{D}"
|
|
52
|
+
set abc_fine_tune "buffer;upsize,{D};dnsize,{D}"
|
|
53
|
+
} elseif {$sizing} {
|
|
54
|
+
set abc_fine_tune "upsize,{D};dnsize,{D}"
|
|
55
|
+
} else {
|
|
56
|
+
set abc_fine_tune ""
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# TODO: all of these scripts used to begin with a call to `read_constr` which
|
|
60
|
+
# took in a pass to an SDC file. In OpenLANE, this file was autogenerated and
|
|
61
|
+
# only includes a set_driving_cell and set_load call that are set up based on
|
|
62
|
+
# user-provided params (i.e. not a user-provided SDC file). We can consider
|
|
63
|
+
# adding something like this back if we want.
|
|
64
|
+
|
|
65
|
+
# Also had to adjust each script to rewrite 'retime,-D,{D}' as 'retime,{D}' to
|
|
66
|
+
# avoid errors when a -D flag isn't passed in. I think this should be equivalent
|
|
67
|
+
# -- the default Yosys scripts use a similar syntax.
|
|
68
|
+
|
|
69
|
+
dict set syn_strategies "DELAY0" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_map_old_dly};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
|
|
70
|
+
dict set syn_strategies "DELAY1" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice2};${abc_map_old_dly};${abc_area_recovery_2}; retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
|
|
71
|
+
dict set syn_strategies "DELAY2" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice};${abc_map_old_dly};${abc_area_recovery_1}; retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
|
|
72
|
+
dict set syn_strategies "DELAY3" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_old_dly};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
|
|
73
|
+
dict set syn_strategies "AREA0" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
|
|
74
|
+
dict set syn_strategies "AREA1" "+fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
|
|
75
|
+
dict set syn_strategies "AREA2" "+fx;mfs;strash;refactor;${abc_choice2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,{D};${abc_fine_tune};stime,-p;print_stats -m"
|
|
76
|
+
|
|
77
|
+
# Adopted from: https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/3c605819af855200bf567bfd04b7309218cc8013/flow/scripts/abc_area.script
|
|
78
|
+
dict set syn_strategies "AREA3" "+strash;dch;map,-B,0.9;topo;stime,-c;buffer,-c;upsize,-c;dnsize,-c;stime,-p;print_stats,-m"
|
|
79
|
+
# Adopted from: https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/blob/3c605819af855200bf567bfd04b7309218cc8013/flow/scripts/abc_speed.script
|
|
80
|
+
set or_abc_loop "&get,-n;&st;&syn2;&if,-g,-K,6;&synch2;&nf;&put"
|
|
81
|
+
dict set syn_strategies "DELAY4" "+&get,-n;&st;&dch;&nf;&put;${or_abc_loop};${or_abc_loop};${or_abc_loop};${or_abc_loop};${or_abc_loop};buffer,-c;topo;stime,-c;upsize,-c;dnsize,-c;stime,-p;print_stats,-m"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
(* techmap_celltype = "$lcu" *)
|
|
2
|
+
module _80_lcu_kogge_stone (
|
|
3
|
+
P,
|
|
4
|
+
G,
|
|
5
|
+
CI,
|
|
6
|
+
CO
|
|
7
|
+
);
|
|
8
|
+
parameter WIDTH = 2;
|
|
9
|
+
|
|
10
|
+
(* force_downto *)
|
|
11
|
+
input [WIDTH-1:0] P, G;
|
|
12
|
+
input CI;
|
|
13
|
+
|
|
14
|
+
(* force_downto *)
|
|
15
|
+
output [WIDTH-1:0] CO;
|
|
16
|
+
|
|
17
|
+
integer i, j;
|
|
18
|
+
(* force_downto *)
|
|
19
|
+
reg [WIDTH-1:0] p, g;
|
|
20
|
+
|
|
21
|
+
wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast";
|
|
22
|
+
|
|
23
|
+
always @* begin
|
|
24
|
+
p = P;
|
|
25
|
+
g = G;
|
|
26
|
+
|
|
27
|
+
// in almost all cases CI will be constant zero
|
|
28
|
+
g[0] = g[0] | (p[0] & CI);
|
|
29
|
+
|
|
30
|
+
for (i = 0; i < $clog2(WIDTH); i = i + 1) begin
|
|
31
|
+
for (j = WIDTH - 1; j >= 2 ** i; j = j - 1) begin
|
|
32
|
+
g[j] = g[j] | p[j] & g[j-2**i];
|
|
33
|
+
p[j] = p[j] & p[j-2**i];
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
assign CO = g;
|
|
39
|
+
endmodule
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Yosys is a framework for RTL synthesis that takes synthesizable
|
|
3
|
+
Verilog-2005 design and converts it to BLIF, EDIF, BTOR, SMT,
|
|
4
|
+
Verilog netlist etc. The tool supports logical synthesis and
|
|
5
|
+
tech mapping to ASIC standard cell libraries, FPGA architectures.
|
|
6
|
+
In addition it has built in formal methods for property and
|
|
7
|
+
equivalence checking.
|
|
8
|
+
|
|
9
|
+
Documentation: https://yosyshq.readthedocs.io/projects/yosys/en/latest/
|
|
10
|
+
|
|
11
|
+
Sources: https://github.com/YosysHQ/yosys
|
|
12
|
+
|
|
13
|
+
Installation: https://github.com/YosysHQ/yosys
|
|
14
|
+
'''
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
import json
|
|
18
|
+
from siliconcompiler import sc_open
|
|
19
|
+
from siliconcompiler.tools._common import get_tool_task, record_metric
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
######################################################################
|
|
23
|
+
# Make Docs
|
|
24
|
+
######################################################################
|
|
25
|
+
def make_docs(chip):
|
|
26
|
+
chip.load_target("asap7_demo")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
################################
|
|
30
|
+
# Setup Tool (pre executable)
|
|
31
|
+
################################
|
|
32
|
+
def setup(chip):
|
|
33
|
+
''' Tool specific function to run before step execution
|
|
34
|
+
'''
|
|
35
|
+
|
|
36
|
+
# If the 'lock' bit is set, don't reconfigure.
|
|
37
|
+
tool = 'yosys'
|
|
38
|
+
refdir = 'tools/' + tool
|
|
39
|
+
step = chip.get('arg', 'step')
|
|
40
|
+
index = chip.get('arg', 'index')
|
|
41
|
+
_, task = get_tool_task(chip, step, index)
|
|
42
|
+
|
|
43
|
+
# Standard Setup
|
|
44
|
+
chip.set('tool', tool, 'exe', 'yosys')
|
|
45
|
+
chip.set('tool', tool, 'vswitch', '--version')
|
|
46
|
+
chip.set('tool', tool, 'version', '>=0.41', clobber=False)
|
|
47
|
+
chip.set('tool', tool, 'format', 'tcl', clobber=False)
|
|
48
|
+
|
|
49
|
+
# Task Setup
|
|
50
|
+
# common to all
|
|
51
|
+
option = []
|
|
52
|
+
if chip.get('option', 'breakpoint', step=step, index=index):
|
|
53
|
+
option.append('-C')
|
|
54
|
+
option.append('-c')
|
|
55
|
+
chip.set('tool', tool, 'task', task, 'option', option, step=step, index=index, clobber=False)
|
|
56
|
+
chip.set('tool', tool, 'task', task, 'refdir', refdir, step=step, index=index,
|
|
57
|
+
package='siliconcompiler', clobber=False)
|
|
58
|
+
chip.set('tool', tool, 'task', task, 'regex', 'warnings', "Warning:",
|
|
59
|
+
step=step, index=index, clobber=False)
|
|
60
|
+
chip.set('tool', tool, 'task', task, 'regex', 'errors', "^ERROR",
|
|
61
|
+
step=step, index=index, clobber=False)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
################################
|
|
65
|
+
# Version Check
|
|
66
|
+
################################
|
|
67
|
+
def parse_version(stdout):
|
|
68
|
+
# Yosys 0.9+3672 (git sha1 014c7e26, gcc 7.5.0-3ubuntu1~18.04 -fPIC -Os)
|
|
69
|
+
return stdout.split()[1]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def normalize_version(version):
|
|
73
|
+
# Replace '+', which represents a "local version label", with '-', which is
|
|
74
|
+
# an "implicit post release number".
|
|
75
|
+
return version.replace('+', '-')
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def syn_setup(chip):
|
|
79
|
+
''' Helper method for configs specific to synthesis tasks.
|
|
80
|
+
'''
|
|
81
|
+
|
|
82
|
+
# Generic tool setup.
|
|
83
|
+
setup(chip)
|
|
84
|
+
|
|
85
|
+
tool = 'yosys'
|
|
86
|
+
step = chip.get('arg', 'step')
|
|
87
|
+
index = chip.get('arg', 'index')
|
|
88
|
+
_, task = get_tool_task(chip, step, index)
|
|
89
|
+
design = chip.top()
|
|
90
|
+
|
|
91
|
+
# Set yosys script path.
|
|
92
|
+
chip.set('tool', tool, 'task', task, 'script', 'sc_syn.tcl',
|
|
93
|
+
step=step, index=index, clobber=False)
|
|
94
|
+
|
|
95
|
+
# Input/output requirements.
|
|
96
|
+
chip.set('tool', tool, 'task', task, 'input', design + '.v', step=step, index=index)
|
|
97
|
+
chip.set('tool', tool, 'task', task, 'output', design + '.vg', step=step, index=index)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
##################################################
|
|
101
|
+
def syn_post_process(chip):
|
|
102
|
+
''' Tool specific function to run after step execution
|
|
103
|
+
'''
|
|
104
|
+
|
|
105
|
+
step = chip.get('arg', 'step')
|
|
106
|
+
index = chip.get('arg', 'index')
|
|
107
|
+
|
|
108
|
+
with sc_open("reports/stat.json") as f:
|
|
109
|
+
metrics = json.load(f)
|
|
110
|
+
if "design" in metrics:
|
|
111
|
+
metrics = metrics["design"]
|
|
112
|
+
|
|
113
|
+
if "area" in metrics:
|
|
114
|
+
record_metric(chip, step, index, 'cellarea',
|
|
115
|
+
float(metrics["area"]),
|
|
116
|
+
"reports/stat.json",
|
|
117
|
+
source_unit='um^2')
|
|
118
|
+
if "num_cells" in metrics:
|
|
119
|
+
record_metric(chip, step, index, 'cells',
|
|
120
|
+
metrics["num_cells"],
|
|
121
|
+
"reports/stat.json")
|
|
122
|
+
if "num_wire_bits" in metrics:
|
|
123
|
+
record_metric(chip, step, index, 'nets',
|
|
124
|
+
metrics["num_wire_bits"],
|
|
125
|
+
"reports/stat.json")
|
|
126
|
+
if "num_port_bits" in metrics:
|
|
127
|
+
record_metric(chip, step, index, 'pins',
|
|
128
|
+
metrics["num_port_bits"],
|
|
129
|
+
"reports/stat.json")
|
|
130
|
+
|
|
131
|
+
registers = None
|
|
132
|
+
with sc_open(f"{step}.log") as f:
|
|
133
|
+
for line in f:
|
|
134
|
+
line_registers = re.findall(r"^\s*mapped ([0-9]+) \$_DFF.*", line)
|
|
135
|
+
if line_registers:
|
|
136
|
+
if registers is None:
|
|
137
|
+
registers = 0
|
|
138
|
+
registers += int(line_registers[0])
|
|
139
|
+
if registers is not None:
|
|
140
|
+
record_metric(chip, step, index, 'registers', registers, f"{step}.log")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
##################################################
|
|
144
|
+
if __name__ == "__main__":
|
|
145
|
+
|
|
146
|
+
chip = make_docs()
|
|
147
|
+
chip.write_manifest("yosys.json")
|