aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--Makefile84
-rw-r--r--README.md4
-rw-r--r--backends/aiger/aiger.cc60
-rw-r--r--backends/aiger/xaiger.cc50
-rw-r--r--backends/blif/blif.cc150
-rw-r--r--backends/btor/btor.cc493
-rw-r--r--backends/cxxrtl/Makefile.inc2
-rw-r--r--backends/cxxrtl/cxxrtl.cc1763
-rw-r--r--backends/cxxrtl/cxxrtl.h1138
-rw-r--r--backends/edif/edif.cc41
-rw-r--r--backends/firrtl/firrtl.cc222
-rw-r--r--backends/ilang/ilang_backend.cc12
-rw-r--r--backends/intersynth/intersynth.cc41
-rw-r--r--backends/json/json.cc44
-rw-r--r--backends/simplec/simplec.cc82
-rw-r--r--backends/smt2/Makefile.inc14
-rw-r--r--backends/smt2/smt2.cc352
-rw-r--r--backends/smt2/smtbmc.py3
-rw-r--r--backends/smv/smv.cc276
-rw-r--r--backends/spice/spice.cc22
-rw-r--r--backends/verilog/verilog_backend.cc567
-rw-r--r--examples/cxx-api/evaldemo.cc4
-rw-r--r--frontends/aiger/aigerparse.cc60
-rw-r--r--frontends/ast/ast.cc152
-rw-r--r--frontends/ast/ast.h8
-rw-r--r--frontends/ast/genrtlil.cc366
-rw-r--r--frontends/ast/simplify.cc73
-rw-r--r--frontends/blif/blifparse.cc64
-rw-r--r--frontends/ilang/ilang_lexer.l13
-rw-r--r--frontends/ilang/ilang_parser.y11
-rw-r--r--frontends/liberty/liberty.cc152
-rw-r--r--frontends/rpc/rpc_frontend.cc4
-rw-r--r--frontends/verific/verific.cc98
-rw-r--r--frontends/verilog/const2ast.cc3
-rw-r--r--frontends/verilog/verilog_parser.y64
-rw-r--r--kernel/cellaigs.cc30
-rw-r--r--kernel/celledges.cc84
-rw-r--r--kernel/celltypes.h177
-rw-r--r--kernel/consteval.h36
-rw-r--r--kernel/constids.inc213
-rw-r--r--kernel/macc.h12
-rw-r--r--kernel/modtools.h15
-rw-r--r--kernel/rtlil.cc1289
-rw-r--r--kernel/rtlil.h398
-rw-r--r--kernel/satgen.h112
-rw-r--r--kernel/sigtools.h76
-rw-r--r--kernel/timinginfo.h26
-rw-r--r--kernel/yosys.cc49
-rw-r--r--kernel/yosys.h8
-rw-r--r--libs/ezsat/ezsat.cc160
-rw-r--r--manual/command-reference-manual.tex2498
-rw-r--r--misc/yosys-config.in8
-rw-r--r--passes/cmds/add.cc8
-rw-r--r--passes/cmds/blackbox.cc2
-rw-r--r--passes/cmds/bugpoint.cc32
-rw-r--r--passes/cmds/check.cc51
-rw-r--r--passes/cmds/chformal.cc82
-rw-r--r--passes/cmds/connect.cc26
-rw-r--r--passes/cmds/connwrappers.cc22
-rw-r--r--passes/cmds/copy.cc4
-rw-r--r--passes/cmds/delete.cc43
-rw-r--r--passes/cmds/design.cc6
-rw-r--r--passes/cmds/qwp.cc2
-rw-r--r--passes/cmds/setattr.cc40
-rw-r--r--passes/cmds/setundef.cc61
-rw-r--r--passes/cmds/show.cc98
-rw-r--r--passes/cmds/splice.cc60
-rw-r--r--passes/cmds/splitnets.cc17
-rw-r--r--passes/cmds/stat.cc80
-rw-r--r--passes/cmds/torder.cc4
-rw-r--r--passes/cmds/trace.cc2
-rw-r--r--passes/equiv/equiv_add.cc2
-rw-r--r--passes/equiv/equiv_induct.cc20
-rw-r--r--passes/equiv/equiv_make.cc2
-rw-r--r--passes/equiv/equiv_mark.cc20
-rw-r--r--passes/equiv/equiv_miter.cc18
-rw-r--r--passes/equiv/equiv_purge.cc14
-rw-r--r--passes/equiv/equiv_remove.cc6
-rw-r--r--passes/equiv/equiv_simple.cc22
-rw-r--r--passes/equiv/equiv_status.cc6
-rw-r--r--passes/equiv/equiv_struct.cc20
-rw-r--r--passes/fsm/fsm_detect.cc68
-rw-r--r--passes/fsm/fsm_expand.cc76
-rw-r--r--passes/fsm/fsm_export.cc19
-rw-r--r--passes/fsm/fsm_extract.cc80
-rw-r--r--passes/fsm/fsm_info.cc19
-rw-r--r--passes/fsm/fsm_map.cc136
-rw-r--r--passes/fsm/fsm_opt.cc34
-rw-r--r--passes/fsm/fsm_recode.cc15
-rw-r--r--passes/fsm/fsmdata.h46
-rw-r--r--passes/hierarchy/hierarchy.cc74
-rw-r--r--passes/hierarchy/submod.cc59
-rw-r--r--passes/hierarchy/uniquify.cc10
-rw-r--r--passes/memory/memory_bram.cc112
-rw-r--r--passes/memory/memory_collect.cc101
-rw-r--r--passes/memory/memory_dff.cc106
-rw-r--r--passes/memory/memory_map.cc261
-rw-r--r--passes/memory/memory_memx.cc20
-rw-r--r--passes/memory/memory_nordff.cc40
-rw-r--r--passes/memory/memory_share.cc210
-rw-r--r--passes/memory/memory_unpack.cc93
-rw-r--r--passes/opt/muxpack.cc14
-rw-r--r--passes/opt/opt_clean.cc50
-rw-r--r--passes/opt/opt_expr.cc532
-rw-r--r--passes/opt/opt_lut.cc22
-rw-r--r--passes/opt/opt_lut_ins.cc26
-rw-r--r--passes/opt/opt_mem.cc6
-rw-r--r--passes/opt/opt_merge.cc244
-rw-r--r--passes/opt/opt_muxtree.cc12
-rw-r--r--passes/opt/opt_reduce.cc36
-rw-r--r--passes/opt/opt_rmdff.cc178
-rw-r--r--passes/opt/opt_share.cc32
-rw-r--r--passes/opt/pmux2shiftx.cc38
-rw-r--r--passes/opt/share.cc214
-rw-r--r--passes/opt/wreduce.cc60
-rw-r--r--passes/pmgen/ice40_dsp.cc46
-rw-r--r--passes/pmgen/ice40_wrapcarry.cc52
-rw-r--r--passes/pmgen/peepopt.cc4
-rw-r--r--passes/pmgen/test_pmgen.cc10
-rw-r--r--passes/pmgen/xilinx_dsp.cc188
-rw-r--r--passes/pmgen/xilinx_srl.cc56
-rw-r--r--passes/proc/proc_arst.cc50
-rw-r--r--passes/proc/proc_dff.cc196
-rw-r--r--passes/proc/proc_dlatch.cc50
-rw-r--r--passes/proc/proc_init.cc2
-rw-r--r--passes/proc/proc_mux.cc64
-rw-r--r--passes/proc/proc_prune.cc4
-rw-r--r--passes/proc/proc_rmdead.cc4
-rw-r--r--passes/sat/assertpmux.cc30
-rw-r--r--passes/sat/async2sync.cc98
-rw-r--r--passes/sat/clk2fflogic.cc134
-rw-r--r--passes/sat/cutpoint.cc2
-rw-r--r--passes/sat/eval.cc8
-rw-r--r--passes/sat/expose.cc76
-rw-r--r--passes/sat/fmcombine.cc14
-rw-r--r--passes/sat/fminit.cc4
-rw-r--r--passes/sat/freduce.cc10
-rw-r--r--passes/sat/miter.cc150
-rw-r--r--passes/sat/mutate.cc6
-rw-r--r--passes/sat/sat.cc16
-rw-r--r--passes/sat/sim.cc136
-rw-r--r--passes/techmap/Makefile.inc7
-rw-r--r--passes/techmap/abc.cc158
-rw-r--r--passes/techmap/abc9.cc6
-rw-r--r--passes/techmap/abc9_exe.cc12
-rw-r--r--passes/techmap/abc9_ops.cc109
-rw-r--r--passes/techmap/alumacc.cc26
-rw-r--r--passes/techmap/clkbufmap.cc12
-rw-r--r--passes/techmap/deminout.cc2
-rw-r--r--passes/techmap/dff2dffe.cc40
-rw-r--r--passes/techmap/dff2dffs.cc12
-rw-r--r--passes/techmap/dffinit.cc18
-rw-r--r--passes/techmap/dfflibmap.cc54
-rw-r--r--passes/techmap/dffsr2dff.cc213
-rw-r--r--passes/techmap/extract.cc141
-rw-r--r--passes/techmap/extract_counter.cc94
-rw-r--r--passes/techmap/extract_fa.cc14
-rw-r--r--passes/techmap/extract_reduce.cc8
-rw-r--r--passes/techmap/extractinv.cc2
-rw-r--r--passes/techmap/flowmap.cc4
-rw-r--r--passes/techmap/hilomap.cc8
-rw-r--r--passes/techmap/insbuf.cc14
-rw-r--r--passes/techmap/iopadmap.cc24
-rw-r--r--passes/techmap/lut2mux.cc2
-rw-r--r--passes/techmap/maccmap.cc16
-rw-r--r--passes/techmap/muxcover.cc66
-rw-r--r--passes/techmap/pmuxtree.cc2
-rw-r--r--passes/techmap/shregmap.cc32
-rw-r--r--passes/techmap/simplemap.cc206
-rw-r--r--passes/techmap/techmap.cc86
-rw-r--r--passes/techmap/tribuf.cc14
-rw-r--r--passes/techmap/zinit.cc64
-rw-r--r--passes/tests/test_abcloop.cc2
-rw-r--r--passes/tests/test_autotb.cc30
-rw-r--r--passes/tests/test_cell.cc270
-rw-r--r--techlibs/achronix/synth_achronix.cc1
-rw-r--r--techlibs/anlogic/anlogic_eqn.cc24
-rw-r--r--techlibs/anlogic/anlogic_fixcarry.cc38
-rw-r--r--techlibs/anlogic/synth_anlogic.cc1
-rw-r--r--techlibs/common/Makefile.inc1
-rw-r--r--techlibs/common/cmp2lcu.v116
-rw-r--r--techlibs/common/cmp2lut.v8
-rw-r--r--techlibs/common/gen_fine_ffs.py238
-rw-r--r--techlibs/common/simcells.v86
-rw-r--r--techlibs/common/simlib.v2
-rw-r--r--techlibs/common/synth.cc6
-rw-r--r--techlibs/coolrunner2/coolrunner2_fixup.cc166
-rw-r--r--techlibs/coolrunner2/coolrunner2_sop.cc112
-rw-r--r--techlibs/ecp5/brams.txt62
-rw-r--r--techlibs/ecp5/ecp5_ffinit.cc44
-rw-r--r--techlibs/ecp5/ecp5_gsr.cc4
-rw-r--r--techlibs/ecp5/lutrams.txt9
-rw-r--r--techlibs/ecp5/synth_ecp5.cc5
-rw-r--r--techlibs/efinix/efinix_fixcarry.cc38
-rw-r--r--techlibs/efinix/efinix_gbuf.cc20
-rw-r--r--techlibs/efinix/synth_efinix.cc1
-rw-r--r--techlibs/gowin/determine_init.cc10
-rw-r--r--techlibs/gowin/synth_gowin.cc1
-rw-r--r--techlibs/greenpak4/greenpak4_dffinv.cc76
-rw-r--r--techlibs/ice40/brams.txt60
-rw-r--r--techlibs/ice40/ice40_braminit.cc14
-rw-r--r--techlibs/ice40/ice40_ffinit.cc32
-rw-r--r--techlibs/ice40/ice40_ffssr.cc34
-rw-r--r--techlibs/ice40/ice40_opt.cc94
-rw-r--r--techlibs/ice40/synth_ice40.cc13
-rw-r--r--techlibs/intel/Makefile.inc1
-rw-r--r--techlibs/intel/synth_intel.cc1
-rw-r--r--techlibs/intel_alm/Makefile.inc23
-rw-r--r--techlibs/intel_alm/common/alm_map.v56
-rw-r--r--techlibs/intel_alm/common/alm_sim.v482
-rw-r--r--techlibs/intel_alm/common/arith_alm_map.v64
-rw-r--r--techlibs/intel_alm/common/bram_m10k.txt33
-rw-r--r--techlibs/intel_alm/common/bram_m10k_map.v31
-rw-r--r--techlibs/intel_alm/common/bram_m20k.txt33
-rw-r--r--techlibs/intel_alm/common/bram_m20k_map.v31
-rw-r--r--techlibs/intel_alm/common/dff_map.v124
-rw-r--r--techlibs/intel_alm/common/dff_sim.v48
-rw-r--r--techlibs/intel_alm/common/lutram_mlab.txt20
-rw-r--r--techlibs/intel_alm/common/lutram_mlab_map.v29
-rw-r--r--techlibs/intel_alm/common/megafunction_bb.v108
-rw-r--r--techlibs/intel_alm/common/quartus_rename.v19
-rw-r--r--techlibs/intel_alm/cyclone10gx/quartus_rename.v54
-rw-r--r--techlibs/intel_alm/cyclonev/quartus_rename.v54
-rw-r--r--techlibs/intel_alm/synth_intel_alm.cc241
-rw-r--r--techlibs/sf2/sf2_iobs.cc42
-rw-r--r--techlibs/sf2/synth_sf2.cc1
-rw-r--r--techlibs/xilinx/synth_xilinx.cc6
-rw-r--r--techlibs/xilinx/xilinx_dffopt.cc26
-rw-r--r--tests/arch/anlogic/fsm.ys5
-rw-r--r--tests/arch/common/blockram.v42
-rw-r--r--tests/arch/common/blockrom.v31
-rw-r--r--tests/arch/ecp5/memories.ys330
-rw-r--r--tests/arch/efinix/fsm.ys5
-rw-r--r--tests/arch/ice40/lutram.ys15
-rw-r--r--tests/arch/ice40/memories.ys168
-rw-r--r--tests/arch/intel_alm/add_sub.ys8
-rw-r--r--tests/arch/intel_alm/adffs.ys48
-rw-r--r--tests/arch/intel_alm/counter.ys13
-rw-r--r--tests/arch/intel_alm/dffs.ys22
-rw-r--r--tests/arch/intel_alm/fsm.ys18
-rw-r--r--tests/arch/intel_alm/logic.ys11
-rw-r--r--tests/arch/intel_alm/mux.ys45
-rwxr-xr-xtests/arch/intel_alm/run-test.sh20
-rw-r--r--tests/arch/intel_alm/shifter.ys10
-rw-r--r--tests/arch/intel_alm/tribuf.ys13
-rw-r--r--tests/opt/opt_expr.ys28
-rw-r--r--tests/opt/opt_expr_alu.ys111
-rw-r--r--tests/opt/opt_expr_xor.ys52
-rw-r--r--tests/opt/opt_merge_init.ys28
-rw-r--r--tests/opt/opt_merge_keep.ys64
-rw-r--r--tests/select/.gitignore1
-rw-r--r--tests/simple/dynslice.v12
-rw-r--r--tests/svtypes/typedef_package.sv11
-rw-r--r--tests/techmap/cmp2lcu.ys52
-rw-r--r--tests/techmap/dffinit.ys25
-rw-r--r--tests/techmap/iopadmap.ys10
-rw-r--r--tests/techmap/zinit.ys57
-rw-r--r--tests/various/.gitignore1
-rw-r--r--tests/various/bug1876.ys60
-rw-r--r--tests/various/plugin.cc15
-rw-r--r--tests/various/plugin.sh6
262 files changed, 15774 insertions, 7081 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 18f82bdd1..5fd82fccf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -63,6 +63,7 @@ Yosys 0.9 .. Yosys 0.9-dev
- Improved support of $readmem[hb] Memory Content File inclusion
- Added "opt_lut_ins" pass
- Added "logger" pass
+ - Removed "dffsr2dff" (use opt_rmdff instead)
Yosys 0.8 .. Yosys 0.9
----------------------
diff --git a/Makefile b/Makefile
index 3c89fed20..fc417ab9d 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,7 @@ SANITIZER =
# SANITIZER = undefined
# SANITIZER = cfi
+PROGRAM_PREFIX :=
OS := $(shell uname -s)
PREFIX ?= /usr/local
@@ -51,16 +52,20 @@ ifneq ($(wildcard Makefile.conf),)
include Makefile.conf
endif
+ifeq ($(ENABLE_PYOSYS),1)
+ENABLE_LIBYOSYS := 1
+endif
+
BINDIR := $(PREFIX)/bin
-LIBDIR := $(PREFIX)/lib
-DATDIR := $(PREFIX)/share/yosys
+LIBDIR := $(PREFIX)/lib/$(PROGRAM_PREFIX)yosys
+DATDIR := $(PREFIX)/share/$(PROGRAM_PREFIX)yosys
EXE =
OBJS =
GENFILES =
EXTRA_OBJS =
EXTRA_TARGETS =
-TARGETS = yosys$(EXE) yosys-config
+TARGETS = $(PROGRAM_PREFIX)yosys$(EXE) $(PROGRAM_PREFIX)yosys-config
PRETTY = 1
SMALL = 0
@@ -115,7 +120,7 @@ LDFLAGS += -rdynamic
LDLIBS += -lrt
endif
-YOSYS_VER := 0.9+1706
+YOSYS_VER := 0.9+2406
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
OBJS = kernel/version_$(GIT_REV).o
@@ -245,7 +250,7 @@ LDFLAGS += $(EMCCFLAGS)
LDLIBS =
EXE = .js
-TARGETS := $(filter-out yosys-config,$(TARGETS))
+TARGETS := $(filter-out $(PROGRAM_PREFIX)yosys-config,$(TARGETS))
EXTRA_TARGETS += yosysjs-$(YOSYS_VER).zip
ifeq ($(ENABLE_ABC),1)
@@ -459,7 +464,7 @@ LDLIBS += -lpthread
endif
else
ifeq ($(ABCEXTERNAL),)
-TARGETS += yosys-abc$(EXE)
+TARGETS += $(PROGRAM_PREFIX)yosys-abc$(EXE)
endif
endif
endif
@@ -509,8 +514,8 @@ endef
ifeq ($(PRETTY), 1)
P_STATUS = 0
P_OFFSET = 0
-P_UPDATE = $(eval P_STATUS=$(shell echo $(OBJS) yosys$(EXE) | $(AWK) 'BEGIN { RS = " "; I = $(P_STATUS)+0; } $$1 == "$@" && NR > I { I = NR; } END { print I; }'))
-P_SHOW = [$(shell $(AWK) "BEGIN { N=$(words $(OBJS) yosys$(EXE)); printf \"%3d\", $(P_OFFSET)+90*$(P_STATUS)/N; exit; }")%]
+P_UPDATE = $(eval P_STATUS=$(shell echo $(OBJS) $(PROGRAM_PREFIX)yosys$(EXE) | $(AWK) 'BEGIN { RS = " "; I = $(P_STATUS)+0; } $$1 == "$@" && NR > I { I = NR; } END { print I; }'))
+P_SHOW = [$(shell $(AWK) "BEGIN { N=$(words $(OBJS) $(PROGRAM_PREFIX)yosys$(EXE)); printf \"%3d\", $(P_OFFSET)+90*$(P_STATUS)/N; exit; }")%]
P = @echo "$(if $(findstring $@,$(TARGETS) $(EXTRA_TARGETS)),$(eval P_OFFSET = 10))$(call P_UPDATE)$(call P_SHOW) Building $@";
Q = @
S = -s
@@ -529,6 +534,7 @@ $(eval $(call add_include_file,kernel/register.h))
$(eval $(call add_include_file,kernel/celltypes.h))
$(eval $(call add_include_file,kernel/celledges.h))
$(eval $(call add_include_file,kernel/consteval.h))
+$(eval $(call add_include_file,kernel/constids.inc))
$(eval $(call add_include_file,kernel/sigtools.h))
$(eval $(call add_include_file,kernel/modtools.h))
$(eval $(call add_include_file,kernel/macc.h))
@@ -541,12 +547,13 @@ $(eval $(call add_include_file,libs/json11/json11.hpp))
$(eval $(call add_include_file,passes/fsm/fsmdata.h))
$(eval $(call add_include_file,frontends/ast/ast.h))
$(eval $(call add_include_file,backends/ilang/ilang_backend.h))
+$(eval $(call add_include_file,backends/cxxrtl/cxxrtl.h))
OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o
OBJS += kernel/cellaigs.o kernel/celledges.o
kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"'
-kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"'
+kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"'
OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o
OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o
@@ -599,7 +606,7 @@ include techlibs/common/Makefile.inc
endif
ifeq ($(LINK_ABC),1)
-OBJS += yosys-libabc.a
+OBJS += $(PROGRAM_PREFIX)yosys-libabc.a
endif
top-all: $(TARGETS) $(EXTRA_TARGETS)
@@ -611,14 +618,14 @@ ifeq ($(CONFIG),emcc)
yosys.js: $(filter-out yosysjs-$(YOSYS_VER).zip,$(EXTRA_TARGETS))
endif
-yosys$(EXE): $(OBJS)
- $(P) $(LD) -o yosys$(EXE) $(LDFLAGS) $(OBJS) $(LDLIBS)
+$(PROGRAM_PREFIX)yosys$(EXE): $(OBJS)
+ $(P) $(LD) -o $(PROGRAM_PREFIX)yosys$(EXE) $(LDFLAGS) $(OBJS) $(LDLIBS)
libyosys.so: $(filter-out kernel/driver.o,$(OBJS))
ifeq ($(OS), Darwin)
- $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,libyosys.so $(LDFLAGS) $^ $(LDLIBS)
+ $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,$(DESTDIR)$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS)
else
- $(P) $(LD) -o libyosys.so -shared -Wl,-soname,libyosys.so $(LDFLAGS) $^ $(LDLIBS)
+ $(P) $(LD) -o libyosys.so -shared -Wl,-soname,$(DESTDIR)$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS)
endif
%.o: %.cc
@@ -654,11 +661,11 @@ CXXFLAGS_NOVERIFIC = $(CXXFLAGS)
LDLIBS_NOVERIFIC = $(LDLIBS)
endif
-yosys-config: misc/yosys-config.in
+$(PROGRAM_PREFIX)yosys-config: misc/yosys-config.in
$(P) $(SED) -e 's#@CXXFLAGS@#$(subst -I. -I"$(YOSYS_SRC)",-I"$(DATDIR)/include",$(strip $(CXXFLAGS_NOVERIFIC)))#;' \
-e 's#@CXX@#$(strip $(CXX))#;' -e 's#@LDFLAGS@#$(strip $(LDFLAGS) $(PLUGIN_LDFLAGS))#;' -e 's#@LDLIBS@#$(strip $(LDLIBS_NOVERIFIC))#;' \
- -e 's#@BINDIR@#$(strip $(BINDIR))#;' -e 's#@DATDIR@#$(strip $(DATDIR))#;' < $< > yosys-config
- $(Q) chmod +x yosys-config
+ -e 's#@BINDIR@#$(strip $(BINDIR))#;' -e 's#@DATDIR@#$(strip $(DATDIR))#;' < $< > $(PROGRAM_PREFIX)yosys-config
+ $(Q) chmod +x $(PROGRAM_PREFIX)yosys-config
abc/abc-$(ABCREV)$(EXE) abc/libabc-$(ABCREV).a:
$(P)
@@ -685,11 +692,11 @@ ifeq ($(ABCREV),default)
.PHONY: abc/libabc-$(ABCREV).a
endif
-yosys-abc$(EXE): abc/abc-$(ABCREV)$(EXE)
- $(P) cp abc/abc-$(ABCREV)$(EXE) yosys-abc$(EXE)
+$(PROGRAM_PREFIX)yosys-abc$(EXE): abc/abc-$(ABCREV)$(EXE)
+ $(P) cp abc/abc-$(ABCREV)$(EXE) $(PROGRAM_PREFIX)yosys-abc$(EXE)
-yosys-libabc.a: abc/libabc-$(ABCREV).a
- $(P) cp abc/libabc-$(ABCREV).a yosys-libabc.a
+$(PROGRAM_PREFIX)yosys-libabc.a: abc/libabc-$(ABCREV).a
+ $(P) cp abc/libabc-$(ABCREV).a $(PROGRAM_PREFIX)yosys-libabc.a
ifneq ($(SEED),)
SEEDOPT="-S $(SEED)"
@@ -730,6 +737,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/arch/efinix && bash run-test.sh $(SEEDOPT)
+cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT)
+cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
+ +cd tests/arch/intel_alm && bash run-test.sh $(SEEDOPT)
+cd tests/rpc && bash run-test.sh
+cd tests/memfile && bash run-test.sh
@echo ""
@@ -769,14 +777,14 @@ clean-unit-test:
install: $(TARGETS) $(EXTRA_TARGETS)
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(BINDIR)
$(INSTALL_SUDO) cp $(filter-out libyosys.so,$(TARGETS)) $(DESTDIR)$(BINDIR)
-ifneq ($(filter yosys,$(TARGETS)),)
- $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/yosys
+ifneq ($(filter $(PROGRAM_PREFIX)yosys,$(TARGETS)),)
+ $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys
endif
-ifneq ($(filter yosys-abc,$(TARGETS)),)
- $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/yosys-abc
+ifneq ($(filter $(PROGRAM_PREFIX)yosys-abc,$(TARGETS)),)
+ $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-abc
endif
-ifneq ($(filter yosys-filterlib,$(TARGETS)),)
- $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/yosys-filterlib
+ifneq ($(filter $(PROGRAM_PREFIX)yosys-filterlib,$(TARGETS)),)
+ $(INSTALL_SUDO) $(STRIP) $(DESTDIR)$(BINDIR)/$(PROGRAM_PREFIX)yosys-filterlib
endif
$(INSTALL_SUDO) mkdir -p $(DESTDIR)$(DATDIR)
$(INSTALL_SUDO) cp -r share/. $(DESTDIR)$(DATDIR)/.
@@ -785,9 +793,9 @@ ifeq ($(ENABLE_LIBYOSYS),1)
$(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(LIBDIR)/
$(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so
ifeq ($(ENABLE_PYOSYS),1)
- $(INSTALL_SUDO) mkdir -p $(PYTHON_DESTDIR)/pyosys
- $(INSTALL_SUDO) cp libyosys.so $(PYTHON_DESTDIR)/pyosys/
- $(INSTALL_SUDO) cp misc/__init__.py $(PYTHON_DESTDIR)/pyosys/
+ $(INSTALL_SUDO) mkdir -p $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys
+ $(INSTALL_SUDO) cp libyosys.so $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so
+ $(INSTALL_SUDO) cp misc/__init__.py $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/
endif
endif
@@ -797,14 +805,14 @@ uninstall:
ifeq ($(ENABLE_LIBYOSYS),1)
$(INSTALL_SUDO) rm -vf $(DESTDIR)$(LIBDIR)/libyosys.so
ifeq ($(ENABLE_PYOSYS),1)
- $(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/pyosys/libyosys.so
- $(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/pyosys/__init__.py
- $(INSTALL_SUDO) rmdir $(PYTHON_DESTDIR)/pyosys
+ $(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so
+ $(INSTALL_SUDO) rm -vf $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py
+ $(INSTALL_SUDO) rmdir $(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys
endif
endif
update-manual: $(TARGETS) $(EXTRA_TARGETS)
- cd manual && ../yosys -p 'help -write-tex-command-reference-manual'
+ cd manual && ../$(PROGRAM_PREFIX)yosys -p 'help -write-tex-command-reference-manual'
manual: $(TARGETS) $(EXTRA_TARGETS)
cd manual && bash appnotes.sh
@@ -830,13 +838,13 @@ clean:
clean-abc:
$(MAKE) -C abc DEP= clean
- rm -f yosys-abc$(EXE) yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a
+ rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a
mrproper: clean
git clean -xdf
coverage:
- ./yosys -qp 'help; help -all'
+ ./$(PROGRAM_PREFIX)yosys -qp 'help; help -all'
rm -rf coverage.info coverage_html
lcov --capture -d . --no-external -o coverage.info
genhtml coverage.info --output-directory coverage_html
@@ -862,9 +870,9 @@ ifeq ($(CONFIG),mxe)
mxebin: $(TARGETS) $(EXTRA_TARGETS)
rm -rf yosys-win32-mxebin-$(YOSYS_VER){,.zip}
mkdir -p yosys-win32-mxebin-$(YOSYS_VER)
- cp -r yosys.exe share/ yosys-win32-mxebin-$(YOSYS_VER)/
+ cp -r $(PROGRAM_PREFIX)yosys.exe share/ yosys-win32-mxebin-$(YOSYS_VER)/
ifeq ($(ENABLE_ABC),1)
- cp -r yosys-abc.exe abc/lib/x86/pthreadVC2.dll yosys-win32-mxebin-$(YOSYS_VER)/
+ cp -r $(PROGRAM_PREFIX)yosys-abc.exe abc/lib/x86/pthreadVC2.dll yosys-win32-mxebin-$(YOSYS_VER)/
endif
echo -en 'This is Yosys $(YOSYS_VER) for Win32.\r\n' > yosys-win32-mxebin-$(YOSYS_VER)/readme.txt
echo -en 'Documentation at http://www.clifford.at/yosys/.\r\n' >> yosys-win32-mxebin-$(YOSYS_VER)/readme.txt
diff --git a/README.md b/README.md
index ce7b26411..0a81d8bb9 100644
--- a/README.md
+++ b/README.md
@@ -443,8 +443,8 @@ Verilog Attributes and non-standard features
- The ``wiretype`` attribute is added by the verilog parser for wires of a
typedef'd type to indicate the type identifier.
-- Various ``enum_{width}_{value}`` attributes are added to wires of an
- enumerated type to give a map of possible enum items to their values.
+- Various ``enum_value_{value}`` attributes are added to wires of an enumerated type
+ to give a map of possible enum items to their values.
- The ``enum_base_type`` attribute is added to enum items to indicate which
enum they belong to (enums -- anonymous and otherwise -- are
diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc
index a51e3648c..cac32a8da 100644
--- a/backends/aiger/aiger.cc
+++ b/backends/aiger/aiger.cc
@@ -126,9 +126,9 @@ struct AigerWriter
for (auto wire : module->wires())
{
- if (wire->attributes.count("\\init")) {
+ if (wire->attributes.count(ID::init)) {
SigSpec initsig = sigmap(wire);
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(wire) && i < GetSize(initval); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
init_map[initsig[i]] = initval[i] == State::S1;
@@ -169,31 +169,31 @@ struct AigerWriter
for (auto cell : module->cells())
{
- if (cell->type == "$_NOT_")
+ if (cell->type == ID($_NOT_))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
undriven_bits.erase(Y);
not_map[Y] = A;
continue;
}
- if (cell->type.in("$_FF_", "$_DFF_N_", "$_DFF_P_"))
+ if (cell->type.in(ID($_FF_), ID($_DFF_N_), ID($_DFF_P_)))
{
- SigBit D = sigmap(cell->getPort("\\D").as_bit());
- SigBit Q = sigmap(cell->getPort("\\Q").as_bit());
+ SigBit D = sigmap(cell->getPort(ID::D).as_bit());
+ SigBit Q = sigmap(cell->getPort(ID::Q).as_bit());
unused_bits.erase(D);
undriven_bits.erase(Q);
ff_map[Q] = D;
continue;
}
- if (cell->type == "$_AND_")
+ if (cell->type == ID($_AND_))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit B = sigmap(cell->getPort("\\B").as_bit());
- SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit B = sigmap(cell->getPort(ID::B).as_bit());
+ SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
unused_bits.erase(B);
undriven_bits.erase(Y);
@@ -201,66 +201,66 @@ struct AigerWriter
continue;
}
- if (cell->type == "$initstate")
+ if (cell->type == ID($initstate))
{
- SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
+ SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
undriven_bits.erase(Y);
initstate_bits.insert(Y);
continue;
}
- if (cell->type == "$assert")
+ if (cell->type == ID($assert))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
asserts.push_back(make_pair(A, EN));
continue;
}
- if (cell->type == "$assume")
+ if (cell->type == ID($assume))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
assumes.push_back(make_pair(A, EN));
continue;
}
- if (cell->type == "$live")
+ if (cell->type == ID($live))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
liveness.push_back(make_pair(A, EN));
continue;
}
- if (cell->type == "$fair")
+ if (cell->type == ID($fair))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit EN = sigmap(cell->getPort("\\EN").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit EN = sigmap(cell->getPort(ID::EN).as_bit());
unused_bits.erase(A);
unused_bits.erase(EN);
fairness.push_back(make_pair(A, EN));
continue;
}
- if (cell->type == "$anyconst")
+ if (cell->type == ID($anyconst))
{
- for (auto bit : sigmap(cell->getPort("\\Y"))) {
+ for (auto bit : sigmap(cell->getPort(ID::Y))) {
undriven_bits.erase(bit);
ff_map[bit] = bit;
}
continue;
}
- if (cell->type == "$anyseq")
+ if (cell->type == ID($anyseq))
{
- for (auto bit : sigmap(cell->getPort("\\Y"))) {
+ for (auto bit : sigmap(cell->getPort(ID::Y))) {
undriven_bits.erase(bit);
input_bits.insert(bit);
}
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc
index cde6d066a..3c7c745fe 100644
--- a/backends/aiger/xaiger.cc
+++ b/backends/aiger/xaiger.cc
@@ -174,7 +174,7 @@ struct XAigerWriter
undriven_bits.insert(bit);
unused_bits.insert(bit);
- bool scc = wire->attributes.count(ID(abc9_scc));
+ bool scc = wire->attributes.count(ID::abc9_scc);
if (wire->port_input || scc)
input_bits.insert(bit);
@@ -190,21 +190,21 @@ struct XAigerWriter
for (auto cell : module->cells()) {
if (!cell->has_keep_attr()) {
- if (cell->type == "$_NOT_")
+ if (cell->type == ID($_NOT_))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
undriven_bits.erase(Y);
not_map[Y] = A;
continue;
}
- if (cell->type == "$_AND_")
+ if (cell->type == ID($_AND_))
{
- SigBit A = sigmap(cell->getPort("\\A").as_bit());
- SigBit B = sigmap(cell->getPort("\\B").as_bit());
- SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
+ SigBit A = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit B = sigmap(cell->getPort(ID::B).as_bit());
+ SigBit Y = sigmap(cell->getPort(ID::Y).as_bit());
unused_bits.erase(A);
unused_bits.erase(B);
undriven_bits.erase(Y);
@@ -212,13 +212,13 @@ struct XAigerWriter
continue;
}
- if (cell->type == "$__ABC9_FF_" &&
+ if (cell->type == ID($__ABC9_FF_) &&
// The presence of an abc9_mergeability attribute indicates
// that we do want to pass this flop to ABC
- cell->attributes.count("\\abc9_mergeability"))
+ cell->attributes.count(ID::abc9_mergeability))
{
- SigBit D = sigmap(cell->getPort("\\D").as_bit());
- SigBit Q = sigmap(cell->getPort("\\Q").as_bit());
+ SigBit D = sigmap(cell->getPort(ID::D).as_bit());
+ SigBit Q = sigmap(cell->getPort(ID::Q).as_bit());
unused_bits.erase(D);
undriven_bits.erase(Q);
alias_map[Q] = D;
@@ -227,7 +227,7 @@ struct XAigerWriter
continue;
}
- if (cell->type.in("$specify2", "$specify3", "$specrule"))
+ if (cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
continue;
}
@@ -239,7 +239,7 @@ struct XAigerWriter
bool abc9_flop = false;
if (!cell->has_keep_attr()) {
- auto it = cell->attributes.find("\\abc9_box_seq");
+ auto it = cell->attributes.find(ID::abc9_box_seq);
if (it != cell->attributes.end()) {
int abc9_box_seq = it->second.as_int();
if (GetSize(box_list) <= abc9_box_seq)
@@ -247,7 +247,7 @@ struct XAigerWriter
box_list[abc9_box_seq] = cell;
// Only flop boxes may have arrival times
// (all others are combinatorial)
- abc9_flop = inst_module->get_bool_attribute("\\abc9_flop");
+ abc9_flop = inst_module->get_bool_attribute(ID::abc9_flop);
if (!abc9_flop)
continue;
}
@@ -280,6 +280,10 @@ struct XAigerWriter
if (abc9_flop)
continue;
}
+ else {
+ if (cell->type == ID($__ABC9_DELAY))
+ log_error("Cell type '%s' not recognised. Check that '+/abc9_model.v' has been read.\n", cell->type.c_str());
+ }
bool cell_known = inst_module || cell->known();
for (const auto &c : cell->connections()) {
@@ -315,7 +319,7 @@ struct XAigerWriter
RTLIL::Module* box_module = module->design->module(cell->type);
log_assert(box_module);
- log_assert(box_module->attributes.count("\\abc9_box_id") || box_module->get_bool_attribute("\\abc9_flop"));
+ log_assert(box_module->attributes.count(ID::abc9_box_id) || box_module->get_bool_attribute(ID::abc9_flop));
auto r = box_ports.insert(cell->type);
if (r.second) {
@@ -325,7 +329,7 @@ struct XAigerWriter
for (const auto &port_name : box_module->ports) {
auto w = box_module->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
if (w->port_input) {
if (carry_in != IdString())
log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(box_module));
@@ -381,7 +385,7 @@ struct XAigerWriter
}
// Connect <cell>.abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box
- if (box_module->get_bool_attribute("\\abc9_flop")) {
+ if (box_module->get_bool_attribute(ID::abc9_flop)) {
SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str()));
if (rhs.empty())
log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module));
@@ -437,7 +441,7 @@ struct XAigerWriter
for (const auto &i : ff_bits) {
const Cell *cell = i.second;
- const SigBit &q = sigmap(cell->getPort("\\Q"));
+ const SigBit &q = sigmap(cell->getPort(ID::Q));
aig_m++, aig_i++;
log_assert(!aig_map.count(q));
aig_map[q] = 2*aig_m;
@@ -608,12 +612,12 @@ struct XAigerWriter
// For flops only, create an extra 1-bit input that drives a new wire
// called "<cell>.abc9_ff.Q" that is used below
- if (box_module->get_bool_attribute("\\abc9_flop"))
+ if (box_module->get_bool_attribute(ID::abc9_flop))
box_inputs++;
std::get<0>(v) = box_inputs;
std::get<1>(v) = box_outputs;
- std::get<2>(v) = box_module->attributes.at("\\abc9_box_id").as_int();
+ std::get<2>(v) = box_module->attributes.at(ID::abc9_box_id).as_int();
}
write_h_buffer(std::get<0>(v));
@@ -635,11 +639,11 @@ struct XAigerWriter
const SigBit &d = i.first;
const Cell *cell = i.second;
- int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int();
+ int mergeability = cell->attributes.at(ID::abc9_mergeability).as_int();
log_assert(mergeability > 0);
write_r_buffer(mergeability);
- Const init = cell->attributes.at(ID(abc9_init), State::Sx);
+ Const init = cell->attributes.at(ID::abc9_init, State::Sx);
log_assert(GetSize(init) == 1);
if (init == State::S1)
write_s_buffer(1);
diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc
index b6e38c16c..b028df848 100644
--- a/backends/blif/blif.cc
+++ b/backends/blif/blif.cc
@@ -69,9 +69,9 @@ struct BlifDumper
f(f), module(module), design(design), config(config), ct(design), sigmap(module)
{
for (Wire *wire : module->wires())
- if (wire->attributes.count("\\init")) {
+ if (wire->attributes.count(ID::init)) {
SigSpec initsig = sigmap(wire);
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
switch (initval[i]) {
case State::S0:
@@ -138,9 +138,9 @@ struct BlifDumper
{
if (!config->gates_mode)
return "subckt";
- if (!design->modules_.count(RTLIL::escape_id(cell_type)))
+ if (design->module(RTLIL::escape_id(cell_type)) == nullptr)
return "gate";
- if (design->modules_.at(RTLIL::escape_id(cell_type))->get_blackbox_attribute())
+ if (design->module(RTLIL::escape_id(cell_type))->get_blackbox_attribute())
return "gate";
return "subckt";
}
@@ -148,7 +148,7 @@ struct BlifDumper
void dump_params(const char *command, dict<IdString, Const> &params)
{
for (auto &param : params) {
- f << stringf("%s %s ", command, RTLIL::id2cstr(param.first));
+ f << stringf("%s %s ", command, log_id(param.first));
if (param.second.flags & RTLIL::CONST_FLAG_STRING) {
std::string str = param.second.decode_string();
f << stringf("\"");
@@ -172,8 +172,7 @@ struct BlifDumper
std::map<int, RTLIL::Wire*> inputs, outputs;
- for (auto &wire_it : module->wires_) {
- RTLIL::Wire *wire = wire_it.second;
+ for (auto wire : module->wires()) {
if (wire->port_input)
inputs[wire->port_id] = wire;
if (wire->port_output)
@@ -229,10 +228,8 @@ struct BlifDumper
f << stringf(".names $undef\n");
}
- for (auto &cell_it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = cell_it.second;
-
if (config->unbuf_types.count(cell->type)) {
auto portnames = config->unbuf_types.at(cell->type);
f << stringf(".names %s %s\n1 1\n",
@@ -240,142 +237,142 @@ struct BlifDumper
continue;
}
- if (!config->icells_mode && cell->type == "$_NOT_") {
+ if (!config->icells_mode && cell->type == ID($_NOT_)) {
f << stringf(".names %s %s\n0 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_AND_") {
+ if (!config->icells_mode && cell->type == ID($_AND_)) {
f << stringf(".names %s %s %s\n11 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_OR_") {
+ if (!config->icells_mode && cell->type == ID($_OR_)) {
f << stringf(".names %s %s %s\n1- 1\n-1 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_XOR_") {
+ if (!config->icells_mode && cell->type == ID($_XOR_)) {
f << stringf(".names %s %s %s\n10 1\n01 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_NAND_") {
+ if (!config->icells_mode && cell->type == ID($_NAND_)) {
f << stringf(".names %s %s %s\n0- 1\n-0 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_NOR_") {
+ if (!config->icells_mode && cell->type == ID($_NOR_)) {
f << stringf(".names %s %s %s\n00 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_XNOR_") {
+ if (!config->icells_mode && cell->type == ID($_XNOR_)) {
f << stringf(".names %s %s %s\n11 1\n00 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_ANDNOT_") {
+ if (!config->icells_mode && cell->type == ID($_ANDNOT_)) {
f << stringf(".names %s %s %s\n10 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_ORNOT_") {
+ if (!config->icells_mode && cell->type == ID($_ORNOT_)) {
f << stringf(".names %s %s %s\n1- 1\n-0 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_AOI3_") {
+ if (!config->icells_mode && cell->type == ID($_AOI3_)) {
f << stringf(".names %s %s %s %s\n-00 1\n0-0 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\C")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_OAI3_") {
+ if (!config->icells_mode && cell->type == ID($_OAI3_)) {
f << stringf(".names %s %s %s %s\n00- 1\n--0 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")), cstr(cell->getPort("\\C")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)), cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_AOI4_") {
+ if (!config->icells_mode && cell->type == ID($_AOI4_)) {
f << stringf(".names %s %s %s %s %s\n-0-0 1\n-00- 1\n0--0 1\n0-0- 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
- cstr(cell->getPort("\\C")), cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
+ cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_OAI4_") {
+ if (!config->icells_mode && cell->type == ID($_OAI4_)) {
f << stringf(".names %s %s %s %s %s\n00-- 1\n--00 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
- cstr(cell->getPort("\\C")), cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
+ cstr(cell->getPort(ID::C)), cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_MUX_") {
+ if (!config->icells_mode && cell->type == ID($_MUX_)) {
f << stringf(".names %s %s %s %s\n1-0 1\n-11 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
- cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
+ cstr(cell->getPort(ID::S)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_NMUX_") {
+ if (!config->icells_mode && cell->type == ID($_NMUX_)) {
f << stringf(".names %s %s %s %s\n0-0 1\n-01 1\n",
- cstr(cell->getPort("\\A")), cstr(cell->getPort("\\B")),
- cstr(cell->getPort("\\S")), cstr(cell->getPort("\\Y")));
+ cstr(cell->getPort(ID::A)), cstr(cell->getPort(ID::B)),
+ cstr(cell->getPort(ID::S)), cstr(cell->getPort(ID::Y)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_FF_") {
- f << stringf(".latch %s %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
- cstr_init(cell->getPort("\\Q")));
+ if (!config->icells_mode && cell->type == ID($_FF_)) {
+ f << stringf(".latch %s %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
+ cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_DFF_N_") {
- f << stringf(".latch %s %s fe %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
- cstr(cell->getPort("\\C")), cstr_init(cell->getPort("\\Q")));
+ if (!config->icells_mode && cell->type == ID($_DFF_N_)) {
+ f << stringf(".latch %s %s fe %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
+ cstr(cell->getPort(ID::C)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_DFF_P_") {
- f << stringf(".latch %s %s re %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
- cstr(cell->getPort("\\C")), cstr_init(cell->getPort("\\Q")));
+ if (!config->icells_mode && cell->type == ID($_DFF_P_)) {
+ f << stringf(".latch %s %s re %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
+ cstr(cell->getPort(ID::C)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_DLATCH_N_") {
- f << stringf(".latch %s %s al %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
- cstr(cell->getPort("\\E")), cstr_init(cell->getPort("\\Q")));
+ if (!config->icells_mode && cell->type == ID($_DLATCH_N_)) {
+ f << stringf(".latch %s %s al %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
+ cstr(cell->getPort(ID::E)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$_DLATCH_P_") {
- f << stringf(".latch %s %s ah %s%s\n", cstr(cell->getPort("\\D")), cstr(cell->getPort("\\Q")),
- cstr(cell->getPort("\\E")), cstr_init(cell->getPort("\\Q")));
+ if (!config->icells_mode && cell->type == ID($_DLATCH_P_)) {
+ f << stringf(".latch %s %s ah %s%s\n", cstr(cell->getPort(ID::D)), cstr(cell->getPort(ID::Q)),
+ cstr(cell->getPort(ID::E)), cstr_init(cell->getPort(ID::Q)));
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$lut") {
+ if (!config->icells_mode && cell->type == ID($lut)) {
f << stringf(".names");
- auto &inputs = cell->getPort("\\A");
- auto width = cell->parameters.at("\\WIDTH").as_int();
+ auto &inputs = cell->getPort(ID::A);
+ auto width = cell->parameters.at(ID::WIDTH).as_int();
log_assert(inputs.size() == width);
for (int i = width-1; i >= 0; i--)
f << stringf(" %s", cstr(inputs.extract(i, 1)));
- auto &output = cell->getPort("\\Y");
+ auto &output = cell->getPort(ID::Y);
log_assert(output.size() == 1);
f << stringf(" %s", cstr(output));
f << stringf("\n");
- RTLIL::SigSpec mask = cell->parameters.at("\\LUT");
+ RTLIL::SigSpec mask = cell->parameters.at(ID::LUT);
for (int i = 0; i < (1 << width); i++)
if (mask[i] == State::S1) {
for (int j = width-1; j >= 0; j--) {
@@ -386,18 +383,18 @@ struct BlifDumper
goto internal_cell;
}
- if (!config->icells_mode && cell->type == "$sop") {
+ if (!config->icells_mode && cell->type == ID($sop)) {
f << stringf(".names");
- auto &inputs = cell->getPort("\\A");
- auto width = cell->parameters.at("\\WIDTH").as_int();
- auto depth = cell->parameters.at("\\DEPTH").as_int();
- vector<State> table = cell->parameters.at("\\TABLE").bits;
+ auto &inputs = cell->getPort(ID::A);
+ auto width = cell->parameters.at(ID::WIDTH).as_int();
+ auto depth = cell->parameters.at(ID::DEPTH).as_int();
+ vector<State> table = cell->parameters.at(ID::TABLE).bits;
while (GetSize(table) < 2*width*depth)
table.push_back(State::S0);
log_assert(inputs.size() == width);
for (int i = 0; i < width; i++)
f << stringf(" %s", cstr(inputs.extract(i, 1)));
- auto &output = cell->getPort("\\Y");
+ auto &output = cell->getPort(ID::Y);
log_assert(output.size() == 1);
f << stringf(" %s", cstr(output));
f << stringf("\n");
@@ -649,25 +646,24 @@ struct BlifBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
- for (auto & mod_it:design->modules_)
- if (mod_it.second->get_bool_attribute("\\top"))
- top_module_name = mod_it.first.str();
+ for (auto module : design->modules())
+ if (module->get_bool_attribute(ID::top))
+ top_module_name = module->name.str();
*f << stringf("# Generated by %s\n", yosys_version_str);
std::vector<RTLIL::Module*> mod_list;
design->sort();
- for (auto module_it : design->modules_)
+ for (auto module : design->modules())
{
- RTLIL::Module *module = module_it.second;
if (module->get_blackbox_attribute() && !config.blackbox_mode)
continue;
if (module->processes.size() != 0)
- log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name));
+ log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", log_id(module->name));
if (module->memories.size() != 0)
- log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name));
+ log_error("Found unmapped memories in module %s: unmapped memories are not supported in BLIF backend!\n", log_id(module->name));
if (module->name == RTLIL::escape_id(top_module_name)) {
BlifDumper::dump(*f, module, design, config);
diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc
index c1da4b127..14c8484e8 100644
--- a/backends/btor/btor.cc
+++ b/backends/btor/btor.cc
@@ -39,6 +39,7 @@ struct BtorWorker
RTLIL::Module *module;
bool verbose;
bool single_bad;
+ bool cover_mode;
int next_nid = 1;
int initstate_nid = -1;
@@ -71,7 +72,11 @@ struct BtorWorker
vector<int> bad_properties;
dict<SigBit, bool> initbits;
pool<Wire*> statewires;
- string indent;
+ pool<string> srcsymbols;
+
+ string indent, info_filename;
+ vector<string> info_lines;
+ dict<int, int> info_clocks;
void btorf(const char *fmt, ...)
{
@@ -81,6 +86,40 @@ struct BtorWorker
va_end(ap);
}
+ void infof(const char *fmt, ...)
+ {
+ va_list ap;
+ va_start(ap, fmt);
+ info_lines.push_back(vstringf(fmt, ap));
+ va_end(ap);
+ }
+
+ template<typename T>
+ string getinfo(T *obj, bool srcsym = false)
+ {
+ string infostr = log_id(obj);
+ if (obj->attributes.count(ID::src)) {
+ string src = obj->attributes.at(ID::src).decode_string().c_str();
+ if (srcsym && infostr[0] == '$') {
+ std::replace(src.begin(), src.end(), ' ', '_');
+ if (srcsymbols.count(src) || module->count_id("\\" + src)) {
+ for (int i = 1;; i++) {
+ string s = stringf("%s-%d", src.c_str(), i);
+ if (!srcsymbols.count(s) && !module->count_id("\\" + s)) {
+ src = s;
+ break;
+ }
+ }
+ }
+ srcsymbols.insert(src);
+ infostr = src;
+ } else {
+ infostr += " ; " + src;
+ }
+ }
+ return infostr;
+ }
+
void btorf_push(const string &id)
{
if (verbose) {
@@ -144,40 +183,40 @@ struct BtorWorker
cell_recursion_guard.insert(cell);
btorf_push(log_id(cell));
- if (cell->type.in("$add", "$sub", "$mul", "$and", "$or", "$xor", "$xnor", "$shl", "$sshl", "$shr", "$sshr", "$shift", "$shiftx",
- "$concat", "$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_"))
+ if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx),
+ ID($concat), ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_)))
{
string btor_op;
- if (cell->type == "$add") btor_op = "add";
- if (cell->type == "$sub") btor_op = "sub";
- if (cell->type == "$mul") btor_op = "mul";
- if (cell->type.in("$shl", "$sshl")) btor_op = "sll";
- if (cell->type == "$shr") btor_op = "srl";
- if (cell->type == "$sshr") btor_op = "sra";
- if (cell->type.in("$shift", "$shiftx")) btor_op = "shift";
- if (cell->type.in("$and", "$_AND_")) btor_op = "and";
- if (cell->type.in("$or", "$_OR_")) btor_op = "or";
- if (cell->type.in("$xor", "$_XOR_")) btor_op = "xor";
- if (cell->type == "$concat") btor_op = "concat";
- if (cell->type == "$_NAND_") btor_op = "nand";
- if (cell->type == "$_NOR_") btor_op = "nor";
- if (cell->type.in("$xnor", "$_XNOR_")) btor_op = "xnor";
+ if (cell->type == ID($add)) btor_op = "add";
+ if (cell->type == ID($sub)) btor_op = "sub";
+ if (cell->type == ID($mul)) btor_op = "mul";
+ if (cell->type.in(ID($shl), ID($sshl))) btor_op = "sll";
+ if (cell->type == ID($shr)) btor_op = "srl";
+ if (cell->type == ID($sshr)) btor_op = "sra";
+ if (cell->type.in(ID($shift), ID($shiftx))) btor_op = "shift";
+ if (cell->type.in(ID($and), ID($_AND_))) btor_op = "and";
+ if (cell->type.in(ID($or), ID($_OR_))) btor_op = "or";
+ if (cell->type.in(ID($xor), ID($_XOR_))) btor_op = "xor";
+ if (cell->type == ID($concat)) btor_op = "concat";
+ if (cell->type == ID($_NAND_)) btor_op = "nand";
+ if (cell->type == ID($_NOR_)) btor_op = "nor";
+ if (cell->type.in(ID($xnor), ID($_XNOR_))) btor_op = "xnor";
log_assert(!btor_op.empty());
- int width = GetSize(cell->getPort("\\Y"));
- width = std::max(width, GetSize(cell->getPort("\\A")));
- width = std::max(width, GetSize(cell->getPort("\\B")));
+ int width = GetSize(cell->getPort(ID::Y));
+ width = std::max(width, GetSize(cell->getPort(ID::A)));
+ width = std::max(width, GetSize(cell->getPort(ID::B)));
- bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
- bool b_signed = cell->hasParam("\\B_SIGNED") ? cell->getParam("\\B_SIGNED").as_bool() : false;
+ bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
+ bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
if (btor_op == "shift" && !b_signed)
btor_op = "srl";
- if (cell->type.in("$shl", "$sshl", "$shr", "$sshr"))
+ if (cell->type.in(ID($shl), ID($sshl), ID($shr), ID($sshr)))
b_signed = false;
- if (cell->type == "$sshr" && !a_signed)
+ if (cell->type == ID($sshr) && !a_signed)
btor_op = "srl";
int sid = get_bv_sid(width);
@@ -185,8 +224,8 @@ struct BtorWorker
if (btor_op == "shift")
{
- int nid_a = get_sig_nid(cell->getPort("\\A"), width, false);
- int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
+ int nid_a = get_sig_nid(cell->getPort(ID::A), width, false);
+ int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
int nid_r = next_nid++;
btorf("%d srl %d %d %d\n", nid_r, sid, nid_a, nid_b);
@@ -203,18 +242,18 @@ struct BtorWorker
btorf("%d slt %d %d %d\n", nid_b_ltz, sid_bit, nid_b, nid_zero);
nid = next_nid++;
- btorf("%d ite %d %d %d %d\n", nid, sid, nid_b_ltz, nid_l, nid_r);
+ btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_b_ltz, nid_l, nid_r, getinfo(cell).c_str());
}
else
{
- int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
- int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
+ int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
+ int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
nid = next_nid++;
- btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b);
+ btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
}
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) < width) {
int sid = get_bv_sid(GetSize(sig));
@@ -227,28 +266,28 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$div", "$mod"))
+ if (cell->type.in(ID($div), ID($mod)))
{
string btor_op;
- if (cell->type == "$div") btor_op = "div";
- if (cell->type == "$mod") btor_op = "rem";
+ if (cell->type == ID($div)) btor_op = "div";
+ if (cell->type == ID($mod)) btor_op = "rem";
log_assert(!btor_op.empty());
- int width = GetSize(cell->getPort("\\Y"));
- width = std::max(width, GetSize(cell->getPort("\\A")));
- width = std::max(width, GetSize(cell->getPort("\\B")));
+ int width = GetSize(cell->getPort(ID::Y));
+ width = std::max(width, GetSize(cell->getPort(ID::A)));
+ width = std::max(width, GetSize(cell->getPort(ID::B)));
- bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
- bool b_signed = cell->hasParam("\\B_SIGNED") ? cell->getParam("\\B_SIGNED").as_bool() : false;
+ bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
+ bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
- int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
- int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
+ int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
+ int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
int sid = get_bv_sid(width);
int nid = next_nid++;
- btorf("%d %c%s %d %d %d\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b);
+ btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) < width) {
int sid = get_bv_sid(GetSize(sig));
@@ -261,120 +300,120 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$_ANDNOT_", "$_ORNOT_"))
+ if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
{
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"));
- int nid_b = get_sig_nid(cell->getPort("\\B"));
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
+ int nid_b = get_sig_nid(cell->getPort(ID::B));
int nid1 = next_nid++;
int nid2 = next_nid++;
- if (cell->type == "$_ANDNOT_") {
+ if (cell->type == ID($_ANDNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
- btorf("%d and %d %d %d\n", nid2, sid, nid_a, nid1);
+ btorf("%d and %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
}
- if (cell->type == "$_ORNOT_") {
+ if (cell->type == ID($_ORNOT_)) {
btorf("%d not %d %d\n", nid1, sid, nid_b);
- btorf("%d or %d %d %d\n", nid2, sid, nid_a, nid1);
+ btorf("%d or %d %d %d %s\n", nid2, sid, nid_a, nid1, getinfo(cell).c_str());
}
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
add_nid_sig(nid2, sig);
goto okay;
}
- if (cell->type.in("$_OAI3_", "$_AOI3_"))
+ if (cell->type.in(ID($_OAI3_), ID($_AOI3_)))
{
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"));
- int nid_b = get_sig_nid(cell->getPort("\\B"));
- int nid_c = get_sig_nid(cell->getPort("\\C"));
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
+ int nid_b = get_sig_nid(cell->getPort(ID::B));
+ int nid_c = get_sig_nid(cell->getPort(ID::C));
int nid1 = next_nid++;
int nid2 = next_nid++;
int nid3 = next_nid++;
- if (cell->type == "$_OAI3_") {
+ if (cell->type == ID($_OAI3_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid1, nid_c);
- btorf("%d not %d %d\n", nid3, sid, nid2);
+ btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str());
}
- if (cell->type == "$_AOI3_") {
+ if (cell->type == ID($_AOI3_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid1, nid_c);
- btorf("%d not %d %d\n", nid3, sid, nid2);
+ btorf("%d not %d %d %s\n", nid3, sid, nid2, getinfo(cell).c_str());
}
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
add_nid_sig(nid3, sig);
goto okay;
}
- if (cell->type.in("$_OAI4_", "$_AOI4_"))
+ if (cell->type.in(ID($_OAI4_), ID($_AOI4_)))
{
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"));
- int nid_b = get_sig_nid(cell->getPort("\\B"));
- int nid_c = get_sig_nid(cell->getPort("\\C"));
- int nid_d = get_sig_nid(cell->getPort("\\D"));
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
+ int nid_b = get_sig_nid(cell->getPort(ID::B));
+ int nid_c = get_sig_nid(cell->getPort(ID::C));
+ int nid_d = get_sig_nid(cell->getPort(ID::D));
int nid1 = next_nid++;
int nid2 = next_nid++;
int nid3 = next_nid++;
int nid4 = next_nid++;
- if (cell->type == "$_OAI4_") {
+ if (cell->type == ID($_OAI4_)) {
btorf("%d or %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d or %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d and %d %d %d\n", nid3, sid, nid1, nid2);
- btorf("%d not %d %d\n", nid4, sid, nid3);
+ btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str());
}
- if (cell->type == "$_AOI4_") {
+ if (cell->type == ID($_AOI4_)) {
btorf("%d and %d %d %d\n", nid1, sid, nid_a, nid_b);
btorf("%d and %d %d %d\n", nid2, sid, nid_c, nid_d);
btorf("%d or %d %d %d\n", nid3, sid, nid1, nid2);
- btorf("%d not %d %d\n", nid4, sid, nid3);
+ btorf("%d not %d %d %s\n", nid4, sid, nid3, getinfo(cell).c_str());
}
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
add_nid_sig(nid4, sig);
goto okay;
}
- if (cell->type.in("$lt", "$le", "$eq", "$eqx", "$ne", "$nex", "$ge", "$gt"))
+ if (cell->type.in(ID($lt), ID($le), ID($eq), ID($eqx), ID($ne), ID($nex), ID($ge), ID($gt)))
{
string btor_op;
- if (cell->type == "$lt") btor_op = "lt";
- if (cell->type == "$le") btor_op = "lte";
- if (cell->type.in("$eq", "$eqx")) btor_op = "eq";
- if (cell->type.in("$ne", "$nex")) btor_op = "neq";
- if (cell->type == "$ge") btor_op = "gte";
- if (cell->type == "$gt") btor_op = "gt";
+ if (cell->type == ID($lt)) btor_op = "lt";
+ if (cell->type == ID($le)) btor_op = "lte";
+ if (cell->type.in(ID($eq), ID($eqx))) btor_op = "eq";
+ if (cell->type.in(ID($ne), ID($nex))) btor_op = "neq";
+ if (cell->type == ID($ge)) btor_op = "gte";
+ if (cell->type == ID($gt)) btor_op = "gt";
log_assert(!btor_op.empty());
int width = 1;
- width = std::max(width, GetSize(cell->getPort("\\A")));
- width = std::max(width, GetSize(cell->getPort("\\B")));
+ width = std::max(width, GetSize(cell->getPort(ID::A)));
+ width = std::max(width, GetSize(cell->getPort(ID::B)));
- bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
- bool b_signed = cell->hasParam("\\B_SIGNED") ? cell->getParam("\\B_SIGNED").as_bool() : false;
+ bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
+ bool b_signed = cell->hasParam(ID::B_SIGNED) ? cell->getParam(ID::B_SIGNED).as_bool() : false;
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
- int nid_b = get_sig_nid(cell->getPort("\\B"), width, b_signed);
+ int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
+ int nid_b = get_sig_nid(cell->getPort(ID::B), width, b_signed);
int nid = next_nid++;
- if (cell->type.in("$lt", "$le", "$ge", "$gt")) {
- btorf("%d %c%s %d %d %d\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b);
+ if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt))) {
+ btorf("%d %c%s %d %d %d %s\n", nid, a_signed || b_signed ? 's' : 'u', btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
} else {
- btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b);
+ btorf("%d %s %d %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
}
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) > 1) {
int sid = get_bv_sid(GetSize(sig));
@@ -387,25 +426,24 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$not", "$neg", "$_NOT_"))
+ if (cell->type.in(ID($not), ID($neg), ID($_NOT_)))
{
string btor_op;
- if (cell->type.in("$not", "$_NOT_")) btor_op = "not";
- if (cell->type == "$neg") btor_op = "neg";
+ if (cell->type.in(ID($not), ID($_NOT_))) btor_op = "not";
+ if (cell->type == ID($neg)) btor_op = "neg";
log_assert(!btor_op.empty());
- int width = GetSize(cell->getPort("\\Y"));
- width = std::max(width, GetSize(cell->getPort("\\A")));
+ int width = std::max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::Y)));
- bool a_signed = cell->hasParam("\\A_SIGNED") ? cell->getParam("\\A_SIGNED").as_bool() : false;
+ bool a_signed = cell->hasParam(ID::A_SIGNED) ? cell->getParam(ID::A_SIGNED).as_bool() : false;
int sid = get_bv_sid(width);
- int nid_a = get_sig_nid(cell->getPort("\\A"), width, a_signed);
+ int nid_a = get_sig_nid(cell->getPort(ID::A), width, a_signed);
int nid = next_nid++;
- btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a);
+ btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) < width) {
int sid = get_bv_sid(GetSize(sig));
@@ -418,25 +456,25 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$logic_and", "$logic_or", "$logic_not"))
+ if (cell->type.in(ID($logic_and), ID($logic_or), ID($logic_not)))
{
string btor_op;
- if (cell->type == "$logic_and") btor_op = "and";
- if (cell->type == "$logic_or") btor_op = "or";
- if (cell->type == "$logic_not") btor_op = "not";
+ if (cell->type == ID($logic_and)) btor_op = "and";
+ if (cell->type == ID($logic_or)) btor_op = "or";
+ if (cell->type == ID($logic_not)) btor_op = "not";
log_assert(!btor_op.empty());
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"));
- int nid_b = btor_op != "not" ? get_sig_nid(cell->getPort("\\B")) : 0;
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
+ int nid_b = btor_op != "not" ? get_sig_nid(cell->getPort(ID::B)) : 0;
- if (GetSize(cell->getPort("\\A")) > 1) {
+ if (GetSize(cell->getPort(ID::A)) > 1) {
int nid_red_a = next_nid++;
btorf("%d redor %d %d\n", nid_red_a, sid, nid_a);
nid_a = nid_red_a;
}
- if (btor_op != "not" && GetSize(cell->getPort("\\B")) > 1) {
+ if (btor_op != "not" && GetSize(cell->getPort(ID::B)) > 1) {
int nid_red_b = next_nid++;
btorf("%d redor %d %d\n", nid_red_b, sid, nid_b);
nid_b = nid_red_b;
@@ -444,11 +482,11 @@ struct BtorWorker
int nid = next_nid++;
if (btor_op != "not")
- btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b);
+ btorf("%d %s %d %d %d\n", nid, btor_op.c_str(), sid, nid_a, nid_b, getinfo(cell).c_str());
else
- btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a);
+ btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) > 1) {
int sid = get_bv_sid(GetSize(sig));
@@ -462,27 +500,29 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool", "$reduce_xor", "$reduce_xnor"))
+ if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor)))
{
string btor_op;
- if (cell->type == "$reduce_and") btor_op = "redand";
- if (cell->type.in("$reduce_or", "$reduce_bool")) btor_op = "redor";
- if (cell->type.in("$reduce_xor", "$reduce_xnor")) btor_op = "redxor";
+ if (cell->type == ID($reduce_and)) btor_op = "redand";
+ if (cell->type.in(ID($reduce_or), ID($reduce_bool))) btor_op = "redor";
+ if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) btor_op = "redxor";
log_assert(!btor_op.empty());
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"));
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
int nid = next_nid++;
- btorf("%d %s %d %d\n", nid, btor_op.c_str(), sid, nid_a);
- if (cell->type == "$reduce_xnor") {
+ if (cell->type == ID($reduce_xnor)) {
int nid2 = next_nid++;
+ btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
btorf("%d not %d %d %d\n", nid2, sid, nid);
nid = nid2;
+ } else {
+ btorf("%d %s %d %d %s\n", nid, btor_op.c_str(), sid, nid_a, getinfo(cell).c_str());
}
- SigSpec sig = sigmap(cell->getPort("\\Y"));
+ SigSpec sig = sigmap(cell->getPort(ID::Y));
if (GetSize(sig) > 1) {
int sid = get_bv_sid(GetSize(sig));
@@ -496,12 +536,12 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$mux", "$_MUX_", "$_NMUX_"))
+ if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_)))
{
- SigSpec sig_a = sigmap(cell->getPort("\\A"));
- SigSpec sig_b = sigmap(cell->getPort("\\B"));
- SigSpec sig_s = sigmap(cell->getPort("\\S"));
- SigSpec sig_y = sigmap(cell->getPort("\\Y"));
+ SigSpec sig_a = sigmap(cell->getPort(ID::A));
+ SigSpec sig_b = sigmap(cell->getPort(ID::B));
+ SigSpec sig_s = sigmap(cell->getPort(ID::S));
+ SigSpec sig_y = sigmap(cell->getPort(ID::Y));
int nid_a = get_sig_nid(sig_a);
int nid_b = get_sig_nid(sig_b);
@@ -509,24 +549,26 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig_y));
int nid = next_nid++;
- btorf("%d ite %d %d %d %d\n", nid, sid, nid_s, nid_b, nid_a);
- if (cell->type == "$_NMUX_") {
+ if (cell->type == ID($_NMUX_)) {
int tmp = nid;
nid = next_nid++;
- btorf("%d not %d %d\n", nid, sid, tmp);
+ btorf("%d ite %d %d %d %d\n", tmp, sid, nid_s, nid_b, nid_a);
+ btorf("%d not %d %d %s\n", nid, sid, tmp, getinfo(cell).c_str());
+ } else {
+ btorf("%d ite %d %d %d %d %s\n", nid, sid, nid_s, nid_b, nid_a, getinfo(cell).c_str());
}
add_nid_sig(nid, sig_y);
goto okay;
}
- if (cell->type == "$pmux")
+ if (cell->type == ID($pmux))
{
- SigSpec sig_a = sigmap(cell->getPort("\\A"));
- SigSpec sig_b = sigmap(cell->getPort("\\B"));
- SigSpec sig_s = sigmap(cell->getPort("\\S"));
- SigSpec sig_y = sigmap(cell->getPort("\\Y"));
+ SigSpec sig_a = sigmap(cell->getPort(ID::A));
+ SigSpec sig_b = sigmap(cell->getPort(ID::B));
+ SigSpec sig_s = sigmap(cell->getPort(ID::S));
+ SigSpec sig_y = sigmap(cell->getPort(ID::Y));
int width = GetSize(sig_a);
int sid = get_bv_sid(width);
@@ -536,7 +578,10 @@ struct BtorWorker
int nid_b = get_sig_nid(sig_b.extract(i*width, width));
int nid_s = get_sig_nid(sig_s.extract(i));
int nid2 = next_nid++;
- btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid);
+ if (i == GetSize(sig_s)-1)
+ btorf("%d ite %d %d %d %d %s\n", nid2, sid, nid_s, nid_b, nid, getinfo(cell).c_str());
+ else
+ btorf("%d ite %d %d %d %d\n", nid2, sid, nid_s, nid_b, nid);
nid = nid2;
}
@@ -544,10 +589,25 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$dff", "$ff", "$_DFF_P_", "$_DFF_N", "$_FF_"))
+ if (cell->type.in(ID($dff), ID($ff), ID($_DFF_P_), ID($_DFF_N), ID($_FF_)))
{
- SigSpec sig_d = sigmap(cell->getPort("\\D"));
- SigSpec sig_q = sigmap(cell->getPort("\\Q"));
+ SigSpec sig_d = sigmap(cell->getPort(ID::D));
+ SigSpec sig_q = sigmap(cell->getPort(ID::Q));
+
+ if (!info_filename.empty() && cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)))
+ {
+ SigSpec sig_c = sigmap(cell->getPort(cell->type == ID($dff) ? ID::CLK : ID::C));
+ int nid = get_sig_nid(sig_c);
+ bool negedge = false;
+
+ if (cell->type == ID($_DFF_N_))
+ negedge = true;
+
+ if (cell->type == ID($dff) && !cell->getParam(ID::CLK_POLARITY).as_bool())
+ negedge = true;
+
+ info_clocks[nid] |= negedge ? 2 : 1;
+ }
IdString symbol;
@@ -591,16 +651,16 @@ struct BtorWorker
goto okay;
}
- if (cell->type.in("$anyconst", "$anyseq"))
+ if (cell->type.in(ID($anyconst), ID($anyseq)))
{
- SigSpec sig_y = sigmap(cell->getPort("\\Y"));
+ SigSpec sig_y = sigmap(cell->getPort(ID::Y));
int sid = get_bv_sid(GetSize(sig_y));
int nid = next_nid++;
btorf("%d state %d\n", nid, sid);
- if (cell->type == "$anyconst") {
+ if (cell->type == ID($anyconst)) {
int nid2 = next_nid++;
btorf("%d next %d %d %d\n", nid2, sid, nid, nid);
}
@@ -609,9 +669,9 @@ struct BtorWorker
goto okay;
}
- if (cell->type == "$initstate")
+ if (cell->type == ID($initstate))
{
- SigSpec sig_y = sigmap(cell->getPort("\\Y"));
+ SigSpec sig_y = sigmap(cell->getPort(ID::Y));
if (initstate_nid < 0)
{
@@ -628,16 +688,16 @@ struct BtorWorker
goto okay;
}
- if (cell->type == "$mem")
+ if (cell->type == ID($mem))
{
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
- int nwords = cell->getParam("\\SIZE").as_int();
- int rdports = cell->getParam("\\RD_PORTS").as_int();
- int wrports = cell->getParam("\\WR_PORTS").as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int nwords = cell->getParam(ID::SIZE).as_int();
+ int rdports = cell->getParam(ID::RD_PORTS).as_int();
+ int wrports = cell->getParam(ID::WR_PORTS).as_int();
- Const wr_clk_en = cell->getParam("\\WR_CLK_ENABLE");
- Const rd_clk_en = cell->getParam("\\RD_CLK_ENABLE");
+ Const wr_clk_en = cell->getParam(ID::WR_CLK_ENABLE);
+ Const rd_clk_en = cell->getParam(ID::RD_CLK_ENABLE);
bool asyncwr = wr_clk_en.is_fully_zero();
@@ -649,18 +709,18 @@ struct BtorWorker
log_error("Memory %s.%s has sync read ports.\n",
log_id(module), log_id(cell));
- SigSpec sig_rd_addr = sigmap(cell->getPort("\\RD_ADDR"));
- SigSpec sig_rd_data = sigmap(cell->getPort("\\RD_DATA"));
+ SigSpec sig_rd_addr = sigmap(cell->getPort(ID::RD_ADDR));
+ SigSpec sig_rd_data = sigmap(cell->getPort(ID::RD_DATA));
- SigSpec sig_wr_addr = sigmap(cell->getPort("\\WR_ADDR"));
- SigSpec sig_wr_data = sigmap(cell->getPort("\\WR_DATA"));
- SigSpec sig_wr_en = sigmap(cell->getPort("\\WR_EN"));
+ SigSpec sig_wr_addr = sigmap(cell->getPort(ID::WR_ADDR));
+ SigSpec sig_wr_data = sigmap(cell->getPort(ID::WR_DATA));
+ SigSpec sig_wr_en = sigmap(cell->getPort(ID::WR_EN));
int data_sid = get_bv_sid(width);
int bool_sid = get_bv_sid(1);
int sid = get_mem_sid(abits, width);
- Const initdata = cell->getParam("\\INIT");
+ Const initdata = cell->getParam(ID::INIT);
initdata.exts(nwords*width);
int nid_init_val = -1;
@@ -983,15 +1043,18 @@ struct BtorWorker
return nid;
}
- BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad) :
- f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad)
+ BtorWorker(std::ostream &f, RTLIL::Module *module, bool verbose, bool single_bad, bool cover_mode, string info_filename) :
+ f(f), sigmap(module), module(module), verbose(verbose), single_bad(single_bad), cover_mode(cover_mode), info_filename(info_filename)
{
+ if (!info_filename.empty())
+ infof("name %s\n", log_id(module));
+
btorf_push("inputs");
for (auto wire : module->wires())
{
- if (wire->attributes.count("\\init")) {
- Const attrval = wire->attributes.at("\\init");
+ if (wire->attributes.count(ID::init)) {
+ Const attrval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(wire) && i < GetSize(attrval); i++)
if (attrval[i] == State::S0 || attrval[i] == State::S1)
initbits[sigmap(SigBit(wire, i))] = (attrval[i] == State::S1);
@@ -1004,7 +1067,7 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig));
int nid = next_nid++;
- btorf("%d input %d %s\n", nid, sid, log_id(wire));
+ btorf("%d input %d %s\n", nid, sid, getinfo(wire).c_str());
add_nid_sig(nid, sig);
}
@@ -1028,20 +1091,20 @@ struct BtorWorker
btorf_push(stringf("output %s", log_id(wire)));
int nid = get_sig_nid(wire);
- btorf("%d output %d %s\n", next_nid++, nid, log_id(wire));
+ btorf("%d output %d %s\n", next_nid++, nid, getinfo(wire).c_str());
btorf_pop(stringf("output %s", log_id(wire)));
}
for (auto cell : module->cells())
{
- if (cell->type == "$assume")
+ if (cell->type == ID($assume))
{
btorf_push(log_id(cell));
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"));
- int nid_en = get_sig_nid(cell->getPort("\\EN"));
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
+ int nid_en = get_sig_nid(cell->getPort(ID::EN));
int nid_not_en = next_nid++;
int nid_a_or_not_en = next_nid++;
int nid = next_nid++;
@@ -1053,29 +1116,49 @@ struct BtorWorker
btorf_pop(log_id(cell));
}
- if (cell->type == "$assert")
+ if (cell->type == ID($assert))
{
btorf_push(log_id(cell));
int sid = get_bv_sid(1);
- int nid_a = get_sig_nid(cell->getPort("\\A"));
- int nid_en = get_sig_nid(cell->getPort("\\EN"));
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
+ int nid_en = get_sig_nid(cell->getPort(ID::EN));
int nid_not_a = next_nid++;
int nid_en_and_not_a = next_nid++;
btorf("%d not %d %d\n", nid_not_a, sid, nid_a);
btorf("%d and %d %d %d\n", nid_en_and_not_a, sid, nid_en, nid_not_a);
- if (single_bad) {
+ if (single_bad && !cover_mode) {
bad_properties.push_back(nid_en_and_not_a);
} else {
- int nid = next_nid++;
- string infostr = log_id(cell);
- if (infostr[0] == '$' && cell->attributes.count("\\src")) {
- infostr = cell->attributes.at("\\src").decode_string().c_str();
- std::replace(infostr.begin(), infostr.end(), ' ', '_');
+ if (cover_mode) {
+ infof("bad %d %s\n", nid_en_and_not_a, getinfo(cell, true).c_str());
+ } else {
+ int nid = next_nid++;
+ btorf("%d bad %d %s\n", nid, nid_en_and_not_a, getinfo(cell, true).c_str());
}
- btorf("%d bad %d %s\n", nid, nid_en_and_not_a, infostr.c_str());
+ }
+
+ btorf_pop(log_id(cell));
+ }
+
+ if (cell->type == ID($cover) && cover_mode)
+ {
+ btorf_push(log_id(cell));
+
+ int sid = get_bv_sid(1);
+ int nid_a = get_sig_nid(cell->getPort(ID::A));
+ int nid_en = get_sig_nid(cell->getPort(ID::EN));
+ int nid_en_and_a = next_nid++;
+
+ btorf("%d and %d %d %d\n", nid_en_and_a, sid, nid_en, nid_a);
+
+ if (single_bad) {
+ bad_properties.push_back(nid_en_and_a);
+ } else {
+ int nid = next_nid++;
+ btorf("%d bad %d %s\n", nid, nid_en_and_a, getinfo(cell, true).c_str());
}
btorf_pop(log_id(cell));
@@ -1096,7 +1179,7 @@ struct BtorWorker
continue;
int this_nid = next_nid++;
- btorf("%d uext %d %d %d %s\n", this_nid, sid, nid, 0, log_id(wire));
+ btorf("%d uext %d %d %d %s\n", this_nid, sid, nid, 0, getinfo(wire).c_str());
btorf_pop(stringf("wire %s", log_id(wire)));
continue;
@@ -1114,15 +1197,15 @@ struct BtorWorker
btorf_push(stringf("next %s", log_id(cell)));
- if (cell->type == "$mem")
+ if (cell->type == ID($mem))
{
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
- int wrports = cell->getParam("\\WR_PORTS").as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int wrports = cell->getParam(ID::WR_PORTS).as_int();
- SigSpec sig_wr_addr = sigmap(cell->getPort("\\WR_ADDR"));
- SigSpec sig_wr_data = sigmap(cell->getPort("\\WR_DATA"));
- SigSpec sig_wr_en = sigmap(cell->getPort("\\WR_EN"));
+ SigSpec sig_wr_addr = sigmap(cell->getPort(ID::WR_ADDR));
+ SigSpec sig_wr_data = sigmap(cell->getPort(ID::WR_DATA));
+ SigSpec sig_wr_en = sigmap(cell->getPort(ID::WR_EN));
int data_sid = get_bv_sid(width);
int bool_sid = get_bv_sid(1);
@@ -1167,14 +1250,14 @@ struct BtorWorker
}
int nid2 = next_nid++;
- btorf("%d next %d %d %d\n", nid2, sid, nid, nid_head);
+ btorf("%d next %d %d %d %s\n", nid2, sid, nid, nid_head, getinfo(cell).c_str());
}
else
{
- SigSpec sig = sigmap(cell->getPort("\\D"));
+ SigSpec sig = sigmap(cell->getPort(ID::D));
int nid_q = get_sig_nid(sig);
int sid = get_bv_sid(GetSize(sig));
- btorf("%d next %d %d %d\n", next_nid++, sid, nid, nid_q);
+ btorf("%d next %d %d %d %s\n", next_nid++, sid, nid, nid_q, getinfo(cell).c_str());
}
btorf_pop(stringf("next %s", log_id(cell)));
@@ -1210,6 +1293,35 @@ struct BtorWorker
btorf("%d bad %d\n", nid, todo[cursor]);
}
}
+
+ if (!info_filename.empty())
+ {
+ for (auto &it : info_clocks)
+ {
+ switch (it.second)
+ {
+ case 1:
+ infof("posedge %d\n", it.first);
+ break;
+ case 2:
+ infof("negedge %d\n", it.first);
+ break;
+ case 3:
+ infof("event %d\n", it.first);
+ break;
+ default:
+ log_abort();
+ }
+ }
+
+ std::ofstream f;
+ f.open(info_filename.c_str(), std::ofstream::trunc);
+ if (f.fail())
+ log_error("Can't open file `%s' for writing: %s\n", info_filename.c_str(), strerror(errno));
+ for (auto &it : info_lines)
+ f << it;
+ f.close();
+ }
}
};
@@ -1229,10 +1341,17 @@ struct BtorBackend : public Backend {
log(" -s\n");
log(" Output only a single bad property for all asserts\n");
log("\n");
+ log(" -c\n");
+ log(" Output cover properties using 'bad' statements instead of asserts\n");
+ log("\n");
+ log(" -i <filename>\n");
+ log(" Create additional info file with auxiliary information\n");
+ log("\n");
}
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- bool verbose = false, single_bad = false;
+ bool verbose = false, single_bad = false, cover_mode = false;
+ string info_filename;
log_header(design, "Executing BTOR backend.\n");
@@ -1247,6 +1366,14 @@ struct BtorBackend : public Backend {
single_bad = true;
continue;
}
+ if (args[argidx] == "-c") {
+ cover_mode = true;
+ continue;
+ }
+ if (args[argidx] == "-i" && argidx+1 < args.size()) {
+ info_filename = args[++argidx];
+ continue;
+ }
break;
}
extra_args(f, filename, args, argidx);
@@ -1259,7 +1386,7 @@ struct BtorBackend : public Backend {
*f << stringf("; BTOR description generated by %s for module %s.\n",
yosys_version_str, log_id(topmod));
- BtorWorker(*f, topmod, verbose, single_bad);
+ BtorWorker(*f, topmod, verbose, single_bad, cover_mode, info_filename);
*f << stringf("; end of yosys output\n");
}
diff --git a/backends/cxxrtl/Makefile.inc b/backends/cxxrtl/Makefile.inc
new file mode 100644
index 000000000..f93e65f85
--- /dev/null
+++ b/backends/cxxrtl/Makefile.inc
@@ -0,0 +1,2 @@
+
+OBJS += backends/cxxrtl/cxxrtl.o
diff --git a/backends/cxxrtl/cxxrtl.cc b/backends/cxxrtl/cxxrtl.cc
new file mode 100644
index 000000000..d1a855bf0
--- /dev/null
+++ b/backends/cxxrtl/cxxrtl.cc
@@ -0,0 +1,1763 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2019-2020 whitequark <whitequark@whitequark.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/rtlil.h"
+#include "kernel/register.h"
+#include "kernel/sigtools.h"
+#include "kernel/utils.h"
+#include "kernel/celltypes.h"
+#include "kernel/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+// [[CITE]]
+// Peter Eades; Xuemin Lin; W. F. Smyth, "A Fast Effective Heuristic For The Feedback Arc Set Problem"
+// Information Processing Letters, Vol. 47, pp 319-323, 1993
+// https://pdfs.semanticscholar.org/c7ed/d9acce96ca357876540e19664eb9d976637f.pdf
+
+// A topological sort (on a cell/wire graph) is always possible in a fully flattened RTLIL design without
+// processes or logic loops where every wire has a single driver. Logic loops are illegal in RTLIL and wires
+// with multiple drivers can be split by the `splitnets` pass; however, interdependencies between processes
+// or module instances can create strongly connected components without introducing evaluation nondeterminism.
+// We wish to support designs with such benign SCCs (as well as designs with multiple drivers per wire), so
+// we sort the graph in a way that minimizes feedback arcs. If there are no feedback arcs in the sorted graph,
+// then a more efficient evaluation method is possible, since eval() will always immediately converge.
+template<class T>
+struct Scheduler {
+ struct Vertex {
+ T *data;
+ Vertex *prev, *next;
+ pool<Vertex*, hash_ptr_ops> preds, succs;
+
+ Vertex() : data(NULL), prev(this), next(this) {}
+ Vertex(T *data) : data(data), prev(NULL), next(NULL) {}
+
+ bool empty() const
+ {
+ log_assert(data == NULL);
+ if (next == this) {
+ log_assert(prev == next);
+ return true;
+ }
+ return false;
+ }
+
+ void link(Vertex *list)
+ {
+ log_assert(prev == NULL && next == NULL);
+ next = list;
+ prev = list->prev;
+ list->prev->next = this;
+ list->prev = this;
+ }
+
+ void unlink()
+ {
+ log_assert(prev->next == this && next->prev == this);
+ prev->next = next;
+ next->prev = prev;
+ next = prev = NULL;
+ }
+
+ int delta() const
+ {
+ return succs.size() - preds.size();
+ }
+ };
+
+ std::vector<Vertex*> vertices;
+ Vertex *sources = new Vertex;
+ Vertex *sinks = new Vertex;
+ dict<int, Vertex*> bins;
+
+ ~Scheduler()
+ {
+ delete sources;
+ delete sinks;
+ for (auto bin : bins)
+ delete bin.second;
+ for (auto vertex : vertices)
+ delete vertex;
+ }
+
+ Vertex *add(T *data)
+ {
+ Vertex *vertex = new Vertex(data);
+ vertices.push_back(vertex);
+ return vertex;
+ }
+
+ void relink(Vertex *vertex)
+ {
+ if (vertex->succs.empty())
+ vertex->link(sinks);
+ else if (vertex->preds.empty())
+ vertex->link(sources);
+ else {
+ int delta = vertex->delta();
+ if (!bins.count(delta))
+ bins[delta] = new Vertex;
+ vertex->link(bins[delta]);
+ }
+ }
+
+ Vertex *remove(Vertex *vertex)
+ {
+ vertex->unlink();
+ for (auto pred : vertex->preds) {
+ if (pred == vertex)
+ continue;
+ log_assert(pred->succs[vertex]);
+ pred->unlink();
+ pred->succs.erase(vertex);
+ relink(pred);
+ }
+ for (auto succ : vertex->succs) {
+ if (succ == vertex)
+ continue;
+ log_assert(succ->preds[vertex]);
+ succ->unlink();
+ succ->preds.erase(vertex);
+ relink(succ);
+ }
+ vertex->preds.clear();
+ vertex->succs.clear();
+ return vertex;
+ }
+
+ std::vector<Vertex*> schedule()
+ {
+ std::vector<Vertex*> s1, s2r;
+ for (auto vertex : vertices)
+ relink(vertex);
+ bool bins_empty = false;
+ while (!(sinks->empty() && sources->empty() && bins_empty)) {
+ while (!sinks->empty())
+ s2r.push_back(remove(sinks->next));
+ while (!sources->empty())
+ s1.push_back(remove(sources->next));
+ // Choosing u in this implementation isn't O(1), but the paper handwaves which data structure they suggest
+ // using to get O(1) relinking *and* find-max-key ("it is clear"... no it isn't), so this code uses a very
+ // naive implementation of find-max-key.
+ bins_empty = true;
+ bins.template sort<std::greater<int>>();
+ for (auto bin : bins) {
+ if (!bin.second->empty()) {
+ bins_empty = false;
+ s1.push_back(remove(bin.second->next));
+ break;
+ }
+ }
+ }
+ s1.insert(s1.end(), s2r.rbegin(), s2r.rend());
+ return s1;
+ }
+};
+
+static bool is_unary_cell(RTLIL::IdString type)
+{
+ return type.in(
+ ID($not), ID($logic_not), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
+ ID($pos), ID($neg));
+}
+
+static bool is_binary_cell(RTLIL::IdString type)
+{
+ return type.in(
+ ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or),
+ ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx),
+ ID($eq), ID($ne), ID($eqx), ID($nex), ID($gt), ID($ge), ID($lt), ID($le),
+ ID($add), ID($sub), ID($mul), ID($div), ID($mod));
+}
+
+static bool is_elidable_cell(RTLIL::IdString type)
+{
+ return is_unary_cell(type) || is_binary_cell(type) || type.in(
+ ID($mux), ID($concat), ID($slice));
+}
+
+static bool is_sync_ff_cell(RTLIL::IdString type)
+{
+ return type.in(
+ ID($dff), ID($dffe));
+}
+
+static bool is_ff_cell(RTLIL::IdString type)
+{
+ return is_sync_ff_cell(type) || type.in(
+ ID($adff), ID($dffsr), ID($dlatch), ID($dlatchsr), ID($sr));
+}
+
+static bool is_internal_cell(RTLIL::IdString type)
+{
+ return type[0] == '$' && !type.begins_with("$paramod\\");
+}
+
+struct FlowGraph {
+ struct Node {
+ enum class Type {
+ CONNECT,
+ CELL,
+ PROCESS
+ };
+
+ Type type;
+ RTLIL::SigSig connect = {};
+ const RTLIL::Cell *cell = NULL;
+ const RTLIL::Process *process = NULL;
+ };
+
+ std::vector<Node*> nodes;
+ dict<const RTLIL::Wire*, pool<Node*, hash_ptr_ops>> wire_defs, wire_uses;
+ dict<const RTLIL::Wire*, bool> wire_def_elidable, wire_use_elidable;
+
+ ~FlowGraph()
+ {
+ for (auto node : nodes)
+ delete node;
+ }
+
+ void add_defs(Node *node, const RTLIL::SigSpec &sig, bool elidable)
+ {
+ for (auto chunk : sig.chunks())
+ if (chunk.wire)
+ wire_defs[chunk.wire].insert(node);
+ // Only defs of an entire wire in the right order can be elided.
+ if (sig.is_wire())
+ wire_def_elidable[sig.as_wire()] = elidable;
+ }
+
+ void add_uses(Node *node, const RTLIL::SigSpec &sig)
+ {
+ for (auto chunk : sig.chunks())
+ if (chunk.wire) {
+ wire_uses[chunk.wire].insert(node);
+ // Only a single use of an entire wire in the right order can be elided.
+ // (But the use can include other chunks.)
+ if (!wire_use_elidable.count(chunk.wire))
+ wire_use_elidable[chunk.wire] = true;
+ else
+ wire_use_elidable[chunk.wire] = false;
+ }
+ }
+
+ bool is_elidable(const RTLIL::Wire *wire) const
+ {
+ if (wire_def_elidable.count(wire) && wire_use_elidable.count(wire))
+ return wire_def_elidable.at(wire) && wire_use_elidable.at(wire);
+ return false;
+ }
+
+ // Connections
+ void add_connect_defs_uses(Node *node, const RTLIL::SigSig &conn)
+ {
+ add_defs(node, conn.first, /*elidable=*/true);
+ add_uses(node, conn.second);
+ }
+
+ Node *add_node(const RTLIL::SigSig &conn)
+ {
+ Node *node = new Node;
+ node->type = Node::Type::CONNECT;
+ node->connect = conn;
+ nodes.push_back(node);
+ add_connect_defs_uses(node, conn);
+ return node;
+ }
+
+ // Cells
+ void add_cell_defs_uses(Node *node, const RTLIL::Cell *cell)
+ {
+ log_assert(cell->known());
+ for (auto conn : cell->connections()) {
+ if (cell->output(conn.first)) {
+ if (is_sync_ff_cell(cell->type) || (cell->type == ID($memrd) && cell->getParam(ID(CLK_ENABLE)).as_bool()))
+ /* non-combinatorial outputs do not introduce defs */;
+ else if (is_elidable_cell(cell->type))
+ add_defs(node, conn.second, /*elidable=*/true);
+ else if (is_internal_cell(cell->type))
+ add_defs(node, conn.second, /*elidable=*/false);
+ else {
+ // Unlike outputs of internal cells (which generate code that depends on the ability to set the output
+ // wire bits), outputs of user cells are normal wires, and the wires connected to them can be elided.
+ add_defs(node, conn.second, /*elidable=*/true);
+ }
+ }
+ if (cell->input(conn.first))
+ add_uses(node, conn.second);
+ }
+ }
+
+ Node *add_node(const RTLIL::Cell *cell)
+ {
+ Node *node = new Node;
+ node->type = Node::Type::CELL;
+ node->cell = cell;
+ nodes.push_back(node);
+ add_cell_defs_uses(node, cell);
+ return node;
+ }
+
+ // Processes
+ void add_case_defs_uses(Node *node, const RTLIL::CaseRule *case_)
+ {
+ for (auto &action : case_->actions) {
+ add_defs(node, action.first, /*elidable=*/false);
+ add_uses(node, action.second);
+ }
+ for (auto sub_switch : case_->switches) {
+ add_uses(node, sub_switch->signal);
+ for (auto sub_case : sub_switch->cases) {
+ for (auto &compare : sub_case->compare)
+ add_uses(node, compare);
+ add_case_defs_uses(node, sub_case);
+ }
+ }
+ }
+
+ void add_process_defs_uses(Node *node, const RTLIL::Process *process)
+ {
+ add_case_defs_uses(node, &process->root_case);
+ for (auto sync : process->syncs)
+ for (auto action : sync->actions) {
+ if (sync->type == RTLIL::STp || sync->type == RTLIL::STn || sync->type == RTLIL::STe)
+ /* sync actions do not introduce feedback */;
+ else
+ add_defs(node, action.first, /*elidable=*/false);
+ add_uses(node, action.second);
+ }
+ }
+
+ Node *add_node(const RTLIL::Process *process)
+ {
+ Node *node = new Node;
+ node->type = Node::Type::PROCESS;
+ node->process = process;
+ nodes.push_back(node);
+ add_process_defs_uses(node, process);
+ return node;
+ }
+};
+
+struct CxxrtlWorker {
+ bool split_intf = false;
+ std::string intf_filename;
+ std::string design_ns = "cxxrtl_design";
+ std::ostream *impl_f = nullptr;
+ std::ostream *intf_f = nullptr;
+
+ bool elide_internal = false;
+ bool elide_public = false;
+ bool localize_internal = false;
+ bool localize_public = false;
+ bool run_splitnets = false;
+
+ std::ostringstream f;
+ std::string indent;
+ int temporary = 0;
+
+ dict<const RTLIL::Module*, SigMap> sigmaps;
+ pool<const RTLIL::Wire*> sync_wires;
+ dict<RTLIL::SigBit, RTLIL::SyncType> sync_types;
+ pool<const RTLIL::Memory*> writable_memories;
+ dict<const RTLIL::Cell*, pool<const RTLIL::Cell*>> transparent_for;
+ dict<const RTLIL::Cell*, dict<RTLIL::Wire*, RTLIL::IdString>> cell_wire_defs;
+ dict<const RTLIL::Wire*, FlowGraph::Node> elided_wires;
+ dict<const RTLIL::Module*, std::vector<FlowGraph::Node>> schedule;
+ pool<const RTLIL::Wire*> localized_wires;
+
+ void inc_indent() {
+ indent += "\t";
+ }
+ void dec_indent() {
+ indent.resize(indent.size() - 1);
+ }
+
+ // RTLIL allows any characters in names other than whitespace. This presents an issue for generating C++ code
+ // because C++ identifiers may be only alphanumeric, cannot clash with C++ keywords, and cannot clash with cxxrtl
+ // identifiers. This issue can be solved with a name mangling scheme. We choose a name mangling scheme that results
+ // in readable identifiers, does not depend on an up-to-date list of C++ keywords, and is easy to apply. Its rules:
+ // 1. All generated identifiers start with `_`.
+ // 1a. Generated identifiers for public names (beginning with `\`) start with `p_`.
+ // 1b. Generated identifiers for internal names (beginning with `$`) start with `i_`.
+ // 2. An underscore is escaped with another underscore, i.e. `__`.
+ // 3. Any other non-alnum character is escaped with underscores around its lowercase hex code, e.g. `@` as `_40_`.
+ std::string mangle_name(const RTLIL::IdString &name)
+ {
+ std::string mangled;
+ bool first = true;
+ for (char c : name.str()) {
+ if (first) {
+ first = false;
+ if (c == '\\')
+ mangled += "p_";
+ else if (c == '$')
+ mangled += "i_";
+ else
+ log_assert(false);
+ } else {
+ if (isalnum(c)) {
+ mangled += c;
+ } else if (c == '_') {
+ mangled += "__";
+ } else {
+ char l = c & 0xf, h = (c >> 4) & 0xf;
+ mangled += '_';
+ mangled += (h < 10 ? '0' + h : 'a' + h - 10);
+ mangled += (l < 10 ? '0' + l : 'a' + l - 10);
+ mangled += '_';
+ }
+ }
+ }
+ return mangled;
+ }
+
+ std::string mangle_module_name(const RTLIL::IdString &name)
+ {
+ // Class namespace.
+ return mangle_name(name);
+ }
+
+ std::string mangle_memory_name(const RTLIL::IdString &name)
+ {
+ // Class member namespace.
+ return "memory_" + mangle_name(name);
+ }
+
+ std::string mangle_cell_name(const RTLIL::IdString &name)
+ {
+ // Class member namespace.
+ return "cell_" + mangle_name(name);
+ }
+
+ std::string mangle_wire_name(const RTLIL::IdString &name)
+ {
+ // Class member namespace.
+ return mangle_name(name);
+ }
+
+ std::string mangle(const RTLIL::Module *module)
+ {
+ return mangle_module_name(module->name);
+ }
+
+ std::string mangle(const RTLIL::Memory *memory)
+ {
+ return mangle_memory_name(memory->name);
+ }
+
+ std::string mangle(const RTLIL::Cell *cell)
+ {
+ return mangle_cell_name(cell->name);
+ }
+
+ std::string mangle(const RTLIL::Wire *wire)
+ {
+ return mangle_wire_name(wire->name);
+ }
+
+ std::string mangle(RTLIL::SigBit sigbit)
+ {
+ log_assert(sigbit.wire != NULL);
+ if (sigbit.wire->width == 1)
+ return mangle(sigbit.wire);
+ return mangle(sigbit.wire) + "_" + std::to_string(sigbit.offset);
+ }
+
+ std::string fresh_temporary()
+ {
+ return stringf("tmp_%d", temporary++);
+ }
+
+ void dump_attrs(const RTLIL::AttrObject *object)
+ {
+ for (auto attr : object->attributes) {
+ f << indent << "// " << attr.first.str() << ": ";
+ if (attr.second.flags & RTLIL::CONST_FLAG_STRING) {
+ f << attr.second.decode_string();
+ } else {
+ f << attr.second.as_int(/*is_signed=*/attr.second.flags & RTLIL::CONST_FLAG_SIGNED);
+ }
+ f << "\n";
+ }
+ }
+
+ void dump_const_init(const RTLIL::Const &data, int width, int offset = 0, bool fixed_width = false)
+ {
+ f << "{";
+ while (width > 0) {
+ const int CHUNK_SIZE = 32;
+ uint32_t chunk = data.extract(offset, width > CHUNK_SIZE ? CHUNK_SIZE : width).as_int();
+ if (fixed_width)
+ f << stringf("0x%08xu", chunk);
+ else
+ f << stringf("%#xu", chunk);
+ if (width > CHUNK_SIZE)
+ f << ',';
+ offset += CHUNK_SIZE;
+ width -= CHUNK_SIZE;
+ }
+ f << "}";
+ }
+
+ void dump_const_init(const RTLIL::Const &data)
+ {
+ dump_const_init(data, data.size());
+ }
+
+ void dump_const(const RTLIL::Const &data, int width, int offset = 0, bool fixed_width = false)
+ {
+ f << "value<" << width << ">";
+ dump_const_init(data, width, offset, fixed_width);
+ }
+
+ void dump_const(const RTLIL::Const &data)
+ {
+ dump_const(data, data.size());
+ }
+
+ bool dump_sigchunk(const RTLIL::SigChunk &chunk, bool is_lhs)
+ {
+ if (chunk.wire == NULL) {
+ dump_const(chunk.data, chunk.width, chunk.offset);
+ return false;
+ } else {
+ if (!is_lhs && elided_wires.count(chunk.wire)) {
+ const FlowGraph::Node &node = elided_wires[chunk.wire];
+ switch (node.type) {
+ case FlowGraph::Node::Type::CONNECT:
+ dump_connect_elided(node.connect);
+ break;
+ case FlowGraph::Node::Type::CELL:
+ if (is_elidable_cell(node.cell->type)) {
+ dump_cell_elided(node.cell);
+ } else {
+ f << mangle(node.cell) << "." << mangle_wire_name(cell_wire_defs[node.cell][chunk.wire]) << ".curr";
+ }
+ break;
+ default:
+ log_assert(false);
+ }
+ } else if (localized_wires[chunk.wire]) {
+ f << mangle(chunk.wire);
+ } else {
+ f << mangle(chunk.wire) << (is_lhs ? ".next" : ".curr");
+ }
+ if (chunk.width == chunk.wire->width && chunk.offset == 0)
+ return false;
+ else if (chunk.width == 1)
+ f << ".slice<" << chunk.offset << ">()";
+ else
+ f << ".slice<" << chunk.offset+chunk.width-1 << "," << chunk.offset << ">()";
+ return true;
+ }
+ }
+
+ bool dump_sigspec(const RTLIL::SigSpec &sig, bool is_lhs)
+ {
+ if (sig.empty()) {
+ f << "value<0>()";
+ return false;
+ } else if (sig.is_chunk()) {
+ return dump_sigchunk(sig.as_chunk(), is_lhs);
+ } else {
+ dump_sigchunk(*sig.chunks().rbegin(), is_lhs);
+ for (auto it = sig.chunks().rbegin() + 1; it != sig.chunks().rend(); ++it) {
+ f << ".concat(";
+ dump_sigchunk(*it, is_lhs);
+ f << ")";
+ }
+ return true;
+ }
+ }
+
+ void dump_sigspec_lhs(const RTLIL::SigSpec &sig)
+ {
+ dump_sigspec(sig, /*is_lhs=*/true);
+ }
+
+ void dump_sigspec_rhs(const RTLIL::SigSpec &sig)
+ {
+ // In the contexts where we want template argument deduction to occur for `template<size_t Bits> ... value<Bits>`,
+ // it is necessary to have the argument to already be a `value<N>`, since template argument deduction and implicit
+ // type conversion are mutually exclusive. In these contexts, we use dump_sigspec_rhs() to emit an explicit
+ // type conversion, but only if the expression needs it.
+ bool is_complex = dump_sigspec(sig, /*is_lhs=*/false);
+ if (is_complex)
+ f << ".val()";
+ }
+
+ void collect_sigspec_rhs(const RTLIL::SigSpec &sig, std::vector<RTLIL::IdString> &cells)
+ {
+ for (auto chunk : sig.chunks()) {
+ if (!chunk.wire || !elided_wires.count(chunk.wire))
+ continue;
+
+ const FlowGraph::Node &node = elided_wires[chunk.wire];
+ switch (node.type) {
+ case FlowGraph::Node::Type::CONNECT:
+ collect_connect(node.connect, cells);
+ break;
+ case FlowGraph::Node::Type::CELL:
+ collect_cell(node.cell, cells);
+ break;
+ default:
+ log_assert(false);
+ }
+ }
+ }
+
+ void dump_connect_elided(const RTLIL::SigSig &conn)
+ {
+ dump_sigspec_rhs(conn.second);
+ }
+
+ bool is_connect_elided(const RTLIL::SigSig &conn)
+ {
+ return conn.first.is_wire() && elided_wires.count(conn.first.as_wire());
+ }
+
+ void collect_connect(const RTLIL::SigSig &conn, std::vector<RTLIL::IdString> &cells)
+ {
+ if (!is_connect_elided(conn))
+ return;
+
+ collect_sigspec_rhs(conn.second, cells);
+ }
+
+ void dump_connect(const RTLIL::SigSig &conn)
+ {
+ if (is_connect_elided(conn))
+ return;
+
+ f << indent << "// connection\n";
+ f << indent;
+ dump_sigspec_lhs(conn.first);
+ f << " = ";
+ dump_connect_elided(conn);
+ f << ";\n";
+ }
+
+ void dump_cell_elided(const RTLIL::Cell *cell)
+ {
+ // Unary cells
+ if (is_unary_cell(cell->type)) {
+ f << cell->type.substr(1) << '_' <<
+ (cell->getParam(ID(A_SIGNED)).as_bool() ? 's' : 'u') <<
+ "<" << cell->getParam(ID(Y_WIDTH)).as_int() << ">(";
+ dump_sigspec_rhs(cell->getPort(ID(A)));
+ f << ")";
+ // Binary cells
+ } else if (is_binary_cell(cell->type)) {
+ f << cell->type.substr(1) << '_' <<
+ (cell->getParam(ID(A_SIGNED)).as_bool() ? 's' : 'u') <<
+ (cell->getParam(ID(B_SIGNED)).as_bool() ? 's' : 'u') <<
+ "<" << cell->getParam(ID(Y_WIDTH)).as_int() << ">(";
+ dump_sigspec_rhs(cell->getPort(ID(A)));
+ f << ", ";
+ dump_sigspec_rhs(cell->getPort(ID(B)));
+ f << ")";
+ // Muxes
+ } else if (cell->type == ID($mux)) {
+ f << "(";
+ dump_sigspec_rhs(cell->getPort(ID(S)));
+ f << " ? ";
+ dump_sigspec_rhs(cell->getPort(ID(B)));
+ f << " : ";
+ dump_sigspec_rhs(cell->getPort(ID(A)));
+ f << ")";
+ // Concats
+ } else if (cell->type == ID($concat)) {
+ dump_sigspec_rhs(cell->getPort(ID(B)));
+ f << ".concat(";
+ dump_sigspec_rhs(cell->getPort(ID(A)));
+ f << ").val()";
+ // Slices
+ } else if (cell->type == ID($slice)) {
+ dump_sigspec_rhs(cell->getPort(ID(A)));
+ f << ".slice<";
+ f << cell->getParam(ID(OFFSET)).as_int() + cell->getParam(ID(Y_WIDTH)).as_int() - 1;
+ f << ",";
+ f << cell->getParam(ID(OFFSET)).as_int();
+ f << ">().val()";
+ } else {
+ log_assert(false);
+ }
+ }
+
+ bool is_cell_elided(const RTLIL::Cell *cell)
+ {
+ return is_elidable_cell(cell->type) && cell->hasPort(ID(Y)) && cell->getPort(ID(Y)).is_wire() &&
+ elided_wires.count(cell->getPort(ID(Y)).as_wire());
+ }
+
+ void collect_cell(const RTLIL::Cell *cell, std::vector<RTLIL::IdString> &cells)
+ {
+ if (!is_cell_elided(cell))
+ return;
+
+ cells.push_back(cell->name);
+ for (auto port : cell->connections())
+ if (port.first != ID(Y))
+ collect_sigspec_rhs(port.second, cells);
+ }
+
+ void dump_cell(const RTLIL::Cell *cell)
+ {
+ if (is_cell_elided(cell))
+ return;
+ if (cell->type == ID($meminit))
+ return; // Handled elsewhere.
+
+ std::vector<RTLIL::IdString> elided_cells;
+ if (is_elidable_cell(cell->type)) {
+ for (auto port : cell->connections())
+ if (port.first != ID(Y))
+ collect_sigspec_rhs(port.second, elided_cells);
+ }
+ if (elided_cells.empty()) {
+ dump_attrs(cell);
+ f << indent << "// cell " << cell->name.str() << "\n";
+ } else {
+ f << indent << "// cells";
+ for (auto elided_cell : elided_cells)
+ f << " " << elided_cell.str();
+ f << "\n";
+ }
+
+ // Elidable cells
+ if (is_elidable_cell(cell->type)) {
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Y)));
+ f << " = ";
+ dump_cell_elided(cell);
+ f << ";\n";
+ // Parallel (one-hot) muxes
+ } else if (cell->type == ID($pmux)) {
+ int width = cell->getParam(ID(WIDTH)).as_int();
+ int s_width = cell->getParam(ID(S_WIDTH)).as_int();
+ bool first = true;
+ for (int part = 0; part < s_width; part++) {
+ f << (first ? indent : " else ");
+ first = false;
+ f << "if (";
+ dump_sigspec_rhs(cell->getPort(ID(S)).extract(part));
+ f << ") {\n";
+ inc_indent();
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Y)));
+ f << " = ";
+ dump_sigspec_rhs(cell->getPort(ID(B)).extract(part * width, width));
+ f << ";\n";
+ dec_indent();
+ f << indent << "}";
+ }
+ f << " else {\n";
+ inc_indent();
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Y)));
+ f << " = ";
+ dump_sigspec_rhs(cell->getPort(ID(A)));
+ f << ";\n";
+ dec_indent();
+ f << indent << "}\n";
+ // Flip-flops
+ } else if (is_ff_cell(cell->type)) {
+ if (cell->hasPort(ID(CLK)) && cell->getPort(ID(CLK)).is_wire()) {
+ // Edge-sensitive logic
+ RTLIL::SigBit clk_bit = cell->getPort(ID(CLK))[0];
+ clk_bit = sigmaps[clk_bit.wire->module](clk_bit);
+ f << indent << "if (" << (cell->getParam(ID(CLK_POLARITY)).as_bool() ? "posedge_" : "negedge_")
+ << mangle(clk_bit) << ") {\n";
+ inc_indent();
+ if (cell->type == ID($dffe)) {
+ f << indent << "if (";
+ dump_sigspec_rhs(cell->getPort(ID(EN)));
+ f << " == value<1> {" << cell->getParam(ID(EN_POLARITY)).as_bool() << "u}) {\n";
+ inc_indent();
+ }
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Q)));
+ f << " = ";
+ dump_sigspec_rhs(cell->getPort(ID(D)));
+ f << ";\n";
+ if (cell->type == ID($dffe)) {
+ dec_indent();
+ f << indent << "}\n";
+ }
+ dec_indent();
+ f << indent << "}\n";
+ } else if (cell->hasPort(ID(EN))) {
+ // Level-sensitive logic
+ f << indent << "if (";
+ dump_sigspec_rhs(cell->getPort(ID(EN)));
+ f << " == value<1> {" << cell->getParam(ID(EN_POLARITY)).as_bool() << "u}) {\n";
+ inc_indent();
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Q)));
+ f << " = ";
+ dump_sigspec_rhs(cell->getPort(ID(D)));
+ f << ";\n";
+ dec_indent();
+ f << indent << "}\n";
+ }
+ if (cell->hasPort(ID(ARST))) {
+ // Asynchronous reset (entire coarse cell at once)
+ f << indent << "if (";
+ dump_sigspec_rhs(cell->getPort(ID(ARST)));
+ f << " == value<1> {" << cell->getParam(ID(ARST_POLARITY)).as_bool() << "u}) {\n";
+ inc_indent();
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Q)));
+ f << " = ";
+ dump_const(cell->getParam(ID(ARST_VALUE)));
+ f << ";\n";
+ dec_indent();
+ f << indent << "}\n";
+ }
+ if (cell->hasPort(ID(SET))) {
+ // Asynchronous set (for individual bits)
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Q)));
+ f << " = ";
+ dump_sigspec_lhs(cell->getPort(ID(Q)));
+ f << ".update(";
+ dump_const(RTLIL::Const(RTLIL::S1, cell->getParam(ID(WIDTH)).as_int()));
+ f << ", ";
+ dump_sigspec_rhs(cell->getPort(ID(SET)));
+ f << (cell->getParam(ID(SET_POLARITY)).as_bool() ? "" : ".bit_not()") << ");\n";
+ }
+ if (cell->hasPort(ID(CLR))) {
+ // Asynchronous clear (for individual bits; priority over set)
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(Q)));
+ f << " = ";
+ dump_sigspec_lhs(cell->getPort(ID(Q)));
+ f << ".update(";
+ dump_const(RTLIL::Const(RTLIL::S0, cell->getParam(ID(WIDTH)).as_int()));
+ f << ", ";
+ dump_sigspec_rhs(cell->getPort(ID(CLR)));
+ f << (cell->getParam(ID(CLR_POLARITY)).as_bool() ? "" : ".bit_not()") << ");\n";
+ }
+ // Memory ports
+ } else if (cell->type.in(ID($memrd), ID($memwr))) {
+ if (cell->getParam(ID(CLK_ENABLE)).as_bool()) {
+ RTLIL::SigBit clk_bit = cell->getPort(ID(CLK))[0];
+ clk_bit = sigmaps[clk_bit.wire->module](clk_bit);
+ f << indent << "if (" << (cell->getParam(ID(CLK_POLARITY)).as_bool() ? "posedge_" : "negedge_")
+ << mangle(clk_bit) << ") {\n";
+ inc_indent();
+ }
+ RTLIL::Memory *memory = cell->module->memories[cell->getParam(ID(MEMID)).decode_string()];
+ std::string valid_index_temp = fresh_temporary();
+ f << indent << "auto " << valid_index_temp << " = memory_index(";
+ dump_sigspec_rhs(cell->getPort(ID(ADDR)));
+ f << ", " << memory->start_offset << ", " << memory->size << ");\n";
+ if (cell->type == ID($memrd)) {
+ bool has_enable = cell->getParam(ID(CLK_ENABLE)).as_bool() && !cell->getPort(ID(EN)).is_fully_ones();
+ if (has_enable) {
+ f << indent << "if (";
+ dump_sigspec_rhs(cell->getPort(ID(EN)));
+ f << ") {\n";
+ inc_indent();
+ }
+ // The generated code has two bounds checks; one in an assertion, and another that guards the read.
+ // This is done so that the code does not invoke undefined behavior under any conditions, but nevertheless
+ // loudly crashes if an illegal condition is encountered. The assert may be turned off with -NDEBUG not
+ // just for release builds, but also to make sure the simulator (which is presumably embedded in some
+ // larger program) will never crash the code that calls into it.
+ //
+ // If assertions are disabled, out of bounds reads are defined to return zero.
+ f << indent << "assert(" << valid_index_temp << ".valid && \"out of bounds read\");\n";
+ f << indent << "if(" << valid_index_temp << ".valid) {\n";
+ inc_indent();
+ if (writable_memories[memory]) {
+ std::string addr_temp = fresh_temporary();
+ f << indent << "const value<" << cell->getPort(ID(ADDR)).size() << "> &" << addr_temp << " = ";
+ dump_sigspec_rhs(cell->getPort(ID(ADDR)));
+ f << ";\n";
+ std::string lhs_temp = fresh_temporary();
+ f << indent << "value<" << memory->width << "> " << lhs_temp << " = "
+ << mangle(memory) << "[" << valid_index_temp << ".index];\n";
+ std::vector<const RTLIL::Cell*> memwr_cells(transparent_for[cell].begin(), transparent_for[cell].end());
+ std::sort(memwr_cells.begin(), memwr_cells.end(),
+ [](const RTLIL::Cell *a, const RTLIL::Cell *b) {
+ return a->getParam(ID(PRIORITY)).as_int() < b->getParam(ID(PRIORITY)).as_int();
+ });
+ for (auto memwr_cell : memwr_cells) {
+ f << indent << "if (" << addr_temp << " == ";
+ dump_sigspec_rhs(memwr_cell->getPort(ID(ADDR)));
+ f << ") {\n";
+ inc_indent();
+ f << indent << lhs_temp << " = " << lhs_temp;
+ f << ".update(";
+ dump_sigspec_rhs(memwr_cell->getPort(ID(DATA)));
+ f << ", ";
+ dump_sigspec_rhs(memwr_cell->getPort(ID(EN)));
+ f << ");\n";
+ dec_indent();
+ f << indent << "}\n";
+ }
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(DATA)));
+ f << " = " << lhs_temp << ";\n";
+ } else {
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(DATA)));
+ f << " = " << mangle(memory) << "[" << valid_index_temp << ".index];\n";
+ }
+ dec_indent();
+ f << indent << "} else {\n";
+ inc_indent();
+ f << indent;
+ dump_sigspec_lhs(cell->getPort(ID(DATA)));
+ f << " = value<" << memory->width << "> {};\n";
+ dec_indent();
+ f << indent << "}\n";
+ if (has_enable) {
+ dec_indent();
+ f << indent << "}\n";
+ }
+ } else /*if (cell->type == ID($memwr))*/ {
+ log_assert(writable_memories[memory]);
+ // See above for rationale of having both the assert and the condition.
+ //
+ // If assertions are disabled, out of bounds writes are defined to do nothing.
+ f << indent << "assert(" << valid_index_temp << ".valid && \"out of bounds write\");\n";
+ f << indent << "if (" << valid_index_temp << ".valid) {\n";
+ inc_indent();
+ f << indent << mangle(memory) << ".update(" << valid_index_temp << ".index, ";
+ dump_sigspec_rhs(cell->getPort(ID(DATA)));
+ f << ", ";
+ dump_sigspec_rhs(cell->getPort(ID(EN)));
+ f << ", " << cell->getParam(ID(PRIORITY)).as_int() << ");\n";
+ dec_indent();
+ f << indent << "}\n";
+ }
+ if (cell->getParam(ID(CLK_ENABLE)).as_bool()) {
+ dec_indent();
+ f << indent << "}\n";
+ }
+ // Internal cells
+ } else if (is_internal_cell(cell->type)) {
+ log_cmd_error("Unsupported internal cell `%s'.\n", cell->type.c_str());
+ // User cells
+ } else {
+ log_assert(cell->known());
+ for (auto conn : cell->connections())
+ if (cell->input(conn.first)) {
+ f << indent << mangle(cell) << "." << mangle_wire_name(conn.first) << ".next = ";
+ dump_sigspec_rhs(conn.second);
+ f << ";\n";
+ }
+ f << indent << mangle(cell) << ".eval();\n";
+ for (auto conn : cell->connections()) {
+ if (conn.second.is_wire()) {
+ RTLIL::Wire *wire = conn.second.as_wire();
+ if (elided_wires.count(wire) && cell_wire_defs[cell].count(wire))
+ continue;
+ }
+ if (cell->output(conn.first)) {
+ if (conn.second.empty())
+ continue; // ignore disconnected ports
+ f << indent;
+ dump_sigspec_lhs(conn.second);
+ f << " = " << mangle(cell) << "." << mangle_wire_name(conn.first) << ".curr;\n";
+ }
+ }
+ }
+ }
+
+ void dump_assign(const RTLIL::SigSig &sigsig)
+ {
+ f << indent;
+ dump_sigspec_lhs(sigsig.first);
+ f << " = ";
+ dump_sigspec_rhs(sigsig.second);
+ f << ";\n";
+ }
+
+ void dump_case_rule(const RTLIL::CaseRule *rule)
+ {
+ for (auto action : rule->actions)
+ dump_assign(action);
+ for (auto switch_ : rule->switches)
+ dump_switch_rule(switch_);
+ }
+
+ void dump_switch_rule(const RTLIL::SwitchRule *rule)
+ {
+ // The switch attributes are printed before the switch condition is captured.
+ dump_attrs(rule);
+ std::string signal_temp = fresh_temporary();
+ f << indent << "const value<" << rule->signal.size() << "> &" << signal_temp << " = ";
+ dump_sigspec(rule->signal, /*is_lhs=*/false);
+ f << ";\n";
+
+ bool first = true;
+ for (auto case_ : rule->cases) {
+ // The case attributes (for nested cases) are printed before the if/else if/else statement.
+ dump_attrs(rule);
+ f << indent;
+ if (!first)
+ f << "} else ";
+ first = false;
+ if (!case_->compare.empty()) {
+ f << "if (";
+ bool first = true;
+ for (auto &compare : case_->compare) {
+ if (!first)
+ f << " || ";
+ first = false;
+ if (compare.is_fully_def()) {
+ f << signal_temp << " == ";
+ dump_sigspec(compare, /*is_lhs=*/false);
+ } else if (compare.is_fully_const()) {
+ RTLIL::Const compare_mask, compare_value;
+ for (auto bit : compare.as_const()) {
+ switch (bit) {
+ case RTLIL::S0:
+ case RTLIL::S1:
+ compare_mask.bits.push_back(RTLIL::S1);
+ compare_value.bits.push_back(bit);
+ break;
+
+ case RTLIL::Sx:
+ case RTLIL::Sz:
+ case RTLIL::Sa:
+ compare_mask.bits.push_back(RTLIL::S0);
+ compare_value.bits.push_back(RTLIL::S0);
+ break;
+
+ default:
+ log_assert(false);
+ }
+ }
+ f << "and_uu<" << compare.size() << ">(" << signal_temp << ", ";
+ dump_const(compare_mask);
+ f << ") == ";
+ dump_const(compare_value);
+ } else {
+ log_assert(false);
+ }
+ }
+ f << ") ";
+ }
+ f << "{\n";
+ inc_indent();
+ dump_case_rule(case_);
+ dec_indent();
+ }
+ f << indent << "}\n";
+ }
+
+ void dump_process(const RTLIL::Process *proc)
+ {
+ dump_attrs(proc);
+ f << indent << "// process " << proc->name.str() << "\n";
+ // The case attributes (for root case) are always empty.
+ log_assert(proc->root_case.attributes.empty());
+ dump_case_rule(&proc->root_case);
+ for (auto sync : proc->syncs) {
+ RTLIL::SigBit sync_bit = sync->signal[0];
+ sync_bit = sigmaps[sync_bit.wire->module](sync_bit);
+
+ pool<std::string> events;
+ switch (sync->type) {
+ case RTLIL::STp:
+ events.insert("posedge_" + mangle(sync_bit));
+ break;
+ case RTLIL::STn:
+ events.insert("negedge_" + mangle(sync_bit));
+ case RTLIL::STe:
+ events.insert("posedge_" + mangle(sync_bit));
+ events.insert("negedge_" + mangle(sync_bit));
+ break;
+
+ case RTLIL::ST0:
+ case RTLIL::ST1:
+ case RTLIL::STa:
+ case RTLIL::STg:
+ case RTLIL::STi:
+ log_assert(false);
+ }
+ if (!events.empty()) {
+ f << indent << "if (";
+ bool first = true;
+ for (auto &event : events) {
+ if (!first)
+ f << " || ";
+ first = false;
+ f << event;
+ }
+ f << ") {\n";
+ inc_indent();
+ for (auto action : sync->actions)
+ dump_assign(action);
+ dec_indent();
+ f << indent << "}\n";
+ }
+ }
+ }
+
+ void dump_wire(const RTLIL::Wire *wire, bool is_local)
+ {
+ if (elided_wires.count(wire))
+ return;
+
+ if (is_local) {
+ if (!localized_wires.count(wire))
+ return;
+
+ dump_attrs(wire);
+ f << indent << "value<" << wire->width << "> " << mangle(wire) << ";\n";
+ } else {
+ if (localized_wires.count(wire))
+ return;
+
+ dump_attrs(wire);
+ f << indent << "wire<" << wire->width << "> " << mangle(wire);
+ if (wire->attributes.count(ID(init))) {
+ f << " ";
+ dump_const_init(wire->attributes.at(ID(init)));
+ }
+ f << ";\n";
+ if (sync_wires[wire]) {
+ for (auto sync_type : sync_types) {
+ if (sync_type.first.wire == wire) {
+ if (sync_type.second != RTLIL::STn)
+ f << indent << "bool posedge_" << mangle(sync_type.first) << " = false;\n";
+ if (sync_type.second != RTLIL::STp)
+ f << indent << "bool negedge_" << mangle(sync_type.first) << " = false;\n";
+ }
+ }
+ }
+ }
+ }
+
+ void dump_memory(RTLIL::Module *module, const RTLIL::Memory *memory)
+ {
+ vector<const RTLIL::Cell*> init_cells;
+ for (auto cell : module->cells())
+ if (cell->type == ID($meminit) && cell->getParam(ID(MEMID)).decode_string() == memory->name.str())
+ init_cells.push_back(cell);
+
+ std::sort(init_cells.begin(), init_cells.end(), [](const RTLIL::Cell *a, const RTLIL::Cell *b) {
+ int a_addr = a->getPort(ID(ADDR)).as_int(), b_addr = b->getPort(ID(ADDR)).as_int();
+ int a_prio = a->getParam(ID(PRIORITY)).as_int(), b_prio = b->getParam(ID(PRIORITY)).as_int();
+ return a_prio > b_prio || (a_prio == b_prio && a_addr < b_addr);
+ });
+
+ dump_attrs(memory);
+ f << indent << (writable_memories[memory] ? "" : "const ")
+ << "memory<" << memory->width << "> " << mangle(memory)
+ << " { " << memory->size << "u";
+ if (init_cells.empty()) {
+ f << " };\n";
+ } else {
+ f << ",\n";
+ inc_indent();
+ for (auto cell : init_cells) {
+ dump_attrs(cell);
+ RTLIL::Const data = cell->getPort(ID(DATA)).as_const();
+ size_t width = cell->getParam(ID(WIDTH)).as_int();
+ size_t words = cell->getParam(ID(WORDS)).as_int();
+ f << indent << "memory<" << memory->width << ">::init<" << words << "> { "
+ << stringf("%#x", cell->getPort(ID(ADDR)).as_int()) << ", {";
+ inc_indent();
+ for (size_t n = 0; n < words; n++) {
+ if (n % 4 == 0)
+ f << "\n" << indent;
+ else
+ f << " ";
+ dump_const(data, width, n * width, /*fixed_width=*/true);
+ f << ",";
+ }
+ dec_indent();
+ f << "\n" << indent << "}},\n";
+ }
+ dec_indent();
+ f << indent << "};\n";
+ }
+ }
+
+ void dump_module_intf(RTLIL::Module *module)
+ {
+ dump_attrs(module);
+ f << "struct " << mangle(module) << " : public module {\n";
+ inc_indent();
+ for (auto wire : module->wires())
+ dump_wire(wire, /*is_local=*/false);
+ f << "\n";
+ bool has_memories = false;
+ for (auto memory : module->memories) {
+ dump_memory(module, memory.second);
+ has_memories = true;
+ }
+ if (has_memories)
+ f << "\n";
+ bool has_cells = false;
+ for (auto cell : module->cells()) {
+ if (is_internal_cell(cell->type))
+ continue;
+ f << indent << mangle_module_name(cell->type) << " " << mangle(cell) << ";\n";
+ has_cells = true;
+ }
+ if (has_cells)
+ f << "\n";
+ f << indent << "void eval() override;\n";
+ f << indent << "bool commit() override;\n";
+ dec_indent();
+ f << "}; // struct " << mangle(module) << "\n";
+ f << "\n";
+ }
+
+ void dump_module_impl(RTLIL::Module *module)
+ {
+ f << "void " << mangle(module) << "::eval() {\n";
+ inc_indent();
+ for (auto wire : module->wires())
+ dump_wire(wire, /*is_local=*/true);
+ for (auto node : schedule[module]) {
+ switch (node.type) {
+ case FlowGraph::Node::Type::CONNECT:
+ dump_connect(node.connect);
+ break;
+ case FlowGraph::Node::Type::CELL:
+ dump_cell(node.cell);
+ break;
+ case FlowGraph::Node::Type::PROCESS:
+ dump_process(node.process);
+ break;
+ }
+ }
+ for (auto sync_type : sync_types) {
+ if (sync_type.first.wire->module == module) {
+ if (sync_type.second != RTLIL::STn)
+ f << indent << "posedge_" << mangle(sync_type.first) << " = false;\n";
+ if (sync_type.second != RTLIL::STp)
+ f << indent << "negedge_" << mangle(sync_type.first) << " = false;\n";
+ }
+ }
+ dec_indent();
+ f << "}\n";
+ f << "\n";
+
+ f << "bool " << mangle(module) << "::commit() {\n";
+ inc_indent();
+ f << indent << "bool changed = false;\n";
+ for (auto wire : module->wires()) {
+ if (elided_wires.count(wire) || localized_wires.count(wire))
+ continue;
+ if (sync_wires[wire]) {
+ std::string wire_prev = mangle(wire) + "_prev";
+ std::string wire_curr = mangle(wire) + ".curr";
+ std::string wire_edge = mangle(wire) + "_edge";
+ f << indent << "value<" << wire->width << "> " << wire_prev << " = " << wire_curr << ";\n";
+ f << indent << "if (" << mangle(wire) << ".commit()) {\n";
+ inc_indent();
+ f << indent << "value<" << wire->width << "> " << wire_edge << " = "
+ << wire_prev << ".bit_xor(" << wire_curr << ");\n";
+ for (auto sync_type : sync_types) {
+ if (sync_type.first.wire != wire)
+ continue;
+ if (sync_type.second != RTLIL::STn) {
+ f << indent << "if (" << wire_edge << ".slice<" << sync_type.first.offset << ">().val() && "
+ << wire_curr << ".slice<" << sync_type.first.offset << ">().val())\n";
+ inc_indent();
+ f << indent << "posedge_" << mangle(sync_type.first) << " = true;\n";
+ dec_indent();
+ }
+ if (sync_type.second != RTLIL::STp) {
+ f << indent << "if (" << wire_edge << ".slice<" << sync_type.first.offset << ">().val() && "
+ << "!" << wire_curr << ".slice<" << sync_type.first.offset << ">().val())\n";
+ inc_indent();
+ f << indent << "negedge_" << mangle(sync_type.first) << " = true;\n";
+ dec_indent();
+ }
+ f << indent << "changed = true;\n";
+ }
+ dec_indent();
+ f << indent << "}\n";
+ } else {
+ f << indent << "changed |= " << mangle(wire) << ".commit();\n";
+ }
+ }
+ for (auto memory : module->memories) {
+ if (!writable_memories[memory.second])
+ continue;
+ f << indent << "changed |= " << mangle(memory.second) << ".commit();\n";
+ }
+ for (auto cell : module->cells()) {
+ if (is_internal_cell(cell->type))
+ continue;
+ f << indent << "changed |= " << mangle(cell) << ".commit();\n";
+ }
+ f << indent << "return changed;\n";
+ dec_indent();
+ f << "}\n";
+ f << "\n";
+ }
+
+ void dump_design(RTLIL::Design *design)
+ {
+ TopoSort<RTLIL::Module*> topo_design;
+ for (auto module : design->modules()) {
+ if (module->get_blackbox_attribute() || !design->selected_module(module))
+ continue;
+ topo_design.node(module);
+
+ for (auto cell : module->cells()) {
+ if (is_internal_cell(cell->type))
+ continue;
+ log_assert(design->has(cell->type));
+ topo_design.edge(design->module(cell->type), module);
+ }
+ }
+ log_assert(topo_design.sort());
+
+ if (split_intf) {
+ // The only thing more depraved than include guards, is mangling filenames to turn them into include guards.
+ std::string include_guard = design_ns + "_header";
+ std::transform(include_guard.begin(), include_guard.end(), include_guard.begin(), ::toupper);
+
+ f << "#ifndef " << include_guard << "\n";
+ f << "#define " << include_guard << "\n";
+ f << "\n";
+ f << "#include <backends/cxxrtl/cxxrtl.h>\n";
+ f << "\n";
+ f << "using namespace cxxrtl;\n";
+ f << "\n";
+ f << "namespace " << design_ns << " {\n";
+ f << "\n";
+ for (auto module : topo_design.sorted) {
+ if (!design->selected_module(module))
+ continue;
+ dump_module_intf(module);
+ }
+ f << "} // namespace " << design_ns << "\n";
+ f << "\n";
+ f << "#endif\n";
+ *intf_f << f.str(); f.str("");
+ }
+
+ if (split_intf)
+ f << "#include \"" << intf_filename << "\"\n";
+ else
+ f << "#include <backends/cxxrtl/cxxrtl.h>\n";
+ f << "\n";
+ f << "using namespace cxxrtl_yosys;\n";
+ f << "\n";
+ f << "namespace " << design_ns << " {\n";
+ f << "\n";
+ for (auto module : topo_design.sorted) {
+ if (!design->selected_module(module))
+ continue;
+ if (!split_intf)
+ dump_module_intf(module);
+ dump_module_impl(module);
+ }
+ f << "} // namespace " << design_ns << "\n";
+ *impl_f << f.str(); f.str("");
+ }
+
+ // Edge-type sync rules require us to emit edge detectors, which require coordination between
+ // eval and commit phases. To do this we need to collect them upfront.
+ //
+ // Note that the simulator commit phase operates at wire granularity but edge-type sync rules
+ // operate at wire bit granularity; it is possible to have code similar to:
+ // wire [3:0] clocks;
+ // always @(posedge clocks[0]) ...
+ // To handle this we track edge sensitivity both for wires and wire bits.
+ void register_edge_signal(SigMap &sigmap, RTLIL::SigSpec signal, RTLIL::SyncType type)
+ {
+ signal = sigmap(signal);
+ log_assert(signal.is_wire() && signal.is_bit());
+ log_assert(type == RTLIL::STp || type == RTLIL::STn || type == RTLIL::STe);
+
+ RTLIL::SigBit sigbit = signal[0];
+ if (!sync_types.count(sigbit))
+ sync_types[sigbit] = type;
+ else if (sync_types[sigbit] != type)
+ sync_types[sigbit] = RTLIL::STe;
+ sync_wires.insert(signal.as_wire());
+ }
+
+ void analyze_design(RTLIL::Design *design)
+ {
+ bool has_feedback_arcs = false;
+ for (auto module : design->modules()) {
+ if (!design->selected_module(module))
+ continue;
+
+ FlowGraph flow;
+ SigMap &sigmap = sigmaps[module];
+ sigmap.set(module);
+
+ for (auto conn : module->connections())
+ flow.add_node(conn);
+
+ dict<const RTLIL::Cell*, FlowGraph::Node*> memrw_cell_nodes;
+ dict<std::pair<RTLIL::SigBit, const RTLIL::Memory*>,
+ pool<const RTLIL::Cell*>> memwr_per_domain;
+ for (auto cell : module->cells()) {
+ FlowGraph::Node *node = flow.add_node(cell);
+
+ // Various DFF cells are treated like posedge/negedge processes, see above for details.
+ if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($dffsr))) {
+ if (cell->getPort(ID(CLK)).is_wire())
+ register_edge_signal(sigmap, cell->getPort(ID(CLK)),
+ cell->parameters[ID(CLK_POLARITY)].as_bool() ? RTLIL::STp : RTLIL::STn);
+ // The $adff and $dffsr cells are level-sensitive, not edge-sensitive (in spite of the fact that they
+ // are inferred from an edge-sensitive Verilog process) and do not correspond to an edge-type sync rule.
+ }
+ // Similar for memory port cells.
+ if (cell->type.in(ID($memrd), ID($memwr))) {
+ if (cell->getParam(ID(CLK_ENABLE)).as_bool()) {
+ if (cell->getPort(ID(CLK)).is_wire())
+ register_edge_signal(sigmap, cell->getPort(ID(CLK)),
+ cell->parameters[ID(CLK_POLARITY)].as_bool() ? RTLIL::STp : RTLIL::STn);
+ }
+ memrw_cell_nodes[cell] = node;
+ }
+ // Optimize access to read-only memories.
+ if (cell->type == ID($memwr))
+ writable_memories.insert(module->memories[cell->getParam(ID(MEMID)).decode_string()]);
+ // Collect groups of memory write ports in the same domain.
+ if (cell->type == ID($memwr) && cell->getParam(ID(CLK_ENABLE)).as_bool() && cell->getPort(ID(CLK)).is_wire()) {
+ RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID(CLK)))[0];
+ const RTLIL::Memory *memory = module->memories[cell->getParam(ID(MEMID)).decode_string()];
+ memwr_per_domain[{clk_bit, memory}].insert(cell);
+ }
+ // Handling of packed memories is delegated to the `memory_unpack` pass, so we can rely on the presence
+ // of RTLIL memory objects and $memrd/$memwr/$meminit cells.
+ if (cell->type.in(ID($mem)))
+ log_assert(false);
+ }
+ for (auto cell : module->cells()) {
+ // Collect groups of memory write ports read by every transparent read port.
+ if (cell->type == ID($memrd) && cell->getParam(ID(CLK_ENABLE)).as_bool() && cell->getPort(ID(CLK)).is_wire() &&
+ cell->getParam(ID(TRANSPARENT)).as_bool()) {
+ RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID(CLK)))[0];
+ const RTLIL::Memory *memory = module->memories[cell->getParam(ID(MEMID)).decode_string()];
+ for (auto memwr_cell : memwr_per_domain[{clk_bit, memory}]) {
+ transparent_for[cell].insert(memwr_cell);
+ // Our implementation of transparent $memrd cells reads \EN, \ADDR and \DATA from every $memwr cell
+ // in the same domain, which isn't directly visible in the netlist. Add these uses explicitly.
+ flow.add_uses(memrw_cell_nodes[cell], memwr_cell->getPort(ID(EN)));
+ flow.add_uses(memrw_cell_nodes[cell], memwr_cell->getPort(ID(ADDR)));
+ flow.add_uses(memrw_cell_nodes[cell], memwr_cell->getPort(ID(DATA)));
+ }
+ }
+ }
+
+ for (auto proc : module->processes) {
+ flow.add_node(proc.second);
+
+ for (auto sync : proc.second->syncs)
+ switch (sync->type) {
+ // Edge-type sync rules require pre-registration.
+ case RTLIL::STp:
+ case RTLIL::STn:
+ case RTLIL::STe:
+ register_edge_signal(sigmap, sync->signal, sync->type);
+ break;
+
+ // Level-type sync rules require no special handling.
+ case RTLIL::ST0:
+ case RTLIL::ST1:
+ case RTLIL::STa:
+ break;
+
+ // Handling of init-type sync rules is delegated to the `proc_init` pass, so we can use the wire
+ // attribute regardless of input.
+ case RTLIL::STi:
+ log_assert(false);
+
+ case RTLIL::STg:
+ log_cmd_error("Global clock is not supported.\n");
+ }
+ }
+
+ for (auto wire : module->wires()) {
+ if (!flow.is_elidable(wire)) continue;
+ if (wire->port_id != 0) continue;
+ if (wire->get_bool_attribute(ID(keep))) continue;
+ if (wire->name.begins_with("$") && !elide_internal) continue;
+ if (wire->name.begins_with("\\") && !elide_public) continue;
+ if (sync_wires[wire]) continue;
+ log_assert(flow.wire_defs[wire].size() == 1);
+ elided_wires[wire] = **flow.wire_defs[wire].begin();
+ }
+
+ // Elided wires that are outputs of internal cells are always connected to a well known port (Y).
+ // For user cells, there could be multiple of them, and we need a way to look up the port name
+ // knowing only the wire.
+ for (auto cell : module->cells())
+ for (auto conn : cell->connections())
+ if (conn.second.is_wire() && elided_wires.count(conn.second.as_wire()))
+ cell_wire_defs[cell][conn.second.as_wire()] = conn.first;
+
+ dict<FlowGraph::Node*, pool<const RTLIL::Wire*>, hash_ptr_ops> node_defs;
+ for (auto wire_def : flow.wire_defs)
+ for (auto node : wire_def.second)
+ node_defs[node].insert(wire_def.first);
+
+ Scheduler<FlowGraph::Node> scheduler;
+ dict<FlowGraph::Node*, Scheduler<FlowGraph::Node>::Vertex*, hash_ptr_ops> node_map;
+ for (auto node : flow.nodes)
+ node_map[node] = scheduler.add(node);
+ for (auto node_def : node_defs) {
+ auto vertex = node_map[node_def.first];
+ for (auto wire : node_def.second)
+ for (auto succ_node : flow.wire_uses[wire]) {
+ auto succ_vertex = node_map[succ_node];
+ vertex->succs.insert(succ_vertex);
+ succ_vertex->preds.insert(vertex);
+ }
+ }
+
+ auto eval_order = scheduler.schedule();
+ pool<FlowGraph::Node*, hash_ptr_ops> evaluated;
+ pool<const RTLIL::Wire*> feedback_wires;
+ for (auto vertex : eval_order) {
+ auto node = vertex->data;
+ schedule[module].push_back(*node);
+ // Any wire that is an output of node vo and input of node vi where vo is scheduled later than vi
+ // is a feedback wire. Feedback wires indicate apparent logic loops in the design, which may be
+ // caused by a true logic loop, but usually are a benign result of dependency tracking that works
+ // on wire, not bit, level. Nevertheless, feedback wires cannot be localized.
+ evaluated.insert(node);
+ for (auto wire : node_defs[node])
+ for (auto succ_node : flow.wire_uses[wire])
+ if (evaluated[succ_node]) {
+ feedback_wires.insert(wire);
+ // Feedback wires may never be elided because feedback requires state, but the point of elision
+ // (and localization) is to eliminate state.
+ elided_wires.erase(wire);
+ }
+ }
+
+ if (!feedback_wires.empty()) {
+ has_feedback_arcs = true;
+ log("Module `%s` contains feedback arcs through wires:\n", module->name.c_str());
+ for (auto wire : feedback_wires) {
+ log(" %s\n", wire->name.c_str());
+ }
+ }
+
+ for (auto wire : module->wires()) {
+ if (feedback_wires[wire]) continue;
+ if (wire->port_id != 0) continue;
+ if (wire->get_bool_attribute(ID(keep))) continue;
+ if (wire->name.begins_with("$") && !localize_internal) continue;
+ if (wire->name.begins_with("\\") && !localize_public) continue;
+ if (sync_wires[wire]) continue;
+ // Outputs of FF/$memrd cells and LHS of sync actions do not end up in defs.
+ if (flow.wire_defs[wire].size() != 1) continue;
+ localized_wires.insert(wire);
+ }
+ }
+ if (has_feedback_arcs) {
+ log("Feedback arcs require delta cycles during evaluation.\n");
+ }
+ }
+
+ void check_design(RTLIL::Design *design, bool &has_sync_init, bool &has_packed_mem)
+ {
+ has_sync_init = has_packed_mem = false;
+
+ for (auto module : design->modules()) {
+ if (module->get_blackbox_attribute())
+ continue;
+
+ if (!design->selected_whole_module(module))
+ if (design->selected_module(module))
+ log_cmd_error("Can't handle partially selected module `%s`!\n", id2cstr(module->name));
+ if (!design->selected_module(module))
+ continue;
+
+ for (auto proc : module->processes)
+ for (auto sync : proc.second->syncs)
+ if (sync->type == RTLIL::STi)
+ has_sync_init = true;
+
+ for (auto cell : module->cells())
+ if (cell->type == ID($mem))
+ has_packed_mem = true;
+ }
+ }
+
+ void prepare_design(RTLIL::Design *design)
+ {
+ bool has_sync_init, has_packed_mem;
+ check_design(design, has_sync_init, has_packed_mem);
+ if (has_sync_init) {
+ // We're only interested in proc_init, but it depends on proc_prune and proc_clean, so call those
+ // in case they weren't already. (This allows `yosys foo.v -o foo.cc` to work.)
+ Pass::call(design, "proc_prune");
+ Pass::call(design, "proc_clean");
+ Pass::call(design, "proc_init");
+ }
+ if (has_packed_mem)
+ Pass::call(design, "memory_unpack");
+ // Recheck the design if it was modified.
+ if (has_sync_init || has_packed_mem)
+ check_design(design, has_sync_init, has_packed_mem);
+ log_assert(!(has_sync_init || has_packed_mem));
+
+ if (run_splitnets) {
+ Pass::call(design, "splitnets -driver");
+ Pass::call(design, "opt_clean -purge");
+ }
+ log("\n");
+ analyze_design(design);
+ }
+};
+
+struct CxxrtlBackend : public Backend {
+ static const int DEFAULT_OPT_LEVEL = 5;
+
+ CxxrtlBackend() : Backend("cxxrtl", "convert design to C++ RTL simulation") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" write_cxxrtl [options] [filename]\n");
+ log("\n");
+ log("Write C++ code for simulating the design. The generated code requires a driver;\n");
+ log("the following simple driver is provided as an example:\n");
+ log("\n");
+ log(" #include \"top.cc\"\n");
+ log("\n");
+ log(" int main() {\n");
+ log(" cxxrtl_design::p_top top;\n");
+ log(" while (1) {\n");
+ log(" top.p_clk.next = value<1> {1u};\n");
+ log(" top.step();\n");
+ log(" top.p_clk.next = value<1> {0u};\n");
+ log(" top.step();\n");
+ log(" }\n");
+ log(" }\n");
+ log("\n");
+ log("The following options are supported by this backend:\n");
+ log("\n");
+ log(" -header\n");
+ log(" generate separate interface (.h) and implementation (.cc) files.\n");
+ log(" if specified, the backend must be called with a filename, and filename\n");
+ log(" of the interface is derived from filename of the implementation.\n");
+ log(" otherwise, interface and implementation are generated together.\n");
+ log("\n");
+ log(" -namespace <ns-name>\n");
+ log(" place the generated code into namespace <ns-name>. if not specified,\n");
+ log(" \"cxxrtl_design\" is used.\n");
+ log("\n");
+ log(" -O <level>\n");
+ log(" set the optimization level. the default is -O%d. higher optimization\n", DEFAULT_OPT_LEVEL);
+ log(" levels dramatically decrease compile and run time, and highest level\n");
+ log(" possible for a design should be used.\n");
+ log("\n");
+ log(" -O0\n");
+ log(" no optimization.\n");
+ log("\n");
+ log(" -O1\n");
+ log(" elide internal wires if possible.\n");
+ log("\n");
+ log(" -O2\n");
+ log(" like -O1, and localize internal wires if possible.\n");
+ log("\n");
+ log(" -O3\n");
+ log(" like -O2, and elide public wires not marked (*keep*) if possible.\n");
+ log("\n");
+ log(" -O4\n");
+ log(" like -O3, and localize public wires not marked (*keep*) if possible.\n");
+ log("\n");
+ log(" -O5\n");
+ log(" like -O4, and run `splitnets -driver; opt_clean -purge` first.\n");
+ log("\n");
+ }
+ void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ int opt_level = DEFAULT_OPT_LEVEL;
+ CxxrtlWorker worker;
+
+ log_header(design, "Executing CXXRTL backend.\n");
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ if (args[argidx] == "-O" && argidx+1 < args.size()) {
+ opt_level = std::stoi(args[++argidx]);
+ continue;
+ }
+ if (args[argidx].substr(0, 2) == "-O" && args[argidx].size() == 3 && isdigit(args[argidx][2])) {
+ opt_level = std::stoi(args[argidx].substr(2));
+ continue;
+ }
+ if (args[argidx] == "-header") {
+ worker.split_intf = true;
+ continue;
+ }
+ if (args[argidx] == "-namespace" && argidx+1 < args.size()) {
+ worker.design_ns = args[++argidx];
+ continue;
+ }
+ break;
+ }
+ extra_args(f, filename, args, argidx);
+
+ switch (opt_level) {
+ case 5:
+ worker.run_splitnets = true;
+ case 4:
+ worker.localize_public = true;
+ case 3:
+ worker.elide_public = true;
+ case 2:
+ worker.localize_internal = true;
+ case 1:
+ worker.elide_internal = true;
+ case 0:
+ break;
+ default:
+ log_cmd_error("Invalid optimization level %d.\n", opt_level);
+ }
+
+ std::ofstream intf_f;
+ if (worker.split_intf) {
+ if (filename == "<stdout>")
+ log_cmd_error("Option -header must be used with a filename.\n");
+
+ worker.intf_filename = filename.substr(0, filename.rfind('.')) + ".h";
+ intf_f.open(worker.intf_filename, std::ofstream::trunc);
+ if (intf_f.fail())
+ log_cmd_error("Can't open file `%s' for writing: %s\n",
+ worker.intf_filename.c_str(), strerror(errno));
+
+ worker.intf_f = &intf_f;
+ }
+ worker.impl_f = f;
+
+ worker.prepare_design(design);
+ worker.dump_design(design);
+ }
+} CxxrtlBackend;
+
+PRIVATE_NAMESPACE_END
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
new file mode 100644
index 000000000..593c31c28
--- /dev/null
+++ b/backends/cxxrtl/cxxrtl.h
@@ -0,0 +1,1138 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2019-2020 whitequark <whitequark@whitequark.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+// This file is included by the designs generated with `write_cxxrtl`. It is not used in Yosys itself.
+
+#ifndef CXXRTL_H
+#define CXXRTL_H
+
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+#include <type_traits>
+#include <tuple>
+#include <vector>
+#include <algorithm>
+#include <sstream>
+
+// The cxxrtl support library implements compile time specialized arbitrary width arithmetics, as well as provides
+// composite lvalues made out of bit slices and concatenations of lvalues. This allows the `write_cxxrtl` pass
+// to perform a straightforward translation of RTLIL structures to readable C++, relying on the C++ compiler
+// to unwrap the abstraction and generate efficient code.
+namespace cxxrtl {
+
+// All arbitrary-width values in cxxrtl are backed by arrays of unsigned integers called chunks. The chunk size
+// is the same regardless of the value width to simplify manipulating values via FFI interfaces, e.g. driving
+// and introspecting the simulation in Python.
+//
+// It is practical to use chunk sizes between 32 bits and platform register size because when arithmetics on
+// narrower integer types is legalized by the C++ compiler, it inserts code to clear the high bits of the register.
+// However, (a) most of our operations do not change those bits in the first place because of invariants that are
+// invisible to the compiler, (b) we often operate on non-power-of-2 values and have to clear the high bits anyway.
+// Therefore, using relatively wide chunks and clearing the high bits explicitly and only when we know they may be
+// clobbered results in simpler generated code.
+template<typename T>
+struct chunk_traits {
+ static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
+ "chunk type must be an unsigned integral type");
+ using type = T;
+ static constexpr size_t bits = std::numeric_limits<T>::digits;
+ static constexpr T mask = std::numeric_limits<T>::max();
+};
+
+template<class T>
+struct expr_base;
+
+template<size_t Bits>
+struct value : public expr_base<value<Bits>> {
+ static constexpr size_t bits = Bits;
+
+ using chunk = chunk_traits<uint32_t>;
+ static constexpr chunk::type msb_mask = (Bits % chunk::bits == 0) ? chunk::mask
+ : chunk::mask >> (chunk::bits - (Bits % chunk::bits));
+
+ static constexpr size_t chunks = (Bits + chunk::bits - 1) / chunk::bits;
+ chunk::type data[chunks] = {};
+
+ value() = default;
+ template<typename... Init>
+ explicit constexpr value(Init ...init) : data{init...} {}
+
+ value(const value<Bits> &) = default;
+ value(value<Bits> &&) = default;
+ value<Bits> &operator=(const value<Bits> &) = default;
+
+ // A (no-op) helper that forces the cast to value<>.
+ const value<Bits> &val() const {
+ return *this;
+ }
+
+ std::string str() const {
+ std::stringstream ss;
+ ss << *this;
+ return ss.str();
+ }
+
+ // Operations with compile-time parameters.
+ //
+ // These operations are used to implement slicing, concatenation, and blitting.
+ // The trunc, zext and sext operations add or remove most significant bits (i.e. on the left);
+ // the rtrunc and rzext operations add or remove least significant bits (i.e. on the right).
+ template<size_t NewBits>
+ value<NewBits> trunc() const {
+ static_assert(NewBits <= Bits, "trunc() may not increase width");
+ value<NewBits> result;
+ for (size_t n = 0; n < result.chunks; n++)
+ result.data[n] = data[n];
+ result.data[result.chunks - 1] &= result.msb_mask;
+ return result;
+ }
+
+ template<size_t NewBits>
+ value<NewBits> zext() const {
+ static_assert(NewBits >= Bits, "zext() may not decrease width");
+ value<NewBits> result;
+ for (size_t n = 0; n < chunks; n++)
+ result.data[n] = data[n];
+ return result;
+ }
+
+ template<size_t NewBits>
+ value<NewBits> sext() const {
+ static_assert(NewBits >= Bits, "sext() may not decrease width");
+ value<NewBits> result;
+ for (size_t n = 0; n < chunks; n++)
+ result.data[n] = data[n];
+ if (is_neg()) {
+ result.data[chunks - 1] |= ~msb_mask;
+ for (size_t n = chunks; n < result.chunks; n++)
+ result.data[n] = chunk::mask;
+ result.data[result.chunks - 1] &= result.msb_mask;
+ }
+ return result;
+ }
+
+ template<size_t NewBits>
+ value<NewBits> rtrunc() const {
+ static_assert(NewBits <= Bits, "rtrunc() may not increase width");
+ value<NewBits> result;
+ constexpr size_t shift_chunks = (Bits - NewBits) / chunk::bits;
+ constexpr size_t shift_bits = (Bits - NewBits) % chunk::bits;
+ chunk::type carry = 0;
+ if (shift_chunks + result.chunks < chunks) {
+ carry = (shift_bits == 0) ? 0
+ : data[shift_chunks + result.chunks] << (chunk::bits - shift_bits);
+ }
+ for (size_t n = result.chunks; n > 0; n--) {
+ result.data[n - 1] = carry | (data[shift_chunks + n - 1] >> shift_bits);
+ carry = (shift_bits == 0) ? 0
+ : data[shift_chunks + n - 1] << (chunk::bits - shift_bits);
+ }
+ return result;
+ }
+
+ template<size_t NewBits>
+ value<NewBits> rzext() const {
+ static_assert(NewBits >= Bits, "rzext() may not decrease width");
+ value<NewBits> result;
+ constexpr size_t shift_chunks = (NewBits - Bits) / chunk::bits;
+ constexpr size_t shift_bits = (NewBits - Bits) % chunk::bits;
+ chunk::type carry = 0;
+ for (size_t n = 0; n < chunks; n++) {
+ result.data[shift_chunks + n] = (data[n] << shift_bits) | carry;
+ carry = (shift_bits == 0) ? 0
+ : data[n] >> (chunk::bits - shift_bits);
+ }
+ if (carry != 0)
+ result.data[result.chunks - 1] = carry;
+ return result;
+ }
+
+ // Bit blit operation, i.e. a partial read-modify-write.
+ template<size_t Stop, size_t Start>
+ value<Bits> blit(const value<Stop - Start + 1> &source) const {
+ static_assert(Stop >= Start, "blit() may not reverse bit order");
+ constexpr chunk::type start_mask = ~(chunk::mask << (Start % chunk::bits));
+ constexpr chunk::type stop_mask = (Stop % chunk::bits + 1 == chunk::bits) ? 0
+ : (chunk::mask << (Stop % chunk::bits + 1));
+ value<Bits> masked = *this;
+ if (Start / chunk::bits == Stop / chunk::bits) {
+ masked.data[Start / chunk::bits] &= stop_mask | start_mask;
+ } else {
+ masked.data[Start / chunk::bits] &= start_mask;
+ for (size_t n = Start / chunk::bits + 1; n < Stop / chunk::bits; n++)
+ masked.data[n] = 0;
+ masked.data[Stop / chunk::bits] &= stop_mask;
+ }
+ value<Bits> shifted = source
+ .template rzext<Stop + 1>()
+ .template zext<Bits>();
+ return masked.bit_or(shifted);
+ }
+
+ // Helpers for selecting extending or truncating operation depending on whether the result is wider or narrower
+ // than the operand. In C++17 these can be replaced with `if constexpr`.
+ template<size_t NewBits, typename = void>
+ struct zext_cast {
+ value<NewBits> operator()(const value<Bits> &val) {
+ return val.template zext<NewBits>();
+ }
+ };
+
+ template<size_t NewBits>
+ struct zext_cast<NewBits, typename std::enable_if<(NewBits < Bits)>::type> {
+ value<NewBits> operator()(const value<Bits> &val) {
+ return val.template trunc<NewBits>();
+ }
+ };
+
+ template<size_t NewBits, typename = void>
+ struct sext_cast {
+ value<NewBits> operator()(const value<Bits> &val) {
+ return val.template sext<NewBits>();
+ }
+ };
+
+ template<size_t NewBits>
+ struct sext_cast<NewBits, typename std::enable_if<(NewBits < Bits)>::type> {
+ value<NewBits> operator()(const value<Bits> &val) {
+ return val.template trunc<NewBits>();
+ }
+ };
+
+ template<size_t NewBits>
+ value<NewBits> zcast() const {
+ return zext_cast<NewBits>()(*this);
+ }
+
+ template<size_t NewBits>
+ value<NewBits> scast() const {
+ return sext_cast<NewBits>()(*this);
+ }
+
+ // Operations with run-time parameters (offsets, amounts, etc).
+ //
+ // These operations are used for computations.
+ bool bit(size_t offset) const {
+ return data[offset / chunk::bits] & (1 << (offset % chunk::bits));
+ }
+
+ void set_bit(size_t offset, bool value = true) {
+ size_t offset_chunks = offset / chunk::bits;
+ size_t offset_bits = offset % chunk::bits;
+ data[offset_chunks] &= ~(1 << offset_bits);
+ data[offset_chunks] |= value ? 1 << offset_bits : 0;
+ }
+
+ bool is_zero() const {
+ for (size_t n = 0; n < chunks; n++)
+ if (data[n] != 0)
+ return false;
+ return true;
+ }
+
+ explicit operator bool() const {
+ return !is_zero();
+ }
+
+ bool is_neg() const {
+ return data[chunks - 1] & (1 << ((Bits - 1) % chunk::bits));
+ }
+
+ bool operator ==(const value<Bits> &other) const {
+ for (size_t n = 0; n < chunks; n++)
+ if (data[n] != other.data[n])
+ return false;
+ return true;
+ }
+
+ bool operator !=(const value<Bits> &other) const {
+ return !(*this == other);
+ }
+
+ value<Bits> bit_not() const {
+ value<Bits> result;
+ for (size_t n = 0; n < chunks; n++)
+ result.data[n] = ~data[n];
+ result.data[chunks - 1] &= msb_mask;
+ return result;
+ }
+
+ value<Bits> bit_and(const value<Bits> &other) const {
+ value<Bits> result;
+ for (size_t n = 0; n < chunks; n++)
+ result.data[n] = data[n] & other.data[n];
+ return result;
+ }
+
+ value<Bits> bit_or(const value<Bits> &other) const {
+ value<Bits> result;
+ for (size_t n = 0; n < chunks; n++)
+ result.data[n] = data[n] | other.data[n];
+ return result;
+ }
+
+ value<Bits> bit_xor(const value<Bits> &other) const {
+ value<Bits> result;
+ for (size_t n = 0; n < chunks; n++)
+ result.data[n] = data[n] ^ other.data[n];
+ return result;
+ }
+
+ value<Bits> update(const value<Bits> &val, const value<Bits> &mask) const {
+ return bit_and(mask.bit_not()).bit_or(val.bit_and(mask));
+ }
+
+ template<size_t AmountBits>
+ value<Bits> shl(const value<AmountBits> &amount) const {
+ // Ensure our early return is correct by prohibiting values larger than 4 Gbit.
+ static_assert(Bits <= chunk::mask, "shl() of unreasonably large values is not supported");
+ // Detect shifts definitely large than Bits early.
+ for (size_t n = 1; n < amount.chunks; n++)
+ if (amount.data[n] != 0)
+ return {};
+ // Past this point we can use the least significant chunk as the shift size.
+ size_t shift_chunks = amount.data[0] / chunk::bits;
+ size_t shift_bits = amount.data[0] % chunk::bits;
+ if (shift_chunks >= chunks)
+ return {};
+ value<Bits> result;
+ chunk::type carry = 0;
+ for (size_t n = 0; n < chunks - shift_chunks; n++) {
+ result.data[shift_chunks + n] = (data[n] << shift_bits) | carry;
+ carry = (shift_bits == 0) ? 0
+ : data[n] >> (chunk::bits - shift_bits);
+ }
+ return result;
+ }
+
+ template<size_t AmountBits, bool Signed = false>
+ value<Bits> shr(const value<AmountBits> &amount) const {
+ // Ensure our early return is correct by prohibiting values larger than 4 Gbit.
+ static_assert(Bits <= chunk::mask, "shr() of unreasonably large values is not supported");
+ // Detect shifts definitely large than Bits early.
+ for (size_t n = 1; n < amount.chunks; n++)
+ if (amount.data[n] != 0)
+ return {};
+ // Past this point we can use the least significant chunk as the shift size.
+ size_t shift_chunks = amount.data[0] / chunk::bits;
+ size_t shift_bits = amount.data[0] % chunk::bits;
+ if (shift_chunks >= chunks)
+ return {};
+ value<Bits> result;
+ chunk::type carry = 0;
+ for (size_t n = 0; n < chunks - shift_chunks; n++) {
+ result.data[chunks - shift_chunks - 1 - n] = carry | (data[chunks - 1 - n] >> shift_bits);
+ carry = (shift_bits == 0) ? 0
+ : data[chunks - 1 - n] << (chunk::bits - shift_bits);
+ }
+ if (Signed && is_neg()) {
+ for (size_t n = chunks - shift_chunks; n < chunks; n++)
+ result.data[n] = chunk::mask;
+ if (shift_bits != 0)
+ result.data[chunks - shift_chunks] |= chunk::mask << (chunk::bits - shift_bits);
+ }
+ return result;
+ }
+
+ template<size_t AmountBits>
+ value<Bits> sshr(const value<AmountBits> &amount) const {
+ return shr<AmountBits, /*Signed=*/true>(amount);
+ }
+
+ size_t ctpop() const {
+ size_t count = 0;
+ for (size_t n = 0; n < chunks; n++) {
+ // This loop implements the population count idiom as recognized by LLVM and GCC.
+ for (chunk::type x = data[n]; x != 0; count++)
+ x = x & (x - 1);
+ }
+ return count;
+ }
+
+ size_t ctlz() const {
+ size_t count = 0;
+ for (size_t n = 0; n < chunks; n++) {
+ chunk::type x = data[chunks - 1 - n];
+ if (x == 0) {
+ count += (n == 0 ? Bits % chunk::bits : chunk::bits);
+ } else {
+ // This loop implements the find first set idiom as recognized by LLVM.
+ for (; x != 0; count++)
+ x >>= 1;
+ }
+ }
+ return count;
+ }
+
+ template<bool Invert, bool CarryIn>
+ std::pair<value<Bits>, bool /*CarryOut*/> alu(const value<Bits> &other) const {
+ value<Bits> result;
+ bool carry = CarryIn;
+ for (size_t n = 0; n < result.chunks; n++) {
+ result.data[n] = data[n] + (Invert ? ~other.data[n] : other.data[n]) + carry;
+ carry = (result.data[n] < data[n]) ||
+ (result.data[n] == data[n] && carry);
+ }
+ result.data[result.chunks - 1] &= result.msb_mask;
+ return {result, carry};
+ }
+
+ value<Bits> add(const value<Bits> &other) const {
+ return alu</*Invert=*/false, /*CarryIn=*/false>(other).first;
+ }
+
+ value<Bits> sub(const value<Bits> &other) const {
+ return alu</*Invert=*/true, /*CarryIn=*/true>(other).first;
+ }
+
+ value<Bits> neg() const {
+ return value<Bits> { 0u }.sub(*this);
+ }
+
+ bool ucmp(const value<Bits> &other) const {
+ bool carry;
+ std::tie(std::ignore, carry) = alu</*Invert=*/true, /*CarryIn=*/true>(other);
+ return !carry; // a.ucmp(b) ≡ a u< b
+ }
+
+ bool scmp(const value<Bits> &other) const {
+ value<Bits> result;
+ bool carry;
+ std::tie(result, carry) = alu</*Invert=*/true, /*CarryIn=*/true>(other);
+ bool overflow = (is_neg() == !other.is_neg()) && (is_neg() != result.is_neg());
+ return result.is_neg() ^ overflow; // a.scmp(b) ≡ a s< b
+ }
+};
+
+// Expression template for a slice, usable as lvalue or rvalue, and composable with other expression templates here.
+template<class T, size_t Stop, size_t Start>
+struct slice_expr : public expr_base<slice_expr<T, Stop, Start>> {
+ static_assert(Stop >= Start, "slice_expr() may not reverse bit order");
+ static_assert(Start < T::bits && Stop < T::bits, "slice_expr() must be within bounds");
+ static constexpr size_t bits = Stop - Start + 1;
+
+ T &expr;
+
+ slice_expr(T &expr) : expr(expr) {}
+ slice_expr(const slice_expr<T, Stop, Start> &) = delete;
+
+ operator value<bits>() const {
+ return static_cast<const value<T::bits> &>(expr)
+ .template rtrunc<T::bits - Start>()
+ .template trunc<bits>();
+ }
+
+ slice_expr<T, Stop, Start> &operator=(const value<bits> &rhs) {
+ // Generic partial assignment implemented using a read-modify-write operation on the sliced expression.
+ expr = static_cast<const value<T::bits> &>(expr)
+ .template blit<Stop, Start>(rhs);
+ return *this;
+ }
+
+ // A helper that forces the cast to value<>, which allows deduction to work.
+ value<bits> val() const {
+ return static_cast<const value<bits> &>(*this);
+ }
+};
+
+// Expression template for a concatenation, usable as lvalue or rvalue, and composable with other expression templates here.
+template<class T, class U>
+struct concat_expr : public expr_base<concat_expr<T, U>> {
+ static constexpr size_t bits = T::bits + U::bits;
+
+ T &ms_expr;
+ U &ls_expr;
+
+ concat_expr(T &ms_expr, U &ls_expr) : ms_expr(ms_expr), ls_expr(ls_expr) {}
+ concat_expr(const concat_expr<T, U> &) = delete;
+
+ operator value<bits>() const {
+ value<bits> ms_shifted = static_cast<const value<T::bits> &>(ms_expr)
+ .template rzext<bits>();
+ value<bits> ls_extended = static_cast<const value<U::bits> &>(ls_expr)
+ .template zext<bits>();
+ return ms_shifted.bit_or(ls_extended);
+ }
+
+ concat_expr<T, U> &operator=(const value<bits> &rhs) {
+ ms_expr = rhs.template rtrunc<T::bits>();
+ ls_expr = rhs.template trunc<U::bits>();
+ return *this;
+ }
+
+ // A helper that forces the cast to value<>, which allows deduction to work.
+ value<bits> val() const {
+ return static_cast<const value<bits> &>(*this);
+ }
+};
+
+// Base class for expression templates, providing helper methods for operations that are valid on both rvalues and lvalues.
+//
+// Note that expression objects (slices and concatenations) constructed in this way should NEVER be captured because
+// they refer to temporaries that will, in general, only live until the end of the statement. For example, both of
+// these snippets perform use-after-free:
+//
+// const auto &a = val.slice<7,0>().slice<1>();
+// value<1> b = a;
+//
+// auto &&c = val.slice<7,0>().slice<1>();
+// c = value<1>{1u};
+//
+// An easy way to write code using slices and concatenations safely is to follow two simple rules:
+// * Never explicitly name any type except `value<W>` or `const value<W> &`.
+// * Never use a `const auto &` or `auto &&` in any such expression.
+// Then, any code that compiles will be well-defined.
+template<class T>
+struct expr_base {
+ template<size_t Stop, size_t Start = Stop>
+ slice_expr<const T, Stop, Start> slice() const {
+ return {*static_cast<const T *>(this)};
+ }
+
+ template<size_t Stop, size_t Start = Stop>
+ slice_expr<T, Stop, Start> slice() {
+ return {*static_cast<T *>(this)};
+ }
+
+ template<class U>
+ concat_expr<const T, typename std::remove_reference<const U>::type> concat(const U &other) const {
+ return {*static_cast<const T *>(this), other};
+ }
+
+ template<class U>
+ concat_expr<T, typename std::remove_reference<U>::type> concat(U &&other) {
+ return {*static_cast<T *>(this), other};
+ }
+};
+
+template<size_t Bits>
+std::ostream &operator<<(std::ostream &os, const value<Bits> &val) {
+ auto old_flags = os.flags(std::ios::right);
+ auto old_width = os.width(0);
+ auto old_fill = os.fill('0');
+ os << val.bits << '\'' << std::hex;
+ for (size_t n = val.chunks - 1; n != (size_t)-1; n--) {
+ if (n == val.chunks - 1 && Bits % value<Bits>::chunk::bits != 0)
+ os.width((Bits % value<Bits>::chunk::bits + 3) / 4);
+ else
+ os.width((value<Bits>::chunk::bits + 3) / 4);
+ os << val.data[n];
+ }
+ os.fill(old_fill);
+ os.width(old_width);
+ os.flags(old_flags);
+ return os;
+}
+
+template<size_t Bits>
+struct wire {
+ static constexpr size_t bits = Bits;
+
+ value<Bits> curr;
+ value<Bits> next;
+
+ wire() = default;
+ constexpr wire(const value<Bits> &init) : curr(init), next(init) {}
+ template<typename... Init>
+ explicit constexpr wire(Init ...init) : curr{init...}, next{init...} {}
+
+ wire(const wire<Bits> &) = delete;
+ wire(wire<Bits> &&) = default;
+ wire<Bits> &operator=(const wire<Bits> &) = delete;
+
+ bool commit() {
+ if (curr != next) {
+ curr = next;
+ return true;
+ }
+ return false;
+ }
+};
+
+template<size_t Bits>
+std::ostream &operator<<(std::ostream &os, const wire<Bits> &val) {
+ os << val.curr;
+ return os;
+}
+
+template<size_t Width>
+struct memory {
+ std::vector<value<Width>> data;
+
+ size_t depth() const {
+ return data.size();
+ }
+
+ memory() = delete;
+ explicit memory(size_t depth) : data(depth) {}
+
+ memory(const memory<Width> &) = delete;
+ memory<Width> &operator=(const memory<Width> &) = delete;
+
+ // The only way to get the compiler to put the initializer in .rodata and do not copy it on stack is to stuff it
+ // into a plain array. You'd think an std::initializer_list would work here, but it doesn't, because you can't
+ // construct an initializer_list in a constexpr (or something) and so if you try to do that the whole thing is
+ // first copied on the stack (probably overflowing it) and then again into `data`.
+ template<size_t Size>
+ struct init {
+ size_t offset;
+ value<Width> data[Size];
+ };
+
+ template<size_t... InitSize>
+ explicit memory(size_t depth, const init<InitSize> &...init) : data(depth) {
+ data.resize(depth);
+ // This utterly reprehensible construct is the most reasonable way to apply a function to every element
+ // of a parameter pack, if the elements all have different types and so cannot be cast to an initializer list.
+ auto _ = {std::move(std::begin(init.data), std::end(init.data), data.begin() + init.offset)...};
+ }
+
+ value<Width> &operator [](size_t index) {
+ assert(index < data.size());
+ return data[index];
+ }
+
+ const value<Width> &operator [](size_t index) const {
+ assert(index < data.size());
+ return data[index];
+ }
+
+ // A simple way to make a writable memory would be to use an array of wires instead of an array of values.
+ // However, there are two significant downsides to this approach: first, it has large overhead (2× space
+ // overhead, and O(depth) time overhead during commit); second, it does not simplify handling write port
+ // priorities. Although in principle write ports could be ordered or conditionally enabled in generated
+ // code based on their priorities and selected addresses, the feedback arc set problem is computationally
+ // expensive, and the heuristic based algorithms are not easily modified to guarantee (rather than prefer)
+ // a particular write port evaluation order.
+ //
+ // The approach used here instead is to queue writes into a buffer during the eval phase, then perform
+ // the writes during the commit phase in the priority order. This approach has low overhead, with both space
+ // and time proportional to the amount of write ports. Because virtually every memory in a practical design
+ // has at most two write ports, linear search is used on every write, being the fastest and simplest approach.
+ struct write {
+ size_t index;
+ value<Width> val;
+ value<Width> mask;
+ int priority;
+ };
+ std::vector<write> write_queue;
+
+ void update(size_t index, const value<Width> &val, const value<Width> &mask, int priority = 0) {
+ assert(index < data.size());
+ write_queue.emplace_back(write { index, val, mask, priority });
+ }
+
+ bool commit() {
+ bool changed = false;
+ std::sort(write_queue.begin(), write_queue.end(),
+ [](const write &a, const write &b) { return a.priority < b.priority; });
+ for (const write &entry : write_queue) {
+ value<Width> elem = data[entry.index];
+ elem = elem.update(entry.val, entry.mask);
+ changed |= (data[entry.index] != elem);
+ data[entry.index] = elem;
+ }
+ write_queue.clear();
+ return changed;
+ }
+};
+
+struct module {
+ module() {}
+ virtual ~module() {}
+
+ module(const module &) = delete;
+ module &operator=(const module &) = delete;
+
+ virtual void eval() = 0;
+ virtual bool commit() = 0;
+
+ size_t step() {
+ size_t deltas = 0;
+ do {
+ eval();
+ deltas++;
+ } while (commit());
+ return deltas;
+ }
+};
+
+} // namespace cxxrtl
+
+// Definitions of internal Yosys cells. Other than the functions in this namespace, cxxrtl is fully generic
+// and indepenent of Yosys implementation details.
+//
+// The `write_cxxrtl` pass translates internal cells (cells with names that start with `$`) to calls of these
+// functions. All of Yosys arithmetic and logical cells perform sign or zero extension on their operands,
+// whereas basic operations on arbitrary width values require operands to be of the same width. These functions
+// bridge the gap by performing the necessary casts. They are named similar to `cell_A[B]`, where A and B are `u`
+// if the corresponding operand is unsigned, and `s` if it is signed.
+namespace cxxrtl_yosys {
+
+using namespace cxxrtl;
+
+// std::max isn't constexpr until C++14 for no particular reason (it's an oversight), so we define our own.
+template<class T>
+constexpr T max(const T &a, const T &b) {
+ return a > b ? a : b;
+}
+
+// Logic operations
+template<size_t BitsY, size_t BitsA>
+value<BitsY> not_u(const value<BitsA> &a) {
+ return a.template zcast<BitsY>().bit_not();
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> not_s(const value<BitsA> &a) {
+ return a.template scast<BitsY>().bit_not();
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> logic_not_u(const value<BitsA> &a) {
+ return value<BitsY> { a ? 0u : 1u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> logic_not_s(const value<BitsA> &a) {
+ return value<BitsY> { a ? 0u : 1u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_and_u(const value<BitsA> &a) {
+ return value<BitsY> { a.bit_not().is_zero() ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_and_s(const value<BitsA> &a) {
+ return value<BitsY> { a.bit_not().is_zero() ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_or_u(const value<BitsA> &a) {
+ return value<BitsY> { a ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_or_s(const value<BitsA> &a) {
+ return value<BitsY> { a ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_xor_u(const value<BitsA> &a) {
+ return value<BitsY> { (a.ctpop() % 2) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_xor_s(const value<BitsA> &a) {
+ return value<BitsY> { (a.ctpop() % 2) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_xnor_u(const value<BitsA> &a) {
+ return value<BitsY> { (a.ctpop() % 2) ? 0u : 1u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_xnor_s(const value<BitsA> &a) {
+ return value<BitsY> { (a.ctpop() % 2) ? 0u : 1u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_bool_u(const value<BitsA> &a) {
+ return value<BitsY> { a ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> reduce_bool_s(const value<BitsA> &a) {
+ return value<BitsY> { a ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> and_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().bit_and(b.template zcast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> and_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().bit_and(b.template scast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> or_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().bit_or(b.template zcast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> or_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().bit_or(b.template scast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> xor_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().bit_xor(b.template zcast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> xor_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().bit_xor(b.template scast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> xnor_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().bit_xor(b.template zcast<BitsY>()).bit_not();
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> xnor_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().bit_xor(b.template scast<BitsY>()).bit_not();
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> logic_and_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return value<BitsY> { (bool(a) & bool(b)) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> logic_and_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return value<BitsY> { (bool(a) & bool(b)) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> logic_or_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return value<BitsY> { (bool(a) | bool(b)) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> logic_or_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return value<BitsY> { (bool(a) | bool(b)) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shl_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().template shl(b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shl_su(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().template shl(b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> sshl_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().template shl(b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> sshl_su(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().template shl(b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shr_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template shr(b).template zcast<BitsY>();
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shr_su(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template shr(b).template scast<BitsY>();
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> sshr_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template shr(b).template zcast<BitsY>();
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> sshr_su(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template shr(b).template scast<BitsY>();
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shift_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return shr_uu<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shift_su(const value<BitsA> &a, const value<BitsB> &b) {
+ return shr_su<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shift_us(const value<BitsA> &a, const value<BitsB> &b) {
+ return b.is_neg() ? shl_uu<BitsY>(a, b.template sext<BitsB + 1>().neg()) : shr_uu<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shift_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return b.is_neg() ? shl_su<BitsY>(a, b.template sext<BitsB + 1>().neg()) : shr_su<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shiftx_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return shift_uu<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shiftx_su(const value<BitsA> &a, const value<BitsB> &b) {
+ return shift_su<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shiftx_us(const value<BitsA> &a, const value<BitsB> &b) {
+ return shift_us<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> shiftx_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return shift_ss<BitsY>(a, b);
+}
+
+// Comparison operations
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> eq_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY>{ a.template zext<BitsExt>() == b.template zext<BitsExt>() ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> eq_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY>{ a.template sext<BitsExt>() == b.template sext<BitsExt>() ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> ne_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY>{ a.template zext<BitsExt>() != b.template zext<BitsExt>() ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> ne_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY>{ a.template sext<BitsExt>() != b.template sext<BitsExt>() ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> eqx_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return eq_uu<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> eqx_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return eq_ss<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> nex_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return ne_uu<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> nex_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return ne_ss<BitsY>(a, b);
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> gt_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { b.template zext<BitsExt>().ucmp(a.template zext<BitsExt>()) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> gt_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { b.template sext<BitsExt>().scmp(a.template sext<BitsExt>()) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> ge_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { !a.template zext<BitsExt>().ucmp(b.template zext<BitsExt>()) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> ge_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { !a.template sext<BitsExt>().scmp(b.template sext<BitsExt>()) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> lt_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { a.template zext<BitsExt>().ucmp(b.template zext<BitsExt>()) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> lt_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { a.template sext<BitsExt>().scmp(b.template sext<BitsExt>()) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> le_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { !b.template zext<BitsExt>().ucmp(a.template zext<BitsExt>()) ? 1u : 0u };
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> le_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t BitsExt = max(BitsA, BitsB);
+ return value<BitsY> { !b.template sext<BitsExt>().scmp(a.template sext<BitsExt>()) ? 1u : 0u };
+}
+
+// Arithmetic operations
+template<size_t BitsY, size_t BitsA>
+value<BitsY> pos_u(const value<BitsA> &a) {
+ return a.template zcast<BitsY>();
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> pos_s(const value<BitsA> &a) {
+ return a.template scast<BitsY>();
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> neg_u(const value<BitsA> &a) {
+ return a.template zcast<BitsY>().neg();
+}
+
+template<size_t BitsY, size_t BitsA>
+value<BitsY> neg_s(const value<BitsA> &a) {
+ return a.template scast<BitsY>().neg();
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> add_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().add(b.template zcast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> add_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().add(b.template scast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> sub_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template zcast<BitsY>().sub(b.template zcast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> sub_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return a.template scast<BitsY>().sub(b.template scast<BitsY>());
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> mul_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ value<BitsY> product;
+ value<BitsY> multiplicand = a.template zcast<BitsY>();
+ const value<BitsB> &multiplier = b;
+ uint32_t multiplicand_shift = 0;
+ for (size_t step = 0; step < BitsB; step++) {
+ if (multiplier.bit(step)) {
+ multiplicand = multiplicand.shl(value<32> { multiplicand_shift });
+ product = product.add(multiplicand);
+ multiplicand_shift = 0;
+ }
+ multiplicand_shift++;
+ }
+ return product;
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> mul_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ value<BitsB + 1> ub = b.template sext<BitsB + 1>();
+ if (ub.is_neg()) ub = ub.neg();
+ value<BitsY> y = mul_uu<BitsY>(a.template scast<BitsY>(), ub);
+ return b.is_neg() ? y.neg() : y;
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+std::pair<value<BitsY>, value<BitsY>> divmod_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ constexpr size_t Bits = max(BitsY, max(BitsA, BitsB));
+ value<Bits> quotient;
+ value<Bits> dividend = a.template zext<Bits>();
+ value<Bits> divisor = b.template zext<Bits>();
+ if (dividend.ucmp(divisor))
+ return {/*quotient=*/value<BitsY> { 0u }, /*remainder=*/dividend.template trunc<BitsY>()};
+ uint32_t divisor_shift = dividend.ctlz() - divisor.ctlz();
+ divisor = divisor.shl(value<32> { divisor_shift });
+ for (size_t step = 0; step <= divisor_shift; step++) {
+ quotient = quotient.shl(value<1> { 1u });
+ if (!dividend.ucmp(divisor)) {
+ dividend = dividend.sub(divisor);
+ quotient.set_bit(0, true);
+ }
+ divisor = divisor.shr(value<1> { 1u });
+ }
+ return {quotient.template trunc<BitsY>(), /*remainder=*/dividend.template trunc<BitsY>()};
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+std::pair<value<BitsY>, value<BitsY>> divmod_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ value<BitsA + 1> ua = a.template sext<BitsA + 1>();
+ value<BitsB + 1> ub = b.template sext<BitsB + 1>();
+ if (ua.is_neg()) ua = ua.neg();
+ if (ub.is_neg()) ub = ub.neg();
+ value<BitsY> y, r;
+ std::tie(y, r) = divmod_uu<BitsY>(ua, ub);
+ if (a.is_neg() != b.is_neg()) y = y.neg();
+ if (a.is_neg()) r = r.neg();
+ return {y, r};
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> div_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return divmod_uu<BitsY>(a, b).first;
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> div_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return divmod_ss<BitsY>(a, b).first;
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> mod_uu(const value<BitsA> &a, const value<BitsB> &b) {
+ return divmod_uu<BitsY>(a, b).second;
+}
+
+template<size_t BitsY, size_t BitsA, size_t BitsB>
+value<BitsY> mod_ss(const value<BitsA> &a, const value<BitsB> &b) {
+ return divmod_ss<BitsY>(a, b).second;
+}
+
+// Memory helper
+struct memory_index {
+ bool valid;
+ size_t index;
+
+ template<size_t BitsAddr>
+ memory_index(const value<BitsAddr> &addr, size_t offset, size_t depth) {
+ static_assert(value<BitsAddr>::chunks <= 1, "memory address is too wide");
+ size_t offset_index = addr.data[0];
+
+ valid = (offset_index >= offset && offset_index < offset + depth);
+ index = offset_index - offset;
+ }
+};
+
+} // namespace cxxrtl_yosys
+
+#endif
diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc
index 199560ad0..cc20f17fc 100644
--- a/backends/edif/edif.cc
+++ b/backends/edif/edif.cc
@@ -171,13 +171,12 @@ struct EdifBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
- for (auto & mod_it:design->modules_)
- if (mod_it.second->get_bool_attribute("\\top"))
- top_module_name = mod_it.first.str();
+ for (auto module : design->modules())
+ if (module->get_bool_attribute(ID::top))
+ top_module_name = module->name.str();
- for (auto module_it : design->modules_)
+ for (auto module : design->modules())
{
- RTLIL::Module *module = module_it.second;
if (module->get_blackbox_attribute())
continue;
@@ -185,14 +184,13 @@ struct EdifBackend : public Backend {
top_module_name = module->name.str();
if (module->processes.size() != 0)
- log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name));
+ log_error("Found unmapped processes in module %s: unmapped processes are not supported in EDIF backend!\n", log_id(module->name));
if (module->memories.size() != 0)
- log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", RTLIL::id2cstr(module->name));
+ log_error("Found unmapped memories in module %s: unmapped memories are not supported in EDIF backend!\n", log_id(module->name));
- for (auto cell_it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = cell_it.second;
- if (!design->modules_.count(cell->type) || design->modules_.at(cell->type)->get_blackbox_attribute()) {
+ if (design->module(cell->type) == nullptr || design->module(cell->type)->get_blackbox_attribute()) {
lib_cell_ports[cell->type];
for (auto p : cell->connections())
lib_cell_ports[cell->type][p.first] = GetSize(p.second);
@@ -277,11 +275,11 @@ struct EdifBackend : public Backend {
// extract module dependencies
std::map<RTLIL::Module*, std::set<RTLIL::Module*>> module_deps;
- for (auto &mod_it : design->modules_) {
- module_deps[mod_it.second] = std::set<RTLIL::Module*>();
- for (auto &cell_it : mod_it.second->cells_)
- if (design->modules_.count(cell_it.second->type) > 0)
- module_deps[mod_it.second].insert(design->modules_.at(cell_it.second->type));
+ for (auto module : design->modules()) {
+ module_deps[module] = std::set<RTLIL::Module*>();
+ for (auto cell : module->cells())
+ if (design->module(cell->type) != nullptr)
+ module_deps[module].insert(design->module(cell->type));
}
// simple good-enough topological sort
@@ -292,12 +290,12 @@ struct EdifBackend : public Backend {
for (auto &dep : it.second)
if (module_deps.count(dep) > 0)
goto not_ready_yet;
- // log("Next in topological sort: %s\n", RTLIL::id2cstr(it.first->name));
+ // log("Next in topological sort: %s\n", log_id(it.first->name));
sorted_modules.push_back(it.first);
not_ready_yet:;
}
if (sorted_modules_idx == sorted_modules.size())
- log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", RTLIL::id2cstr(module_deps.begin()->first->name));
+ log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name));
while (sorted_modules_idx < sorted_modules.size())
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
}
@@ -339,8 +337,7 @@ struct EdifBackend : public Backend {
*f << stringf(" (view VIEW_NETLIST\n");
*f << stringf(" (viewType NETLIST)\n");
*f << stringf(" (interface\n");
- for (auto &wire_it : module->wires_) {
- RTLIL::Wire *wire = wire_it.second;
+ for (auto wire : module->wires()) {
if (wire->port_id == 0)
continue;
const char *dir = "INOUT";
@@ -378,8 +375,7 @@ struct EdifBackend : public Backend {
*f << stringf(" (instance GND (viewRef VIEW_NETLIST (cellRef GND (libraryRef LIB))))\n");
*f << stringf(" (instance VCC (viewRef VIEW_NETLIST (cellRef VCC (libraryRef LIB))))\n");
}
- for (auto &cell_it : module->cells_) {
- RTLIL::Cell *cell = cell_it.second;
+ for (auto cell : module->cells()) {
*f << stringf(" (instance %s\n", EDIF_DEF(cell->name));
*f << stringf(" (viewRef VIEW_NETLIST (cellRef %s%s))", EDIF_REF(cell->type),
lib_cell_ports.count(cell->type) > 0 ? " (libraryRef LIB)" : "");
@@ -459,8 +455,7 @@ struct EdifBackend : public Backend {
add_prop(p.first, p.second);
*f << stringf("\n )\n");
}
- for (auto &wire_it : module->wires_) {
- RTLIL::Wire *wire = wire_it.second;
+ for (auto wire : module->wires()) {
if (!wire->get_bool_attribute(ID::keep))
continue;
for(int i = 0; i < wire->width; i++) {
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index 22aa686a7..1f750b359 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -199,7 +199,7 @@ struct FirrtlWorker
const char *atLine() {
if (srcLine == "") {
if (pCell) {
- auto p = pCell->attributes.find("\\src");
+ auto p = pCell->attributes.find(ID::src);
srcLine = " at " + p->second.decode_string();
}
}
@@ -401,9 +401,9 @@ struct FirrtlWorker
{
const auto wireName = make_id(wire->name);
// If a wire has initial data, issue a warning since FIRRTL doesn't currently support it.
- if (wire->attributes.count("\\init")) {
+ if (wire->attributes.count(ID::init)) {
log_warning("Initial value (%s) for (%s.%s) not supported\n",
- wire->attributes.at("\\init").as_string().c_str(),
+ wire->attributes.at(ID::init).as_string().c_str(),
log_id(module), log_id(wire));
}
if (wire->port_id)
@@ -431,20 +431,20 @@ struct FirrtlWorker
}
// Not a module instance. Set up cell properties
bool extract_y_bits = false; // Assume no extraction of final bits will be required.
- int a_width = cell->parameters.at("\\A_WIDTH", ndef).as_int(); // The width of "A"
- int b_width = cell->parameters.at("\\B_WIDTH", ndef).as_int(); // The width of "A"
- const int y_width = cell->parameters.at("\\Y_WIDTH", ndef).as_int(); // The width of the result
- const bool a_signed = cell->parameters.at("\\A_SIGNED", ndef).as_bool();
- const bool b_signed = cell->parameters.at("\\B_SIGNED", ndef).as_bool();
+ int a_width = cell->parameters.at(ID::A_WIDTH, ndef).as_int(); // The width of "A"
+ int b_width = cell->parameters.at(ID::B_WIDTH, ndef).as_int(); // The width of "A"
+ const int y_width = cell->parameters.at(ID::Y_WIDTH, ndef).as_int(); // The width of the result
+ const bool a_signed = cell->parameters.at(ID::A_SIGNED, ndef).as_bool();
+ const bool b_signed = cell->parameters.at(ID::B_SIGNED, ndef).as_bool();
bool firrtl_is_signed = a_signed; // The result is signed (subsequent code may change this).
int firrtl_width = 0;
string primop;
bool always_uint = false;
string y_id = make_id(cell->name);
- if (cell->type.in("$not", "$logic_not", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_bool", "$reduce_xnor"))
+ if (cell->type.in(ID($not), ID($logic_not), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor)))
{
- string a_expr = make_expr(cell->getPort("\\A"));
+ string a_expr = make_expr(cell->getPort(ID::A));
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
if (a_signed) {
@@ -452,29 +452,29 @@ struct FirrtlWorker
}
// Don't use the results of logical operations (a single bit) to control padding
- if (!(cell->type.in("$eq", "$eqx", "$gt", "$ge", "$lt", "$le", "$ne", "$nex", "$reduce_bool", "$logic_not") && y_width == 1) ) {
+ if (!(cell->type.in(ID($eq), ID($eqx), ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($reduce_bool), ID($logic_not)) && y_width == 1) ) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
}
// Assume the FIRRTL width is a single bit.
firrtl_width = 1;
- if (cell->type == "$not") primop = "not";
- else if (cell->type == "$neg") {
+ if (cell->type == ID($not)) primop = "not";
+ else if (cell->type == ID($neg)) {
primop = "neg";
firrtl_is_signed = true; // Result of "neg" is signed (an SInt).
firrtl_width = a_width;
- } else if (cell->type == "$logic_not") {
+ } else if (cell->type == ID($logic_not)) {
primop = "eq";
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
}
- else if (cell->type == "$reduce_and") primop = "andr";
- else if (cell->type == "$reduce_or") primop = "orr";
- else if (cell->type == "$reduce_xor") primop = "xorr";
- else if (cell->type == "$reduce_xnor") {
+ else if (cell->type == ID($reduce_and)) primop = "andr";
+ else if (cell->type == ID($reduce_or)) primop = "orr";
+ else if (cell->type == ID($reduce_xor)) primop = "xorr";
+ else if (cell->type == ID($reduce_xnor)) {
primop = "not";
a_expr = stringf("xorr(%s)", a_expr.c_str());
}
- else if (cell->type == "$reduce_bool") {
+ else if (cell->type == ID($reduce_bool)) {
primop = "neq";
// Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand.
a_expr = stringf("%s, %cInt<%d>(0)", a_expr.c_str(), a_signed ? 'S' : 'U', a_width);
@@ -486,16 +486,16 @@ struct FirrtlWorker
expr = stringf("asUInt(%s)", expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
- register_reverse_wire_map(y_id, cell->getPort("\\Y"));
+ register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
- if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$xnor", "$and", "$or", "$eq", "$eqx",
- "$gt", "$ge", "$lt", "$le", "$ne", "$nex", "$shr", "$sshr", "$sshl", "$shl",
- "$logic_and", "$logic_or", "$pow"))
+ if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($xnor), ID($and), ID($or), ID($eq), ID($eqx),
+ ID($gt), ID($ge), ID($lt), ID($le), ID($ne), ID($nex), ID($shr), ID($sshr), ID($sshl), ID($shl),
+ ID($logic_and), ID($logic_or), ID($pow)))
{
- string a_expr = make_expr(cell->getPort("\\A"));
- string b_expr = make_expr(cell->getPort("\\B"));
+ string a_expr = make_expr(cell->getPort(ID::A));
+ string b_expr = make_expr(cell->getPort(ID::B));
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
if (a_signed) {
@@ -508,7 +508,7 @@ struct FirrtlWorker
}
// Shift amount is always unsigned, and needn't be padded to result width,
// otherwise, we need to cast the b_expr appropriately
- if (b_signed && !cell->type.in("$shr", "$sshr", "$shl", "$sshl", "$pow")) {
+ if (b_signed && !cell->type.in(ID($shr), ID($sshr), ID($shl), ID($sshl), ID($pow))) {
b_expr = "asSInt(" + b_expr + ")";
// Expand the "B" operand to the result width
if (b_width < y_width) {
@@ -519,7 +519,7 @@ struct FirrtlWorker
// For the arithmetic ops, expand operand widths to result widths befor performing the operation.
// This corresponds (according to iverilog) to what verilog compilers implement.
- if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$xnor", "$and", "$or"))
+ if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($xor), ID($xnor), ID($and), ID($or)))
{
if (a_width < y_width) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
@@ -532,85 +532,85 @@ struct FirrtlWorker
}
// Assume the FIRRTL width is the width of "A"
firrtl_width = a_width;
- auto a_sig = cell->getPort("\\A");
+ auto a_sig = cell->getPort(ID::A);
- if (cell->type == "$add") {
+ if (cell->type == ID($add)) {
primop = "add";
firrtl_is_signed = a_signed | b_signed;
firrtl_width = max(a_width, b_width);
- } else if (cell->type == "$sub") {
+ } else if (cell->type == ID($sub)) {
primop = "sub";
firrtl_is_signed = true;
int a_widthInc = (!a_signed && b_signed) ? 2 : (a_signed && !b_signed) ? 1 : 0;
int b_widthInc = (a_signed && !b_signed) ? 2 : (!a_signed && b_signed) ? 1 : 0;
firrtl_width = max(a_width + a_widthInc, b_width + b_widthInc);
- } else if (cell->type == "$mul") {
+ } else if (cell->type == ID($mul)) {
primop = "mul";
firrtl_is_signed = a_signed | b_signed;
firrtl_width = a_width + b_width;
- } else if (cell->type == "$div") {
+ } else if (cell->type == ID($div)) {
primop = "div";
firrtl_is_signed = a_signed | b_signed;
firrtl_width = a_width;
- } else if (cell->type == "$mod") {
+ } else if (cell->type == ID($mod)) {
primop = "rem";
firrtl_width = min(a_width, b_width);
- } else if (cell->type == "$and") {
+ } else if (cell->type == ID($and)) {
primop = "and";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
- else if (cell->type == "$or" ) {
+ else if (cell->type == ID($or) ) {
primop = "or";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
- else if (cell->type == "$xor") {
+ else if (cell->type == ID($xor)) {
primop = "xor";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
- else if (cell->type == "$xnor") {
+ else if (cell->type == ID($xnor)) {
primop = "xnor";
always_uint = true;
firrtl_width = max(a_width, b_width);
}
- else if ((cell->type == "$eq") | (cell->type == "$eqx")) {
+ else if ((cell->type == ID($eq)) | (cell->type == ID($eqx))) {
primop = "eq";
always_uint = true;
firrtl_width = 1;
}
- else if ((cell->type == "$ne") | (cell->type == "$nex")) {
+ else if ((cell->type == ID($ne)) | (cell->type == ID($nex))) {
primop = "neq";
always_uint = true;
firrtl_width = 1;
}
- else if (cell->type == "$gt") {
+ else if (cell->type == ID($gt)) {
primop = "gt";
always_uint = true;
firrtl_width = 1;
}
- else if (cell->type == "$ge") {
+ else if (cell->type == ID($ge)) {
primop = "geq";
always_uint = true;
firrtl_width = 1;
}
- else if (cell->type == "$lt") {
+ else if (cell->type == ID($lt)) {
primop = "lt";
always_uint = true;
firrtl_width = 1;
}
- else if (cell->type == "$le") {
+ else if (cell->type == ID($le)) {
primop = "leq";
always_uint = true;
firrtl_width = 1;
}
- else if ((cell->type == "$shl") | (cell->type == "$sshl")) {
+ else if ((cell->type == ID($shl)) | (cell->type == ID($sshl))) {
// FIRRTL will widen the result (y) by the amount of the shift.
// We'll need to offset this by extracting the un-widened portion as Verilog would do.
extract_y_bits = true;
// Is the shift amount constant?
- auto b_sig = cell->getPort("\\B");
+ auto b_sig = cell->getPort(ID::B);
if (b_sig.is_fully_const()) {
primop = "shl";
int shift_amount = b_sig.as_int();
@@ -623,11 +623,11 @@ struct FirrtlWorker
firrtl_width = a_width + (1 << b_width) - 1;
}
}
- else if ((cell->type == "$shr") | (cell->type == "$sshr")) {
+ else if ((cell->type == ID($shr)) | (cell->type == ID($sshr))) {
// We don't need to extract a specific range of bits.
extract_y_bits = false;
// Is the shift amount constant?
- auto b_sig = cell->getPort("\\B");
+ auto b_sig = cell->getPort(ID::B);
if (b_sig.is_fully_const()) {
primop = "shr";
int shift_amount = b_sig.as_int();
@@ -640,26 +640,26 @@ struct FirrtlWorker
// We'll need to do some special fixups if the source (and thus result) is signed.
if (firrtl_is_signed) {
// If this is a "logical" shift right, pretend the source is unsigned.
- if (cell->type == "$shr") {
+ if (cell->type == ID($shr)) {
a_expr = "asUInt(" + a_expr + ")";
}
}
}
- else if ((cell->type == "$logic_and")) {
+ else if ((cell->type == ID($logic_and))) {
primop = "and";
a_expr = "neq(" + a_expr + ", UInt(0))";
b_expr = "neq(" + b_expr + ", UInt(0))";
always_uint = true;
firrtl_width = 1;
}
- else if ((cell->type == "$logic_or")) {
+ else if ((cell->type == ID($logic_or))) {
primop = "or";
a_expr = "neq(" + a_expr + ", UInt(0))";
b_expr = "neq(" + b_expr + ", UInt(0))";
always_uint = true;
firrtl_width = 1;
}
- else if ((cell->type == "$pow")) {
+ else if ((cell->type == ID($pow))) {
if (a_sig.is_fully_const() && a_sig.as_int() == 2) {
// We'll convert this to a shift. To simplify things, change the a_expr to "1"
// so we can use b_expr directly as a shift amount.
@@ -669,7 +669,7 @@ struct FirrtlWorker
a_expr = firrtl_is_signed ? "SInt(1)" : "UInt(1)";
extract_y_bits = true;
// Is the shift amount constant?
- auto b_sig = cell->getPort("\\B");
+ auto b_sig = cell->getPort(ID::B);
if (b_sig.is_fully_const()) {
primop = "shl";
int shiftAmount = b_sig.as_int();
@@ -689,7 +689,7 @@ struct FirrtlWorker
}
}
- if (!cell->parameters.at("\\B_SIGNED").as_bool()) {
+ if (!cell->parameters.at(ID::B_SIGNED).as_bool()) {
b_expr = "asUInt(" + b_expr + ")";
}
@@ -713,47 +713,47 @@ struct FirrtlWorker
expr = stringf("asUInt(%s)", expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
- register_reverse_wire_map(y_id, cell->getPort("\\Y"));
+ register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
- if (cell->type.in("$mux"))
+ if (cell->type.in(ID($mux)))
{
- int width = cell->parameters.at("\\WIDTH").as_int();
- string a_expr = make_expr(cell->getPort("\\A"));
- string b_expr = make_expr(cell->getPort("\\B"));
- string s_expr = make_expr(cell->getPort("\\S"));
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ string a_expr = make_expr(cell->getPort(ID::A));
+ string b_expr = make_expr(cell->getPort(ID::B));
+ string s_expr = make_expr(cell->getPort(ID::S));
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), width));
string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
- register_reverse_wire_map(y_id, cell->getPort("\\Y"));
+ register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
- if (cell->type.in("$mem"))
+ if (cell->type.in(ID($mem)))
{
string mem_id = make_id(cell->name);
- int abits = cell->parameters.at("\\ABITS").as_int();
- int width = cell->parameters.at("\\WIDTH").as_int();
- int size = cell->parameters.at("\\SIZE").as_int();
+ int abits = cell->parameters.at(ID::ABITS).as_int();
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ int size = cell->parameters.at(ID::SIZE).as_int();
memory m(cell, mem_id, abits, size, width);
- int rd_ports = cell->parameters.at("\\RD_PORTS").as_int();
- int wr_ports = cell->parameters.at("\\WR_PORTS").as_int();
+ int rd_ports = cell->parameters.at(ID::RD_PORTS).as_int();
+ int wr_ports = cell->parameters.at(ID::WR_PORTS).as_int();
- Const initdata = cell->parameters.at("\\INIT");
+ Const initdata = cell->parameters.at(ID::INIT);
for (State bit : initdata.bits)
if (bit != State::Sx)
log_error("Memory with initialization data: %s.%s\n", log_id(module), log_id(cell));
- Const rd_clk_enable = cell->parameters.at("\\RD_CLK_ENABLE");
- Const wr_clk_enable = cell->parameters.at("\\WR_CLK_ENABLE");
- Const wr_clk_polarity = cell->parameters.at("\\WR_CLK_POLARITY");
+ Const rd_clk_enable = cell->parameters.at(ID::RD_CLK_ENABLE);
+ Const wr_clk_enable = cell->parameters.at(ID::WR_CLK_ENABLE);
+ Const wr_clk_polarity = cell->parameters.at(ID::WR_CLK_POLARITY);
- int offset = cell->parameters.at("\\OFFSET").as_int();
+ int offset = cell->parameters.at(ID::OFFSET).as_int();
if (offset != 0)
log_error("Memory with nonzero offset: %s.%s\n", log_id(module), log_id(cell));
@@ -762,8 +762,8 @@ struct FirrtlWorker
if (rd_clk_enable[i] != State::S0)
log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(cell));
- SigSpec addr_sig = cell->getPort("\\RD_ADDR").extract(i*abits, abits);
- SigSpec data_sig = cell->getPort("\\RD_DATA").extract(i*width, width);
+ SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(i*abits, abits);
+ SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(i*width, width);
string addr_expr = make_expr(addr_sig);
string name(stringf("%s.r%d", m.name.c_str(), i));
bool clk_enable = false;
@@ -789,14 +789,14 @@ struct FirrtlWorker
bool clk_enable = true;
bool clk_parity = true;
bool transparency = false;
- SigSpec addr_sig =cell->getPort("\\WR_ADDR").extract(i*abits, abits);
+ SigSpec addr_sig =cell->getPort(ID::WR_ADDR).extract(i*abits, abits);
string addr_expr = make_expr(addr_sig);
- SigSpec data_sig =cell->getPort("\\WR_DATA").extract(i*width, width);
+ SigSpec data_sig =cell->getPort(ID::WR_DATA).extract(i*width, width);
string data_expr = make_expr(data_sig);
- SigSpec clk_sig = cell->getPort("\\WR_CLK").extract(i);
+ SigSpec clk_sig = cell->getPort(ID::WR_CLK).extract(i);
string clk_expr = make_expr(clk_sig);
- SigSpec wen_sig = cell->getPort("\\WR_EN").extract(i*width, width);
+ SigSpec wen_sig = cell->getPort(ID::WR_EN).extract(i*width, width);
string wen_expr = make_expr(wen_sig[0]);
for (int i = 1; i < GetSize(wen_sig); i++)
@@ -813,23 +813,23 @@ struct FirrtlWorker
continue;
}
- if (cell->type.in("$memwr", "$memrd", "$meminit"))
+ if (cell->type.in(ID($memwr), ID($memrd), ID($meminit)))
{
std::string cell_type = fid(cell->type);
- std::string mem_id = make_id(cell->parameters["\\MEMID"].decode_string());
- int abits = cell->parameters.at("\\ABITS").as_int();
- int width = cell->parameters.at("\\WIDTH").as_int();
+ std::string mem_id = make_id(cell->parameters[ID::MEMID].decode_string());
+ int abits = cell->parameters.at(ID::ABITS).as_int();
+ int width = cell->parameters.at(ID::WIDTH).as_int();
memory *mp = nullptr;
- if (cell->type == "$meminit" ) {
+ if (cell->type == ID($meminit) ) {
log_error("$meminit (%s.%s.%s) currently unsupported\n", log_id(module), log_id(cell), mem_id.c_str());
} else {
// It's a $memwr or $memrd. Remember the read/write port parameters for the eventual FIRRTL memory definition.
- auto addrSig = cell->getPort("\\ADDR");
- auto dataSig = cell->getPort("\\DATA");
- auto enableSig = cell->getPort("\\EN");
- auto clockSig = cell->getPort("\\CLK");
- Const clk_enable = cell->parameters.at("\\CLK_ENABLE");
- Const clk_polarity = cell->parameters.at("\\CLK_POLARITY");
+ auto addrSig = cell->getPort(ID::ADDR);
+ auto dataSig = cell->getPort(ID::DATA);
+ auto enableSig = cell->getPort(ID::EN);
+ auto clockSig = cell->getPort(ID::CLK);
+ Const clk_enable = cell->parameters.at(ID::CLK_ENABLE);
+ Const clk_polarity = cell->parameters.at(ID::CLK_POLARITY);
// Do we already have an entry for this memory?
if (memories.count(mem_id) == 0) {
@@ -840,13 +840,13 @@ struct FirrtlWorker
int portNum = 0;
bool transparency = false;
string data_expr = make_expr(dataSig);
- if (cell->type.in("$memwr")) {
+ if (cell->type.in(ID($memwr))) {
portNum = (int) mp->write_ports.size();
write_port wp(stringf("%s.w%d", mem_id.c_str(), portNum), clk_enable.as_bool(), clk_polarity.as_bool(), transparency, clockSig, enableSig, addrSig, dataSig);
mp->add_memory_write_port(wp);
cell_exprs.push_back(stringf("%s%s.data <= %s\n", indent.c_str(), wp.name.c_str(), data_expr.c_str()));
cell_exprs.push_back(wp.gen_write(indent.c_str()));
- } else if (cell->type.in("$memrd")) {
+ } else if (cell->type.in(ID($memrd))) {
portNum = (int) mp->read_ports.size();
read_port rp(stringf("%s.r%d", mem_id.c_str(), portNum), clk_enable.as_bool(), clk_polarity.as_bool(), transparency, clockSig, enableSig, addrSig);
mp->add_memory_read_port(rp);
@@ -857,20 +857,20 @@ struct FirrtlWorker
continue;
}
- if (cell->type.in("$dff"))
+ if (cell->type.in(ID($dff)))
{
- bool clkpol = cell->parameters.at("\\CLK_POLARITY").as_bool();
+ bool clkpol = cell->parameters.at(ID::CLK_POLARITY).as_bool();
if (clkpol == false)
log_error("Negative edge clock on FF %s.%s.\n", log_id(module), log_id(cell));
- int width = cell->parameters.at("\\WIDTH").as_int();
- string expr = make_expr(cell->getPort("\\D"));
- string clk_expr = "asClock(" + make_expr(cell->getPort("\\CLK")) + ")";
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ string expr = make_expr(cell->getPort(ID::D));
+ string clk_expr = "asClock(" + make_expr(cell->getPort(ID::CLK)) + ")";
wire_decls.push_back(stringf(" reg %s: UInt<%d>, %s\n", y_id.c_str(), width, clk_expr.c_str()));
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
- register_reverse_wire_map(y_id, cell->getPort("\\Q"));
+ register_reverse_wire_map(y_id, cell->getPort(ID::Q));
continue;
}
@@ -881,38 +881,38 @@ struct FirrtlWorker
process_instance(cell, wire_exprs);
continue;
}
- if (cell->type == "$shiftx") {
+ if (cell->type == ID($shiftx)) {
// assign y = a[b +: y_width];
// We'll extract the correct bits as part of the primop.
- string a_expr = make_expr(cell->getPort("\\A"));
+ string a_expr = make_expr(cell->getPort(ID::A));
// Get the initial bit selector
- string b_expr = make_expr(cell->getPort("\\B"));
+ string b_expr = make_expr(cell->getPort(ID::B));
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
- if (cell->getParam("\\B_SIGNED").as_bool()) {
+ if (cell->getParam(ID::B_SIGNED).as_bool()) {
// Use validif to constrain the selection (test the sign bit)
auto b_string = b_expr.c_str();
- int b_sign = cell->parameters.at("\\B_WIDTH").as_int() - 1;
+ int b_sign = cell->parameters.at(ID::B_WIDTH).as_int() - 1;
b_expr = stringf("validif(not(bits(%s, %d, %d)), %s)", b_string, b_sign, b_sign, b_string);
}
string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
- register_reverse_wire_map(y_id, cell->getPort("\\Y"));
+ register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
- if (cell->type == "$shift") {
+ if (cell->type == ID($shift)) {
// assign y = a >> b;
// where b may be negative
- string a_expr = make_expr(cell->getPort("\\A"));
- string b_expr = make_expr(cell->getPort("\\B"));
+ string a_expr = make_expr(cell->getPort(ID::A));
+ string b_expr = make_expr(cell->getPort(ID::B));
auto b_string = b_expr.c_str();
string expr;
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
- if (cell->getParam("\\B_SIGNED").as_bool()) {
+ if (cell->getParam(ID::B_SIGNED).as_bool()) {
// We generate a left or right shift based on the sign of b.
std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr.c_str(), gen_dshl(b_expr, b_width).c_str(), y_width);
std::string dshr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
@@ -925,13 +925,13 @@ struct FirrtlWorker
expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
}
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
- register_reverse_wire_map(y_id, cell->getPort("\\Y"));
+ register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
- if (cell->type == "$pos") {
+ if (cell->type == ID($pos)) {
// assign y = a;
// printCell(cell);
- string a_expr = make_expr(cell->getPort("\\A"));
+ string a_expr = make_expr(cell->getPort(ID::A));
// Verilog appears to treat the result as signed, so if the result is wider than "A",
// we need to pad.
if (a_width < y_width) {
@@ -939,7 +939,7 @@ struct FirrtlWorker
}
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), a_expr.c_str()));
- register_reverse_wire_map(y_id, cell->getPort("\\Y"));
+ register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell));
@@ -1112,7 +1112,7 @@ struct FirrtlBackend : public Backend {
for (auto module : design->modules()) {
make_id(module->name);
last = module;
- if (top == nullptr && module->get_bool_attribute("\\top")) {
+ if (top == nullptr && module->get_bool_attribute(ID::top)) {
top = module;
}
for (auto wire : module->wires())
diff --git a/backends/ilang/ilang_backend.cc b/backends/ilang/ilang_backend.cc
index e06786220..5445fad90 100644
--- a/backends/ilang/ilang_backend.cc
+++ b/backends/ilang/ilang_backend.cc
@@ -358,10 +358,10 @@ void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
if (!flag_m) {
int count_selected_mods = 0;
- for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) {
- if (design->selected_whole_module(it->first))
+ for (auto module : design->modules()) {
+ if (design->selected_whole_module(module->name))
flag_m = true;
- if (design->selected(it->second))
+ if (design->selected(module))
count_selected_mods++;
}
if (count_selected_mods > 1)
@@ -374,11 +374,11 @@ void ILANG_BACKEND::dump_design(std::ostream &f, RTLIL::Design *design, bool onl
f << stringf("autoidx %d\n", autoidx);
}
- for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) {
- if (!only_selected || design->selected(it->second)) {
+ for (auto module : design->modules()) {
+ if (!only_selected || design->selected(module)) {
if (only_selected)
f << stringf("\n");
- dump_module(f, "", it->second, design, only_selected, flag_m, flag_n);
+ dump_module(f, "", module, design, only_selected, flag_m, flag_n);
}
}
diff --git a/backends/intersynth/intersynth.cc b/backends/intersynth/intersynth.cc
index 809a0fa09..31dce1cca 100644
--- a/backends/intersynth/intersynth.cc
+++ b/backends/intersynth/intersynth.cc
@@ -122,70 +122,67 @@ struct IntersynthBackend : public Backend {
for (auto lib : libs)
ct.setup_design(lib);
- for (auto module_it : design->modules_)
+ for (auto module : design->modules())
{
- RTLIL::Module *module = module_it.second;
SigMap sigmap(module);
if (module->get_blackbox_attribute())
continue;
- if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells_.size() == 0)
+ if (module->memories.size() == 0 && module->processes.size() == 0 && module->cells().size() == 0)
continue;
if (selected && !design->selected_whole_module(module->name)) {
if (design->selected_module(module->name))
- log_cmd_error("Can't handle partially selected module %s!\n", RTLIL::id2cstr(module->name));
+ log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name));
continue;
}
- log("Generating netlist %s.\n", RTLIL::id2cstr(module->name));
+ log("Generating netlist %s.\n", log_id(module->name));
if (module->memories.size() != 0 || module->processes.size() != 0)
log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n");
std::set<std::string> constcells_code;
- netlists_code += stringf("# Netlist of module %s\n", RTLIL::id2cstr(module->name));
- netlists_code += stringf("netlist %s\n", RTLIL::id2cstr(module->name));
+ netlists_code += stringf("# Netlist of module %s\n", log_id(module->name));
+ netlists_code += stringf("netlist %s\n", log_id(module->name));
// Module Ports: "std::set<string> celltypes_code" prevents duplicate top level ports
- for (auto wire_it : module->wires_) {
- RTLIL::Wire *wire = wire_it.second;
+ for (auto wire : module->wires()) {
if (wire->port_input || wire->port_output) {
celltypes_code.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n",
- RTLIL::id2cstr(wire->name), wire->width, wire->port_input ? "*" : "",
- wire->port_input ? "input" : "output", RTLIL::id2cstr(wire->name), wire->width, RTLIL::id2cstr(wire->name)));
- netlists_code += stringf("node %s %s PORT %s\n", RTLIL::id2cstr(wire->name), RTLIL::id2cstr(wire->name),
+ log_id(wire->name), wire->width, wire->port_input ? "*" : "",
+ wire->port_input ? "input" : "output", log_id(wire->name), wire->width, log_id(wire->name)));
+ netlists_code += stringf("node %s %s PORT %s\n", log_id(wire->name), log_id(wire->name),
netname(conntypes_code, celltypes_code, constcells_code, sigmap(wire)).c_str());
}
}
// Submodules: "std::set<string> celltypes_code" prevents duplicate cell types
- for (auto cell_it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = cell_it.second;
std::string celltype_code, node_code;
if (!ct.cell_known(cell->type))
- log_error("Found unknown cell type %s in module!\n", RTLIL::id2cstr(cell->type));
+ log_error("Found unknown cell type %s in module!\n", log_id(cell->type));
- celltype_code = stringf("celltype %s", RTLIL::id2cstr(cell->type));
- node_code = stringf("node %s %s", RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
+ celltype_code = stringf("celltype %s", log_id(cell->type));
+ node_code = stringf("node %s %s", log_id(cell->name), log_id(cell->type));
for (auto &port : cell->connections()) {
RTLIL::SigSpec sig = sigmap(port.second);
if (sig.size() != 0) {
conntypes_code.insert(stringf("conntype b%d %d 2 %d\n", sig.size(), sig.size(), sig.size()));
- celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", RTLIL::id2cstr(port.first));
- node_code += stringf(" %s %s", RTLIL::id2cstr(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str());
+ celltype_code += stringf(" b%d %s%s", sig.size(), ct.cell_output(cell->type, port.first) ? "*" : "", log_id(port.first));
+ node_code += stringf(" %s %s", log_id(port.first), netname(conntypes_code, celltypes_code, constcells_code, sig).c_str());
}
}
for (auto &param : cell->parameters) {
- celltype_code += stringf(" cfg:%d %s", int(param.second.bits.size()), RTLIL::id2cstr(param.first));
+ celltype_code += stringf(" cfg:%d %s", int(param.second.bits.size()), log_id(param.first));
if (param.second.bits.size() != 32) {
- node_code += stringf(" %s '", RTLIL::id2cstr(param.first));
+ node_code += stringf(" %s '", log_id(param.first));
for (int i = param.second.bits.size()-1; i >= 0; i--)
node_code += param.second.bits[i] == State::S1 ? "1" : "0";
} else
- node_code += stringf(" %s 0x%x", RTLIL::id2cstr(param.first), param.second.as_int());
+ node_code += stringf(" %s 0x%x", log_id(param.first), param.second.as_int());
}
celltypes_code.insert(celltype_code + "\n");
diff --git a/backends/json/json.cc b/backends/json/json.cc
index 6c924ff99..1da23bb7d 100644
--- a/backends/json/json.cc
+++ b/backends/json/json.cc
@@ -303,8 +303,13 @@ struct JsonBackend : public Backend {
log("The general syntax of the JSON output created by this command is as follows:\n");
log("\n");
log(" {\n");
+ log(" \"creator\": \"Yosys <version info>\",\n");
log(" \"modules\": {\n");
log(" <module_name>: {\n");
+ log(" \"attributes\": {\n");
+ log(" <attribute_name>: <attribute_value>,\n");
+ log(" ...\n");
+ log(" },\n");
log(" \"ports\": {\n");
log(" <port_name>: <port_details>,\n");
log(" ...\n");
@@ -329,13 +334,19 @@ struct JsonBackend : public Backend {
log(" {\n");
log(" \"direction\": <\"input\" | \"output\" | \"inout\">,\n");
log(" \"bits\": <bit_vector>\n");
+ log(" \"offset\": <the lowest bit index in use, if non-0>\n");
+ log(" \"upto\": <1 if the port bit indexing is MSB-first>\n");
log(" }\n");
log("\n");
+ log("The \"offset\" and \"upto\" fields are skipped if their value would be 0.");
+ log("They don't affect connection semantics, and are only used to preserve original");
+ log("HDL bit indexing.");
log("And <cell_details> is:\n");
log("\n");
log(" {\n");
log(" \"hide_name\": <1 | 0>,\n");
log(" \"type\": <cell_type>,\n");
+ log(" \"model\": <AIG model name, if -aig option used>,\n");
log(" \"parameters\": {\n");
log(" <parameter_name>: <parameter_value>,\n");
log(" ...\n");
@@ -359,6 +370,8 @@ struct JsonBackend : public Backend {
log(" {\n");
log(" \"hide_name\": <1 | 0>,\n");
log(" \"bits\": <bit_vector>\n");
+ log(" \"offset\": <the lowest bit index in use, if non-0>\n");
+ log(" \"upto\": <1 if the port bit indexing is MSB-first>\n");
log(" }\n");
log("\n");
log("The \"hide_name\" fields are set to 1 when the name of this cell or net is\n");
@@ -386,9 +399,15 @@ struct JsonBackend : public Backend {
log("\n");
log("Translates to the following JSON output:\n");
log("\n");
+
log(" {\n");
+ log(" \"creator\": \"Yosys 0.9+2406 (git sha1 fb1168d8, clang 9.0.1 -fPIC -Os)\",\n");
log(" \"modules\": {\n");
log(" \"test\": {\n");
+ log(" \"attributes\": {\n");
+ log(" \"cells_not_processed\": \"00000000000000000000000000000001\",\n");
+ log(" \"src\": \"test.v:1.1-4.10\"\n");
+ log(" },\n");
log(" \"ports\": {\n");
log(" \"x\": {\n");
log(" \"direction\": \"input\",\n");
@@ -404,33 +423,34 @@ struct JsonBackend : public Backend {
log(" \"hide_name\": 0,\n");
log(" \"type\": \"foo\",\n");
log(" \"parameters\": {\n");
- log(" \"Q\": 1337,\n");
- log(" \"P\": 42\n");
+ log(" \"P\": \"00000000000000000000000000101010\",\n");
+ log(" \"Q\": \"00000000000000000000010100111001\"\n");
log(" },\n");
log(" \"attributes\": {\n");
- log(" \"keep\": 1,\n");
- log(" \"src\": \"test.v:2\"\n");
+ log(" \"keep\": \"00000000000000000000000000000001\",\n");
+ log(" \"module_not_derived\": \"00000000000000000000000000000001\",\n");
+ log(" \"src\": \"test.v:3.1-3.55\"\n");
log(" },\n");
log(" \"connections\": {\n");
- log(" \"C\": [ 2, 2, 2, 2, \"0\", \"1\", \"0\", \"1\" ],\n");
+ log(" \"A\": [ 3, 2 ],\n");
log(" \"B\": [ 2, 3 ],\n");
- log(" \"A\": [ 3, 2 ]\n");
+ log(" \"C\": [ 2, 2, 2, 2, \"0\", \"1\", \"0\", \"1\" ]\n");
log(" }\n");
log(" }\n");
log(" },\n");
log(" \"netnames\": {\n");
- log(" \"y\": {\n");
+ log(" \"x\": {\n");
log(" \"hide_name\": 0,\n");
- log(" \"bits\": [ 3 ],\n");
+ log(" \"bits\": [ 2 ],\n");
log(" \"attributes\": {\n");
- log(" \"src\": \"test.v:1\"\n");
+ log(" \"src\": \"test.v:1.19-1.20\"\n");
log(" }\n");
log(" },\n");
- log(" \"x\": {\n");
+ log(" \"y\": {\n");
log(" \"hide_name\": 0,\n");
- log(" \"bits\": [ 2 ],\n");
+ log(" \"bits\": [ 3 ],\n");
log(" \"attributes\": {\n");
- log(" \"src\": \"test.v:1\"\n");
+ log(" \"src\": \"test.v:1.22-1.23\"\n");
log(" }\n");
log(" }\n");
log(" }\n");
diff --git a/backends/simplec/simplec.cc b/backends/simplec/simplec.cc
index 54dbb84af..83ed5e6e0 100644
--- a/backends/simplec/simplec.cc
+++ b/backends/simplec/simplec.cc
@@ -378,16 +378,16 @@ struct SimplecWorker
void eval_cell(HierDirtyFlags *work, Cell *cell)
{
- if (cell->type.in("$_BUF_", "$_NOT_"))
+ if (cell->type.in(ID($_BUF_), ID($_NOT_)))
{
- SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
- SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
+ SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
+ SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string expr;
- if (cell->type == "$_BUF_") expr = a_expr;
- if (cell->type == "$_NOT_") expr = "!" + a_expr;
+ if (cell->type == ID($_BUF_)) expr = a_expr;
+ if (cell->type == ID($_NOT_)) expr = "!" + a_expr;
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@@ -397,24 +397,24 @@ struct SimplecWorker
return;
}
- if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
+ if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
{
- SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
- SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
- SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
+ SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
+ SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
+ SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
string expr;
- if (cell->type == "$_AND_") expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
- if (cell->type == "$_NAND_") expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
- if (cell->type == "$_OR_") expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
- if (cell->type == "$_NOR_") expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
- if (cell->type == "$_XOR_") expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
- if (cell->type == "$_XNOR_") expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
- if (cell->type == "$_ANDNOT_") expr = stringf("%s & (!%s)", a_expr.c_str(), b_expr.c_str());
- if (cell->type == "$_ORNOT_") expr = stringf("%s | (!%s)", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_AND_)) expr = stringf("%s & %s", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_NAND_)) expr = stringf("!(%s & %s)", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_OR_)) expr = stringf("%s | %s", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_NOR_)) expr = stringf("!(%s | %s)", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_XOR_)) expr = stringf("%s ^ %s", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_XNOR_)) expr = stringf("!(%s ^ %s)", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_ANDNOT_)) expr = stringf("%s & (!%s)", a_expr.c_str(), b_expr.c_str());
+ if (cell->type == ID($_ORNOT_)) expr = stringf("%s | (!%s)", a_expr.c_str(), b_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@@ -424,20 +424,20 @@ struct SimplecWorker
return;
}
- if (cell->type.in("$_AOI3_", "$_OAI3_"))
+ if (cell->type.in(ID($_AOI3_), ID($_OAI3_)))
{
- SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
- SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
- SigBit c = sigmaps.at(work->module)(cell->getPort("\\C"));
- SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
+ SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
+ SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
+ SigBit c = sigmaps.at(work->module)(cell->getPort(ID::C));
+ SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
string c_expr = c.wire ? util_get_bit(work->prefix + cid(c.wire->name), c.wire->width, c.offset) : c.data ? "1" : "0";
string expr;
- if (cell->type == "$_AOI3_") expr = stringf("!((%s & %s) | %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
- if (cell->type == "$_OAI3_") expr = stringf("!((%s | %s) & %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
+ if (cell->type == ID($_AOI3_)) expr = stringf("!((%s & %s) | %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
+ if (cell->type == ID($_OAI3_)) expr = stringf("!((%s | %s) & %s)", a_expr.c_str(), b_expr.c_str(), c_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@@ -447,13 +447,13 @@ struct SimplecWorker
return;
}
- if (cell->type.in("$_AOI4_", "$_OAI4_"))
+ if (cell->type.in(ID($_AOI4_), ID($_OAI4_)))
{
- SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
- SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
- SigBit c = sigmaps.at(work->module)(cell->getPort("\\C"));
- SigBit d = sigmaps.at(work->module)(cell->getPort("\\D"));
- SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
+ SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
+ SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
+ SigBit c = sigmaps.at(work->module)(cell->getPort(ID::C));
+ SigBit d = sigmaps.at(work->module)(cell->getPort(ID::D));
+ SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
@@ -461,8 +461,8 @@ struct SimplecWorker
string d_expr = d.wire ? util_get_bit(work->prefix + cid(d.wire->name), d.wire->width, d.offset) : d.data ? "1" : "0";
string expr;
- if (cell->type == "$_AOI4_") expr = stringf("!((%s & %s) | (%s & %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
- if (cell->type == "$_OAI4_") expr = stringf("!((%s | %s) & (%s | %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
+ if (cell->type == ID($_AOI4_)) expr = stringf("!((%s & %s) | (%s & %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
+ if (cell->type == ID($_OAI4_)) expr = stringf("!((%s | %s) & (%s | %s))", a_expr.c_str(), b_expr.c_str(), c_expr.c_str(), d_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@@ -472,12 +472,12 @@ struct SimplecWorker
return;
}
- if (cell->type.in("$_MUX_", "$_NMUX_"))
+ if (cell->type.in(ID($_MUX_), ID($_NMUX_)))
{
- SigBit a = sigmaps.at(work->module)(cell->getPort("\\A"));
- SigBit b = sigmaps.at(work->module)(cell->getPort("\\B"));
- SigBit s = sigmaps.at(work->module)(cell->getPort("\\S"));
- SigBit y = sigmaps.at(work->module)(cell->getPort("\\Y"));
+ SigBit a = sigmaps.at(work->module)(cell->getPort(ID::A));
+ SigBit b = sigmaps.at(work->module)(cell->getPort(ID::B));
+ SigBit s = sigmaps.at(work->module)(cell->getPort(ID::S));
+ SigBit y = sigmaps.at(work->module)(cell->getPort(ID::Y));
string a_expr = a.wire ? util_get_bit(work->prefix + cid(a.wire->name), a.wire->width, a.offset) : a.data ? "1" : "0";
string b_expr = b.wire ? util_get_bit(work->prefix + cid(b.wire->name), b.wire->width, b.offset) : b.data ? "1" : "0";
@@ -485,8 +485,8 @@ struct SimplecWorker
// casts to bool are a workaround for CBMC bug (https://github.com/diffblue/cbmc/issues/933)
string expr = stringf("%s ? %s(bool)%s : %s(bool)%s", s_expr.c_str(),
- cell->type == "$_NMUX_" ? "!" : "", b_expr.c_str(),
- cell->type == "$_NMUX_" ? "!" : "", a_expr.c_str());
+ cell->type == ID($_NMUX_) ? "!" : "", b_expr.c_str(),
+ cell->type == ID($_NMUX_) ? "!" : "", a_expr.c_str());
log_assert(y.wire);
funct_declarations.push_back(util_set_bit(work->prefix + cid(y.wire->name), y.wire->width, y.offset, expr) +
@@ -653,10 +653,10 @@ struct SimplecWorker
for (Wire *w : module->wires())
{
- if (w->attributes.count("\\init"))
+ if (w->attributes.count(ID::init))
{
SigSpec sig = sigmaps.at(module)(w);
- Const val = w->attributes.at("\\init");
+ Const val = w->attributes.at(ID::init);
val.bits.resize(GetSize(sig), State::Sx);
for (int i = 0; i < GetSize(sig); i++)
diff --git a/backends/smt2/Makefile.inc b/backends/smt2/Makefile.inc
index 68394a909..fb01308bd 100644
--- a/backends/smt2/Makefile.inc
+++ b/backends/smt2/Makefile.inc
@@ -6,23 +6,23 @@ ifneq ($(CONFIG),emcc)
# MSYS targets support yosys-smtbmc, but require a launcher script
ifeq ($(CONFIG),$(filter $(CONFIG),msys2 msys2-64))
-TARGETS += yosys-smtbmc.exe yosys-smtbmc-script.py
+TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc.exe $(PROGRAM_PREFIX)yosys-smtbmc-script.py
# Needed to find the Python interpreter for yosys-smtbmc scripts.
# Override if necessary, it is only used for msys2 targets.
PYTHON := $(shell cygpath -w -m $(PREFIX)/bin/python3)
-yosys-smtbmc-script.py: backends/smt2/smtbmc.py
- $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/yosys/python3"]]|;' \
+$(PROGRAM_PREFIX)yosys-smtbmc-script.py: backends/smt2/smtbmc.py
+ $(P) sed -e 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' \
-e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@
-yosys-smtbmc.exe: misc/launcher.c yosys-smtbmc-script.py
+$(PROGRAM_PREFIX)yosys-smtbmc.exe: misc/launcher.c $(PROGRAM_PREFIX)yosys-smtbmc-script.py
$(P) $(CXX) -DGUI=0 -O -s -o $@ $<
# Other targets
else
-TARGETS += yosys-smtbmc
+TARGETS += $(PROGRAM_PREFIX)yosys-smtbmc
-yosys-smtbmc: backends/smt2/smtbmc.py
- $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/yosys/python3"]]|;' < $< > $@.new
+$(PROGRAM_PREFIX)yosys-smtbmc: backends/smt2/smtbmc.py
+ $(P) sed 's|##yosys-sys-path##|sys.path += [os.path.dirname(os.path.realpath(__file__)) + p for p in ["/share/python3", "/../share/$(PROGRAM_PREFIX)yosys/python3"]]|;' < $< > $@.new
$(Q) chmod +x $@.new
$(Q) mv $@.new $@
endif
diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc
index 628765831..3e67e55f2 100644
--- a/backends/smt2/smt2.cc
+++ b/backends/smt2/smt2.cc
@@ -135,7 +135,7 @@ struct Smt2Worker
log_error("Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n",
log_id(conn.first), log_id(module), log_id(cell), log_id(cell->type));
- if (cell->type.in("$mem") && conn.first.in("\\RD_CLK", "\\WR_CLK"))
+ if (cell->type.in(ID($mem)) && conn.first.in(ID::RD_CLK, ID::WR_CLK))
{
SigSpec clk = sigmap(conn.second);
for (int i = 0; i < GetSize(clk); i++)
@@ -143,19 +143,19 @@ struct Smt2Worker
if (clk[i].wire == nullptr)
continue;
- if (cell->getParam(conn.first == "\\RD_CLK" ? "\\RD_CLK_ENABLE" : "\\WR_CLK_ENABLE")[i] != State::S1)
+ if (cell->getParam(conn.first == ID::RD_CLK ? ID::RD_CLK_ENABLE : ID::WR_CLK_ENABLE)[i] != State::S1)
continue;
- if (cell->getParam(conn.first == "\\RD_CLK" ? "\\RD_CLK_POLARITY" : "\\WR_CLK_POLARITY")[i] == State::S1)
+ if (cell->getParam(conn.first == ID::RD_CLK ? ID::RD_CLK_POLARITY : ID::WR_CLK_POLARITY)[i] == State::S1)
clock_posedge.insert(clk[i]);
else
clock_negedge.insert(clk[i]);
}
}
else
- if (cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_") && conn.first.in("\\CLK", "\\C"))
+ if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_)) && conn.first.in(ID::CLK, ID::C))
{
- bool posedge = (cell->type == "$_DFF_N_") || (cell->type == "$dff" && cell->getParam("\\CLK_POLARITY").as_bool());
+ bool posedge = (cell->type == ID($_DFF_N_)) || (cell->type == ID($dff) && cell->getParam(ID::CLK_POLARITY).as_bool());
for (auto bit : sigmap(conn.second)) {
if (posedge)
clock_posedge.insert(bit);
@@ -367,15 +367,15 @@ struct Smt2Worker
void export_gate(RTLIL::Cell *cell, std::string expr)
{
- RTLIL::SigBit bit = sigmap(cell->getPort("\\Y").as_bit());
+ RTLIL::SigBit bit = sigmap(cell->getPort(ID::Y).as_bit());
std::string processed_expr;
for (char ch : expr) {
- if (ch == 'A') processed_expr += get_bool(cell->getPort("\\A"));
- else if (ch == 'B') processed_expr += get_bool(cell->getPort("\\B"));
- else if (ch == 'C') processed_expr += get_bool(cell->getPort("\\C"));
- else if (ch == 'D') processed_expr += get_bool(cell->getPort("\\D"));
- else if (ch == 'S') processed_expr += get_bool(cell->getPort("\\S"));
+ if (ch == 'A') processed_expr += get_bool(cell->getPort(ID::A));
+ else if (ch == 'B') processed_expr += get_bool(cell->getPort(ID::B));
+ else if (ch == 'C') processed_expr += get_bool(cell->getPort(ID::C));
+ else if (ch == 'D') processed_expr += get_bool(cell->getPort(ID::D));
+ else if (ch == 'S') processed_expr += get_bool(cell->getPort(ID::S));
else processed_expr += ch;
}
@@ -391,23 +391,23 @@ struct Smt2Worker
void export_bvop(RTLIL::Cell *cell, std::string expr, char type = 0)
{
RTLIL::SigSpec sig_a, sig_b;
- RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y"));
- bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
+ RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y));
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
int width = GetSize(sig_y);
if (type == 's' || type == 'd' || type == 'b') {
- width = max(width, GetSize(cell->getPort("\\A")));
- if (cell->hasPort("\\B"))
- width = max(width, GetSize(cell->getPort("\\B")));
+ width = max(width, GetSize(cell->getPort(ID::A)));
+ if (cell->hasPort(ID::B))
+ width = max(width, GetSize(cell->getPort(ID::B)));
}
- if (cell->hasPort("\\A")) {
- sig_a = cell->getPort("\\A");
+ if (cell->hasPort(ID::A)) {
+ sig_a = cell->getPort(ID::A);
sig_a.extend_u0(width, is_signed);
}
- if (cell->hasPort("\\B")) {
- sig_b = cell->getPort("\\B");
+ if (cell->hasPort(ID::B)) {
+ sig_b = cell->getPort(ID::B);
sig_b.extend_u0(width, is_signed && !(type == 's'));
}
@@ -416,7 +416,7 @@ struct Smt2Worker
for (char ch : expr) {
if (ch == 'A') processed_expr += get_bv(sig_a);
else if (ch == 'B') processed_expr += get_bv(sig_b);
- else if (ch == 'P') processed_expr += get_bv(cell->getPort("\\B"));
+ else if (ch == 'P') processed_expr += get_bv(cell->getPort(ID::B));
else if (ch == 'L') processed_expr += is_signed ? "a" : "l";
else if (ch == 'U') processed_expr += is_signed ? "s" : "u";
else processed_expr += ch;
@@ -443,7 +443,7 @@ struct Smt2Worker
void export_reduce(RTLIL::Cell *cell, std::string expr, bool identity_val)
{
- RTLIL::SigSpec sig_y = sigmap(cell->getPort("\\Y"));
+ RTLIL::SigSpec sig_y = sigmap(cell->getPort(ID::Y));
std::string processed_expr;
for (char ch : expr)
@@ -480,9 +480,9 @@ struct Smt2Worker
exported_cells.insert(cell);
recursive_cells.insert(cell);
- if (cell->type == "$initstate")
+ if (cell->type == ID($initstate))
{
- SigBit bit = sigmap(cell->getPort("\\Y").as_bit());
+ SigBit bit = sigmap(cell->getPort(ID::Y).as_bit());
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) Bool (|%s_is| state)) ; %s\n",
get_id(module), idcounter, get_id(module), get_id(module), log_signal(bit)));
register_bool(bit, idcounter++);
@@ -490,132 +490,132 @@ struct Smt2Worker
return;
}
- if (cell->type.in("$_FF_", "$_DFF_P_", "$_DFF_N_"))
+ if (cell->type.in(ID($_FF_), ID($_DFF_P_), ID($_DFF_N_)))
{
registers.insert(cell);
- makebits(stringf("%s#%d", get_id(module), idcounter), 0, log_signal(cell->getPort("\\Q")));
- register_bool(cell->getPort("\\Q"), idcounter++);
+ makebits(stringf("%s#%d", get_id(module), idcounter), 0, log_signal(cell->getPort(ID::Q)));
+ register_bool(cell->getPort(ID::Q), idcounter++);
recursive_cells.erase(cell);
return;
}
- if (cell->type == "$_BUF_") return export_gate(cell, "A");
- if (cell->type == "$_NOT_") return export_gate(cell, "(not A)");
- if (cell->type == "$_AND_") return export_gate(cell, "(and A B)");
- if (cell->type == "$_NAND_") return export_gate(cell, "(not (and A B))");
- if (cell->type == "$_OR_") return export_gate(cell, "(or A B)");
- if (cell->type == "$_NOR_") return export_gate(cell, "(not (or A B))");
- if (cell->type == "$_XOR_") return export_gate(cell, "(xor A B)");
- if (cell->type == "$_XNOR_") return export_gate(cell, "(not (xor A B))");
- if (cell->type == "$_ANDNOT_") return export_gate(cell, "(and A (not B))");
- if (cell->type == "$_ORNOT_") return export_gate(cell, "(or A (not B))");
- if (cell->type == "$_MUX_") return export_gate(cell, "(ite S B A)");
- if (cell->type == "$_NMUX_") return export_gate(cell, "(not (ite S B A))");
- if (cell->type == "$_AOI3_") return export_gate(cell, "(not (or (and A B) C))");
- if (cell->type == "$_OAI3_") return export_gate(cell, "(not (and (or A B) C))");
- if (cell->type == "$_AOI4_") return export_gate(cell, "(not (or (and A B) (and C D)))");
- if (cell->type == "$_OAI4_") return export_gate(cell, "(not (and (or A B) (or C D)))");
+ if (cell->type == ID($_BUF_)) return export_gate(cell, "A");
+ if (cell->type == ID($_NOT_)) return export_gate(cell, "(not A)");
+ if (cell->type == ID($_AND_)) return export_gate(cell, "(and A B)");
+ if (cell->type == ID($_NAND_)) return export_gate(cell, "(not (and A B))");
+ if (cell->type == ID($_OR_)) return export_gate(cell, "(or A B)");
+ if (cell->type == ID($_NOR_)) return export_gate(cell, "(not (or A B))");
+ if (cell->type == ID($_XOR_)) return export_gate(cell, "(xor A B)");
+ if (cell->type == ID($_XNOR_)) return export_gate(cell, "(not (xor A B))");
+ if (cell->type == ID($_ANDNOT_)) return export_gate(cell, "(and A (not B))");
+ if (cell->type == ID($_ORNOT_)) return export_gate(cell, "(or A (not B))");
+ if (cell->type == ID($_MUX_)) return export_gate(cell, "(ite S B A)");
+ if (cell->type == ID($_NMUX_)) return export_gate(cell, "(not (ite S B A))");
+ if (cell->type == ID($_AOI3_)) return export_gate(cell, "(not (or (and A B) C))");
+ if (cell->type == ID($_OAI3_)) return export_gate(cell, "(not (and (or A B) C))");
+ if (cell->type == ID($_AOI4_)) return export_gate(cell, "(not (or (and A B) (and C D)))");
+ if (cell->type == ID($_OAI4_)) return export_gate(cell, "(not (and (or A B) (or C D)))");
// FIXME: $lut
if (bvmode)
{
- if (cell->type.in("$ff", "$dff"))
+ if (cell->type.in(ID($ff), ID($dff)))
{
registers.insert(cell);
- makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Q")), log_signal(cell->getPort("\\Q")));
- register_bv(cell->getPort("\\Q"), idcounter++);
+ makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(ID::Q)), log_signal(cell->getPort(ID::Q)));
+ register_bv(cell->getPort(ID::Q), idcounter++);
recursive_cells.erase(cell);
return;
}
- if (cell->type.in("$anyconst", "$anyseq", "$allconst", "$allseq"))
+ if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq)))
{
registers.insert(cell);
- string infostr = cell->attributes.count("\\src") ? cell->attributes.at("\\src").decode_string().c_str() : get_id(cell);
- if (cell->attributes.count("\\reg"))
- infostr += " " + cell->attributes.at("\\reg").decode_string();
- decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort("\\Y")), infostr.c_str()));
- if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\maximize")){
+ string infostr = cell->attributes.count(ID::src) ? cell->attributes.at(ID::src).decode_string().c_str() : get_id(cell);
+ if (cell->attributes.count(ID::reg))
+ infostr += " " + cell->attributes.at(ID::reg).decode_string();
+ decls.push_back(stringf("; yosys-smt2-%s %s#%d %d %s\n", cell->type.c_str() + 1, get_id(module), idcounter, GetSize(cell->getPort(ID::Y)), infostr.c_str()));
+ if (cell->getPort(ID::Y).is_wire() && cell->getPort(ID::Y).as_wire()->get_bool_attribute(ID::maximize)){
decls.push_back(stringf("; yosys-smt2-maximize %s#%d\n", get_id(module), idcounter));
- log("Wire %s is maximized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
+ log("Wire %s is maximized\n", cell->getPort(ID::Y).as_wire()->name.str().c_str());
}
- else if (cell->getPort("\\Y").is_wire() && cell->getPort("\\Y").as_wire()->get_bool_attribute("\\minimize")){
+ else if (cell->getPort(ID::Y).is_wire() && cell->getPort(ID::Y).as_wire()->get_bool_attribute(ID::minimize)){
decls.push_back(stringf("; yosys-smt2-minimize %s#%d\n", get_id(module), idcounter));
- log("Wire %s is minimized\n", cell->getPort("\\Y").as_wire()->name.str().c_str());
+ log("Wire %s is minimized\n", cell->getPort(ID::Y).as_wire()->name.str().c_str());
}
- makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort("\\Y")), log_signal(cell->getPort("\\Y")));
- if (cell->type == "$anyseq")
+ makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(ID::Y)), log_signal(cell->getPort(ID::Y)));
+ if (cell->type == ID($anyseq))
ex_input_eq.push_back(stringf(" (= (|%s#%d| state) (|%s#%d| other_state))", get_id(module), idcounter, get_id(module), idcounter));
- register_bv(cell->getPort("\\Y"), idcounter++);
+ register_bv(cell->getPort(ID::Y), idcounter++);
recursive_cells.erase(cell);
return;
}
- if (cell->type == "$and") return export_bvop(cell, "(bvand A B)");
- if (cell->type == "$or") return export_bvop(cell, "(bvor A B)");
- if (cell->type == "$xor") return export_bvop(cell, "(bvxor A B)");
- if (cell->type == "$xnor") return export_bvop(cell, "(bvxnor A B)");
+ if (cell->type == ID($and)) return export_bvop(cell, "(bvand A B)");
+ if (cell->type == ID($or)) return export_bvop(cell, "(bvor A B)");
+ if (cell->type == ID($xor)) return export_bvop(cell, "(bvxor A B)");
+ if (cell->type == ID($xnor)) return export_bvop(cell, "(bvxnor A B)");
- if (cell->type == "$shl") return export_bvop(cell, "(bvshl A B)", 's');
- if (cell->type == "$shr") return export_bvop(cell, "(bvlshr A B)", 's');
- if (cell->type == "$sshl") return export_bvop(cell, "(bvshl A B)", 's');
- if (cell->type == "$sshr") return export_bvop(cell, "(bvLshr A B)", 's');
+ if (cell->type == ID($shl)) return export_bvop(cell, "(bvshl A B)", 's');
+ if (cell->type == ID($shr)) return export_bvop(cell, "(bvlshr A B)", 's');
+ if (cell->type == ID($sshl)) return export_bvop(cell, "(bvshl A B)", 's');
+ if (cell->type == ID($sshr)) return export_bvop(cell, "(bvLshr A B)", 's');
- if (cell->type.in("$shift", "$shiftx")) {
- if (cell->getParam("\\B_SIGNED").as_bool()) {
+ if (cell->type.in(ID($shift), ID($shiftx))) {
+ if (cell->getParam(ID::B_SIGNED).as_bool()) {
return export_bvop(cell, stringf("(ite (bvsge P #b%0*d) "
"(bvlshr A B) (bvlshr A (bvneg B)))",
- GetSize(cell->getPort("\\B")), 0), 's');
+ GetSize(cell->getPort(ID::B)), 0), 's');
} else {
return export_bvop(cell, "(bvlshr A B)", 's');
}
}
- if (cell->type == "$lt") return export_bvop(cell, "(bvUlt A B)", 'b');
- if (cell->type == "$le") return export_bvop(cell, "(bvUle A B)", 'b');
- if (cell->type == "$ge") return export_bvop(cell, "(bvUge A B)", 'b');
- if (cell->type == "$gt") return export_bvop(cell, "(bvUgt A B)", 'b');
-
- if (cell->type == "$ne") return export_bvop(cell, "(distinct A B)", 'b');
- if (cell->type == "$nex") return export_bvop(cell, "(distinct A B)", 'b');
- if (cell->type == "$eq") return export_bvop(cell, "(= A B)", 'b');
- if (cell->type == "$eqx") return export_bvop(cell, "(= A B)", 'b');
-
- if (cell->type == "$not") return export_bvop(cell, "(bvnot A)");
- if (cell->type == "$pos") return export_bvop(cell, "A");
- if (cell->type == "$neg") return export_bvop(cell, "(bvneg A)");
-
- if (cell->type == "$add") return export_bvop(cell, "(bvadd A B)");
- if (cell->type == "$sub") return export_bvop(cell, "(bvsub A B)");
- if (cell->type == "$mul") return export_bvop(cell, "(bvmul A B)");
- if (cell->type == "$div") return export_bvop(cell, "(bvUdiv A B)", 'd');
- if (cell->type == "$mod") return export_bvop(cell, "(bvUrem A B)", 'd');
-
- if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool") &&
- 2*GetSize(cell->getPort("\\A").chunks()) < GetSize(cell->getPort("\\A"))) {
- bool is_and = cell->type == "$reduce_and";
- string bits(GetSize(cell->getPort("\\A")), is_and ? '1' : '0');
+ if (cell->type == ID($lt)) return export_bvop(cell, "(bvUlt A B)", 'b');
+ if (cell->type == ID($le)) return export_bvop(cell, "(bvUle A B)", 'b');
+ if (cell->type == ID($ge)) return export_bvop(cell, "(bvUge A B)", 'b');
+ if (cell->type == ID($gt)) return export_bvop(cell, "(bvUgt A B)", 'b');
+
+ if (cell->type == ID($ne)) return export_bvop(cell, "(distinct A B)", 'b');
+ if (cell->type == ID($nex)) return export_bvop(cell, "(distinct A B)", 'b');
+ if (cell->type == ID($eq)) return export_bvop(cell, "(= A B)", 'b');
+ if (cell->type == ID($eqx)) return export_bvop(cell, "(= A B)", 'b');
+
+ if (cell->type == ID($not)) return export_bvop(cell, "(bvnot A)");
+ if (cell->type == ID($pos)) return export_bvop(cell, "A");
+ if (cell->type == ID($neg)) return export_bvop(cell, "(bvneg A)");
+
+ if (cell->type == ID($add)) return export_bvop(cell, "(bvadd A B)");
+ if (cell->type == ID($sub)) return export_bvop(cell, "(bvsub A B)");
+ if (cell->type == ID($mul)) return export_bvop(cell, "(bvmul A B)");
+ if (cell->type == ID($div)) return export_bvop(cell, "(bvUdiv A B)", 'd');
+ if (cell->type == ID($mod)) return export_bvop(cell, "(bvUrem A B)", 'd');
+
+ if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool)) &&
+ 2*GetSize(cell->getPort(ID::A).chunks()) < GetSize(cell->getPort(ID::A))) {
+ bool is_and = cell->type == ID($reduce_and);
+ string bits(GetSize(cell->getPort(ID::A)), is_and ? '1' : '0');
return export_bvop(cell, stringf("(%s A #b%s)", is_and ? "=" : "distinct", bits.c_str()), 'b');
}
- if (cell->type == "$reduce_and") return export_reduce(cell, "(and A)", true);
- if (cell->type == "$reduce_or") return export_reduce(cell, "(or A)", false);
- if (cell->type == "$reduce_xor") return export_reduce(cell, "(xor A)", false);
- if (cell->type == "$reduce_xnor") return export_reduce(cell, "(not (xor A))", false);
- if (cell->type == "$reduce_bool") return export_reduce(cell, "(or A)", false);
+ if (cell->type == ID($reduce_and)) return export_reduce(cell, "(and A)", true);
+ if (cell->type == ID($reduce_or)) return export_reduce(cell, "(or A)", false);
+ if (cell->type == ID($reduce_xor)) return export_reduce(cell, "(xor A)", false);
+ if (cell->type == ID($reduce_xnor)) return export_reduce(cell, "(not (xor A))", false);
+ if (cell->type == ID($reduce_bool)) return export_reduce(cell, "(or A)", false);
- if (cell->type == "$logic_not") return export_reduce(cell, "(not (or A))", false);
- if (cell->type == "$logic_and") return export_reduce(cell, "(and (or A) (or B))", false);
- if (cell->type == "$logic_or") return export_reduce(cell, "(or A B)", false);
+ if (cell->type == ID($logic_not)) return export_reduce(cell, "(not (or A))", false);
+ if (cell->type == ID($logic_and)) return export_reduce(cell, "(and (or A) (or B))", false);
+ if (cell->type == ID($logic_or)) return export_reduce(cell, "(or A B)", false);
- if (cell->type.in("$mux", "$pmux"))
+ if (cell->type.in(ID($mux), ID($pmux)))
{
- int width = GetSize(cell->getPort("\\Y"));
- std::string processed_expr = get_bv(cell->getPort("\\A"));
+ int width = GetSize(cell->getPort(ID::Y));
+ std::string processed_expr = get_bv(cell->getPort(ID::A));
- RTLIL::SigSpec sig_b = cell->getPort("\\B");
- RTLIL::SigSpec sig_s = cell->getPort("\\S");
+ RTLIL::SigSpec sig_b = cell->getPort(ID::B);
+ RTLIL::SigSpec sig_s = cell->getPort(ID::S);
get_bv(sig_b);
get_bv(sig_s);
@@ -626,7 +626,7 @@ struct Smt2Worker
if (verbose)
log("%*s-> import cell: %s\n", 2+2*GetSize(recursive_cells), "", log_id(cell));
- RTLIL::SigSpec sig = sigmap(cell->getPort("\\Y"));
+ RTLIL::SigSpec sig = sigmap(cell->getPort(ID::Y));
decls.push_back(stringf("(define-fun |%s#%d| ((state |%s_s|)) (_ BitVec %d) %s) ; %s\n",
get_id(module), idcounter, get_id(module), width, processed_expr.c_str(), log_signal(sig)));
register_bv(sig, idcounter++);
@@ -637,19 +637,19 @@ struct Smt2Worker
// FIXME: $slice $concat
}
- if (memmode && cell->type == "$mem")
+ if (memmode && cell->type == ID($mem))
{
int arrayid = idcounter++;
memarrays[cell] = arrayid;
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
- int rd_ports = cell->getParam("\\RD_PORTS").as_int();
- int wr_ports = cell->getParam("\\WR_PORTS").as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
+ int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
bool async_read = false;
- if (!cell->getParam("\\WR_CLK_ENABLE").is_fully_ones()) {
- if (!cell->getParam("\\WR_CLK_ENABLE").is_fully_zero())
+ if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_ones()) {
+ if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_zero())
log_error("Memory %s.%s has mixed clocked/nonclocked write ports. This is not supported by \"write_smt2\".\n", log_id(cell), log_id(module));
async_read = true;
}
@@ -665,8 +665,8 @@ struct Smt2Worker
if (statebv)
{
- int mem_size = cell->getParam("\\SIZE").as_int();
- int mem_offset = cell->getParam("\\OFFSET").as_int();
+ int mem_size = cell->getParam(ID::SIZE).as_int();
+ int mem_offset = cell->getParam(ID::OFFSET).as_int();
makebits(memstate, width*mem_size, get_id(cell));
decls.push_back(stringf("(define-fun |%s_m %s| ((state |%s_s|)) (_ BitVec %d) (|%s| state))\n",
@@ -674,11 +674,11 @@ struct Smt2Worker
for (int i = 0; i < rd_ports; i++)
{
- SigSpec addr_sig = cell->getPort("\\RD_ADDR").extract(abits*i, abits);
- SigSpec data_sig = cell->getPort("\\RD_DATA").extract(width*i, width);
+ SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(abits*i, abits);
+ SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(width*i, width);
std::string addr = get_bv(addr_sig);
- if (cell->getParam("\\RD_CLK_ENABLE").extract(i).as_bool())
+ if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool())
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module));
@@ -717,11 +717,11 @@ struct Smt2Worker
for (int i = 0; i < rd_ports; i++)
{
- SigSpec addr_sig = cell->getPort("\\RD_ADDR").extract(abits*i, abits);
- SigSpec data_sig = cell->getPort("\\RD_DATA").extract(width*i, width);
+ SigSpec addr_sig = cell->getPort(ID::RD_ADDR).extract(abits*i, abits);
+ SigSpec data_sig = cell->getPort(ID::RD_DATA).extract(width*i, width);
std::string addr = get_bv(addr_sig);
- if (cell->getParam("\\RD_CLK_ENABLE").extract(i).as_bool())
+ if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool())
log_error("Read port %d (%s) of memory %s.%s is clocked. This is not supported by \"write_smt2\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_signal(data_sig), log_id(cell), log_id(module));
@@ -801,9 +801,9 @@ struct Smt2Worker
pool<SigBit> reg_bits;
for (auto cell : module->cells())
- if (cell->type.in("$ff", "$dff", "$_FF_", "$_DFF_P_", "$_DFF_N_")) {
+ if (cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_P_), ID($_DFF_N_))) {
// not using sigmap -- we want the net directly at the dff output
- for (auto bit : cell->getPort("\\Q"))
+ for (auto bit : cell->getPort(ID::Q))
reg_bits.insert(bit);
}
@@ -812,7 +812,7 @@ struct Smt2Worker
for (auto bit : SigSpec(wire))
if (reg_bits.count(bit))
is_register = true;
- if (wire->port_id || is_register || wire->get_bool_attribute("\\keep") || (wiresmode && wire->name[0] == '\\')) {
+ if (wire->port_id || is_register || wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name[0] == '\\')) {
RTLIL::SigSpec sig = sigmap(wire);
if (wire->port_input)
decls.push_back(stringf("; yosys-smt2-input %s %d\n", get_id(wire), wire->width));
@@ -820,7 +820,7 @@ struct Smt2Worker
decls.push_back(stringf("; yosys-smt2-output %s %d\n", get_id(wire), wire->width));
if (is_register)
decls.push_back(stringf("; yosys-smt2-register %s %d\n", get_id(wire), wire->width));
- if (wire->get_bool_attribute("\\keep") || (wiresmode && wire->name[0] == '\\'))
+ if (wire->get_bool_attribute(ID::keep) || (wiresmode && wire->name[0] == '\\'))
decls.push_back(stringf("; yosys-smt2-wire %s %d\n", get_id(wire), wire->width));
if (GetSize(wire) == 1 && (clock_posedge.count(sig) || clock_negedge.count(sig)))
decls.push_back(stringf("; yosys-smt2-clock %s%s%s\n", get_id(wire),
@@ -854,9 +854,9 @@ struct Smt2Worker
vector<string> init_list;
for (auto wire : module->wires())
- if (wire->attributes.count("\\init")) {
+ if (wire->attributes.count(ID::init)) {
RTLIL::SigSpec sig = sigmap(wire);
- Const val = wire->attributes.at("\\init");
+ Const val = wire->attributes.at(ID::init);
val.bits.resize(GetSize(sig), State::Sx);
if (bvmode && GetSize(sig) > 1) {
Const mask(State::S1, GetSize(sig));
@@ -885,31 +885,31 @@ struct Smt2Worker
for (auto cell : module->cells())
{
- if (cell->type.in("$assert", "$assume", "$cover"))
+ if (cell->type.in(ID($assert), ID($assume), ID($cover)))
{
- int &id = cell->type == "$assert" ? assert_id :
- cell->type == "$assume" ? assume_id :
- cell->type == "$cover" ? cover_id : *(int*)nullptr;
+ int &id = cell->type == ID($assert) ? assert_id :
+ cell->type == ID($assume) ? assume_id :
+ cell->type == ID($cover) ? cover_id : *(int*)nullptr;
- char postfix = cell->type == "$assert" ? 'a' :
- cell->type == "$assume" ? 'u' :
- cell->type == "$cover" ? 'c' : 0;
+ char postfix = cell->type == ID($assert) ? 'a' :
+ cell->type == ID($assume) ? 'u' :
+ cell->type == ID($cover) ? 'c' : 0;
- string name_a = get_bool(cell->getPort("\\A"));
- string name_en = get_bool(cell->getPort("\\EN"));
- string infostr = (cell->name[0] == '$' && cell->attributes.count("\\src")) ? cell->attributes.at("\\src").decode_string() : get_id(cell);
+ string name_a = get_bool(cell->getPort(ID::A));
+ string name_en = get_bool(cell->getPort(ID::EN));
+ string infostr = (cell->name[0] == '$' && cell->attributes.count(ID::src)) ? cell->attributes.at(ID::src).decode_string() : get_id(cell);
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, infostr.c_str()));
- if (cell->type == "$cover")
+ if (cell->type == ID($cover))
decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (and %s %s)) ; %s\n",
get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell)));
else
decls.push_back(stringf("(define-fun |%s_%c %d| ((state |%s_s|)) Bool (or %s (not %s))) ; %s\n",
get_id(module), postfix, id, get_id(module), name_a.c_str(), name_en.c_str(), get_id(cell)));
- if (cell->type == "$assert")
+ if (cell->type == ID($assert))
assert_list.push_back(stringf("(|%s_a %d| state)", get_id(module), id));
- else if (cell->type == "$assume")
+ else if (cell->type == ID($assume))
assume_list.push_back(stringf("(|%s_u %d| state)", get_id(module), id));
id++;
@@ -965,44 +965,44 @@ struct Smt2Worker
for (auto cell : this_regs)
{
- if (cell->type.in("$_FF_", "$_DFF_P_", "$_DFF_N_"))
+ if (cell->type.in(ID($_FF_), ID($_DFF_P_), ID($_DFF_N_)))
{
- std::string expr_d = get_bool(cell->getPort("\\D"));
- std::string expr_q = get_bool(cell->getPort("\\Q"), "next_state");
- trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort("\\Q"))));
- ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort("\\Q")).c_str(), get_bool(cell->getPort("\\Q"), "other_state").c_str()));
+ std::string expr_d = get_bool(cell->getPort(ID::D));
+ std::string expr_q = get_bool(cell->getPort(ID::Q), "next_state");
+ trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
+ ex_state_eq.push_back(stringf("(= %s %s)", get_bool(cell->getPort(ID::Q)).c_str(), get_bool(cell->getPort(ID::Q), "other_state").c_str()));
}
- if (cell->type.in("$ff", "$dff"))
+ if (cell->type.in(ID($ff), ID($dff)))
{
- std::string expr_d = get_bv(cell->getPort("\\D"));
- std::string expr_q = get_bv(cell->getPort("\\Q"), "next_state");
- trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort("\\Q"))));
- ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort("\\Q")).c_str(), get_bv(cell->getPort("\\Q"), "other_state").c_str()));
+ std::string expr_d = get_bv(cell->getPort(ID::D));
+ std::string expr_q = get_bv(cell->getPort(ID::Q), "next_state");
+ trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Q))));
+ ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Q)).c_str(), get_bv(cell->getPort(ID::Q), "other_state").c_str()));
}
- if (cell->type.in("$anyconst", "$allconst"))
+ if (cell->type.in(ID($anyconst), ID($allconst)))
{
- std::string expr_d = get_bv(cell->getPort("\\Y"));
- std::string expr_q = get_bv(cell->getPort("\\Y"), "next_state");
- trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort("\\Y"))));
- if (cell->type == "$anyconst")
- ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort("\\Y")).c_str(), get_bv(cell->getPort("\\Y"), "other_state").c_str()));
+ std::string expr_d = get_bv(cell->getPort(ID::Y));
+ std::string expr_q = get_bv(cell->getPort(ID::Y), "next_state");
+ trans.push_back(stringf(" (= %s %s) ; %s %s\n", expr_d.c_str(), expr_q.c_str(), get_id(cell), log_signal(cell->getPort(ID::Y))));
+ if (cell->type == ID($anyconst))
+ ex_state_eq.push_back(stringf("(= %s %s)", get_bv(cell->getPort(ID::Y)).c_str(), get_bv(cell->getPort(ID::Y), "other_state").c_str()));
}
- if (cell->type == "$mem")
+ if (cell->type == ID($mem))
{
int arrayid = memarrays.at(cell);
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
- int wr_ports = cell->getParam("\\WR_PORTS").as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
bool async_read = false;
string initial_memstate, final_memstate;
- if (!cell->getParam("\\WR_CLK_ENABLE").is_fully_ones()) {
- log_assert(cell->getParam("\\WR_CLK_ENABLE").is_fully_zero());
+ if (!cell->getParam(ID::WR_CLK_ENABLE).is_fully_ones()) {
+ log_assert(cell->getParam(ID::WR_CLK_ENABLE).is_fully_zero());
async_read = true;
initial_memstate = stringf("%s#%d#0", get_id(module), arrayid);
final_memstate = stringf("%s#%d#final", get_id(module), arrayid);
@@ -1010,8 +1010,8 @@ struct Smt2Worker
if (statebv)
{
- int mem_size = cell->getParam("\\SIZE").as_int();
- int mem_offset = cell->getParam("\\OFFSET").as_int();
+ int mem_size = cell->getParam(ID::SIZE).as_int();
+ int mem_offset = cell->getParam(ID::OFFSET).as_int();
if (async_read) {
makebits(final_memstate, width*mem_size, get_id(cell));
@@ -1019,9 +1019,9 @@ struct Smt2Worker
for (int i = 0; i < wr_ports; i++)
{
- SigSpec addr_sig = cell->getPort("\\WR_ADDR").extract(abits*i, abits);
- SigSpec data_sig = cell->getPort("\\WR_DATA").extract(width*i, width);
- SigSpec mask_sig = cell->getPort("\\WR_EN").extract(width*i, width);
+ SigSpec addr_sig = cell->getPort(ID::WR_ADDR).extract(abits*i, abits);
+ SigSpec data_sig = cell->getPort(ID::WR_DATA).extract(width*i, width);
+ SigSpec mask_sig = cell->getPort(ID::WR_EN).extract(width*i, width);
std::string addr = get_bv(addr_sig);
std::string data = get_bv(data_sig);
@@ -1066,9 +1066,9 @@ struct Smt2Worker
for (int i = 0; i < wr_ports; i++)
{
- SigSpec addr_sig = cell->getPort("\\WR_ADDR").extract(abits*i, abits);
- SigSpec data_sig = cell->getPort("\\WR_DATA").extract(width*i, width);
- SigSpec mask_sig = cell->getPort("\\WR_EN").extract(width*i, width);
+ SigSpec addr_sig = cell->getPort(ID::WR_ADDR).extract(abits*i, abits);
+ SigSpec data_sig = cell->getPort(ID::WR_DATA).extract(width*i, width);
+ SigSpec mask_sig = cell->getPort(ID::WR_EN).extract(width*i, width);
std::string addr = get_bv(addr_sig);
std::string data = get_bv(data_sig);
@@ -1104,8 +1104,8 @@ struct Smt2Worker
if (async_read)
hier.push_back(stringf(" (= %s (|%s| state)) ; %s\n", expr_d.c_str(), final_memstate.c_str(), get_id(cell)));
- Const init_data = cell->getParam("\\INIT");
- int memsize = cell->getParam("\\SIZE").as_int();
+ Const init_data = cell->getParam(ID::INIT);
+ int memsize = cell->getParam(ID::SIZE).as_int();
for (int i = 0; i < memsize; i++)
{
@@ -1523,12 +1523,12 @@ struct Smt2Backend : public Backend {
for (auto &dep : it.second)
if (module_deps.count(dep) > 0)
goto not_ready_yet;
- // log("Next in topological sort: %s\n", RTLIL::id2cstr(it.first->name));
+ // log("Next in topological sort: %s\n", log_id(it.first->name));
sorted_modules.push_back(it.first);
not_ready_yet:;
}
if (sorted_modules_idx == sorted_modules.size())
- log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", RTLIL::id2cstr(module_deps.begin()->first->name));
+ log_error("Cyclic dependency between modules found! Cycle includes module %s.\n", log_id(module_deps.begin()->first->name));
while (sorted_modules_idx < sorted_modules.size())
module_deps.erase(sorted_modules.at(sorted_modules_idx++));
}
@@ -1540,7 +1540,7 @@ struct Smt2Backend : public Backend {
for (auto module : sorted_modules)
for (auto cell : module->cells())
- if (cell->type.in("$allconst", "$allseq"))
+ if (cell->type.in(ID($allconst), ID($allseq)))
goto found_forall;
if (0) {
found_forall:
diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py
index 4af4c8ae0..d3015b066 100644
--- a/backends/smt2/smtbmc.py
+++ b/backends/smt2/smtbmc.py
@@ -54,8 +54,7 @@ so = SmtOpts()
def usage():
- print("""
-yosys-smtbmc [options] <yosys_smt2_output>
+ print(os.path.basename(sys.argv[0]) + """ [options] <yosys_smt2_output>
-t <num_steps>
-t <skip_steps>:<num_steps>
diff --git a/backends/smv/smv.cc b/backends/smv/smv.cc
index f755307bf..7113ebc97 100644
--- a/backends/smv/smv.cc
+++ b/backends/smv/smv.cc
@@ -219,30 +219,30 @@ struct SmvWorker
if (wire->port_input)
inputvars.push_back(stringf("%s : unsigned word[%d]; -- %s", cid(wire->name), wire->width, log_id(wire)));
- if (wire->attributes.count("\\init"))
- assignments.push_back(stringf("init(%s) := %s;", lvalue(wire), rvalue(wire->attributes.at("\\init"))));
+ if (wire->attributes.count(ID::init))
+ assignments.push_back(stringf("init(%s) := %s;", lvalue(wire), rvalue(wire->attributes.at(ID::init))));
}
for (auto cell : module->cells())
{
// FIXME: $slice, $concat, $mem
- if (cell->type.in("$assert"))
+ if (cell->type.in(ID($assert)))
{
- SigSpec sig_a = cell->getPort("\\A");
- SigSpec sig_en = cell->getPort("\\EN");
+ SigSpec sig_a = cell->getPort(ID::A);
+ SigSpec sig_en = cell->getPort(ID::EN);
invarspecs.push_back(stringf("!bool(%s) | bool(%s);", rvalue(sig_en), rvalue(sig_a)));
continue;
}
- if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx"))
+ if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
{
- SigSpec sig_a = cell->getPort("\\A");
- SigSpec sig_b = cell->getPort("\\B");
+ SigSpec sig_a = cell->getPort(ID::A);
+ SigSpec sig_b = cell->getPort(ID::B);
- int width_y = GetSize(cell->getPort("\\Y"));
+ int width_y = GetSize(cell->getPort(ID::Y));
int shift_b_width = GetSize(sig_b);
int width_ay = max(GetSize(sig_a), width_y);
int width = width_ay;
@@ -254,12 +254,12 @@ struct SmvWorker
break;
}
- bool signed_a = cell->getParam("\\A_SIGNED").as_bool();
- bool signed_b = cell->getParam("\\B_SIGNED").as_bool();
- string op = cell->type.in("$shl", "$sshl") ? "<<" : ">>";
+ bool signed_a = cell->getParam(ID::A_SIGNED).as_bool();
+ bool signed_b = cell->getParam(ID::B_SIGNED).as_bool();
+ string op = cell->type.in(ID($shl), ID($sshl)) ? "<<" : ">>";
string expr, expr_a;
- if (cell->type == "$sshr" && signed_a)
+ if (cell->type == ID($sshr) && signed_a)
{
expr_a = rvalue_s(sig_a, width);
expr = stringf("resize(unsigned(%s %s %s), %d)", expr_a.c_str(), op.c_str(), rvalue(sig_b.extract(0, shift_b_width)), width_y);
@@ -268,7 +268,7 @@ struct SmvWorker
rvalue(sig_b.extract(shift_b_width, GetSize(sig_b) - shift_b_width)), GetSize(sig_b) - shift_b_width,
rvalue(sig_a[GetSize(sig_a)-1]), width_y, width_y, expr.c_str());
}
- else if (cell->type.in("$shift", "$shiftx") && signed_b)
+ else if (cell->type.in(ID($shift), ID($shiftx)) && signed_b)
{
expr_a = rvalue_u(sig_a, width);
@@ -292,7 +292,7 @@ struct SmvWorker
}
else
{
- if (cell->type.in("$shift", "$shiftx") || !signed_a)
+ if (cell->type.in(ID($shift), ID($shiftx)) || !signed_a)
expr_a = rvalue_u(sig_a, width);
else
expr_a = stringf("resize(unsigned(%s), %d)", rvalue_s(sig_a, width_ay), width);
@@ -303,272 +303,272 @@ struct SmvWorker
GetSize(sig_b)-shift_b_width, width_y, expr.c_str());
}
- definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort("\\Y")), expr.c_str()));
+ definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
continue;
}
- if (cell->type.in("$not", "$pos", "$neg"))
+ if (cell->type.in(ID($not), ID($pos), ID($neg)))
{
- int width = GetSize(cell->getPort("\\Y"));
+ int width = GetSize(cell->getPort(ID::Y));
string expr_a, op;
- if (cell->type == "$not") op = "!";
- if (cell->type == "$pos") op = "";
- if (cell->type == "$neg") op = "-";
+ if (cell->type == ID($not)) op = "!";
+ if (cell->type == ID($pos)) op = "";
+ if (cell->type == ID($neg)) op = "-";
- if (cell->getParam("\\A_SIGNED").as_bool())
+ if (cell->getParam(ID::A_SIGNED).as_bool())
{
- definitions.push_back(stringf("%s := unsigned(%s%s);", lvalue(cell->getPort("\\Y")),
- op.c_str(), rvalue_s(cell->getPort("\\A"), width)));
+ definitions.push_back(stringf("%s := unsigned(%s%s);", lvalue(cell->getPort(ID::Y)),
+ op.c_str(), rvalue_s(cell->getPort(ID::A), width)));
}
else
{
- definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort("\\Y")),
- op.c_str(), rvalue_u(cell->getPort("\\A"), width)));
+ definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)),
+ op.c_str(), rvalue_u(cell->getPort(ID::A), width)));
}
continue;
}
- if (cell->type.in("$add", "$sub", "$mul", "$and", "$or", "$xor", "$xnor"))
+ if (cell->type.in(ID($add), ID($sub), ID($mul), ID($and), ID($or), ID($xor), ID($xnor)))
{
- int width = GetSize(cell->getPort("\\Y"));
+ int width = GetSize(cell->getPort(ID::Y));
string expr_a, expr_b, op;
- if (cell->type == "$add") op = "+";
- if (cell->type == "$sub") op = "-";
- if (cell->type == "$mul") op = "*";
- if (cell->type == "$and") op = "&";
- if (cell->type == "$or") op = "|";
- if (cell->type == "$xor") op = "xor";
- if (cell->type == "$xnor") op = "xnor";
+ if (cell->type == ID($add)) op = "+";
+ if (cell->type == ID($sub)) op = "-";
+ if (cell->type == ID($mul)) op = "*";
+ if (cell->type == ID($and)) op = "&";
+ if (cell->type == ID($or)) op = "|";
+ if (cell->type == ID($xor)) op = "xor";
+ if (cell->type == ID($xnor)) op = "xnor";
- if (cell->getParam("\\A_SIGNED").as_bool())
+ if (cell->getParam(ID::A_SIGNED).as_bool())
{
- definitions.push_back(stringf("%s := unsigned(%s %s %s);", lvalue(cell->getPort("\\Y")),
- rvalue_s(cell->getPort("\\A"), width), op.c_str(), rvalue_s(cell->getPort("\\B"), width)));
+ definitions.push_back(stringf("%s := unsigned(%s %s %s);", lvalue(cell->getPort(ID::Y)),
+ rvalue_s(cell->getPort(ID::A), width), op.c_str(), rvalue_s(cell->getPort(ID::B), width)));
}
else
{
- definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort("\\Y")),
- rvalue_u(cell->getPort("\\A"), width), op.c_str(), rvalue_u(cell->getPort("\\B"), width)));
+ definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort(ID::Y)),
+ rvalue_u(cell->getPort(ID::A), width), op.c_str(), rvalue_u(cell->getPort(ID::B), width)));
}
continue;
}
- if (cell->type.in("$div", "$mod"))
+ if (cell->type.in(ID($div), ID($mod)))
{
- int width_y = GetSize(cell->getPort("\\Y"));
- int width = max(width_y, GetSize(cell->getPort("\\A")));
- width = max(width, GetSize(cell->getPort("\\B")));
+ int width_y = GetSize(cell->getPort(ID::Y));
+ int width = max(width_y, GetSize(cell->getPort(ID::A)));
+ width = max(width, GetSize(cell->getPort(ID::B)));
string expr_a, expr_b, op;
- if (cell->type == "$div") op = "/";
- if (cell->type == "$mod") op = "mod";
+ if (cell->type == ID($div)) op = "/";
+ if (cell->type == ID($mod)) op = "mod";
- if (cell->getParam("\\A_SIGNED").as_bool())
+ if (cell->getParam(ID::A_SIGNED).as_bool())
{
- definitions.push_back(stringf("%s := resize(unsigned(%s %s %s), %d);", lvalue(cell->getPort("\\Y")),
- rvalue_s(cell->getPort("\\A"), width), op.c_str(), rvalue_s(cell->getPort("\\B"), width), width_y));
+ definitions.push_back(stringf("%s := resize(unsigned(%s %s %s), %d);", lvalue(cell->getPort(ID::Y)),
+ rvalue_s(cell->getPort(ID::A), width), op.c_str(), rvalue_s(cell->getPort(ID::B), width), width_y));
}
else
{
- definitions.push_back(stringf("%s := resize(%s %s %s, %d);", lvalue(cell->getPort("\\Y")),
- rvalue_u(cell->getPort("\\A"), width), op.c_str(), rvalue_u(cell->getPort("\\B"), width), width_y));
+ definitions.push_back(stringf("%s := resize(%s %s %s, %d);", lvalue(cell->getPort(ID::Y)),
+ rvalue_u(cell->getPort(ID::A), width), op.c_str(), rvalue_u(cell->getPort(ID::B), width), width_y));
}
continue;
}
- if (cell->type.in("$eq", "$ne", "$eqx", "$nex", "$lt", "$le", "$ge", "$gt"))
+ if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex), ID($lt), ID($le), ID($ge), ID($gt)))
{
- int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B")));
+ int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B)));
string expr_a, expr_b, op;
- if (cell->type == "$eq") op = "=";
- if (cell->type == "$ne") op = "!=";
- if (cell->type == "$eqx") op = "=";
- if (cell->type == "$nex") op = "!=";
- if (cell->type == "$lt") op = "<";
- if (cell->type == "$le") op = "<=";
- if (cell->type == "$ge") op = ">=";
- if (cell->type == "$gt") op = ">";
+ if (cell->type == ID($eq)) op = "=";
+ if (cell->type == ID($ne)) op = "!=";
+ if (cell->type == ID($eqx)) op = "=";
+ if (cell->type == ID($nex)) op = "!=";
+ if (cell->type == ID($lt)) op = "<";
+ if (cell->type == ID($le)) op = "<=";
+ if (cell->type == ID($ge)) op = ">=";
+ if (cell->type == ID($gt)) op = ">";
- if (cell->getParam("\\A_SIGNED").as_bool())
+ if (cell->getParam(ID::A_SIGNED).as_bool())
{
- expr_a = stringf("resize(signed(%s), %d)", rvalue(cell->getPort("\\A")), width);
- expr_b = stringf("resize(signed(%s), %d)", rvalue(cell->getPort("\\B")), width);
+ expr_a = stringf("resize(signed(%s), %d)", rvalue(cell->getPort(ID::A)), width);
+ expr_b = stringf("resize(signed(%s), %d)", rvalue(cell->getPort(ID::B)), width);
}
else
{
- expr_a = stringf("resize(%s, %d)", rvalue(cell->getPort("\\A")), width);
- expr_b = stringf("resize(%s, %d)", rvalue(cell->getPort("\\B")), width);
+ expr_a = stringf("resize(%s, %d)", rvalue(cell->getPort(ID::A)), width);
+ expr_b = stringf("resize(%s, %d)", rvalue(cell->getPort(ID::B)), width);
}
- definitions.push_back(stringf("%s := resize(word1(%s %s %s), %d);", lvalue(cell->getPort("\\Y")),
- expr_a.c_str(), op.c_str(), expr_b.c_str(), GetSize(cell->getPort("\\Y"))));
+ definitions.push_back(stringf("%s := resize(word1(%s %s %s), %d);", lvalue(cell->getPort(ID::Y)),
+ expr_a.c_str(), op.c_str(), expr_b.c_str(), GetSize(cell->getPort(ID::Y))));
continue;
}
- if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_bool"))
+ if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool)))
{
- int width_a = GetSize(cell->getPort("\\A"));
- int width_y = GetSize(cell->getPort("\\Y"));
- const char *expr_a = rvalue(cell->getPort("\\A"));
- const char *expr_y = lvalue(cell->getPort("\\Y"));
+ int width_a = GetSize(cell->getPort(ID::A));
+ int width_y = GetSize(cell->getPort(ID::Y));
+ const char *expr_a = rvalue(cell->getPort(ID::A));
+ const char *expr_y = lvalue(cell->getPort(ID::Y));
string expr;
- if (cell->type == "$reduce_and") expr = stringf("%s = !0ub%d_0", expr_a, width_a);
- if (cell->type == "$reduce_or") expr = stringf("%s != 0ub%d_0", expr_a, width_a);
- if (cell->type == "$reduce_bool") expr = stringf("%s != 0ub%d_0", expr_a, width_a);
+ if (cell->type == ID($reduce_and)) expr = stringf("%s = !0ub%d_0", expr_a, width_a);
+ if (cell->type == ID($reduce_or)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
+ if (cell->type == ID($reduce_bool)) expr = stringf("%s != 0ub%d_0", expr_a, width_a);
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
continue;
}
- if (cell->type.in("$reduce_xor", "$reduce_xnor"))
+ if (cell->type.in(ID($reduce_xor), ID($reduce_xnor)))
{
- int width_y = GetSize(cell->getPort("\\Y"));
- const char *expr_y = lvalue(cell->getPort("\\Y"));
+ int width_y = GetSize(cell->getPort(ID::Y));
+ const char *expr_y = lvalue(cell->getPort(ID::Y));
string expr;
- for (auto bit : cell->getPort("\\A")) {
+ for (auto bit : cell->getPort(ID::A)) {
if (!expr.empty())
expr += " xor ";
expr += rvalue(bit);
}
- if (cell->type == "$reduce_xnor")
+ if (cell->type == ID($reduce_xnor))
expr = "!(" + expr + ")";
definitions.push_back(stringf("%s := resize(%s, %d);", expr_y, expr.c_str(), width_y));
continue;
}
- if (cell->type.in("$logic_and", "$logic_or"))
+ if (cell->type.in(ID($logic_and), ID($logic_or)))
{
- int width_a = GetSize(cell->getPort("\\A"));
- int width_b = GetSize(cell->getPort("\\B"));
- int width_y = GetSize(cell->getPort("\\Y"));
+ int width_a = GetSize(cell->getPort(ID::A));
+ int width_b = GetSize(cell->getPort(ID::B));
+ int width_y = GetSize(cell->getPort(ID::Y));
- string expr_a = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort("\\A")), width_a);
- string expr_b = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort("\\B")), width_b);
- const char *expr_y = lvalue(cell->getPort("\\Y"));
+ string expr_a = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort(ID::A)), width_a);
+ string expr_b = stringf("(%s != 0ub%d_0)", rvalue(cell->getPort(ID::B)), width_b);
+ const char *expr_y = lvalue(cell->getPort(ID::Y));
string expr;
- if (cell->type == "$logic_and") expr = expr_a + " & " + expr_b;
- if (cell->type == "$logic_or") expr = expr_a + " | " + expr_b;
+ if (cell->type == ID($logic_and)) expr = expr_a + " & " + expr_b;
+ if (cell->type == ID($logic_or)) expr = expr_a + " | " + expr_b;
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr.c_str(), width_y));
continue;
}
- if (cell->type.in("$logic_not"))
+ if (cell->type.in(ID($logic_not)))
{
- int width_a = GetSize(cell->getPort("\\A"));
- int width_y = GetSize(cell->getPort("\\Y"));
+ int width_a = GetSize(cell->getPort(ID::A));
+ int width_y = GetSize(cell->getPort(ID::Y));
- string expr_a = stringf("(%s = 0ub%d_0)", rvalue(cell->getPort("\\A")), width_a);
- const char *expr_y = lvalue(cell->getPort("\\Y"));
+ string expr_a = stringf("(%s = 0ub%d_0)", rvalue(cell->getPort(ID::A)), width_a);
+ const char *expr_y = lvalue(cell->getPort(ID::Y));
definitions.push_back(stringf("%s := resize(word1(%s), %d);", expr_y, expr_a.c_str(), width_y));
continue;
}
- if (cell->type.in("$mux", "$pmux"))
+ if (cell->type.in(ID($mux), ID($pmux)))
{
- int width = GetSize(cell->getPort("\\Y"));
- SigSpec sig_a = cell->getPort("\\A");
- SigSpec sig_b = cell->getPort("\\B");
- SigSpec sig_s = cell->getPort("\\S");
+ int width = GetSize(cell->getPort(ID::Y));
+ SigSpec sig_a = cell->getPort(ID::A);
+ SigSpec sig_b = cell->getPort(ID::B);
+ SigSpec sig_s = cell->getPort(ID::S);
string expr;
for (int i = 0; i < GetSize(sig_s); i++)
expr += stringf("bool(%s) ? %s : ", rvalue(sig_s[i]), rvalue(sig_b.extract(i*width, width)));
expr += rvalue(sig_a);
- definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort("\\Y")), expr.c_str()));
+ definitions.push_back(stringf("%s := %s;", lvalue(cell->getPort(ID::Y)), expr.c_str()));
continue;
}
- if (cell->type == "$dff")
+ if (cell->type == ID($dff))
{
- vars.push_back(stringf("%s : unsigned word[%d]; -- %s", lvalue(cell->getPort("\\Q")), GetSize(cell->getPort("\\Q")), log_signal(cell->getPort("\\Q"))));
- assignments.push_back(stringf("next(%s) := %s;", lvalue(cell->getPort("\\Q")), rvalue(cell->getPort("\\D"))));
+ vars.push_back(stringf("%s : unsigned word[%d]; -- %s", lvalue(cell->getPort(ID::Q)), GetSize(cell->getPort(ID::Q)), log_signal(cell->getPort(ID::Q))));
+ assignments.push_back(stringf("next(%s) := %s;", lvalue(cell->getPort(ID::Q)), rvalue(cell->getPort(ID::D))));
continue;
}
- if (cell->type.in("$_BUF_", "$_NOT_"))
+ if (cell->type.in(ID($_BUF_), ID($_NOT_)))
{
- string op = cell->type == "$_NOT_" ? "!" : "";
- definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort("\\Y")), op.c_str(), rvalue(cell->getPort("\\A"))));
+ string op = cell->type == ID($_NOT_) ? "!" : "";
+ definitions.push_back(stringf("%s := %s%s;", lvalue(cell->getPort(ID::Y)), op.c_str(), rvalue(cell->getPort(ID::A))));
continue;
}
- if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
+ if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
{
string op;
- if (cell->type.in("$_AND_", "$_NAND_", "$_ANDNOT_")) op = "&";
- if (cell->type.in("$_OR_", "$_NOR_", "$_ORNOT_")) op = "|";
- if (cell->type.in("$_XOR_")) op = "xor";
- if (cell->type.in("$_XNOR_")) op = "xnor";
+ if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_ANDNOT_))) op = "&";
+ if (cell->type.in(ID($_OR_), ID($_NOR_), ID($_ORNOT_))) op = "|";
+ if (cell->type.in(ID($_XOR_))) op = "xor";
+ if (cell->type.in(ID($_XNOR_))) op = "xnor";
- if (cell->type.in("$_ANDNOT_", "$_ORNOT_"))
- definitions.push_back(stringf("%s := %s %s (!%s);", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
+ if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
+ definitions.push_back(stringf("%s := %s %s (!%s);", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::A)), op.c_str(), rvalue(cell->getPort(ID::B))));
else
- if (cell->type.in("$_NAND_", "$_NOR_"))
- definitions.push_back(stringf("%s := !(%s %s %s);", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
+ if (cell->type.in(ID($_NAND_), ID($_NOR_)))
+ definitions.push_back(stringf("%s := !(%s %s %s);", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::A)), op.c_str(), rvalue(cell->getPort(ID::B))));
else
- definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\A")), op.c_str(), rvalue(cell->getPort("\\B"))));
+ definitions.push_back(stringf("%s := %s %s %s;", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::A)), op.c_str(), rvalue(cell->getPort(ID::B))));
continue;
}
- if (cell->type == "$_MUX_")
+ if (cell->type == ID($_MUX_))
{
- definitions.push_back(stringf("%s := bool(%s) ? %s : %s;", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\S")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\A"))));
+ definitions.push_back(stringf("%s := bool(%s) ? %s : %s;", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::S)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::A))));
continue;
}
- if (cell->type == "$_NMUX_")
+ if (cell->type == ID($_NMUX_))
{
- definitions.push_back(stringf("%s := !(bool(%s) ? %s : %s);", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\S")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\A"))));
+ definitions.push_back(stringf("%s := !(bool(%s) ? %s : %s);", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::S)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::A))));
continue;
}
- if (cell->type == "$_AOI3_")
+ if (cell->type == ID($_AOI3_))
{
- definitions.push_back(stringf("%s := !((%s & %s) | %s);", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C"))));
+ definitions.push_back(stringf("%s := !((%s & %s) | %s);", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C))));
continue;
}
- if (cell->type == "$_OAI3_")
+ if (cell->type == ID($_OAI3_))
{
- definitions.push_back(stringf("%s := !((%s | %s) & %s);", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C"))));
+ definitions.push_back(stringf("%s := !((%s | %s) & %s);", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C))));
continue;
}
- if (cell->type == "$_AOI4_")
+ if (cell->type == ID($_AOI4_))
{
- definitions.push_back(stringf("%s := !((%s & %s) | (%s & %s));", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C")), rvalue(cell->getPort("\\D"))));
+ definitions.push_back(stringf("%s := !((%s & %s) | (%s & %s));", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C)), rvalue(cell->getPort(ID::D))));
continue;
}
- if (cell->type == "$_OAI4_")
+ if (cell->type == ID($_OAI4_))
{
- definitions.push_back(stringf("%s := !((%s | %s) & (%s | %s));", lvalue(cell->getPort("\\Y")),
- rvalue(cell->getPort("\\A")), rvalue(cell->getPort("\\B")), rvalue(cell->getPort("\\C")), rvalue(cell->getPort("\\D"))));
+ definitions.push_back(stringf("%s := !((%s | %s) & (%s | %s));", lvalue(cell->getPort(ID::Y)),
+ rvalue(cell->getPort(ID::A)), rvalue(cell->getPort(ID::B)), rvalue(cell->getPort(ID::C)), rvalue(cell->getPort(ID::D))));
continue;
}
diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc
index 6738a4bbd..84e93b61b 100644
--- a/backends/spice/spice.cc
+++ b/backends/spice/spice.cc
@@ -70,14 +70,13 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
idict<IdString, 1> inums;
int cell_counter = 0, conn_counter = 0, nc_counter = 0;
- for (auto &cell_it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = cell_it.second;
f << stringf("X%d", cell_counter++);
std::vector<RTLIL::SigSpec> port_sigs;
- if (design->modules_.count(cell->type) == 0)
+ if (design->module(cell->type) == nullptr)
{
log_warning("no (blackbox) module for cell type `%s' (%s.%s) found! Guessing order of ports.\n",
log_id(cell->type), log_id(module), log_id(cell));
@@ -88,11 +87,10 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
}
else
{
- RTLIL::Module *mod = design->modules_.at(cell->type);
+ RTLIL::Module *mod = design->module(cell->type);
std::vector<RTLIL::Wire*> ports;
- for (auto wire_it : mod->wires_) {
- RTLIL::Wire *wire = wire_it.second;
+ for (auto wire : mod->wires()) {
if (wire->port_id == 0)
continue;
while (int(ports.size()) < wire->port_id)
@@ -202,16 +200,15 @@ struct SpiceBackend : public Backend {
extra_args(f, filename, args, argidx);
if (top_module_name.empty())
- for (auto & mod_it:design->modules_)
- if (mod_it.second->get_bool_attribute("\\top"))
- top_module_name = mod_it.first.str();
+ for (auto module : design->modules())
+ if (module->get_bool_attribute(ID::top))
+ top_module_name = module->name.str();
*f << stringf("* SPICE netlist generated by %s\n", yosys_version_str);
*f << stringf("\n");
- for (auto module_it : design->modules_)
+ for (auto module : design->modules())
{
- RTLIL::Module *module = module_it.second;
if (module->get_blackbox_attribute())
continue;
@@ -226,8 +223,7 @@ struct SpiceBackend : public Backend {
}
std::vector<RTLIL::Wire*> ports;
- for (auto wire_it : module->wires_) {
- RTLIL::Wire *wire = wire_it.second;
+ for (auto wire : module->wires()) {
if (wire->port_id == 0)
continue;
while (int(ports.size()) < wire->port_id)
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 19541f1c4..11b2ae10f 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -73,12 +73,12 @@ void reset_auto_counter(RTLIL::Module *module)
reset_auto_counter_id(module->name, false);
- for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it)
- reset_auto_counter_id(it->second->name, true);
+ for (auto w : module->wires())
+ reset_auto_counter_id(w->name, true);
- for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it) {
- reset_auto_counter_id(it->second->name, true);
- reset_auto_counter_id(it->second->type, false);
+ for (auto cell : module->cells()) {
+ reset_auto_counter_id(cell->name, true);
+ reset_auto_counter_id(cell->type, false);
}
for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
@@ -378,7 +378,7 @@ void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString,
if (attr2comment)
as_comment = true;
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
- if (it->first == "\\init" && regattr) continue;
+ if (it->first == ID::init && regattr) continue;
f << stringf("%s" "%s %s", indent.c_str(), as_comment ? "/*" : "(*", id(it->first).c_str());
f << stringf(" = ");
if (modattr && (it->second == State::S0 || it->second == Const(0)))
@@ -423,9 +423,9 @@ void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)
f << stringf("%s" "inout%s %s;\n", indent.c_str(), range.c_str(), id(wire->name).c_str());
if (reg_wires.count(wire->name)) {
f << stringf("%s" "reg%s %s", indent.c_str(), range.c_str(), id(wire->name).c_str());
- if (wire->attributes.count("\\init")) {
+ if (wire->attributes.count(ID::init)) {
f << stringf(" = ");
- dump_const(f, wire->attributes.at("\\init"));
+ dump_const(f, wire->attributes.at(ID::init));
}
f << stringf(";\n");
} else if (!wire->port_input && !wire->port_output)
@@ -451,9 +451,9 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b
std::string cellname(RTLIL::Cell *cell)
{
- if (!norename && cell->name[0] == '$' && reg_ct.count(cell->type) && cell->hasPort("\\Q"))
+ if (!norename && cell->name[0] == '$' && reg_ct.count(cell->type) && cell->hasPort(ID::Q))
{
- RTLIL::SigSpec sig = cell->getPort("\\Q");
+ RTLIL::SigSpec sig = cell->getPort(ID::Q);
if (GetSize(sig) != 1 || sig.is_fully_const())
goto no_special_reg_name;
@@ -488,7 +488,7 @@ no_special_reg_name:
void dump_cell_expr_uniop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op)
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = %s ", op.c_str());
dump_attributes(f, "", cell->attributes, ' ');
dump_cell_expr_port(f, cell, "A", true);
@@ -498,7 +498,7 @@ void dump_cell_expr_uniop(std::ostream &f, std::string indent, RTLIL::Cell *cell
void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell, std::string op)
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
dump_cell_expr_port(f, cell, "A", true);
f << stringf(" %s ", op.c_str());
@@ -509,9 +509,9 @@ void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell
bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
{
- if (cell->type == "$_NOT_") {
+ if (cell->type == ID($_NOT_)) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
f << stringf("~");
dump_attributes(f, "", cell->attributes, ' ');
@@ -520,34 +520,34 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_")) {
+ if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_))) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
- if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_"))
+ if (cell->type.in(ID($_NAND_), ID($_NOR_), ID($_XNOR_)))
f << stringf("~(");
dump_cell_expr_port(f, cell, "A", false);
f << stringf(" ");
- if (cell->type.in("$_AND_", "$_NAND_", "$_ANDNOT_"))
+ if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_ANDNOT_)))
f << stringf("&");
- if (cell->type.in("$_OR_", "$_NOR_", "$_ORNOT_"))
+ if (cell->type.in(ID($_OR_), ID($_NOR_), ID($_ORNOT_)))
f << stringf("|");
- if (cell->type.in("$_XOR_", "$_XNOR_"))
+ if (cell->type.in(ID($_XOR_), ID($_XNOR_)))
f << stringf("^");
dump_attributes(f, "", cell->attributes, ' ');
f << stringf(" ");
- if (cell->type.in("$_ANDNOT_", "$_ORNOT_"))
+ if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_)))
f << stringf("~(");
dump_cell_expr_port(f, cell, "B", false);
- if (cell->type.in("$_NAND_", "$_NOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
+ if (cell->type.in(ID($_NAND_), ID($_NOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
f << stringf(")");
f << stringf(";\n");
return true;
}
- if (cell->type == "$_MUX_") {
+ if (cell->type == ID($_MUX_)) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
dump_cell_expr_port(f, cell, "S", false);
f << stringf(" ? ");
@@ -559,9 +559,9 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type == "$_NMUX_") {
+ if (cell->type == ID($_NMUX_)) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = !(");
dump_cell_expr_port(f, cell, "S", false);
f << stringf(" ? ");
@@ -573,14 +573,14 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type.in("$_AOI3_", "$_OAI3_")) {
+ if (cell->type.in(ID($_AOI3_), ID($_OAI3_))) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ~((");
dump_cell_expr_port(f, cell, "A", false);
- f << stringf(cell->type == "$_AOI3_" ? " & " : " | ");
+ f << stringf(cell->type == ID($_AOI3_) ? " & " : " | ");
dump_cell_expr_port(f, cell, "B", false);
- f << stringf(cell->type == "$_AOI3_" ? ") |" : ") &");
+ f << stringf(cell->type == ID($_AOI3_) ? ") |" : ") &");
dump_attributes(f, "", cell->attributes, ' ');
f << stringf(" ");
dump_cell_expr_port(f, cell, "C", false);
@@ -588,18 +588,18 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type.in("$_AOI4_", "$_OAI4_")) {
+ if (cell->type.in(ID($_AOI4_), ID($_OAI4_))) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ~((");
dump_cell_expr_port(f, cell, "A", false);
- f << stringf(cell->type == "$_AOI4_" ? " & " : " | ");
+ f << stringf(cell->type == ID($_AOI4_) ? " & " : " | ");
dump_cell_expr_port(f, cell, "B", false);
- f << stringf(cell->type == "$_AOI4_" ? ") |" : ") &");
+ f << stringf(cell->type == ID($_AOI4_) ? ") |" : ") &");
dump_attributes(f, "", cell->attributes, ' ');
f << stringf(" (");
dump_cell_expr_port(f, cell, "C", false);
- f << stringf(cell->type == "$_AOI4_" ? " & " : " | ");
+ f << stringf(cell->type == ID($_AOI4_) ? " & " : " | ");
dump_cell_expr_port(f, cell, "D", false);
f << stringf("));\n");
return true;
@@ -608,26 +608,26 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (cell->type.begins_with("$_DFF_"))
{
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
+ bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
if (!out_is_reg_wire) {
f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str());
- dump_reg_init(f, cell->getPort("\\Q"));
+ dump_reg_init(f, cell->getPort(ID::Q));
f << ";\n";
}
dump_attributes(f, indent, cell->attributes);
f << stringf("%s" "always @(%sedge ", indent.c_str(), cell->type[6] == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort("\\C"));
+ dump_sigspec(f, cell->getPort(ID::C));
if (cell->type[7] != '_') {
f << stringf(" or %sedge ", cell->type[7] == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort("\\R"));
+ dump_sigspec(f, cell->getPort(ID::R));
}
f << stringf(")\n");
if (cell->type[7] != '_') {
f << stringf("%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!");
- dump_sigspec(f, cell->getPort("\\R"));
+ dump_sigspec(f, cell->getPort(ID::R));
f << stringf(")\n");
f << stringf("%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]);
f << stringf("%s" " else\n", indent.c_str());
@@ -639,7 +639,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (!out_is_reg_wire) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Q"));
+ dump_sigspec(f, cell->getPort(ID::Q));
f << stringf(" = %s;\n", reg_name.c_str());
}
@@ -651,30 +651,30 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10];
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
+ bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
if (!out_is_reg_wire) {
f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str());
- dump_reg_init(f, cell->getPort("\\Q"));
+ dump_reg_init(f, cell->getPort(ID::Q));
f << ";\n";
}
dump_attributes(f, indent, cell->attributes);
f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_c == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort("\\C"));
+ dump_sigspec(f, cell->getPort(ID::C));
f << stringf(" or %sedge ", pol_s == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort("\\S"));
+ dump_sigspec(f, cell->getPort(ID::S));
f << stringf(" or %sedge ", pol_r == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort("\\R"));
+ dump_sigspec(f, cell->getPort(ID::R));
f << stringf(")\n");
f << stringf("%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!");
- dump_sigspec(f, cell->getPort("\\R"));
+ dump_sigspec(f, cell->getPort(ID::R));
f << stringf(")\n");
f << stringf("%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str());
f << stringf("%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!");
- dump_sigspec(f, cell->getPort("\\S"));
+ dump_sigspec(f, cell->getPort(ID::S));
f << stringf(")\n");
f << stringf("%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str());
@@ -685,7 +685,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (!out_is_reg_wire) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Q"));
+ dump_sigspec(f, cell->getPort(ID::Q));
f << stringf(" = %s;\n", reg_name.c_str());
}
@@ -697,117 +697,117 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
#define HANDLE_BINOP(_type, _operator) \
if (cell->type ==_type) { dump_cell_expr_binop(f, indent, cell, _operator); return true; }
- HANDLE_UNIOP("$not", "~")
- HANDLE_UNIOP("$pos", "+")
- HANDLE_UNIOP("$neg", "-")
-
- HANDLE_BINOP("$and", "&")
- HANDLE_BINOP("$or", "|")
- HANDLE_BINOP("$xor", "^")
- HANDLE_BINOP("$xnor", "~^")
-
- HANDLE_UNIOP("$reduce_and", "&")
- HANDLE_UNIOP("$reduce_or", "|")
- HANDLE_UNIOP("$reduce_xor", "^")
- HANDLE_UNIOP("$reduce_xnor", "~^")
- HANDLE_UNIOP("$reduce_bool", "|")
-
- HANDLE_BINOP("$shl", "<<")
- HANDLE_BINOP("$shr", ">>")
- HANDLE_BINOP("$sshl", "<<<")
- HANDLE_BINOP("$sshr", ">>>")
-
- HANDLE_BINOP("$lt", "<")
- HANDLE_BINOP("$le", "<=")
- HANDLE_BINOP("$eq", "==")
- HANDLE_BINOP("$ne", "!=")
- HANDLE_BINOP("$eqx", "===")
- HANDLE_BINOP("$nex", "!==")
- HANDLE_BINOP("$ge", ">=")
- HANDLE_BINOP("$gt", ">")
-
- HANDLE_BINOP("$add", "+")
- HANDLE_BINOP("$sub", "-")
- HANDLE_BINOP("$mul", "*")
- HANDLE_BINOP("$div", "/")
- HANDLE_BINOP("$mod", "%")
- HANDLE_BINOP("$pow", "**")
-
- HANDLE_UNIOP("$logic_not", "!")
- HANDLE_BINOP("$logic_and", "&&")
- HANDLE_BINOP("$logic_or", "||")
+ HANDLE_UNIOP(ID($not), "~")
+ HANDLE_UNIOP(ID($pos), "+")
+ HANDLE_UNIOP(ID($neg), "-")
+
+ HANDLE_BINOP(ID($and), "&")
+ HANDLE_BINOP(ID($or), "|")
+ HANDLE_BINOP(ID($xor), "^")
+ HANDLE_BINOP(ID($xnor), "~^")
+
+ HANDLE_UNIOP(ID($reduce_and), "&")
+ HANDLE_UNIOP(ID($reduce_or), "|")
+ HANDLE_UNIOP(ID($reduce_xor), "^")
+ HANDLE_UNIOP(ID($reduce_xnor), "~^")
+ HANDLE_UNIOP(ID($reduce_bool), "|")
+
+ HANDLE_BINOP(ID($shl), "<<")
+ HANDLE_BINOP(ID($shr), ">>")
+ HANDLE_BINOP(ID($sshl), "<<<")
+ HANDLE_BINOP(ID($sshr), ">>>")
+
+ HANDLE_BINOP(ID($lt), "<")
+ HANDLE_BINOP(ID($le), "<=")
+ HANDLE_BINOP(ID($eq), "==")
+ HANDLE_BINOP(ID($ne), "!=")
+ HANDLE_BINOP(ID($eqx), "===")
+ HANDLE_BINOP(ID($nex), "!==")
+ HANDLE_BINOP(ID($ge), ">=")
+ HANDLE_BINOP(ID($gt), ">")
+
+ HANDLE_BINOP(ID($add), "+")
+ HANDLE_BINOP(ID($sub), "-")
+ HANDLE_BINOP(ID($mul), "*")
+ HANDLE_BINOP(ID($div), "/")
+ HANDLE_BINOP(ID($mod), "%")
+ HANDLE_BINOP(ID($pow), "**")
+
+ HANDLE_UNIOP(ID($logic_not), "!")
+ HANDLE_BINOP(ID($logic_and), "&&")
+ HANDLE_BINOP(ID($logic_or), "||")
#undef HANDLE_UNIOP
#undef HANDLE_BINOP
- if (cell->type == "$shift")
+ if (cell->type == ID($shift))
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
- if (cell->getParam("\\B_SIGNED").as_bool())
+ if (cell->getParam(ID::B_SIGNED).as_bool())
{
f << stringf("$signed(");
- dump_sigspec(f, cell->getPort("\\B"));
+ dump_sigspec(f, cell->getPort(ID::B));
f << stringf(")");
f << stringf(" < 0 ? ");
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(" << - ");
- dump_sigspec(f, cell->getPort("\\B"));
+ dump_sigspec(f, cell->getPort(ID::B));
f << stringf(" : ");
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(" >> ");
- dump_sigspec(f, cell->getPort("\\B"));
+ dump_sigspec(f, cell->getPort(ID::B));
}
else
{
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(" >> ");
- dump_sigspec(f, cell->getPort("\\B"));
+ dump_sigspec(f, cell->getPort(ID::B));
}
f << stringf(";\n");
return true;
}
- if (cell->type == "$shiftx")
+ if (cell->type == ID($shiftx))
{
std::string temp_id = next_auto_id();
- f << stringf("%s" "wire [%d:0] %s = ", indent.c_str(), GetSize(cell->getPort("\\A"))-1, temp_id.c_str());
- dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf("%s" "wire [%d:0] %s = ", indent.c_str(), GetSize(cell->getPort(ID::A))-1, temp_id.c_str());
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(";\n");
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = %s[", temp_id.c_str());
- if (cell->getParam("\\B_SIGNED").as_bool())
+ if (cell->getParam(ID::B_SIGNED).as_bool())
f << stringf("$signed(");
- dump_sigspec(f, cell->getPort("\\B"));
- if (cell->getParam("\\B_SIGNED").as_bool())
+ dump_sigspec(f, cell->getPort(ID::B));
+ if (cell->getParam(ID::B_SIGNED).as_bool())
f << stringf(")");
- f << stringf(" +: %d", cell->getParam("\\Y_WIDTH").as_int());
+ f << stringf(" +: %d", cell->getParam(ID::Y_WIDTH).as_int());
f << stringf("];\n");
return true;
}
- if (cell->type == "$mux")
+ if (cell->type == ID($mux))
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
- dump_sigspec(f, cell->getPort("\\S"));
+ dump_sigspec(f, cell->getPort(ID::S));
f << stringf(" ? ");
dump_attributes(f, "", cell->attributes, ' ');
- dump_sigspec(f, cell->getPort("\\B"));
+ dump_sigspec(f, cell->getPort(ID::B));
f << stringf(" : ");
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(";\n");
return true;
}
- if (cell->type == "$pmux")
+ if (cell->type == ID($pmux))
{
- int width = cell->parameters["\\WIDTH"].as_int();
- int s_width = cell->getPort("\\S").size();
+ int width = cell->parameters[ID::WIDTH].as_int();
+ int s_width = cell->getPort(ID::S).size();
std::string func_name = cellname(cell);
f << stringf("%s" "function [%d:0] %s;\n", indent.c_str(), width-1, func_name.c_str());
@@ -839,76 +839,76 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
f << stringf("%s" "endfunction\n", indent.c_str());
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = %s(", func_name.c_str());
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(", ");
- dump_sigspec(f, cell->getPort("\\B"));
+ dump_sigspec(f, cell->getPort(ID::B));
f << stringf(", ");
- dump_sigspec(f, cell->getPort("\\S"));
+ dump_sigspec(f, cell->getPort(ID::S));
f << stringf(");\n");
return true;
}
- if (cell->type == "$tribuf")
+ if (cell->type == ID($tribuf))
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
- dump_sigspec(f, cell->getPort("\\EN"));
+ dump_sigspec(f, cell->getPort(ID::EN));
f << stringf(" ? ");
- dump_sigspec(f, cell->getPort("\\A"));
- f << stringf(" : %d'bz;\n", cell->parameters.at("\\WIDTH").as_int());
+ dump_sigspec(f, cell->getPort(ID::A));
+ f << stringf(" : %d'bz;\n", cell->parameters.at(ID::WIDTH).as_int());
return true;
}
- if (cell->type == "$slice")
+ if (cell->type == ID($slice))
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
- dump_sigspec(f, cell->getPort("\\A"));
- f << stringf(" >> %d;\n", cell->parameters.at("\\OFFSET").as_int());
+ dump_sigspec(f, cell->getPort(ID::A));
+ f << stringf(" >> %d;\n", cell->parameters.at(ID::OFFSET).as_int());
return true;
}
- if (cell->type == "$concat")
+ if (cell->type == ID($concat))
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = { ");
- dump_sigspec(f, cell->getPort("\\B"));
+ dump_sigspec(f, cell->getPort(ID::B));
f << stringf(" , ");
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(" };\n");
return true;
}
- if (cell->type == "$lut")
+ if (cell->type == ID($lut))
{
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Y"));
+ dump_sigspec(f, cell->getPort(ID::Y));
f << stringf(" = ");
- dump_const(f, cell->parameters.at("\\LUT"));
+ dump_const(f, cell->parameters.at(ID::LUT));
f << stringf(" >> ");
dump_attributes(f, "", cell->attributes, ' ');
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(";\n");
return true;
}
- if (cell->type == "$dffsr")
+ if (cell->type == ID($dffsr))
{
- SigSpec sig_clk = cell->getPort("\\CLK");
- SigSpec sig_set = cell->getPort("\\SET");
- SigSpec sig_clr = cell->getPort("\\CLR");
- SigSpec sig_d = cell->getPort("\\D");
- SigSpec sig_q = cell->getPort("\\Q");
+ SigSpec sig_clk = cell->getPort(ID::CLK);
+ SigSpec sig_set = cell->getPort(ID::SET);
+ SigSpec sig_clr = cell->getPort(ID::CLR);
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
- int width = cell->parameters["\\WIDTH"].as_int();
- bool pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool();
- bool pol_set = cell->parameters["\\SET_POLARITY"].as_bool();
- bool pol_clr = cell->parameters["\\CLR_POLARITY"].as_bool();
+ int width = cell->parameters[ID::WIDTH].as_int();
+ bool pol_clk = cell->parameters[ID::CLK_POLARITY].as_bool();
+ bool pol_set = cell->parameters[ID::SET_POLARITY].as_bool();
+ bool pol_clr = cell->parameters[ID::CLR_POLARITY].as_bool();
std::string reg_name = cellname(cell);
bool out_is_reg_wire = is_reg_wire(sig_q, reg_name);
@@ -950,43 +950,43 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type.in("$dff", "$adff", "$dffe"))
+ if (cell->type.in(ID($dff), ID($adff), ID($dffe)))
{
RTLIL::SigSpec sig_clk, sig_arst, sig_en, val_arst;
bool pol_clk, pol_arst = false, pol_en = false;
- sig_clk = cell->getPort("\\CLK");
- pol_clk = cell->parameters["\\CLK_POLARITY"].as_bool();
+ sig_clk = cell->getPort(ID::CLK);
+ pol_clk = cell->parameters[ID::CLK_POLARITY].as_bool();
- if (cell->type == "$adff") {
- sig_arst = cell->getPort("\\ARST");
- pol_arst = cell->parameters["\\ARST_POLARITY"].as_bool();
- val_arst = RTLIL::SigSpec(cell->parameters["\\ARST_VALUE"]);
+ if (cell->type == ID($adff)) {
+ sig_arst = cell->getPort(ID::ARST);
+ pol_arst = cell->parameters[ID::ARST_POLARITY].as_bool();
+ val_arst = RTLIL::SigSpec(cell->parameters[ID::ARST_VALUE]);
}
- if (cell->type == "$dffe") {
- sig_en = cell->getPort("\\EN");
- pol_en = cell->parameters["\\EN_POLARITY"].as_bool();
+ if (cell->type == ID($dffe)) {
+ sig_en = cell->getPort(ID::EN);
+ pol_en = cell->parameters[ID::EN_POLARITY].as_bool();
}
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
+ bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
if (!out_is_reg_wire) {
- f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str());
- dump_reg_init(f, cell->getPort("\\Q"));
+ f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters[ID::WIDTH].as_int()-1, reg_name.c_str());
+ dump_reg_init(f, cell->getPort(ID::Q));
f << ";\n";
}
f << stringf("%s" "always @(%sedge ", indent.c_str(), pol_clk ? "pos" : "neg");
dump_sigspec(f, sig_clk);
- if (cell->type == "$adff") {
+ if (cell->type == ID($adff)) {
f << stringf(" or %sedge ", pol_arst ? "pos" : "neg");
dump_sigspec(f, sig_arst);
}
f << stringf(")\n");
- if (cell->type == "$adff") {
+ if (cell->type == ID($adff)) {
f << stringf("%s" " if (%s", indent.c_str(), pol_arst ? "" : "!");
dump_sigspec(f, sig_arst);
f << stringf(")\n");
@@ -996,7 +996,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
f << stringf("%s" " else\n", indent.c_str());
}
- if (cell->type == "$dffe") {
+ if (cell->type == ID($dffe)) {
f << stringf("%s" " if (%s", indent.c_str(), pol_en ? "" : "!");
dump_sigspec(f, sig_en);
f << stringf(")\n");
@@ -1008,27 +1008,27 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (!out_is_reg_wire) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Q"));
+ dump_sigspec(f, cell->getPort(ID::Q));
f << stringf(" = %s;\n", reg_name.c_str());
}
return true;
}
- if (cell->type == "$dlatch")
+ if (cell->type == ID($dlatch))
{
RTLIL::SigSpec sig_en;
bool pol_en = false;
- sig_en = cell->getPort("\\EN");
- pol_en = cell->parameters["\\EN_POLARITY"].as_bool();
+ sig_en = cell->getPort(ID::EN);
+ pol_en = cell->parameters[ID::EN_POLARITY].as_bool();
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort("\\Q"), reg_name);
+ bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
if (!out_is_reg_wire) {
- f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str());
- dump_reg_init(f, cell->getPort("\\Q"));
+ f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters[ID::WIDTH].as_int()-1, reg_name.c_str());
+ dump_reg_init(f, cell->getPort(ID::Q));
f << ";\n";
}
@@ -1044,22 +1044,22 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (!out_is_reg_wire) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort("\\Q"));
+ dump_sigspec(f, cell->getPort(ID::Q));
f << stringf(" = %s;\n", reg_name.c_str());
}
return true;
}
- if (cell->type == "$mem")
+ if (cell->type == ID($mem))
{
- RTLIL::IdString memid = cell->parameters["\\MEMID"].decode_string();
- std::string mem_id = id(cell->parameters["\\MEMID"].decode_string());
- int abits = cell->parameters["\\ABITS"].as_int();
- int size = cell->parameters["\\SIZE"].as_int();
- int offset = cell->parameters["\\OFFSET"].as_int();
- int width = cell->parameters["\\WIDTH"].as_int();
- bool use_init = !(RTLIL::SigSpec(cell->parameters["\\INIT"]).is_fully_undef());
+ RTLIL::IdString memid = cell->parameters[ID::MEMID].decode_string();
+ std::string mem_id = id(cell->parameters[ID::MEMID].decode_string());
+ int abits = cell->parameters[ID::ABITS].as_int();
+ int size = cell->parameters[ID::SIZE].as_int();
+ int offset = cell->parameters[ID::OFFSET].as_int();
+ int width = cell->parameters[ID::WIDTH].as_int();
+ bool use_init = !(RTLIL::SigSpec(cell->parameters[ID::INIT]).is_fully_undef());
// for memory block make something like:
// reg [7:0] memid [3:0];
@@ -1099,7 +1099,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
{
for (int i=0; i<size; i++)
{
- RTLIL::Const element = cell->parameters["\\INIT"].extract(i*width, width);
+ RTLIL::Const element = cell->parameters[ID::INIT].extract(i*width, width);
for (int j=0; j<element.size(); j++)
{
switch (element[element.size()-j-1])
@@ -1123,7 +1123,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
for (int i=0; i<size; i++)
{
f << stringf("%s" " %s[%d] = ", indent.c_str(), mem_id.c_str(), i);
- dump_const(f, cell->parameters["\\INIT"].extract(i*width, width));
+ dump_const(f, cell->parameters[ID::INIT].extract(i*width, width));
f << stringf(";\n");
}
f << stringf("%s" "end\n", indent.c_str());
@@ -1137,19 +1137,19 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
// create a list of reg declarations
std::vector<std::string> lof_reg_declarations;
- int nread_ports = cell->parameters["\\RD_PORTS"].as_int();
+ int nread_ports = cell->parameters[ID::RD_PORTS].as_int();
RTLIL::SigSpec sig_rd_clk, sig_rd_en, sig_rd_data, sig_rd_addr;
bool use_rd_clk, rd_clk_posedge, rd_transparent;
// read ports
for (int i=0; i < nread_ports; i++)
{
- sig_rd_clk = cell->getPort("\\RD_CLK").extract(i);
- sig_rd_en = cell->getPort("\\RD_EN").extract(i);
- sig_rd_data = cell->getPort("\\RD_DATA").extract(i*width, width);
- sig_rd_addr = cell->getPort("\\RD_ADDR").extract(i*abits, abits);
- use_rd_clk = cell->parameters["\\RD_CLK_ENABLE"].extract(i).as_bool();
- rd_clk_posedge = cell->parameters["\\RD_CLK_POLARITY"].extract(i).as_bool();
- rd_transparent = cell->parameters["\\RD_TRANSPARENT"].extract(i).as_bool();
+ sig_rd_clk = cell->getPort(ID::RD_CLK).extract(i);
+ sig_rd_en = cell->getPort(ID::RD_EN).extract(i);
+ sig_rd_data = cell->getPort(ID::RD_DATA).extract(i*width, width);
+ sig_rd_addr = cell->getPort(ID::RD_ADDR).extract(i*abits, abits);
+ use_rd_clk = cell->parameters[ID::RD_CLK_ENABLE].extract(i).as_bool();
+ rd_clk_posedge = cell->parameters[ID::RD_CLK_POLARITY].extract(i).as_bool();
+ rd_transparent = cell->parameters[ID::RD_TRANSPARENT].extract(i).as_bool();
if (use_rd_clk)
{
{
@@ -1221,18 +1221,18 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
}
}
- int nwrite_ports = cell->parameters["\\WR_PORTS"].as_int();
+ int nwrite_ports = cell->parameters[ID::WR_PORTS].as_int();
RTLIL::SigSpec sig_wr_clk, sig_wr_data, sig_wr_addr, sig_wr_en;
bool wr_clk_posedge;
// write ports
for (int i=0; i < nwrite_ports; i++)
{
- sig_wr_clk = cell->getPort("\\WR_CLK").extract(i);
- sig_wr_data = cell->getPort("\\WR_DATA").extract(i*width, width);
- sig_wr_addr = cell->getPort("\\WR_ADDR").extract(i*abits, abits);
- sig_wr_en = cell->getPort("\\WR_EN").extract(i*width, width);
- wr_clk_posedge = cell->parameters["\\WR_CLK_POLARITY"].extract(i).as_bool();
+ sig_wr_clk = cell->getPort(ID::WR_CLK).extract(i);
+ sig_wr_data = cell->getPort(ID::WR_DATA).extract(i*width, width);
+ sig_wr_addr = cell->getPort(ID::WR_ADDR).extract(i*abits, abits);
+ sig_wr_en = cell->getPort(ID::WR_EN).extract(i*width, width);
+ wr_clk_posedge = cell->parameters[ID::WR_CLK_POLARITY].extract(i).as_bool();
{
std::ostringstream os;
dump_sigspec(os, sig_wr_clk);
@@ -1319,66 +1319,66 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type.in("$assert", "$assume", "$cover"))
+ if (cell->type.in(ID($assert), ID($assume), ID($cover)))
{
f << stringf("%s" "always @* if (", indent.c_str());
- dump_sigspec(f, cell->getPort("\\EN"));
+ dump_sigspec(f, cell->getPort(ID::EN));
f << stringf(") %s(", cell->type.c_str()+1);
- dump_sigspec(f, cell->getPort("\\A"));
+ dump_sigspec(f, cell->getPort(ID::A));
f << stringf(");\n");
return true;
}
- if (cell->type.in("$specify2", "$specify3"))
+ if (cell->type.in(ID($specify2), ID($specify3)))
{
f << stringf("%s" "specify\n%s ", indent.c_str(), indent.c_str());
- SigSpec en = cell->getPort("\\EN");
+ SigSpec en = cell->getPort(ID::EN);
if (en != State::S1) {
f << stringf("if (");
- dump_sigspec(f, cell->getPort("\\EN"));
+ dump_sigspec(f, cell->getPort(ID::EN));
f << stringf(") ");
}
f << "(";
- if (cell->type == "$specify3" && cell->getParam("\\EDGE_EN").as_bool())
- f << (cell->getParam("\\EDGE_POL").as_bool() ? "posedge ": "negedge ");
+ if (cell->type == ID($specify3) && cell->getParam(ID::EDGE_EN).as_bool())
+ f << (cell->getParam(ID::EDGE_POL).as_bool() ? "posedge ": "negedge ");
- dump_sigspec(f, cell->getPort("\\SRC"));
+ dump_sigspec(f, cell->getPort(ID::SRC));
f << " ";
- if (cell->getParam("\\SRC_DST_PEN").as_bool())
- f << (cell->getParam("\\SRC_DST_POL").as_bool() ? "+": "-");
- f << (cell->getParam("\\FULL").as_bool() ? "*> ": "=> ");
+ if (cell->getParam(ID::SRC_DST_PEN).as_bool())
+ f << (cell->getParam(ID::SRC_DST_POL).as_bool() ? "+": "-");
+ f << (cell->getParam(ID::FULL).as_bool() ? "*> ": "=> ");
- if (cell->type == "$specify3") {
+ if (cell->type == ID($specify3)) {
f << "(";
- dump_sigspec(f, cell->getPort("\\DST"));
+ dump_sigspec(f, cell->getPort(ID::DST));
f << " ";
- if (cell->getParam("\\DAT_DST_PEN").as_bool())
- f << (cell->getParam("\\DAT_DST_POL").as_bool() ? "+": "-");
+ if (cell->getParam(ID::DAT_DST_PEN).as_bool())
+ f << (cell->getParam(ID::DAT_DST_POL).as_bool() ? "+": "-");
f << ": ";
- dump_sigspec(f, cell->getPort("\\DAT"));
+ dump_sigspec(f, cell->getPort(ID::DAT));
f << ")";
} else {
- dump_sigspec(f, cell->getPort("\\DST"));
+ dump_sigspec(f, cell->getPort(ID::DST));
}
bool bak_decimal = decimal;
decimal = 1;
f << ") = (";
- dump_const(f, cell->getParam("\\T_RISE_MIN"));
+ dump_const(f, cell->getParam(ID::T_RISE_MIN));
f << ":";
- dump_const(f, cell->getParam("\\T_RISE_TYP"));
+ dump_const(f, cell->getParam(ID::T_RISE_TYP));
f << ":";
- dump_const(f, cell->getParam("\\T_RISE_MAX"));
+ dump_const(f, cell->getParam(ID::T_RISE_MAX));
f << ", ";
- dump_const(f, cell->getParam("\\T_FALL_MIN"));
+ dump_const(f, cell->getParam(ID::T_FALL_MIN));
f << ":";
- dump_const(f, cell->getParam("\\T_FALL_TYP"));
+ dump_const(f, cell->getParam(ID::T_FALL_TYP));
f << ":";
- dump_const(f, cell->getParam("\\T_FALL_MAX"));
+ dump_const(f, cell->getParam(ID::T_FALL_MAX));
f << ");\n";
decimal = bak_decimal;
@@ -1387,49 +1387,49 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type == "$specrule")
+ if (cell->type == ID($specrule))
{
f << stringf("%s" "specify\n%s ", indent.c_str(), indent.c_str());
- string spec_type = cell->getParam("\\TYPE").decode_string();
+ IdString spec_type = cell->getParam(ID::TYPE).decode_string();
f << stringf("%s(", spec_type.c_str());
- if (cell->getParam("\\SRC_PEN").as_bool())
- f << (cell->getParam("\\SRC_POL").as_bool() ? "posedge ": "negedge ");
- dump_sigspec(f, cell->getPort("\\SRC"));
+ if (cell->getParam(ID::SRC_PEN).as_bool())
+ f << (cell->getParam(ID::SRC_POL).as_bool() ? "posedge ": "negedge ");
+ dump_sigspec(f, cell->getPort(ID::SRC));
- if (cell->getPort("\\SRC_EN") != State::S1) {
+ if (cell->getPort(ID::SRC_EN) != State::S1) {
f << " &&& ";
- dump_sigspec(f, cell->getPort("\\SRC_EN"));
+ dump_sigspec(f, cell->getPort(ID::SRC_EN));
}
f << ", ";
- if (cell->getParam("\\DST_PEN").as_bool())
- f << (cell->getParam("\\DST_POL").as_bool() ? "posedge ": "negedge ");
- dump_sigspec(f, cell->getPort("\\DST"));
+ if (cell->getParam(ID::DST_PEN).as_bool())
+ f << (cell->getParam(ID::DST_POL).as_bool() ? "posedge ": "negedge ");
+ dump_sigspec(f, cell->getPort(ID::DST));
- if (cell->getPort("\\DST_EN") != State::S1) {
+ if (cell->getPort(ID::DST_EN) != State::S1) {
f << " &&& ";
- dump_sigspec(f, cell->getPort("\\DST_EN"));
+ dump_sigspec(f, cell->getPort(ID::DST_EN));
}
bool bak_decimal = decimal;
decimal = 1;
f << ", ";
- dump_const(f, cell->getParam("\\T_LIMIT_MIN"));
+ dump_const(f, cell->getParam(ID::T_LIMIT_MIN));
f << ": ";
- dump_const(f, cell->getParam("\\T_LIMIT_TYP"));
+ dump_const(f, cell->getParam(ID::T_LIMIT_TYP));
f << ": ";
- dump_const(f, cell->getParam("\\T_LIMIT_MAX"));
+ dump_const(f, cell->getParam(ID::T_LIMIT_MAX));
- if (spec_type == "$setuphold" || spec_type == "$recrem" || spec_type == "$fullskew") {
+ if (spec_type.in(ID($setuphold), ID($recrem), ID($fullskew))) {
f << ", ";
- dump_const(f, cell->getParam("\\T_LIMIT2_MIN"));
+ dump_const(f, cell->getParam(ID::T_LIMIT2_MIN));
f << ": ";
- dump_const(f, cell->getParam("\\T_LIMIT2_TYP"));
+ dump_const(f, cell->getParam(ID::T_LIMIT2_TYP));
f << ": ";
- dump_const(f, cell->getParam("\\T_LIMIT2_MAX"));
+ dump_const(f, cell->getParam(ID::T_LIMIT2_MAX));
}
f << ");\n";
@@ -1513,9 +1513,9 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
}
}
- if (siminit && reg_ct.count(cell->type) && cell->hasPort("\\Q")) {
+ if (siminit && reg_ct.count(cell->type) && cell->hasPort(ID::Q)) {
std::stringstream ss;
- dump_reg_init(ss, cell->getPort("\\Q"));
+ dump_reg_init(ss, cell->getPort(ID::Q));
if (!ss.str().empty()) {
f << stringf("%sinitial %s.Q", indent.c_str(), cell_name.c_str());
f << ss.str();
@@ -1698,9 +1698,9 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
active_initdata.clear();
for (auto wire : module->wires())
- if (wire->attributes.count("\\init")) {
+ if (wire->attributes.count(ID::init)) {
SigSpec sig = active_sigmap(wire);
- Const val = wire->attributes.at("\\init");
+ Const val = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(sig) && i < GetSize(val); i++)
if (val[i] == State::S0 || val[i] == State::S1)
active_initdata[sig[i]] = val[i];
@@ -1719,13 +1719,12 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
if (!noexpr)
{
std::set<std::pair<RTLIL::Wire*,int>> reg_bits;
- for (auto &it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = it.second;
- if (!reg_ct.count(cell->type) || !cell->hasPort("\\Q"))
+ if (!reg_ct.count(cell->type) || !cell->hasPort(ID::Q))
continue;
- RTLIL::SigSpec sig = cell->getPort("\\Q");
+ RTLIL::SigSpec sig = cell->getPort(ID::Q);
if (sig.is_chunk()) {
RTLIL::SigChunk chunk = sig.as_chunk();
@@ -1734,9 +1733,8 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
reg_bits.insert(std::pair<RTLIL::Wire*,int>(chunk.wire, chunk.offset+i));
}
}
- for (auto &it : module->wires_)
+ for (auto wire : module->wires())
{
- RTLIL::Wire *wire = it.second;
for (int i = 0; i < wire->width; i++)
if (reg_bits.count(std::pair<RTLIL::Wire*,int>(wire, i)) == 0)
goto this_wire_aint_reg;
@@ -1751,8 +1749,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
bool keep_running = true;
for (int port_id = 1; keep_running; port_id++) {
keep_running = false;
- for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it) {
- RTLIL::Wire *wire = it->second;
+ for (auto wire : module->wires()) {
if (wire->port_id == port_id) {
if (port_id != 1)
f << stringf(", ");
@@ -1764,14 +1761,14 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
}
f << stringf(");\n");
- for (auto it = module->wires_.begin(); it != module->wires_.end(); ++it)
- dump_wire(f, indent + " ", it->second);
+ for (auto w : module->wires())
+ dump_wire(f, indent + " ", w);
for (auto it = module->memories.begin(); it != module->memories.end(); ++it)
dump_memory(f, indent + " ", it->second);
- for (auto it = module->cells_.begin(); it != module->cells_.end(); ++it)
- dump_cell(f, indent + " ", it->second);
+ for (auto cell : module->cells())
+ dump_cell(f, indent + " ", cell);
for (auto it = module->processes.begin(); it != module->processes.end(); ++it)
dump_process(f, indent + " ", it->second);
@@ -1892,31 +1889,31 @@ struct VerilogBackend : public Backend {
reg_wires.clear();
reg_ct.clear();
- reg_ct.insert("$dff");
- reg_ct.insert("$adff");
- reg_ct.insert("$dffe");
- reg_ct.insert("$dlatch");
-
- reg_ct.insert("$_DFF_N_");
- reg_ct.insert("$_DFF_P_");
-
- reg_ct.insert("$_DFF_NN0_");
- reg_ct.insert("$_DFF_NN1_");
- reg_ct.insert("$_DFF_NP0_");
- reg_ct.insert("$_DFF_NP1_");
- reg_ct.insert("$_DFF_PN0_");
- reg_ct.insert("$_DFF_PN1_");
- reg_ct.insert("$_DFF_PP0_");
- reg_ct.insert("$_DFF_PP1_");
-
- reg_ct.insert("$_DFFSR_NNN_");
- reg_ct.insert("$_DFFSR_NNP_");
- reg_ct.insert("$_DFFSR_NPN_");
- reg_ct.insert("$_DFFSR_NPP_");
- reg_ct.insert("$_DFFSR_PNN_");
- reg_ct.insert("$_DFFSR_PNP_");
- reg_ct.insert("$_DFFSR_PPN_");
- reg_ct.insert("$_DFFSR_PPP_");
+ reg_ct.insert(ID($dff));
+ reg_ct.insert(ID($adff));
+ reg_ct.insert(ID($dffe));
+ reg_ct.insert(ID($dlatch));
+
+ reg_ct.insert(ID($_DFF_N_));
+ reg_ct.insert(ID($_DFF_P_));
+
+ reg_ct.insert(ID($_DFF_NN0_));
+ reg_ct.insert(ID($_DFF_NN1_));
+ reg_ct.insert(ID($_DFF_NP0_));
+ reg_ct.insert(ID($_DFF_NP1_));
+ reg_ct.insert(ID($_DFF_PN0_));
+ reg_ct.insert(ID($_DFF_PN1_));
+ reg_ct.insert(ID($_DFF_PP0_));
+ reg_ct.insert(ID($_DFF_PP1_));
+
+ reg_ct.insert(ID($_DFFSR_NNN_));
+ reg_ct.insert(ID($_DFFSR_NNP_));
+ reg_ct.insert(ID($_DFFSR_NPN_));
+ reg_ct.insert(ID($_DFFSR_NPP_));
+ reg_ct.insert(ID($_DFFSR_PNN_));
+ reg_ct.insert(ID($_DFFSR_PNP_));
+ reg_ct.insert(ID($_DFFSR_PPN_));
+ reg_ct.insert(ID($_DFFSR_PPP_));
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
@@ -1987,7 +1984,7 @@ struct VerilogBackend : public Backend {
extra_args(f, filename, args, argidx);
if (extmem)
{
- if (filename.empty())
+ if (filename == "<stdout>")
log_cmd_error("Option -extmem must be used with a filename.\n");
extmem_prefix = filename.substr(0, filename.rfind('.'));
}
@@ -1995,16 +1992,16 @@ struct VerilogBackend : public Backend {
design->sort();
*f << stringf("/* Generated by %s */\n", yosys_version_str);
- for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it) {
- if (it->second->get_blackbox_attribute() != blackboxes)
+ for (auto module : design->modules()) {
+ if (module->get_blackbox_attribute() != blackboxes)
continue;
- if (selected && !design->selected_whole_module(it->first)) {
- if (design->selected_module(it->first))
- log_cmd_error("Can't handle partially selected module %s!\n", RTLIL::id2cstr(it->first));
+ if (selected && !design->selected_whole_module(module->name)) {
+ if (design->selected_module(module->name))
+ log_cmd_error("Can't handle partially selected module %s!\n", log_id(module->name));
continue;
}
- log("Dumping module `%s'.\n", it->first.c_str());
- dump_module(*f, "", it->second);
+ log("Dumping module `%s'.\n", module->name.c_str());
+ dump_module(*f, "", module);
}
auto_name_map.clear();
diff --git a/examples/cxx-api/evaldemo.cc b/examples/cxx-api/evaldemo.cc
index 34373487d..756b7faac 100644
--- a/examples/cxx-api/evaldemo.cc
+++ b/examples/cxx-api/evaldemo.cc
@@ -29,8 +29,8 @@ struct EvalDemoPass : public Pass
if (module == nullptr)
log_error("No top module found!\n");
- Wire *wire_a = module->wire("\\A");
- Wire *wire_y = module->wire("\\Y");
+ Wire *wire_a = module->wire(ID::A);
+ Wire *wire_y = module->wire(ID::Y);
if (wire_a == nullptr)
log_error("No wire A found!\n");
diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc
index 50c2a3ce6..92cf92fa8 100644
--- a/frontends/aiger/aigerparse.cc
+++ b/frontends/aiger/aigerparse.cc
@@ -30,7 +30,9 @@
#include <libkern/OSByteOrder.h>
#define __builtin_bswap32 OSSwapInt32
#endif
+#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
+#endif
#include <inttypes.h>
#include "kernel/yosys.h"
@@ -117,7 +119,7 @@ struct ConstEvalAig
sig2deps[output].insert(output);
RTLIL::Cell *cell = sig2driver.at(output);
- RTLIL::SigBit sig_a = cell->getPort("\\A");
+ RTLIL::SigBit sig_a = cell->getPort(ID::A);
sig2deps[sig_a].reserve(sig2deps[sig_a].size() + sig2deps[output].size()); // Reserve so that any invalidation
// that may occur does so here, and
// not mid insertion (below)
@@ -125,8 +127,8 @@ struct ConstEvalAig
if (!inputs.count(sig_a))
compute_deps(sig_a, inputs);
- if (cell->type == "$_AND_") {
- RTLIL::SigSpec sig_b = cell->getPort("\\B");
+ if (cell->type == ID($_AND_)) {
+ RTLIL::SigSpec sig_b = cell->getPort(ID::B);
sig2deps[sig_b].reserve(sig2deps[sig_b].size() + sig2deps[output].size()); // Reserve so that any invalidation
// that may occur does so here, and
// not mid insertion (below)
@@ -135,34 +137,34 @@ struct ConstEvalAig
if (!inputs.count(sig_b))
compute_deps(sig_b, inputs);
}
- else if (cell->type == "$_NOT_") {
+ else if (cell->type == ID($_NOT_)) {
}
else log_abort();
}
bool eval(RTLIL::Cell *cell)
{
- RTLIL::SigBit sig_y = cell->getPort("\\Y");
+ RTLIL::SigBit sig_y = cell->getPort(ID::Y);
if (values_map.count(sig_y))
return true;
- RTLIL::SigBit sig_a = cell->getPort("\\A");
+ RTLIL::SigBit sig_a = cell->getPort(ID::A);
if (!eval(sig_a))
return false;
RTLIL::State eval_ret = RTLIL::Sx;
- if (cell->type == "$_NOT_") {
+ if (cell->type == ID($_NOT_)) {
if (sig_a == State::S0) eval_ret = State::S1;
else if (sig_a == State::S1) eval_ret = State::S0;
}
- else if (cell->type == "$_AND_") {
+ else if (cell->type == ID($_AND_)) {
if (sig_a == State::S0) {
eval_ret = State::S0;
goto eval_end;
}
{
- RTLIL::SigBit sig_b = cell->getPort("\\B");
+ RTLIL::SigBit sig_b = cell->getPort(ID::B);
if (!eval(sig_b))
return false;
if (sig_b == State::S0) {
@@ -478,9 +480,9 @@ void AigerReader::parse_xaiger()
log_assert(boxUniqueId > 0);
uint32_t oldBoxNum = parse_xaiger_literal(f);
RTLIL::Cell* cell = module->addCell(stringf("$box%u", oldBoxNum), stringf("$__boxid%u", boxUniqueId));
- cell->setPort("\\i", SigSpec(State::S0, boxInputs));
- cell->setPort("\\o", SigSpec(State::S0, boxOutputs));
- cell->attributes["\\abc9_box_seq"] = oldBoxNum;
+ cell->setPort(ID(i), SigSpec(State::S0, boxInputs));
+ cell->setPort(ID(o), SigSpec(State::S0, boxOutputs));
+ cell->attributes[ID::abc9_box_seq] = oldBoxNum;
boxes.emplace_back(cell);
}
}
@@ -548,18 +550,18 @@ void AigerReader::parse_aiger_ascii()
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
if (l3 == 0)
- q_wire->attributes["\\init"] = State::S0;
+ q_wire->attributes[ID::init] = State::S0;
else if (l3 == 1)
- q_wire->attributes["\\init"] = State::S1;
+ q_wire->attributes[ID::init] = State::S1;
else if (l3 == l1) {
- //q_wire->attributes["\\init"] = RTLIL::Sx;
+ //q_wire->attributes[ID::init] = RTLIL::Sx;
}
else
log_error("Line %u has invalid reset literal for latch!\n", line_count);
}
else {
// AIGER latches are assumed to be initialized to zero
- q_wire->attributes["\\init"] = State::S0;
+ q_wire->attributes[ID::init] = State::S0;
}
latches.push_back(q_wire);
}
@@ -673,18 +675,18 @@ void AigerReader::parse_aiger_binary()
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
if (l3 == 0)
- q_wire->attributes["\\init"] = State::S0;
+ q_wire->attributes[ID::init] = State::S0;
else if (l3 == 1)
- q_wire->attributes["\\init"] = State::S1;
+ q_wire->attributes[ID::init] = State::S1;
else if (l3 == l1) {
- //q_wire->attributes["\\init"] = RTLIL::Sx;
+ //q_wire->attributes[ID::init] = RTLIL::Sx;
}
else
log_error("Line %u has invalid reset literal for latch!\n", line_count);
}
else {
// AIGER latches are assumed to be initialized to zero
- q_wire->attributes["\\init"] = State::S0;
+ q_wire->attributes[ID::init] = State::S0;
}
latches.push_back(q_wire);
}
@@ -747,7 +749,7 @@ void AigerReader::post_process()
{
unsigned ci_count = 0, co_count = 0;
for (auto cell : boxes) {
- for (auto &bit : cell->connections_.at("\\i")) {
+ for (auto &bit : cell->connections_.at(ID(i))) {
log_assert(bit == State::S0);
log_assert(co_count < outputs.size());
bit = outputs[co_count++];
@@ -755,7 +757,7 @@ void AigerReader::post_process()
log_assert(bit.wire->port_output);
bit.wire->port_output = false;
}
- for (auto &bit : cell->connections_.at("\\o")) {
+ for (auto &bit : cell->connections_.at(ID(o))) {
log_assert(bit == State::S0);
log_assert((piNum + ci_count) < inputs.size());
bit = inputs[piNum + ci_count++];
@@ -776,10 +778,10 @@ void AigerReader::post_process()
log_assert(q->port_input);
q->port_input = false;
- auto ff = module->addCell(NEW_ID, "$__ABC9_FF_");
- ff->setPort("\\D", d);
- ff->setPort("\\Q", q);
- ff->attributes["\\abc9_mergeability"] = mergeability[i];
+ auto ff = module->addCell(NEW_ID, ID($__ABC9_FF_));
+ ff->setPort(ID::D, d);
+ ff->setPort(ID::Q, q);
+ ff->attributes[ID::abc9_mergeability] = mergeability[i];
}
dict<RTLIL::IdString, int> wideports_cache;
@@ -866,7 +868,7 @@ void AigerReader::post_process()
int init;
mf >> init;
if (init < 2)
- wire->attributes["\\init"] = init;
+ wire->attributes[ID::init] = init;
}
else if (type == "box") {
RTLIL::Cell* cell = module->cell(stringf("$box%d", variable));
@@ -929,8 +931,8 @@ void AigerReader::post_process()
design->add(module);
for (auto cell : module->cells().to_vector()) {
- if (cell->type != "$lut") continue;
- auto y_port = cell->getPort("\\Y").as_bit();
+ if (cell->type != ID($lut)) continue;
+ auto y_port = cell->getPort(ID::Y).as_bit();
if (y_port.wire->width == 1)
module->rename(cell, stringf("$lut%s", y_port.wire->name.c_str()));
else
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index d1f136fd7..2b6002548 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -952,9 +952,9 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
current_module = new AstModule;
current_module->ast = NULL;
current_module->name = ast->str;
- current_module->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line,
+ current_module->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line,
ast->location.first_column, ast->location.last_line, ast->location.last_column);
- current_module->set_bool_attribute("\\cells_not_processed");
+ current_module->set_bool_attribute(ID::cells_not_processed);
current_ast_mod = ast;
AstNode *ast_before_simplify;
@@ -1007,61 +1007,61 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
log("--- END OF AST DUMP ---\n");
}
- if (flag_nowb && ast->attributes.count("\\whitebox")) {
- delete ast->attributes.at("\\whitebox");
- ast->attributes.erase("\\whitebox");
+ if (flag_nowb && ast->attributes.count(ID::whitebox)) {
+ delete ast->attributes.at(ID::whitebox);
+ ast->attributes.erase(ID::whitebox);
}
- if (ast->attributes.count("\\lib_whitebox")) {
+ if (ast->attributes.count(ID::lib_whitebox)) {
if (!flag_lib || flag_nowb) {
- delete ast->attributes.at("\\lib_whitebox");
- ast->attributes.erase("\\lib_whitebox");
+ delete ast->attributes.at(ID::lib_whitebox);
+ ast->attributes.erase(ID::lib_whitebox);
} else {
- if (ast->attributes.count("\\whitebox")) {
- delete ast->attributes.at("\\whitebox");
- ast->attributes.erase("\\whitebox");
+ if (ast->attributes.count(ID::whitebox)) {
+ delete ast->attributes.at(ID::whitebox);
+ ast->attributes.erase(ID::whitebox);
}
- AstNode *n = ast->attributes.at("\\lib_whitebox");
- ast->attributes["\\whitebox"] = n;
- ast->attributes.erase("\\lib_whitebox");
+ AstNode *n = ast->attributes.at(ID::lib_whitebox);
+ ast->attributes[ID::whitebox] = n;
+ ast->attributes.erase(ID::lib_whitebox);
}
}
- if (!blackbox_module && ast->attributes.count("\\blackbox")) {
- AstNode *n = ast->attributes.at("\\blackbox");
+ if (!blackbox_module && ast->attributes.count(ID::blackbox)) {
+ AstNode *n = ast->attributes.at(ID::blackbox);
if (n->type != AST_CONSTANT)
log_file_error(ast->filename, ast->location.first_line, "Got blackbox attribute with non-constant value!\n");
blackbox_module = n->asBool();
}
- if (blackbox_module && ast->attributes.count("\\whitebox")) {
- AstNode *n = ast->attributes.at("\\whitebox");
+ if (blackbox_module && ast->attributes.count(ID::whitebox)) {
+ AstNode *n = ast->attributes.at(ID::whitebox);
if (n->type != AST_CONSTANT)
log_file_error(ast->filename, ast->location.first_line, "Got whitebox attribute with non-constant value!\n");
blackbox_module = !n->asBool();
}
- if (ast->attributes.count("\\noblackbox")) {
+ if (ast->attributes.count(ID::noblackbox)) {
if (blackbox_module) {
- AstNode *n = ast->attributes.at("\\noblackbox");
+ AstNode *n = ast->attributes.at(ID::noblackbox);
if (n->type != AST_CONSTANT)
log_file_error(ast->filename, ast->location.first_line, "Got noblackbox attribute with non-constant value!\n");
blackbox_module = !n->asBool();
}
- delete ast->attributes.at("\\noblackbox");
- ast->attributes.erase("\\noblackbox");
+ delete ast->attributes.at(ID::noblackbox);
+ ast->attributes.erase(ID::noblackbox);
}
if (blackbox_module)
{
- if (ast->attributes.count("\\whitebox")) {
- delete ast->attributes.at("\\whitebox");
- ast->attributes.erase("\\whitebox");
+ if (ast->attributes.count(ID::whitebox)) {
+ delete ast->attributes.at(ID::whitebox);
+ ast->attributes.erase(ID::whitebox);
}
- if (ast->attributes.count("\\lib_whitebox")) {
- delete ast->attributes.at("\\lib_whitebox");
- ast->attributes.erase("\\lib_whitebox");
+ if (ast->attributes.count(ID::lib_whitebox)) {
+ delete ast->attributes.at(ID::lib_whitebox);
+ ast->attributes.erase(ID::lib_whitebox);
}
std::vector<AstNode*> new_children;
@@ -1082,8 +1082,8 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
ast->children.swap(new_children);
- if (ast->attributes.count("\\blackbox") == 0) {
- ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
+ if (ast->attributes.count(ID::blackbox) == 0) {
+ ast->attributes[ID::blackbox] = AstNode::mkconst_int(1, false);
}
}
@@ -1124,7 +1124,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
}
if (ast->type == AST_INTERFACE)
- current_module->set_bool_attribute("\\is_interface");
+ current_module->set_bool_attribute(ID::is_interface);
current_module->ast = ast_before_simplify;
current_module->nolatches = flag_nolatches;
current_module->nomeminit = flag_nomeminit;
@@ -1212,7 +1212,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
continue;
} else {
log("Replacing existing%s module `%s' at %s:%d.%d-%d.%d.\n",
- existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "",
+ existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "",
(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->location.first_line, (*it)->location.first_column, (*it)->location.last_line, (*it)->location.last_column);
design->remove(existing_mod);
}
@@ -1320,7 +1320,7 @@ void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule
// When an interface instance is found in a module, the whole RTLIL for the module will be rederived again
// from AST. The interface members are copied into the AST module with the prefix of the interface.
-void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces)
+void AstModule::reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module*> &local_interfaces)
{
loadconfig();
@@ -1385,12 +1385,12 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
std::string original_name = this->name.str();
std::string changed_name = original_name + "_before_replacing_local_interfaces";
design->rename(this, changed_name);
- this->set_bool_attribute("\\to_delete");
+ this->set_bool_attribute(ID::to_delete);
// Check if the module was the top module. If it was, we need to remove the top attribute and put it on the
// new module.
- if (this->get_bool_attribute("\\initial_top")) {
- this->attributes.erase("\\initial_top");
+ if (this->get_bool_attribute(ID::initial_top)) {
+ this->attributes.erase(ID::initial_top);
is_top = true;
}
@@ -1400,15 +1400,15 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
design->add(newmod);
RTLIL::Module* mod = design->module(original_name);
if (is_top)
- mod->set_bool_attribute("\\top");
+ mod->set_bool_attribute(ID::top);
// Set the attribute "interfaces_replaced_in_module" so that it does not happen again.
- mod->set_bool_attribute("\\interfaces_replaced_in_module");
+ mod->set_bool_attribute(ID::interfaces_replaced_in_module);
}
// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
// This method is used to explode the interface when the interface is a port of the module (not instantiated inside)
-RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool /*mayfail*/)
+RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool /*mayfail*/)
{
AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast);
@@ -1473,7 +1473,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
// We copy the cell of the interface to the sub-module such that it
// can further be found if it is propagated down to sub-sub-modules etc.
RTLIL::Cell *new_subcell = mod->addCell(intf.first, intf.second->name);
- new_subcell->set_bool_attribute("\\is_interface");
+ new_subcell->set_bool_attribute(ID::is_interface);
}
else {
log_error("No port with matching name found (%s) in %s. Stopping\n", log_id(intf.first), modname.c_str());
@@ -1482,7 +1482,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
// If any interfaces were replaced, set the attribute 'interfaces_replaced_in_module':
if (interfaces.size() > 0) {
- mod->set_bool_attribute("\\interfaces_replaced_in_module");
+ mod->set_bool_attribute(ID::interfaces_replaced_in_module);
}
} else {
@@ -1494,9 +1494,9 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
}
// create a new parametric module (when needed) and return the name of the generated module - without support for interfaces
-RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/)
+RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/)
{
- bool quiet = lib || attributes.count(ID(blackbox)) || attributes.count(ID(whitebox));
+ bool quiet = lib || attributes.count(ID::blackbox) || attributes.count(ID::whitebox);
AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast, quiet);
@@ -1514,7 +1514,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
}
// create a new parametric module (when needed) and return the name of the generated module
-std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet)
+std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet)
{
std::string stripped_name = name.str();
@@ -1528,18 +1528,18 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
if (child->type != AST_PARAMETER)
continue;
para_counter++;
- std::string para_id = child->str;
- if (parameters.count(para_id) > 0) {
+ auto it = parameters.find(child->str);
+ if (it != parameters.end()) {
if (!quiet)
- log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
- para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
+ log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second));
+ para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second));
continue;
}
- para_id = stringf("$%d", para_counter);
- if (parameters.count(para_id) > 0) {
+ it = parameters.find(stringf("$%d", para_counter));
+ if (it != parameters.end()) {
if (!quiet)
- log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
- para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
+ log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second));
+ para_info += stringf("%s=%s", child->str.c_str(), log_signal(it->second));
continue;
}
}
@@ -1559,46 +1559,52 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
loadconfig();
+ pool<IdString> rewritten;
+ rewritten.reserve(GetSize(parameters));
+
AstNode *new_ast = ast->clone();
para_counter = 0;
for (auto child : new_ast->children) {
if (child->type != AST_PARAMETER)
continue;
para_counter++;
- std::string para_id = child->str;
- if (parameters.count(para_id) > 0) {
+ auto it = parameters.find(child->str);
+ if (it != parameters.end()) {
if (!quiet)
- log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
+ log("Parameter %s = %s\n", child->str.c_str(), log_signal(it->second));
goto rewrite_parameter;
}
- para_id = stringf("$%d", para_counter);
- if (parameters.count(para_id) > 0) {
+ it = parameters.find(stringf("$%d", para_counter));
+ if (it != parameters.end()) {
if (!quiet)
- log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
+ log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(it->second));
goto rewrite_parameter;
}
continue;
rewrite_parameter:
delete child->children.at(0);
- if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) {
+ if ((it->second.flags & RTLIL::CONST_FLAG_REAL) != 0) {
child->children[0] = new AstNode(AST_REALVALUE);
- child->children[0]->realvalue = std::stod(parameters[para_id].decode_string());
- } else if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0)
- child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string());
+ child->children[0]->realvalue = std::stod(it->second.decode_string());
+ } else if ((it->second.flags & RTLIL::CONST_FLAG_STRING) != 0)
+ child->children[0] = AstNode::mkconst_str(it->second.decode_string());
else
- child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0);
- parameters.erase(para_id);
+ child->children[0] = AstNode::mkconst_bits(it->second.bits, (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0);
+ rewritten.insert(it->first);
}
- for (auto param : parameters) {
- AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER));
- defparam->children[0]->str = param.first.str();
- if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0)
- defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string()));
- else
- defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0));
- new_ast->children.push_back(defparam);
- }
+ if (GetSize(rewritten) < GetSize(parameters))
+ for (const auto &param : parameters) {
+ if (rewritten.count(param.first))
+ continue;
+ AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER));
+ defparam->children[0]->str = param.first.str();
+ if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0)
+ defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string()));
+ else
+ defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0));
+ new_ast->children.push_back(defparam);
+ }
(*new_ast_out) = new_ast;
return modname;
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index e27ab10c2..3dd40238f 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -312,10 +312,10 @@ namespace AST
AstNode *ast;
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
~AstModule() YS_OVERRIDE;
- RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE;
- RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE;
- std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool quiet = false);
- void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE;
+ RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail) YS_OVERRIDE;
+ RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail) YS_OVERRIDE;
+ std::string derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet = false);
+ void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces) YS_OVERRIDE;
RTLIL::Module *clone() const YS_OVERRIDE;
void loadconfig() const;
};
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 54d8a11fa..ab368fdb0 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -41,16 +41,14 @@ using namespace AST;
using namespace AST_INTERNAL;
// helper function for creating RTLIL code for unary operations
-static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
+static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &arg, bool gen_attributes = true)
{
- std::stringstream sstr;
- sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
-
- RTLIL::Cell *cell = current_module->addCell(sstr.str(), type);
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
+ RTLIL::Cell *cell = current_module->addCell(name, type);
+ cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
if (gen_attributes)
for (auto &attr : that->attributes) {
@@ -59,12 +57,12 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, std::string type, int result_wi
cell->attributes[attr.first] = attr.second->asAttrConst();
}
- cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed);
- cell->parameters["\\A_WIDTH"] = RTLIL::Const(arg.size());
- cell->setPort("\\A", arg);
+ cell->parameters[ID::A_SIGNED] = RTLIL::Const(that->children[0]->is_signed);
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(arg.size());
+ cell->setPort(ID::A, arg);
- cell->parameters["\\Y_WIDTH"] = result_width;
- cell->setPort("\\Y", wire);
+ cell->parameters[ID::Y_WIDTH] = result_width;
+ cell->setPort(ID::Y, wire);
return wire;
}
@@ -76,14 +74,12 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
return;
}
- std::stringstream sstr;
- sstr << "$extend" << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
-
- RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$pos");
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ IdString name = stringf("$extend$%s:%d$%d", that->filename.c_str(), that->location.first_line, autoidx++);
+ RTLIL::Cell *cell = current_module->addCell(name, ID($pos));
+ cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", width);
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
if (that != NULL)
for (auto &attr : that->attributes) {
@@ -92,26 +88,24 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s
cell->attributes[attr.first] = attr.second->asAttrConst();
}
- cell->parameters["\\A_SIGNED"] = RTLIL::Const(is_signed);
- cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size());
- cell->setPort("\\A", sig);
+ cell->parameters[ID::A_SIGNED] = RTLIL::Const(is_signed);
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig.size());
+ cell->setPort(ID::A, sig);
- cell->parameters["\\Y_WIDTH"] = width;
- cell->setPort("\\Y", wire);
+ cell->parameters[ID::Y_WIDTH] = width;
+ cell->setPort(ID::Y, wire);
sig = wire;
}
// helper function for creating RTLIL code for binary operations
-static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
+static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
- std::stringstream sstr;
- sstr << type << "$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
-
- RTLIL::Cell *cell = current_module->addCell(sstr.str(), type);
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ IdString name = stringf("%s$%s:%d$%d", type.c_str(), that->filename.c_str(), that->location.first_line, autoidx++);
+ RTLIL::Cell *cell = current_module->addCell(name, type);
+ cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -119,17 +113,17 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, std::string type, int result_wi
cell->attributes[attr.first] = attr.second->asAttrConst();
}
- cell->parameters["\\A_SIGNED"] = RTLIL::Const(that->children[0]->is_signed);
- cell->parameters["\\B_SIGNED"] = RTLIL::Const(that->children[1]->is_signed);
+ cell->parameters[ID::A_SIGNED] = RTLIL::Const(that->children[0]->is_signed);
+ cell->parameters[ID::B_SIGNED] = RTLIL::Const(that->children[1]->is_signed);
- cell->parameters["\\A_WIDTH"] = RTLIL::Const(left.size());
- cell->parameters["\\B_WIDTH"] = RTLIL::Const(right.size());
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(left.size());
+ cell->parameters[ID::B_WIDTH] = RTLIL::Const(right.size());
- cell->setPort("\\A", left);
- cell->setPort("\\B", right);
+ cell->setPort(ID::A, left);
+ cell->setPort(ID::B, right);
- cell->parameters["\\Y_WIDTH"] = result_width;
- cell->setPort("\\Y", wire);
+ cell->parameters[ID::Y_WIDTH] = result_width;
+ cell->setPort(ID::Y, wire);
return wire;
}
@@ -141,11 +135,11 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
std::stringstream sstr;
sstr << "$ternary$" << that->filename << ":" << that->location.first_line << "$" << (autoidx++);
- RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$mux");
- cell->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($mux));
+ cell->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size());
- wire->attributes["\\src"] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d", that->filename.c_str(), that->location.first_line);
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -153,12 +147,12 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
cell->attributes[attr.first] = attr.second->asAttrConst();
}
- cell->parameters["\\WIDTH"] = RTLIL::Const(left.size());
+ cell->parameters[ID::WIDTH] = RTLIL::Const(left.size());
- cell->setPort("\\A", right);
- cell->setPort("\\B", left);
- cell->setPort("\\S", cond);
- cell->setPort("\\Y", wire);
+ cell->setPort(ID::A, right);
+ cell->setPort(ID::B, left);
+ cell->setPort(ID::S, cond);
+ cell->setPort(ID::Y, wire);
return wire;
}
@@ -199,7 +193,7 @@ struct AST_INTERNAL::ProcessGenerator
{
// generate process and simple root case
proc = new RTLIL::Process;
- proc->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
+ proc->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
proc->name = stringf("$proc$%s:%d$%d", always->filename.c_str(), always->location.first_line, autoidx++);
for (auto &attr : always->attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -221,7 +215,7 @@ struct AST_INTERNAL::ProcessGenerator
for (auto child : always->children)
{
if ((child->type == AST_POSEDGE || child->type == AST_NEGEDGE) && GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER &&
- child->children.at(0)->id2ast && child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute("\\gclk")) {
+ child->children.at(0)->id2ast && child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute(ID::gclk)) {
found_global_syncs = true;
}
if (child->type == AST_EDGE) {
@@ -245,7 +239,7 @@ struct AST_INTERNAL::ProcessGenerator
for (auto child : always->children)
if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE) {
if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->id2ast &&
- child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute("\\gclk"))
+ child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute(ID::gclk))
continue;
found_clocked_sync = true;
if (found_global_syncs || found_anyedge_syncs)
@@ -267,7 +261,7 @@ struct AST_INTERNAL::ProcessGenerator
}
// create initial assignments for the temporary signals
- if ((flag_nolatches || always->get_bool_attribute("\\nolatches") || current_module->get_bool_attribute("\\nolatches")) && !found_clocked_sync) {
+ if ((flag_nolatches || always->get_bool_attribute(ID::nolatches) || current_module->get_bool_attribute(ID::nolatches)) && !found_clocked_sync) {
subst_rvalue_map = subst_lvalue_from.to_sigbit_dict(RTLIL::SigSpec(RTLIL::State::Sx, GetSize(subst_lvalue_from)));
} else {
addChunkActions(current_case->actions, subst_lvalue_to, subst_lvalue_from);
@@ -335,7 +329,7 @@ struct AST_INTERNAL::ProcessGenerator
} while (current_module->wires_.count(wire_name) > 0);
RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width);
- wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", always->filename.c_str(), always->location.first_line, always->location.first_column, always->location.last_line, always->location.last_column);
chunk.wire = wire;
chunk.offset = 0;
@@ -420,7 +414,7 @@ struct AST_INTERNAL::ProcessGenerator
for (auto &lvalue_c : lvalue.chunks()) {
RTLIL::SigSpec lhs = lvalue_c;
RTLIL::SigSpec rhs = rvalue.extract(offset, lvalue_c.width);
- if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute("\\nosync"))
+ if (inSyncRule && lvalue_c.wire && lvalue_c.wire->get_bool_attribute(ID::nosync))
rhs = RTLIL::SigSpec(RTLIL::State::Sx, rhs.size());
remove_unwanted_lvalue_bits(lhs, rhs);
actions.push_back(RTLIL::SigSig(lhs, rhs));
@@ -470,7 +464,7 @@ struct AST_INTERNAL::ProcessGenerator
case AST_CASE:
{
RTLIL::SwitchRule *sw = new RTLIL::SwitchRule;
- sw->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column);
+ sw->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column);
sw->signal = ast->children[0]->genWidthRTLIL(-1, &subst_rvalue_map.stdmap());
current_case->switches.push_back(sw);
@@ -504,7 +498,7 @@ struct AST_INTERNAL::ProcessGenerator
RTLIL::CaseRule *backup_case = current_case;
current_case = new RTLIL::CaseRule;
- current_case->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", child->filename.c_str(), child->location.first_line, child->location.first_column, child->location.last_line, child->location.last_column);
+ current_case->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", child->filename.c_str(), child->location.first_line, child->location.first_column, child->location.last_line, child->location.last_column);
last_generated_case = current_case;
addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
for (auto node : child->children) {
@@ -525,7 +519,7 @@ struct AST_INTERNAL::ProcessGenerator
subst_rvalue_map.restore();
}
- if (last_generated_case != NULL && ast->get_bool_attribute("\\full_case") && default_case == NULL) {
+ if (last_generated_case != NULL && ast->get_bool_attribute(ID::full_case) && default_case == NULL) {
#if 0
// this is a valid transformation, but as optimization it is premature.
// better: add a default case that assigns 'x' to everything, and let later
@@ -842,7 +836,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// Clifford's Device (http://www.clifford.at/cfun/cliffdev/). In this
// cases this variable is used to hold the type of the cell that should
// be instantiated for this type of AST node.
- std::string type_name;
+ IdString type_name;
current_filename = filename;
@@ -873,19 +867,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// This is used by the hierarchy pass to know when it can replace interface connection with the individual
// signals.
RTLIL::Wire *wire = current_module->addWire(str, 1);
- wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->start_offset = 0;
wire->port_id = port_id;
wire->port_input = true;
wire->port_output = true;
- wire->set_bool_attribute("\\is_interface");
+ wire->set_bool_attribute(ID::is_interface);
if (children.size() > 0) {
for(size_t i=0; i<children.size();i++) {
if(children[i]->type == AST_INTERFACEPORTTYPE) {
std::pair<std::string,std::string> res = AST::split_modport_from_type(children[i]->str);
- wire->attributes["\\interface_type"] = res.first;
+ wire->attributes[ID::interface_type] = res.first;
if (res.second != "")
- wire->attributes["\\interface_modport"] = res.second;
+ wire->attributes[ID::interface_modport] = res.second;
break;
}
}
@@ -910,8 +904,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::Wire *wire = current_module->addWire(str, GetSize(val));
current_module->connect(wire, val);
- wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
- wire->attributes[type == AST_PARAMETER ? "\\parameter" : "\\localparam"] = 1;
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ wire->attributes[type == AST_PARAMETER ? ID::parameter : ID::localparam] = 1;
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -932,7 +926,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1);
RTLIL::Wire *wire = current_module->addWire(str, range_left - range_right + 1);
- wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->start_offset = range_right;
wire->port_id = port_id;
wire->port_input = is_input;
@@ -945,8 +939,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
wire->attributes[attr.first] = attr.second->asAttrConst();
}
- if (is_wand) wire->set_bool_attribute("\\wand");
- if (is_wor) wire->set_bool_attribute("\\wor");
+ if (is_wand) wire->set_bool_attribute(ID::wand);
+ if (is_wor) wire->set_bool_attribute(ID::wor);
}
break;
@@ -963,7 +957,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Memory `%s' with non-constant width or size!\n", str.c_str());
RTLIL::Memory *memory = new RTLIL::Memory;
- memory->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ memory->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
memory->name = str;
memory->width = children[0]->range_left - children[0]->range_right + 1;
if (children[1]->range_right < children[1]->range_left) {
@@ -1018,7 +1012,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (id2ast && id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) {
RTLIL::Wire *wire = current_module->addWire(str);
- wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
wire->name = str;
if (flag_autowire)
log_file_warning(filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str());
@@ -1033,7 +1027,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
else if (id2ast && (id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wires_.count(str) != 0) {
RTLIL::Wire *current_wire = current_module->wire(str);
- if (current_wire->get_bool_attribute("\\is_interface"))
+ if (current_wire->get_bool_attribute(ID::is_interface))
is_interface = true;
// Ignore
}
@@ -1052,16 +1046,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// This makes it possible for the hierarchy pass to see what are interface connections and then replace them
// with the individual signals:
if (is_interface) {
- RTLIL::Wire *dummy_wire;
- std::string dummy_wire_name = "$dummywireforinterface" + str;
- if (current_module->wires_.count(dummy_wire_name))
- dummy_wire = current_module->wires_[dummy_wire_name];
- else {
+ IdString dummy_wire_name = stringf("$dummywireforinterface%s", str.c_str());
+ RTLIL::Wire *dummy_wire = current_module->wire(dummy_wire_name);
+ if (!dummy_wire) {
dummy_wire = current_module->addWire(dummy_wire_name);
- dummy_wire->set_bool_attribute("\\is_interface");
+ dummy_wire->set_bool_attribute(ID::is_interface);
}
- RTLIL::SigSpec tmp = RTLIL::SigSpec(dummy_wire);
- return tmp;
+ return dummy_wire;
}
wire = current_module->wires_[str];
@@ -1097,7 +1088,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
if (GetSize(shift_val) >= 32)
fake_ast->children[1]->is_signed = true;
- RTLIL::SigSpec sig = binop2rtlil(fake_ast, "$shiftx", width, fake_ast->children[0]->genRTLIL(), shift_val);
+ RTLIL::SigSpec sig = binop2rtlil(fake_ast, ID($shiftx), width, fake_ast->children[0]->genRTLIL(), shift_val);
delete left_at_zero_ast;
delete right_at_zero_ast;
delete fake_ast;
@@ -1181,9 +1172,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for unary operations: $not, $pos, $neg
- if (0) { case AST_BIT_NOT: type_name = "$not"; }
- if (0) { case AST_POS: type_name = "$pos"; }
- if (0) { case AST_NEG: type_name = "$neg"; }
+ if (0) { case AST_BIT_NOT: type_name = ID($not); }
+ if (0) { case AST_POS: type_name = ID($pos); }
+ if (0) { case AST_NEG: type_name = ID($neg); }
{
RTLIL::SigSpec arg = children[0]->genRTLIL(width_hint, sign_hint);
is_signed = children[0]->is_signed;
@@ -1196,10 +1187,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $and, $or, $xor, $xnor
- if (0) { case AST_BIT_AND: type_name = "$and"; }
- if (0) { case AST_BIT_OR: type_name = "$or"; }
- if (0) { case AST_BIT_XOR: type_name = "$xor"; }
- if (0) { case AST_BIT_XNOR: type_name = "$xnor"; }
+ if (0) { case AST_BIT_AND: type_name = ID($and); }
+ if (0) { case AST_BIT_OR: type_name = ID($or); }
+ if (0) { case AST_BIT_XOR: type_name = ID($xor); }
+ if (0) { case AST_BIT_XNOR: type_name = ID($xnor); }
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
@@ -1213,10 +1204,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for unary operations: $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor
- if (0) { case AST_REDUCE_AND: type_name = "$reduce_and"; }
- if (0) { case AST_REDUCE_OR: type_name = "$reduce_or"; }
- if (0) { case AST_REDUCE_XOR: type_name = "$reduce_xor"; }
- if (0) { case AST_REDUCE_XNOR: type_name = "$reduce_xnor"; }
+ if (0) { case AST_REDUCE_AND: type_name = ID($reduce_and); }
+ if (0) { case AST_REDUCE_OR: type_name = ID($reduce_or); }
+ if (0) { case AST_REDUCE_XOR: type_name = ID($reduce_xor); }
+ if (0) { case AST_REDUCE_XNOR: type_name = ID($reduce_xnor); }
{
RTLIL::SigSpec arg = children[0]->genRTLIL();
RTLIL::SigSpec sig = uniop2rtlil(this, type_name, max(width_hint, 1), arg);
@@ -1225,7 +1216,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
// generate cells for unary operations: $reduce_bool
// (this is actually just an $reduce_or, but for clarity a different cell type is used)
- if (0) { case AST_REDUCE_BOOL: type_name = "$reduce_bool"; }
+ if (0) { case AST_REDUCE_BOOL: type_name = ID($reduce_bool); }
{
RTLIL::SigSpec arg = children[0]->genRTLIL();
RTLIL::SigSpec sig = arg.size() > 1 ? uniop2rtlil(this, type_name, max(width_hint, 1), arg) : arg;
@@ -1233,10 +1224,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $shl, $shr, $sshl, $sshr
- if (0) { case AST_SHIFT_LEFT: type_name = "$shl"; }
- if (0) { case AST_SHIFT_RIGHT: type_name = "$shr"; }
- if (0) { case AST_SHIFT_SLEFT: type_name = "$sshl"; }
- if (0) { case AST_SHIFT_SRIGHT: type_name = "$sshr"; }
+ if (0) { case AST_SHIFT_LEFT: type_name = ID($shl); }
+ if (0) { case AST_SHIFT_RIGHT: type_name = ID($shr); }
+ if (0) { case AST_SHIFT_SLEFT: type_name = ID($sshl); }
+ if (0) { case AST_SHIFT_SRIGHT: type_name = ID($sshr); }
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
@@ -1260,19 +1251,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
int width = width_hint > 0 ? width_hint : left.size();
is_signed = children[0]->is_signed;
if (!flag_noopt && left.is_fully_const() && left.as_int() == 2 && !right_signed)
- return binop2rtlil(this, "$shl", width, RTLIL::SigSpec(1, left.size()), right);
- return binop2rtlil(this, "$pow", width, left, right);
+ return binop2rtlil(this, ID($shl), width, RTLIL::SigSpec(1, left.size()), right);
+ return binop2rtlil(this, ID($pow), width, left, right);
}
// generate cells for binary operations: $lt, $le, $eq, $ne, $ge, $gt
- if (0) { case AST_LT: type_name = "$lt"; }
- if (0) { case AST_LE: type_name = "$le"; }
- if (0) { case AST_EQ: type_name = "$eq"; }
- if (0) { case AST_NE: type_name = "$ne"; }
- if (0) { case AST_EQX: type_name = "$eqx"; }
- if (0) { case AST_NEX: type_name = "$nex"; }
- if (0) { case AST_GE: type_name = "$ge"; }
- if (0) { case AST_GT: type_name = "$gt"; }
+ if (0) { case AST_LT: type_name = ID($lt); }
+ if (0) { case AST_LE: type_name = ID($le); }
+ if (0) { case AST_EQ: type_name = ID($eq); }
+ if (0) { case AST_NE: type_name = ID($ne); }
+ if (0) { case AST_EQX: type_name = ID($eqx); }
+ if (0) { case AST_NEX: type_name = ID($nex); }
+ if (0) { case AST_GE: type_name = ID($ge); }
+ if (0) { case AST_GT: type_name = ID($gt); }
{
int width = max(width_hint, 1);
width_hint = -1, sign_hint = true;
@@ -1285,11 +1276,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $add, $sub, $mul, $div, $mod
- if (0) { case AST_ADD: type_name = "$add"; }
- if (0) { case AST_SUB: type_name = "$sub"; }
- if (0) { case AST_MUL: type_name = "$mul"; }
- if (0) { case AST_DIV: type_name = "$div"; }
- if (0) { case AST_MOD: type_name = "$mod"; }
+ if (0) { case AST_ADD: type_name = ID($add); }
+ if (0) { case AST_SUB: type_name = ID($sub); }
+ if (0) { case AST_MUL: type_name = ID($mul); }
+ if (0) { case AST_DIV: type_name = ID($div); }
+ if (0) { case AST_MOD: type_name = ID($mod); }
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
@@ -1315,8 +1306,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
// generate cells for binary operations: $logic_and, $logic_or
- if (0) { case AST_LOGIC_AND: type_name = "$logic_and"; }
- if (0) { case AST_LOGIC_OR: type_name = "$logic_or"; }
+ if (0) { case AST_LOGIC_AND: type_name = ID($logic_and); }
+ if (0) { case AST_LOGIC_OR: type_name = ID($logic_or); }
{
RTLIL::SigSpec left = children[0]->genRTLIL();
RTLIL::SigSpec right = children[1]->genRTLIL();
@@ -1327,7 +1318,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_LOGIC_NOT:
{
RTLIL::SigSpec arg = children[0]->genRTLIL();
- return uniop2rtlil(this, "$logic_not", max(width_hint, 1), arg);
+ return uniop2rtlil(this, ID($logic_not), max(width_hint, 1), arg);
}
// generate multiplexer for ternary operator (aka ?:-operator)
@@ -1335,28 +1326,34 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
{
if (width_hint < 0)
detectSignWidth(width_hint, sign_hint);
+ is_signed = sign_hint;
RTLIL::SigSpec cond = children[0]->genRTLIL();
RTLIL::SigSpec sig;
- if (cond.is_fully_const()) {
+
+ if (cond.is_fully_def())
+ {
if (cond.as_bool()) {
sig = children[1]->genRTLIL(width_hint, sign_hint);
- widthExtend(this, sig, sig.size(), children[1]->is_signed);
- }
- else {
+ log_assert(is_signed == children[1]->is_signed);
+ } else {
sig = children[2]->genRTLIL(width_hint, sign_hint);
- widthExtend(this, sig, sig.size(), children[2]->is_signed);
+ log_assert(is_signed == children[2]->is_signed);
}
+
+ widthExtend(this, sig, sig.size(), is_signed);
}
- else {
+ else
+ {
RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint);
RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint);
if (cond.size() > 1)
- cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false);
+ cond = uniop2rtlil(this, ID($reduce_bool), 1, cond, false);
int width = max(val1.size(), val2.size());
- is_signed = children[1]->is_signed && children[2]->is_signed;
+ log_assert(is_signed == children[1]->is_signed);
+ log_assert(is_signed == children[2]->is_signed);
widthExtend(this, val1, width, is_signed);
widthExtend(this, val2, width, is_signed);
@@ -1374,11 +1371,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::stringstream sstr;
sstr << "$memrd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
- RTLIL::Cell *cell = current_module->addCell(sstr.str(), "$memrd");
- cell->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line);
+ RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($memrd));
+ cell->attributes[ID::src] = stringf("%s:%d", filename.c_str(), location.first_line);
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_DATA", current_module->memories[str]->width);
- wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), location.first_line);
+ wire->attributes[ID::src] = stringf("%s:%d", filename.c_str(), location.first_line);
int mem_width, mem_size, addr_bits;
is_signed = id2ast->is_signed;
@@ -1386,18 +1383,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
RTLIL::SigSpec addr_sig = children[0]->genRTLIL();
- cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
- cell->setPort("\\EN", RTLIL::SigSpec(RTLIL::State::Sx, 1));
- cell->setPort("\\ADDR", addr_sig);
- cell->setPort("\\DATA", RTLIL::SigSpec(wire));
+ cell->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::Sx, 1));
+ cell->setPort(ID::EN, RTLIL::SigSpec(RTLIL::State::Sx, 1));
+ cell->setPort(ID::ADDR, addr_sig);
+ cell->setPort(ID::DATA, RTLIL::SigSpec(wire));
- cell->parameters["\\MEMID"] = RTLIL::Const(str);
- cell->parameters["\\ABITS"] = RTLIL::Const(GetSize(addr_sig));
- cell->parameters["\\WIDTH"] = RTLIL::Const(wire->width);
+ cell->parameters[ID::MEMID] = RTLIL::Const(str);
+ cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig));
+ cell->parameters[ID::WIDTH] = RTLIL::Const(wire->width);
- cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0);
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0);
- cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(0);
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(0);
+ cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
if (!sign_hint)
is_signed = false;
@@ -1412,8 +1409,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
std::stringstream sstr;
sstr << (type == AST_MEMWR ? "$memwr$" : "$meminit$") << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
- RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? "$memwr" : "$meminit");
- cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ RTLIL::Cell *cell = current_module->addCell(sstr.str(), type == AST_MEMWR ? ID($memwr) : ID($meminit));
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
int mem_width, mem_size, addr_bits;
id2ast->meminfo(mem_width, mem_size, addr_bits);
@@ -1423,26 +1420,26 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
if (children[2]->type != AST_CONSTANT)
log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n");
num_words = int(children[2]->asInt(false));
- cell->parameters["\\WORDS"] = RTLIL::Const(num_words);
+ cell->parameters[ID::WORDS] = RTLIL::Const(num_words);
}
SigSpec addr_sig = children[0]->genRTLIL();
- cell->setPort("\\ADDR", addr_sig);
- cell->setPort("\\DATA", children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words));
+ cell->setPort(ID::ADDR, addr_sig);
+ cell->setPort(ID::DATA, children[1]->genWidthRTLIL(current_module->memories[str]->width * num_words));
- cell->parameters["\\MEMID"] = RTLIL::Const(str);
- cell->parameters["\\ABITS"] = RTLIL::Const(GetSize(addr_sig));
- cell->parameters["\\WIDTH"] = RTLIL::Const(current_module->memories[str]->width);
+ cell->parameters[ID::MEMID] = RTLIL::Const(str);
+ cell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr_sig));
+ cell->parameters[ID::WIDTH] = RTLIL::Const(current_module->memories[str]->width);
if (type == AST_MEMWR) {
- cell->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::Sx, 1));
- cell->setPort("\\EN", children[2]->genRTLIL());
- cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(0);
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(0);
+ cell->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::Sx, 1));
+ cell->setPort(ID::EN, children[2]->genRTLIL());
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(0);
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(0);
}
- cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1);
+ cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1);
}
break;
@@ -1453,12 +1450,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_FAIR:
case AST_COVER:
{
- const char *celltype = nullptr;
- if (type == AST_ASSERT) celltype = "$assert";
- if (type == AST_ASSUME) celltype = "$assume";
- if (type == AST_LIVE) celltype = "$live";
- if (type == AST_FAIR) celltype = "$fair";
- if (type == AST_COVER) celltype = "$cover";
+ IdString celltype;
+ if (type == AST_ASSERT) celltype = ID($assert);
+ if (type == AST_ASSUME) celltype = ID($assume);
+ if (type == AST_LIVE) celltype = ID($live);
+ if (type == AST_FAIR) celltype = ID($fair);
+ if (type == AST_COVER) celltype = ID($cover);
log_assert(children.size() == 2);
@@ -1471,16 +1468,13 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
en = current_module->ReduceBool(NEW_ID, en);
IdString cellname;
- if (str.empty()) {
- std::stringstream sstr;
- sstr << celltype << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
- cellname = sstr.str();
- } else {
+ if (str.empty())
+ cellname = stringf("%s$%s:%d$%d", celltype.c_str(), filename.c_str(), location.first_line, autoidx++);
+ else
cellname = str;
- }
RTLIL::Cell *cell = current_module->addCell(cellname, celltype);
- cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
for (auto &attr : attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -1488,8 +1482,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
cell->attributes[attr.first] = attr.second->asAttrConst();
}
- cell->setPort("\\A", check);
- cell->setPort("\\EN", en);
+ cell->setPort(ID::A, check);
+ cell->setPort(ID::EN, en);
}
break;
@@ -1525,9 +1519,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Re-definition of cell `%s'!\n", str.c_str());
RTLIL::Cell *cell = current_module->addCell(str, "");
- cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
// Set attribute 'module_not_derived' which will be cleared again after the hierarchy pass
- cell->set_bool_attribute("\\module_not_derived");
+ cell->set_bool_attribute(ID::module_not_derived);
for (auto it = children.begin(); it != children.end(); it++) {
AstNode *child = *it;
@@ -1575,29 +1569,29 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value.\n", attr.first.c_str());
cell->attributes[attr.first] = attr.second->asAttrConst();
}
- if (cell->type == "$specify2") {
- int src_width = GetSize(cell->getPort("\\SRC"));
- int dst_width = GetSize(cell->getPort("\\DST"));
- bool full = cell->getParam("\\FULL").as_bool();
+ if (cell->type == ID($specify2)) {
+ int src_width = GetSize(cell->getPort(ID::SRC));
+ int dst_width = GetSize(cell->getPort(ID::DST));
+ bool full = cell->getParam(ID::FULL).as_bool();
if (!full && src_width != dst_width)
log_file_error(filename, location.first_line, "Parallel specify SRC width does not match DST width.\n");
- cell->setParam("\\SRC_WIDTH", Const(src_width));
- cell->setParam("\\DST_WIDTH", Const(dst_width));
+ cell->setParam(ID::SRC_WIDTH, Const(src_width));
+ cell->setParam(ID::DST_WIDTH, Const(dst_width));
}
- else if (cell->type == "$specify3") {
- int dat_width = GetSize(cell->getPort("\\DAT"));
- int dst_width = GetSize(cell->getPort("\\DST"));
+ else if (cell->type == ID($specify3)) {
+ int dat_width = GetSize(cell->getPort(ID::DAT));
+ int dst_width = GetSize(cell->getPort(ID::DST));
if (dat_width != dst_width)
log_file_error(filename, location.first_line, "Specify DAT width does not match DST width.\n");
- int src_width = GetSize(cell->getPort("\\SRC"));
- cell->setParam("\\SRC_WIDTH", Const(src_width));
- cell->setParam("\\DST_WIDTH", Const(dst_width));
+ int src_width = GetSize(cell->getPort(ID::SRC));
+ cell->setParam(ID::SRC_WIDTH, Const(src_width));
+ cell->setParam(ID::DST_WIDTH, Const(dst_width));
}
- else if (cell->type == "$specrule") {
- int src_width = GetSize(cell->getPort("\\SRC"));
- int dst_width = GetSize(cell->getPort("\\DST"));
- cell->setParam("\\SRC_WIDTH", Const(src_width));
- cell->setParam("\\DST_WIDTH", Const(dst_width));
+ else if (cell->type == ID($specrule)) {
+ int src_width = GetSize(cell->getPort(ID::SRC));
+ int dst_width = GetSize(cell->getPort(ID::DST));
+ cell->setParam(ID::SRC_WIDTH, Const(src_width));
+ cell->setParam(ID::DST_WIDTH, Const(dst_width));
}
}
break;
@@ -1668,19 +1662,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
log_file_error(filename, location.first_line, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str());
Cell *cell = current_module->addCell(myid, str.substr(1));
- cell->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
- cell->parameters["\\WIDTH"] = width;
+ cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ cell->parameters[ID::WIDTH] = width;
- if (attributes.count("\\reg")) {
- auto &attr = attributes.at("\\reg");
+ if (attributes.count(ID::reg)) {
+ auto &attr = attributes.at(ID::reg);
if (attr->type != AST_CONSTANT)
log_file_error(filename, location.first_line, "Attribute `reg' with non-constant value!\n");
- cell->attributes["\\reg"] = attr->asAttrConst();
+ cell->attributes[ID::reg] = attr->asAttrConst();
}
Wire *wire = current_module->addWire(myid + "_wire", width);
- wire->attributes["\\src"] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
- cell->setPort("\\Y", wire);
+ wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", filename.c_str(), location.first_line, location.first_column, location.last_line, location.last_column);
+ cell->setPort(ID::Y, wire);
is_signed = sign_hint;
return SigSpec(wire);
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 10e9f2683..cb89f58ba 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -172,7 +172,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
deep_recursion_warning = true;
while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { }
- if (!flag_nomem2reg && !get_bool_attribute("\\nomem2reg"))
+ if (!flag_nomem2reg && !get_bool_attribute(ID::nomem2reg))
{
dict<AstNode*, pool<std::string>> mem2reg_places;
dict<AstNode*, uint32_t> mem2reg_candidates, dummy_proc_flags;
@@ -187,10 +187,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
bool this_nomeminit = flag_nomeminit;
log_assert((memflags & ~0x00ffff00) == 0);
- if (mem->get_bool_attribute("\\nomem2reg"))
+ if (mem->get_bool_attribute(ID::nomem2reg))
continue;
- if (mem->get_bool_attribute("\\nomeminit") || get_bool_attribute("\\nomeminit"))
+ if (mem->get_bool_attribute(ID::nomeminit) || get_bool_attribute(ID::nomeminit))
this_nomeminit = true;
if (memflags & AstNode::MEM2REG_FL_FORCED)
@@ -248,7 +248,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
reg->is_reg = true;
reg->is_signed = node->is_signed;
for (auto &it : node->attributes)
- if (it.first != ID(mem2reg))
+ if (it.first != ID::mem2reg)
reg->attributes.emplace(it.first, it.second->clone());
reg->filename = node->filename;
reg->location = node->location;
@@ -345,9 +345,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
for (auto c : node->children[0]->children) {
if (!c->is_simple_const_expr()) {
- if (attributes.count("\\dynports"))
- delete attributes.at("\\dynports");
- attributes["\\dynports"] = AstNode::mkconst_int(1, true);
+ if (attributes.count(ID::dynports))
+ delete attributes.at(ID::dynports);
+ attributes[ID::dynports] = AstNode::mkconst_int(1, true);
}
}
}
@@ -420,9 +420,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
current_scope[node->str] = node;
for (auto enode : node->children) {
log_assert(enode->type==AST_ENUM_ITEM);
- if (current_scope.count(enode->str) == 0) {
+ if (current_scope.count(enode->str) == 0)
current_scope[enode->str] = enode;
- }
+ else
+ log_file_error(filename, location.first_line, "enum item %s already exists\n", enode->str.c_str());
}
}
}
@@ -441,6 +442,29 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
}
+ // create name resolution entries for all objects with names
+ if (type == AST_PACKAGE) {
+ //add names to package scope
+ for (size_t i = 0; i < children.size(); i++) {
+ AstNode *node = children[i];
+ // these nodes appear at the top level in a package and can define names
+ if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_TYPEDEF) {
+ current_scope[node->str] = node;
+ }
+ if (node->type == AST_ENUM) {
+ current_scope[node->str] = node;
+ for (auto enode : node->children) {
+ log_assert(enode->type==AST_ENUM_ITEM);
+ if (current_scope.count(enode->str) == 0)
+ current_scope[enode->str] = enode;
+ else
+ log_file_error(filename, location.first_line, "enum item %s already exists in package\n", enode->str.c_str());
+ }
+ }
+ }
+ }
+
+
auto backup_current_block = current_block;
auto backup_current_block_child = current_block_child;
auto backup_current_top_block = current_top_block;
@@ -907,9 +931,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
);
}
//start building attribute string
- std::string enum_item_str = "\\enum_";
- enum_item_str.append(std::to_string(width));
- enum_item_str.append("_");
+ std::string enum_item_str = "\\enum_value_";
//get enum item value
if(enum_item->children[0]->type != AST_CONSTANT){
log_error("expected const, got %s for %s (%s)\n",
@@ -917,8 +939,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
enum_item->str.c_str(), enum_node->str.c_str()
);
}
- int val = enum_item->children[0]->asInt(is_signed);
- enum_item_str.append(std::to_string(val));
+ RTLIL::Const val = enum_item->children[0]->bitsAsConst(width, is_signed);
+ enum_item_str.append(val.as_string());
//set attribute for available val to enum item name mappings
attributes[enum_item_str.c_str()] = mkconst_str(enum_item->str);
}
@@ -1219,7 +1241,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true)));
wire->str = wire_id;
if (current_block)
- wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
current_ast_mod->children.push_back(wire);
while (wire->simplify(true, false, false, 1, -1, false, false)) { }
@@ -1727,13 +1749,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
did_something = true;
newNode = new AstNode(AST_CASE, shift_expr);
- for (int i = 0; i <= source_width-result_width; i++) {
+ for (int i = 0; i < source_width; i++) {
int start_bit = children[0]->id2ast->range_right + i;
AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true));
AstNode *lvalue = children[0]->clone();
lvalue->delete_children();
+ int end_bit = std::min(start_bit+result_width,source_width) - 1;
lvalue->children.push_back(new AstNode(AST_RANGE,
- mkconst_int(start_bit+result_width-1, true), mkconst_int(start_bit, true)));
+ mkconst_int(end_bit, true), mkconst_int(start_bit, true)));
cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone())));
newNode->children.push_back(cond);
}
@@ -1856,7 +1879,7 @@ skip_dynamic_range_lvalue_expansion:;
wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
current_ast_mod->children.push_back(wire_tmp);
current_scope[wire_tmp->str] = wire_tmp;
- wire_tmp->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire_tmp->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
while (wire_tmp->simplify(true, false, false, 1, -1, false, false)) { }
wire_tmp->is_logic = true;
@@ -2676,7 +2699,7 @@ skip_dynamic_range_lvalue_expansion:;
wire->is_input = false;
wire->is_output = false;
wire->is_reg = true;
- wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
if (child->type == AST_ENUM_ITEM)
wire->attributes["\\enum_base_type"] = child->attributes["\\enum_base_type"];
@@ -3364,10 +3387,10 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
}
// also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg'
- if (type == AST_MEMORY && (get_bool_attribute("\\mem2reg") || (flags & AstNode::MEM2REG_FL_ALL) || !is_reg))
+ if (type == AST_MEMORY && (get_bool_attribute(ID::mem2reg) || (flags & AstNode::MEM2REG_FL_ALL) || !is_reg))
mem2reg_candidates[this] |= AstNode::MEM2REG_FL_FORCED;
- if (type == AST_MODULE && get_bool_attribute("\\mem2reg"))
+ if (type == AST_MODULE && get_bool_attribute(ID::mem2reg))
children_flags |= AstNode::MEM2REG_FL_ALL;
dict<AstNode*, uint32_t> *proc_flags_p = NULL;
@@ -3530,7 +3553,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_addr->str = id_addr;
wire_addr->is_reg = true;
wire_addr->was_checked = true;
- wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_addr);
while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
@@ -3539,7 +3562,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_data->is_reg = true;
wire_data->was_checked = true;
wire_data->is_signed = mem_signed;
- wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_data);
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
@@ -3610,7 +3633,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_addr->is_reg = true;
wire_addr->was_checked = true;
if (block)
- wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_addr);
while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
@@ -3620,7 +3643,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
wire_data->was_checked = true;
wire_data->is_signed = mem_signed;
if (block)
- wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
+ wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_data);
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc
index cab210605..7cc157e49 100644
--- a/frontends/blif/blifparse.cc
+++ b/frontends/blif/blifparse.cc
@@ -176,7 +176,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (!strcmp(cmd, ".blackbox"))
{
- module->attributes["\\blackbox"] = RTLIL::Const(1);
+ module->attributes[ID::blackbox] = RTLIL::Const(1);
continue;
}
@@ -215,17 +215,17 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
vector<Cell*> remove_cells;
for (auto cell : module->cells())
- if (cell->type == "$lut" && cell->getParam("\\LUT") == buffer_lut) {
- module->connect(cell->getPort("\\Y"), cell->getPort("\\A"));
+ if (cell->type == ID($lut) && cell->getParam(ID::LUT) == buffer_lut) {
+ module->connect(cell->getPort(ID::Y), cell->getPort(ID::A));
remove_cells.push_back(cell);
}
for (auto cell : remove_cells)
module->remove(cell);
- Wire *true_wire = module->wire("$true");
- Wire *false_wire = module->wire("$false");
- Wire *undef_wire = module->wire("$undef");
+ Wire *true_wire = module->wire(ID($true));
+ Wire *false_wire = module->wire(ID($false));
+ Wire *undef_wire = module->wire(ID($undef));
if (true_wire != nullptr)
module->rename(true_wire, stringf("$true$%d", ++blif_maxnum));
@@ -337,7 +337,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
}
if (init != nullptr && (init[0] == '0' || init[0] == '1'))
- blif_wire(q)->attributes["\\init"] = Const(init[0] == '1' ? 1 : 0, 1);
+ blif_wire(q)->attributes[ID::init] = Const(init[0] == '1' ? 1 : 0, 1);
if (clock == nullptr)
goto no_latch_clock;
@@ -356,8 +356,8 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
cell = module->addFf(NEW_ID, blif_wire(d), blif_wire(q));
} else {
cell = module->addCell(NEW_ID, dff_name);
- cell->setPort("\\D", blif_wire(d));
- cell->setPort("\\Q", blif_wire(q));
+ cell->setPort(ID::D, blif_wire(d));
+ cell->setPort(ID::Q, blif_wire(q));
}
}
@@ -476,7 +476,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
finished_parsing_constval:
if (state == RTLIL::State::Sa)
state = RTLIL::State::S0;
- if (output_sig.as_wire()->name == "$undef")
+ if (output_sig.as_wire()->name == ID($undef))
state = RTLIL::State::Sx;
module->connect(RTLIL::SigSig(output_sig, state));
goto continue_without_read;
@@ -484,23 +484,23 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (sop_mode)
{
- sopcell = module->addCell(NEW_ID, "$sop");
- sopcell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size());
- sopcell->parameters["\\DEPTH"] = 0;
- sopcell->parameters["\\TABLE"] = RTLIL::Const();
- sopcell->setPort("\\A", input_sig);
- sopcell->setPort("\\Y", output_sig);
+ sopcell = module->addCell(NEW_ID, ID($sop));
+ sopcell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size());
+ sopcell->parameters[ID::DEPTH] = 0;
+ sopcell->parameters[ID::TABLE] = RTLIL::Const();
+ sopcell->setPort(ID::A, input_sig);
+ sopcell->setPort(ID::Y, output_sig);
sopmode = -1;
lastcell = sopcell;
}
else
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$lut");
- cell->parameters["\\WIDTH"] = RTLIL::Const(input_sig.size());
- cell->parameters["\\LUT"] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size());
- cell->setPort("\\A", input_sig);
- cell->setPort("\\Y", output_sig);
- lutptr = &cell->parameters.at("\\LUT");
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($lut));
+ cell->parameters[ID::WIDTH] = RTLIL::Const(input_sig.size());
+ cell->parameters[ID::LUT] = RTLIL::Const(RTLIL::State::Sx, 1 << input_sig.size());
+ cell->setPort(ID::A, input_sig);
+ cell->setPort(ID::Y, output_sig);
+ lutptr = &cell->parameters.at(ID::LUT);
lut_default_state = RTLIL::State::Sx;
lastcell = cell;
}
@@ -523,32 +523,32 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
if (sopcell)
{
- log_assert(sopcell->parameters["\\WIDTH"].as_int() == input_len);
- sopcell->parameters["\\DEPTH"] = sopcell->parameters["\\DEPTH"].as_int() + 1;
+ log_assert(sopcell->parameters[ID::WIDTH].as_int() == input_len);
+ sopcell->parameters[ID::DEPTH] = sopcell->parameters[ID::DEPTH].as_int() + 1;
for (int i = 0; i < input_len; i++)
switch (input[i]) {
case '0':
- sopcell->parameters["\\TABLE"].bits.push_back(State::S1);
- sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
+ sopcell->parameters[ID::TABLE].bits.push_back(State::S1);
+ sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
break;
case '1':
- sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
- sopcell->parameters["\\TABLE"].bits.push_back(State::S1);
+ sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
+ sopcell->parameters[ID::TABLE].bits.push_back(State::S1);
break;
default:
- sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
- sopcell->parameters["\\TABLE"].bits.push_back(State::S0);
+ sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
+ sopcell->parameters[ID::TABLE].bits.push_back(State::S0);
break;
}
if (sopmode == -1) {
sopmode = (*output == '1');
if (!sopmode) {
- SigSpec outnet = sopcell->getPort("\\Y");
+ SigSpec outnet = sopcell->getPort(ID::Y);
SigSpec tempnet = module->addWire(NEW_ID);
module->addNotGate(NEW_ID, tempnet, outnet);
- sopcell->setPort("\\Y", tempnet);
+ sopcell->setPort(ID::Y, tempnet);
}
} else
log_assert(sopmode == (*output == '1'));
diff --git a/frontends/ilang/ilang_lexer.l b/frontends/ilang/ilang_lexer.l
index 4fd0ae855..62f53d18e 100644
--- a/frontends/ilang/ilang_lexer.l
+++ b/frontends/ilang/ilang_lexer.l
@@ -29,6 +29,7 @@
#pragma clang diagnostic ignored "-Wdeprecated-register"
#endif
+#include <cstdlib>
#include "frontends/ilang/ilang_frontend.h"
#include "ilang_parser.tab.hh"
@@ -88,7 +89,16 @@ USING_YOSYS_NAMESPACE
"."[0-9]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; }
[0-9]+'[01xzm-]* { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_VALUE; }
--?[0-9]+ { rtlil_frontend_ilang_yylval.integer = atoi(yytext); return TOK_INT; }
+-?[0-9]+ {
+ char *end = nullptr;
+ long value = strtol(yytext, &end, 10);
+ if (end != yytext + strlen(yytext))
+ return TOK_INVALID; // literal out of range of long
+ if (value < INT_MIN || value > INT_MAX)
+ return TOK_INVALID; // literal out of range of int (relevant mostly for LP64 platforms)
+ rtlil_frontend_ilang_yylval.integer = value;
+ return TOK_INT;
+}
\" { BEGIN(STRING); }
<STRING>\\. { yymore(); }
@@ -136,4 +146,3 @@ USING_YOSYS_NAMESPACE
void *rtlil_frontend_ilang_avoid_input_warnings() {
return (void*)&yyinput;
}
-
diff --git a/frontends/ilang/ilang_parser.y b/frontends/ilang/ilang_parser.y
index 4e0b62edd..0522fa72a 100644
--- a/frontends/ilang/ilang_parser.y
+++ b/frontends/ilang/ilang_parser.y
@@ -169,7 +169,7 @@ wire_stmt:
current_wire->attributes = attrbuf;
attrbuf.clear();
} wire_options TOK_ID EOL {
- if (current_module->wires_.count($4) != 0)
+ if (current_module->wire($4) != nullptr)
rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str());
current_module->rename(current_wire, $4);
free($4);
@@ -179,6 +179,9 @@ wire_options:
wire_options TOK_WIDTH TOK_INT {
current_wire->width = $3;
} |
+ wire_options TOK_WIDTH TOK_INVALID {
+ rtlil_frontend_ilang_yyerror("ilang error: invalid wire width");
+ } |
wire_options TOK_UPTO {
current_wire->upto = true;
} |
@@ -229,7 +232,7 @@ memory_options:
cell_stmt:
TOK_CELL TOK_ID TOK_ID EOL {
- if (current_module->cells_.count($3) != 0)
+ if (current_module->cell($3) != nullptr)
rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str());
current_cell = current_module->addCell($3, $2);
current_cell->attributes = attrbuf;
@@ -424,9 +427,9 @@ sigspec:
delete $1;
} |
TOK_ID {
- if (current_module->wires_.count($1) == 0)
+ if (current_module->wire($1) == nullptr)
rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str());
- $$ = new RTLIL::SigSpec(current_module->wires_[$1]);
+ $$ = new RTLIL::SigSpec(current_module->wire($1));
free($1);
} |
sigspec '[' TOK_INT ']' {
diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc
index 14de95e07..6f0c3fefa 100644
--- a/frontends/liberty/liberty.cc
+++ b/frontends/liberty/liberty.cc
@@ -55,37 +55,37 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&
static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A)
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
- cell->setPort("\\A", A);
- cell->setPort("\\Y", module->addWire(NEW_ID));
- return cell->getPort("\\Y");
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
+ cell->setPort(ID::A, A);
+ cell->setPort(ID::Y, module->addWire(NEW_ID));
+ return cell->getPort(ID::Y);
}
static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_");
- cell->setPort("\\A", A);
- cell->setPort("\\B", B);
- cell->setPort("\\Y", module->addWire(NEW_ID));
- return cell->getPort("\\Y");
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_XOR_));
+ cell->setPort(ID::A, A);
+ cell->setPort(ID::B, B);
+ cell->setPort(ID::Y, module->addWire(NEW_ID));
+ return cell->getPort(ID::Y);
}
static RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_");
- cell->setPort("\\A", A);
- cell->setPort("\\B", B);
- cell->setPort("\\Y", module->addWire(NEW_ID));
- return cell->getPort("\\Y");
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_AND_));
+ cell->setPort(ID::A, A);
+ cell->setPort(ID::B, B);
+ cell->setPort(ID::Y, module->addWire(NEW_ID));
+ return cell->getPort(ID::Y);
}
static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_");
- cell->setPort("\\A", A);
- cell->setPort("\\B", B);
- cell->setPort("\\Y", module->addWire(NEW_ID));
- return cell->getPort("\\Y");
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_OR_));
+ cell->setPort(ID::A, A);
+ cell->setPort(ID::B, B);
+ cell->setPort(ID::Y, module->addWire(NEW_ID));
+ return cell->getPort(ID::Y);
}
static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack, token_t next_token)
@@ -241,32 +241,32 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node)
rerun_invert_rollback = false;
for (auto &it : module->cells_) {
- if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clk_sig) {
- clk_sig = it.second->getPort("\\A");
+ if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == clk_sig) {
+ clk_sig = it.second->getPort(ID::A);
clk_polarity = !clk_polarity;
rerun_invert_rollback = true;
}
- if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) {
- clear_sig = it.second->getPort("\\A");
+ if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == clear_sig) {
+ clear_sig = it.second->getPort(ID::A);
clear_polarity = !clear_polarity;
rerun_invert_rollback = true;
}
- if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) {
- preset_sig = it.second->getPort("\\A");
+ if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == preset_sig) {
+ preset_sig = it.second->getPort(ID::A);
preset_polarity = !preset_polarity;
rerun_invert_rollback = true;
}
}
}
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
- cell->setPort("\\A", iq_sig);
- cell->setPort("\\Y", iqn_sig);
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
+ cell->setPort(ID::A, iq_sig);
+ cell->setPort(ID::Y, iqn_sig);
cell = module->addCell(NEW_ID, "");
- cell->setPort("\\D", data_sig);
- cell->setPort("\\Q", iq_sig);
- cell->setPort("\\C", clk_sig);
+ cell->setPort(ID::D, data_sig);
+ cell->setPort(ID::Q, iq_sig);
+ cell->setPort(ID::C, clk_sig);
if (clear_sig.size() == 0 && preset_sig.size() == 0) {
cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N');
@@ -274,18 +274,18 @@ static void create_ff(RTLIL::Module *module, LibertyAst *node)
if (clear_sig.size() == 1 && preset_sig.size() == 0) {
cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
- cell->setPort("\\R", clear_sig);
+ cell->setPort(ID::R, clear_sig);
}
if (clear_sig.size() == 0 && preset_sig.size() == 1) {
cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N');
- cell->setPort("\\R", preset_sig);
+ cell->setPort(ID::R, preset_sig);
}
if (clear_sig.size() == 1 && preset_sig.size() == 1) {
cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
- cell->setPort("\\S", preset_sig);
- cell->setPort("\\R", clear_sig);
+ cell->setPort(ID::S, preset_sig);
+ cell->setPort(ID::R, clear_sig);
}
log_assert(!cell->type.empty());
@@ -324,27 +324,27 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
rerun_invert_rollback = false;
for (auto &it : module->cells_) {
- if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == enable_sig) {
- enable_sig = it.second->getPort("\\A");
+ if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == enable_sig) {
+ enable_sig = it.second->getPort(ID::A);
enable_polarity = !enable_polarity;
rerun_invert_rollback = true;
}
- if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) {
- clear_sig = it.second->getPort("\\A");
+ if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == clear_sig) {
+ clear_sig = it.second->getPort(ID::A);
clear_polarity = !clear_polarity;
rerun_invert_rollback = true;
}
- if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) {
- preset_sig = it.second->getPort("\\A");
+ if (it.second->type == ID($_NOT_) && it.second->getPort(ID::Y) == preset_sig) {
+ preset_sig = it.second->getPort(ID::A);
preset_polarity = !preset_polarity;
rerun_invert_rollback = true;
}
}
}
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
- cell->setPort("\\A", iq_sig);
- cell->setPort("\\Y", iqn_sig);
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($_NOT_));
+ cell->setPort(ID::A, iq_sig);
+ cell->setPort(ID::Y, iqn_sig);
if (clear_sig.size() == 1)
{
@@ -353,25 +353,25 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
if (clear_polarity == true || clear_polarity != enable_polarity)
{
- RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_");
- inv->setPort("\\A", clear_sig);
- inv->setPort("\\Y", module->addWire(NEW_ID));
+ RTLIL::Cell *inv = module->addCell(NEW_ID, ID($_NOT_));
+ inv->setPort(ID::A, clear_sig);
+ inv->setPort(ID::Y, module->addWire(NEW_ID));
if (clear_polarity == true)
- clear_negative = inv->getPort("\\Y");
+ clear_negative = inv->getPort(ID::Y);
if (clear_polarity != enable_polarity)
- clear_enable = inv->getPort("\\Y");
+ clear_enable = inv->getPort(ID::Y);
}
- RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_");
- data_gate->setPort("\\A", data_sig);
- data_gate->setPort("\\B", clear_negative);
- data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
+ RTLIL::Cell *data_gate = module->addCell(NEW_ID, ID($_AND_));
+ data_gate->setPort(ID::A, data_sig);
+ data_gate->setPort(ID::B, clear_negative);
+ data_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
- RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_");
- enable_gate->setPort("\\A", enable_sig);
- enable_gate->setPort("\\B", clear_enable);
- enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
+ RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? ID($_OR_) : ID($_AND_));
+ enable_gate->setPort(ID::A, enable_sig);
+ enable_gate->setPort(ID::B, clear_enable);
+ enable_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
}
if (preset_sig.size() == 1)
@@ -381,31 +381,31 @@ static bool create_latch(RTLIL::Module *module, LibertyAst *node, bool flag_igno
if (preset_polarity == false || preset_polarity != enable_polarity)
{
- RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_");
- inv->setPort("\\A", preset_sig);
- inv->setPort("\\Y", module->addWire(NEW_ID));
+ RTLIL::Cell *inv = module->addCell(NEW_ID, ID($_NOT_));
+ inv->setPort(ID::A, preset_sig);
+ inv->setPort(ID::Y, module->addWire(NEW_ID));
if (preset_polarity == false)
- preset_positive = inv->getPort("\\Y");
+ preset_positive = inv->getPort(ID::Y);
if (preset_polarity != enable_polarity)
- preset_enable = inv->getPort("\\Y");
+ preset_enable = inv->getPort(ID::Y);
}
- RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_");
- data_gate->setPort("\\A", data_sig);
- data_gate->setPort("\\B", preset_positive);
- data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
+ RTLIL::Cell *data_gate = module->addCell(NEW_ID, ID($_OR_));
+ data_gate->setPort(ID::A, data_sig);
+ data_gate->setPort(ID::B, preset_positive);
+ data_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
- RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_");
- enable_gate->setPort("\\A", enable_sig);
- enable_gate->setPort("\\B", preset_enable);
- enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
+ RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? ID($_OR_) : ID($_AND_));
+ enable_gate->setPort(ID::A, enable_sig);
+ enable_gate->setPort(ID::B, preset_enable);
+ enable_gate->setPort(ID::Y, data_sig = module->addWire(NEW_ID));
}
cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N'));
- cell->setPort("\\D", data_sig);
- cell->setPort("\\Q", iq_sig);
- cell->setPort("\\E", enable_sig);
+ cell->setPort(ID::D, data_sig);
+ cell->setPort(ID::Q, iq_sig);
+ cell->setPort(ID::E, enable_sig);
return true;
}
@@ -550,13 +550,13 @@ struct LibertyFrontend : public Frontend {
if (design->has(cell_name)) {
Module *existing_mod = design->module(cell_name);
- if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute("\\blackbox")) {
+ if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) {
log_error("Re-definition of cell/module %s!\n", log_id(cell_name));
} else if (flag_nooverwrite) {
log("Ignoring re-definition of module %s.\n", log_id(cell_name));
continue;
} else {
- log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "", log_id(cell_name));
+ log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", log_id(cell_name));
design->remove(existing_mod);
}
}
@@ -570,7 +570,7 @@ struct LibertyFrontend : public Frontend {
module->name = cell_name;
if (flag_lib)
- module->set_bool_attribute("\\blackbox");
+ module->set_bool_attribute(ID::blackbox);
for (auto &attr : attributes)
module->attributes[attr] = 1;
diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc
index add17c243..a23f7548e 100644
--- a/frontends/rpc/rpc_frontend.cc
+++ b/frontends/rpc/rpc_frontend.cc
@@ -157,7 +157,7 @@ struct RpcServer {
struct RpcModule : RTLIL::Module {
std::shared_ptr<RpcServer> server;
- RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/) YS_OVERRIDE {
+ RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool /*mayfail*/) YS_OVERRIDE {
std::string stripped_name = name.str();
if (stripped_name.compare(0, 9, "$abstract") == 0)
stripped_name = stripped_name.substr(9);
@@ -216,7 +216,7 @@ struct RpcModule : RTLIL::Module {
module.second->name = mangled_name;
module.second->design = design;
- module.second->attributes.erase("\\top");
+ module.second->attributes.erase(ID::top);
design->modules_[mangled_name] = module.second;
derived_design->modules_.erase(module.first);
}
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index ae5815f8e..519151310 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -155,7 +155,7 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att
Att *attr;
if (obj->Linefile())
- attributes["\\src"] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile()));
+ attributes[ID::src] = stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile()));
// FIXME: Parse numeric attributes
FOREACH_ATTRIBUTE(obj, mi, attr) {
@@ -738,7 +738,7 @@ void VerificImporter::merge_past_ffs_clock(pool<RTLIL::Cell*> &candidates, SigBi
SigSpec dbits;
for (auto cell : candidates) {
- SigBit bit = sigmap(cell->getPort("\\D"));
+ SigBit bit = sigmap(cell->getPort(ID::D));
dbits_db[bit].insert(cell);
dbits.append(bit);
}
@@ -764,7 +764,7 @@ void VerificImporter::merge_past_ffs_clock(pool<RTLIL::Cell*> &candidates, SigBi
if (verific_verbose)
log(" replacing old ff %s on bit %d.\n", log_id(old_ff), i);
- SigBit old_q = old_ff->getPort("\\Q");
+ SigBit old_q = old_ff->getPort(ID::Q);
SigBit new_q = sig_q[i];
sigmap.add(old_q, new_q);
@@ -783,8 +783,8 @@ void VerificImporter::merge_past_ffs(pool<RTLIL::Cell*> &candidates)
for (auto cell : candidates)
{
- SigBit clock = cell->getPort("\\CLK");
- bool clock_pol = cell->getParam("\\CLK_POLARITY").as_bool();
+ SigBit clock = cell->getPort(ID::CLK);
+ bool clock_pol = cell->getParam(ID::CLK_POLARITY).as_bool();
database[make_pair(clock, int(clock_pol))].insert(cell);
}
@@ -822,7 +822,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
if (is_blackbox(nl)) {
log("Importing blackbox module %s.\n", RTLIL::id2cstr(module->name));
- module->set_bool_attribute("\\blackbox");
+ module->set_bool_attribute(ID::blackbox);
} else {
log("Importing module %s.\n", RTLIL::id2cstr(module->name));
}
@@ -952,17 +952,17 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
ascii_initdata++;
}
if (initval_valid) {
- RTLIL::Cell *cell = module->addCell(new_verific_id(net), "$meminit");
- cell->parameters["\\WORDS"] = 1;
+ RTLIL::Cell *cell = module->addCell(new_verific_id(net), ID($meminit));
+ cell->parameters[ID::WORDS] = 1;
if (net->GetOrigTypeRange()->LeftRangeBound() < net->GetOrigTypeRange()->RightRangeBound())
- cell->setPort("\\ADDR", word_idx);
+ cell->setPort(ID::ADDR, word_idx);
else
- cell->setPort("\\ADDR", memory->size - word_idx - 1);
- cell->setPort("\\DATA", initval);
- cell->parameters["\\MEMID"] = RTLIL::Const(memory->name.str());
- cell->parameters["\\ABITS"] = 32;
- cell->parameters["\\WIDTH"] = memory->width;
- cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1);
+ cell->setPort(ID::ADDR, memory->size - word_idx - 1);
+ cell->setPort(ID::DATA, initval);
+ cell->parameters[ID::MEMID] = RTLIL::Const(memory->name.str());
+ cell->parameters[ID::ABITS] = 32;
+ cell->parameters[ID::WIDTH] = memory->width;
+ cell->parameters[ID::PRIORITY] = RTLIL::Const(autoidx-1);
}
}
}
@@ -1079,7 +1079,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
}
if (initval_valid)
- wire->attributes["\\init"] = initval;
+ wire->attributes[ID::init] = initval;
}
else
{
@@ -1133,8 +1133,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
SigBit bit = net_map_at(it.first);
log_assert(bit.wire);
- if (bit.wire->attributes.count("\\init"))
- initval = bit.wire->attributes.at("\\init");
+ if (bit.wire->attributes.count(ID::init))
+ initval = bit.wire->attributes.at(ID::init);
while (GetSize(initval) < GetSize(bit.wire))
initval.bits.push_back(State::Sx);
@@ -1144,7 +1144,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
if (it.second == '1')
initval.bits.at(bit.offset) = State::S1;
- bit.wire->attributes["\\init"] = initval;
+ bit.wire->attributes[ID::init] = initval;
}
for (auto net : anyconst_nets)
@@ -1212,17 +1212,17 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec data = operatorOutput(inst).extract(i * memory->width, memory->width);
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
- RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), "$memrd");
- cell->parameters["\\MEMID"] = memory->name.str();
- cell->parameters["\\CLK_ENABLE"] = false;
- cell->parameters["\\CLK_POLARITY"] = true;
- cell->parameters["\\TRANSPARENT"] = false;
- cell->parameters["\\ABITS"] = GetSize(addr);
- cell->parameters["\\WIDTH"] = GetSize(data);
- cell->setPort("\\CLK", RTLIL::State::Sx);
- cell->setPort("\\EN", RTLIL::State::Sx);
- cell->setPort("\\ADDR", addr);
- cell->setPort("\\DATA", data);
+ RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memrd));
+ cell->parameters[ID::MEMID] = memory->name.str();
+ cell->parameters[ID::CLK_ENABLE] = false;
+ cell->parameters[ID::CLK_POLARITY] = true;
+ cell->parameters[ID::TRANSPARENT] = false;
+ cell->parameters[ID::ABITS] = GetSize(addr);
+ cell->parameters[ID::WIDTH] = GetSize(data);
+ cell->setPort(ID::CLK, RTLIL::State::Sx);
+ cell->setPort(ID::EN, RTLIL::State::Sx);
+ cell->setPort(ID::ADDR, addr);
+ cell->setPort(ID::DATA, data);
}
continue;
}
@@ -1242,21 +1242,21 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::SigSpec data = operatorInput2(inst).extract(i * memory->width, memory->width);
RTLIL::Cell *cell = module->addCell(numchunks == 1 ? inst_name :
- RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), "$memwr");
- cell->parameters["\\MEMID"] = memory->name.str();
- cell->parameters["\\CLK_ENABLE"] = false;
- cell->parameters["\\CLK_POLARITY"] = true;
- cell->parameters["\\PRIORITY"] = 0;
- cell->parameters["\\ABITS"] = GetSize(addr);
- cell->parameters["\\WIDTH"] = GetSize(data);
- cell->setPort("\\EN", RTLIL::SigSpec(net_map_at(inst->GetControl())).repeat(GetSize(data)));
- cell->setPort("\\CLK", RTLIL::State::S0);
- cell->setPort("\\ADDR", addr);
- cell->setPort("\\DATA", data);
+ RTLIL::IdString(stringf("%s_%d", inst_name.c_str(), i)), ID($memwr));
+ cell->parameters[ID::MEMID] = memory->name.str();
+ cell->parameters[ID::CLK_ENABLE] = false;
+ cell->parameters[ID::CLK_POLARITY] = true;
+ cell->parameters[ID::PRIORITY] = 0;
+ cell->parameters[ID::ABITS] = GetSize(addr);
+ cell->parameters[ID::WIDTH] = GetSize(data);
+ cell->setPort(ID::EN, RTLIL::SigSpec(net_map_at(inst->GetControl())).repeat(GetSize(data)));
+ cell->setPort(ID::CLK, RTLIL::State::S0);
+ cell->setPort(ID::ADDR, addr);
+ cell->setPort(ID::DATA, data);
if (inst->Type() == OPER_CLOCKED_WRITE_PORT) {
- cell->parameters["\\CLK_ENABLE"] = true;
- cell->setPort("\\CLK", net_map_at(inst->GetClock()));
+ cell->parameters[ID::CLK_ENABLE] = true;
+ cell->setPort(ID::CLK, net_map_at(inst->GetClock()));
}
}
continue;
@@ -1431,7 +1431,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
RTLIL::Cell *cell = module->addCell(inst_name, inst_type);
if (inst->IsPrimitive() && mode_keep)
- cell->attributes["\\keep"] = 1;
+ cell->attributes[ID::keep] = 1;
dict<IdString, vector<SigBit>> cell_port_conns;
@@ -1514,10 +1514,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
for (auto wire : module->wires())
{
- if (!wire->attributes.count("\\init"))
+ if (!wire->attributes.count(ID::init))
continue;
- Const &initval = wire->attributes.at("\\init");
+ Const &initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval); i++)
{
if (initval[i] != State::S0 && initval[i] != State::S1)
@@ -1528,7 +1528,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
}
if (initval.is_fully_undef())
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
}
}
@@ -1652,10 +1652,10 @@ Cell *VerificClocking::addDff(IdString name, SigSpec sig_d, SigSpec sig_q, Const
if (GetSize(init_value) != 0) {
log_assert(GetSize(sig_q) == GetSize(init_value));
if (sig_q.is_wire()) {
- sig_q.as_wire()->attributes["\\init"] = init_value;
+ sig_q.as_wire()->attributes[ID::init] = init_value;
} else {
Wire *w = module->addWire(NEW_ID, GetSize(sig_q));
- w->attributes["\\init"] = init_value;
+ w->attributes[ID::init] = init_value;
module->connect(sig_q, w);
sig_q = w;
}
diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc
index 49281f7e7..230dfadbf 100644
--- a/frontends/verilog/const2ast.cc
+++ b/frontends/verilog/const2ast.cc
@@ -139,6 +139,9 @@ static void my_strtobin(std::vector<RTLIL::State> &data, const char *str, int le
data.resize(len_in_bits, msb);
}
+ if (len_in_bits == 0)
+ log_file_error(current_filename, get_line_num(), "Illegal integer constant size of zero (IEEE 1800-2012, 5.7).\n");
+
if (len > len_in_bits)
log_warning("Literal has a width of %d bit, but value requires %d bit. (%s:%d)\n",
len_in_bits, len, current_filename.c_str(), get_line_num());
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index be2872e59..76373c2e4 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -436,9 +436,9 @@ module_arg_opt_assignment:
wire->str = ast_stack.back()->children.back()->str;
if (ast_stack.back()->children.back()->is_input) {
AstNode *n = ast_stack.back()->children.back();
- if (n->attributes.count("\\defaultvalue"))
- delete n->attributes.at("\\defaultvalue");
- n->attributes["\\defaultvalue"] = $2;
+ if (n->attributes.count(ID::defaultvalue))
+ delete n->attributes.at(ID::defaultvalue);
+ n->attributes[ID::defaultvalue] = $2;
} else
if (ast_stack.back()->children.back()->is_reg || ast_stack.back()->children.back()->is_logic)
ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $2))));
@@ -521,7 +521,8 @@ package_body:
package_body_stmt:
typedef_decl |
- localparam_decl;
+ localparam_decl |
+ param_decl;
interface:
TOK_INTERFACE {
@@ -1511,24 +1512,24 @@ wire_name_and_opt_assign:
bool attr_anyseq = false;
bool attr_allconst = false;
bool attr_allseq = false;
- if (ast_stack.back()->children.back()->get_bool_attribute("\\anyconst")) {
- delete ast_stack.back()->children.back()->attributes.at("\\anyconst");
- ast_stack.back()->children.back()->attributes.erase("\\anyconst");
+ if (ast_stack.back()->children.back()->get_bool_attribute(ID::anyconst)) {
+ delete ast_stack.back()->children.back()->attributes.at(ID::anyconst);
+ ast_stack.back()->children.back()->attributes.erase(ID::anyconst);
attr_anyconst = true;
}
- if (ast_stack.back()->children.back()->get_bool_attribute("\\anyseq")) {
- delete ast_stack.back()->children.back()->attributes.at("\\anyseq");
- ast_stack.back()->children.back()->attributes.erase("\\anyseq");
+ if (ast_stack.back()->children.back()->get_bool_attribute(ID::anyseq)) {
+ delete ast_stack.back()->children.back()->attributes.at(ID::anyseq);
+ ast_stack.back()->children.back()->attributes.erase(ID::anyseq);
attr_anyseq = true;
}
- if (ast_stack.back()->children.back()->get_bool_attribute("\\allconst")) {
- delete ast_stack.back()->children.back()->attributes.at("\\allconst");
- ast_stack.back()->children.back()->attributes.erase("\\allconst");
+ if (ast_stack.back()->children.back()->get_bool_attribute(ID::allconst)) {
+ delete ast_stack.back()->children.back()->attributes.at(ID::allconst);
+ ast_stack.back()->children.back()->attributes.erase(ID::allconst);
attr_allconst = true;
}
- if (ast_stack.back()->children.back()->get_bool_attribute("\\allseq")) {
- delete ast_stack.back()->children.back()->attributes.at("\\allseq");
- ast_stack.back()->children.back()->attributes.erase("\\allseq");
+ if (ast_stack.back()->children.back()->get_bool_attribute(ID::allseq)) {
+ delete ast_stack.back()->children.back()->attributes.at(ID::allseq);
+ ast_stack.back()->children.back()->attributes.erase(ID::allseq);
attr_allseq = true;
}
if (current_wire_rand || attr_anyconst || attr_anyseq || attr_allconst || attr_allseq) {
@@ -1544,7 +1545,7 @@ wire_name_and_opt_assign:
fcall->str = "\\$allconst";
if (attr_allseq)
fcall->str = "\\$allseq";
- fcall->attributes["\\reg"] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str));
+ fcall->attributes[ID::reg] = AstNode::mkconst_str(RTLIL::unescape_id(wire->str));
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, fcall));
}
} |
@@ -1552,9 +1553,9 @@ wire_name_and_opt_assign:
AstNode *wire = new AstNode(AST_IDENTIFIER);
wire->str = ast_stack.back()->children.back()->str;
if (astbuf1->is_input) {
- if (astbuf1->attributes.count("\\defaultvalue"))
- delete astbuf1->attributes.at("\\defaultvalue");
- astbuf1->attributes["\\defaultvalue"] = $3;
+ if (astbuf1->attributes.count(ID::defaultvalue))
+ delete astbuf1->attributes.at(ID::defaultvalue);
+ astbuf1->attributes[ID::defaultvalue] = $3;
}
else if (astbuf1->is_reg || astbuf1->is_logic){
AstNode *assign = new AstNode(AST_ASSIGN_LE, wire, $3);
@@ -1735,7 +1736,6 @@ single_cell:
ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2));
} '(' cell_port_list ')'{
SET_AST_NODE_LOC(astbuf2, @1, @$);
- SET_AST_NODE_LOC(astbuf3, @1, @$);
};
prim_list:
@@ -1839,7 +1839,7 @@ cell_port:
attr TOK_WILDCARD_CONNECT {
if (!sv_mode)
frontend_verilog_yyerror("Wildcard port connections are only supported in SystemVerilog mode.");
- astbuf2->attributes[ID(wildcard_port_conns)] = AstNode::mkconst_int(1, false);
+ astbuf2->attributes[ID::wildcard_port_conns] = AstNode::mkconst_int(1, false);
};
always_comb_or_latch:
@@ -1863,7 +1863,7 @@ always_stmt:
AstNode *node = new AstNode(AST_ALWAYS);
append_attr(node, $1);
if ($2)
- node->attributes[ID(always_ff)] = AstNode::mkconst_int(1, false);
+ node->attributes[ID::always_ff] = AstNode::mkconst_int(1, false);
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} always_cond {
@@ -1883,9 +1883,9 @@ always_stmt:
AstNode *node = new AstNode(AST_ALWAYS);
append_attr(node, $1);
if ($2)
- node->attributes[ID(always_latch)] = AstNode::mkconst_int(1, false);
+ node->attributes[ID::always_latch] = AstNode::mkconst_int(1, false);
else
- node->attributes[ID(always_comb)] = AstNode::mkconst_int(1, false);
+ node->attributes[ID::always_comb] = AstNode::mkconst_int(1, false);
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
AstNode *block = new AstNode(AST_BLOCK);
@@ -2355,12 +2355,12 @@ case_type:
opt_synopsys_attr:
opt_synopsys_attr TOK_SYNOPSYS_FULL_CASE {
- if (ast_stack.back()->attributes.count("\\full_case") == 0)
- ast_stack.back()->attributes["\\full_case"] = AstNode::mkconst_int(1, false);
+ if (ast_stack.back()->attributes.count(ID::full_case) == 0)
+ ast_stack.back()->attributes[ID::full_case] = AstNode::mkconst_int(1, false);
} |
opt_synopsys_attr TOK_SYNOPSYS_PARALLEL_CASE {
- if (ast_stack.back()->attributes.count("\\parallel_case") == 0)
- ast_stack.back()->attributes["\\parallel_case"] = AstNode::mkconst_int(1, false);
+ if (ast_stack.back()->attributes.count(ID::parallel_case) == 0)
+ ast_stack.back()->attributes[ID::parallel_case] = AstNode::mkconst_int(1, false);
} |
/* empty */;
@@ -2522,6 +2522,7 @@ gen_stmt:
} simple_behavioral_stmt ';' expr {
ast_stack.back()->children.push_back($6);
} ';' simple_behavioral_stmt ')' gen_stmt_block {
+ SET_AST_NODE_LOC(ast_stack.back(), @1, @11);
ast_stack.pop_back();
} |
TOK_IF '(' expr ')' {
@@ -2530,6 +2531,7 @@ gen_stmt:
ast_stack.push_back(node);
ast_stack.back()->children.push_back($3);
} gen_stmt_block opt_gen_else {
+ SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
case_type '(' expr ')' {
@@ -2538,6 +2540,7 @@ gen_stmt:
ast_stack.push_back(node);
} gen_case_body TOK_ENDCASE {
case_type_stack.pop_back();
+ SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
TOK_BEGIN {
@@ -2551,6 +2554,7 @@ gen_stmt:
exitTypeScope();
delete $3;
delete $7;
+ SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
TOK_MSG_TASKS {
@@ -2560,6 +2564,7 @@ gen_stmt:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} opt_arg_list ';'{
+ SET_AST_NODE_LOC(ast_stack.back(), @1, @3);
ast_stack.pop_back();
};
@@ -2569,6 +2574,7 @@ gen_stmt_block:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
} gen_stmt_or_module_body_stmt {
+ SET_AST_NODE_LOC(ast_stack.back(), @2, @2);
ast_stack.pop_back();
};
diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc
index 02854edb2..2c82b1bca 100644
--- a/kernel/cellaigs.cc
+++ b/kernel/cellaigs.cc
@@ -268,9 +268,9 @@ Aig::Aig(Cell *cell)
cell->parameters.sort();
for (auto p : cell->parameters)
{
- if (p.first == ID(A_WIDTH) && mkname_a_signed) {
+ if (p.first == ID::A_WIDTH && mkname_a_signed) {
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
- } else if (p.first == ID(B_WIDTH) && mkname_b_signed) {
+ } else if (p.first == ID::B_WIDTH && mkname_b_signed) {
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
} else {
mkname_last = name;
@@ -280,11 +280,11 @@ Aig::Aig(Cell *cell)
mkname_a_signed = false;
mkname_b_signed = false;
mkname_is_signed = false;
- if (p.first == ID(A_SIGNED)) {
+ if (p.first == ID::A_SIGNED) {
mkname_a_signed = true;
mkname_is_signed = p.second.as_bool();
}
- if (p.first == ID(B_SIGNED)) {
+ if (p.first == ID::B_SIGNED) {
mkname_b_signed = true;
mkname_is_signed = p.second.as_bool();
}
@@ -320,7 +320,7 @@ Aig::Aig(Cell *cell)
if (cell->type.in(ID($mux), ID($_MUX_)))
{
- int S = mk.inport(ID(S));
+ int S = mk.inport(ID::S);
for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) {
int A = mk.inport(ID::A, i);
int B = mk.inport(ID::B, i);
@@ -390,8 +390,8 @@ Aig::Aig(Cell *cell)
int width = GetSize(cell->getPort(ID::Y));
vector<int> A = mk.inport_vec(ID::A, width);
vector<int> B = mk.inport_vec(ID::B, width);
- int carry = mk.inport(ID(CI));
- int binv = mk.inport(ID(BI));
+ int carry = mk.inport(ID::CI);
+ int binv = mk.inport(ID::BI);
for (auto &n : B)
n = mk.xor_gate(n, binv);
vector<int> X(width), CO(width);
@@ -399,8 +399,8 @@ Aig::Aig(Cell *cell)
for (int i = 0; i < width; i++)
X[i] = mk.xor_gate(A[i], B[i]);
mk.outport_vec(Y, ID::Y);
- mk.outport_vec(X, ID(X));
- mk.outport_vec(CO, ID(CO));
+ mk.outport_vec(X, ID::X);
+ mk.outport_vec(CO, ID::CO);
goto optimize;
}
@@ -422,7 +422,7 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
- int C = mk.inport(ID(C));
+ int C = mk.inport(ID::C);
int Y = mk.nor_gate(mk.and_gate(A, B), C);
mk.outport(Y, ID::Y);
goto optimize;
@@ -432,7 +432,7 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
- int C = mk.inport(ID(C));
+ int C = mk.inport(ID::C);
int Y = mk.nand_gate(mk.or_gate(A, B), C);
mk.outport(Y, ID::Y);
goto optimize;
@@ -442,8 +442,8 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
- int C = mk.inport(ID(C));
- int D = mk.inport(ID(D));
+ int C = mk.inport(ID::C);
+ int D = mk.inport(ID::D);
int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D));
mk.outport(Y, ID::Y);
goto optimize;
@@ -453,8 +453,8 @@ Aig::Aig(Cell *cell)
{
int A = mk.inport(ID::A);
int B = mk.inport(ID::B);
- int C = mk.inport(ID(C));
- int D = mk.inport(ID(D));
+ int C = mk.inport(ID::C);
+ int D = mk.inport(ID::D);
int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D));
mk.outport(Y, ID::Y);
goto optimize;
diff --git a/kernel/celledges.cc b/kernel/celledges.cc
index d0bb99e83..54e0168e2 100644
--- a/kernel/celledges.cc
+++ b/kernel/celledges.cc
@@ -24,29 +24,25 @@ PRIVATE_NAMESPACE_BEGIN
void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = ID::A, Y = ID::Y;
-
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
- int a_width = GetSize(cell->getPort(A));
- int y_width = GetSize(cell->getPort(Y));
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
+ int a_width = GetSize(cell->getPort(ID::A));
+ int y_width = GetSize(cell->getPort(ID::Y));
for (int i = 0; i < y_width; i++)
{
if (i < a_width)
- db->add_edge(cell, A, i, Y, i, -1);
+ db->add_edge(cell, ID::A, i, ID::Y, i, -1);
else if (is_signed && a_width > 0)
- db->add_edge(cell, A, a_width-1, Y, i, -1);
+ db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
}
}
void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = ID::A, B = ID::B, Y = ID::Y;
-
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
- int a_width = GetSize(cell->getPort(A));
- int b_width = GetSize(cell->getPort(B));
- int y_width = GetSize(cell->getPort(Y));
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
+ int a_width = GetSize(cell->getPort(ID::A));
+ int b_width = GetSize(cell->getPort(ID::B));
+ int y_width = GetSize(cell->getPort(ID::Y));
if (cell->type == ID($and) && !is_signed) {
if (a_width > b_width)
@@ -58,41 +54,37 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int i = 0; i < y_width; i++)
{
if (i < a_width)
- db->add_edge(cell, A, i, Y, i, -1);
+ db->add_edge(cell, ID::A, i, ID::Y, i, -1);
else if (is_signed && a_width > 0)
- db->add_edge(cell, A, a_width-1, Y, i, -1);
+ db->add_edge(cell, ID::A, a_width-1, ID::Y, i, -1);
if (i < b_width)
- db->add_edge(cell, B, i, Y, i, -1);
+ db->add_edge(cell, ID::B, i, ID::Y, i, -1);
else if (is_signed && b_width > 0)
- db->add_edge(cell, B, b_width-1, Y, i, -1);
+ db->add_edge(cell, ID::B, b_width-1, ID::Y, i, -1);
}
}
void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = ID::A, Y = ID::Y;
-
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
- int a_width = GetSize(cell->getPort(A));
- int y_width = GetSize(cell->getPort(Y));
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
+ int a_width = GetSize(cell->getPort(ID::A));
+ int y_width = GetSize(cell->getPort(ID::Y));
if (is_signed && a_width == 1)
y_width = std::min(y_width, 1);
for (int i = 0; i < y_width; i++)
for (int k = 0; k <= i && k < a_width; k++)
- db->add_edge(cell, A, k, Y, i, -1);
+ db->add_edge(cell, ID::A, k, ID::Y, i, -1);
}
void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = ID::A, B = ID::B, Y = ID::Y;
-
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
- int a_width = GetSize(cell->getPort(A));
- int b_width = GetSize(cell->getPort(B));
- int y_width = GetSize(cell->getPort(Y));
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
+ int a_width = GetSize(cell->getPort(ID::A));
+ int b_width = GetSize(cell->getPort(ID::B));
+ int y_width = GetSize(cell->getPort(ID::Y));
if (!is_signed && cell->type != ID($sub)) {
int ab_width = std::max(a_width, b_width);
@@ -104,55 +96,49 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
for (int k = 0; k <= i; k++)
{
if (k < a_width)
- db->add_edge(cell, A, k, Y, i, -1);
+ db->add_edge(cell, ID::A, k, ID::Y, i, -1);
if (k < b_width)
- db->add_edge(cell, B, k, Y, i, -1);
+ db->add_edge(cell, ID::B, k, ID::Y, i, -1);
}
}
}
void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = ID::A, Y = ID::Y;
-
- int a_width = GetSize(cell->getPort(A));
+ int a_width = GetSize(cell->getPort(ID::A));
for (int i = 0; i < a_width; i++)
- db->add_edge(cell, A, i, Y, 0, -1);
+ db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
}
void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = ID::A, B = ID::B, Y = ID::Y;
-
- int a_width = GetSize(cell->getPort(A));
- int b_width = GetSize(cell->getPort(B));
+ int a_width = GetSize(cell->getPort(ID::A));
+ int b_width = GetSize(cell->getPort(ID::B));
for (int i = 0; i < a_width; i++)
- db->add_edge(cell, A, i, Y, 0, -1);
+ db->add_edge(cell, ID::A, i, ID::Y, 0, -1);
for (int i = 0; i < b_width; i++)
- db->add_edge(cell, B, i, Y, 0, -1);
+ db->add_edge(cell, ID::B, i, ID::Y, 0, -1);
}
void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;
-
- int a_width = GetSize(cell->getPort(A));
- int b_width = GetSize(cell->getPort(B));
- int s_width = GetSize(cell->getPort(S));
+ int a_width = GetSize(cell->getPort(ID::A));
+ int b_width = GetSize(cell->getPort(ID::B));
+ int s_width = GetSize(cell->getPort(ID::S));
for (int i = 0; i < a_width; i++)
{
- db->add_edge(cell, A, i, Y, i, -1);
+ db->add_edge(cell, ID::A, i, ID::Y, i, -1);
for (int k = i; k < b_width; k += a_width)
- db->add_edge(cell, B, k, Y, i, -1);
+ db->add_edge(cell, ID::B, k, ID::Y, i, -1);
for (int k = 0; k < s_width; k++)
- db->add_edge(cell, S, k, Y, i, -1);
+ db->add_edge(cell, ID::S, k, ID::Y, i, -1);
}
}
diff --git a/kernel/celltypes.h b/kernel/celltypes.h
index bc96fd602..450865ce9 100644
--- a/kernel/celltypes.h
+++ b/kernel/celltypes.h
@@ -84,26 +84,22 @@ struct CellTypes
{
setup_internals_eval();
- IdString A = ID::A, B = ID::B, EN = ID(EN), Y = ID::Y;
- IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT);
- IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST);
-
- setup_type(ID($tribuf), {A, EN}, {Y}, true);
-
- setup_type(ID($assert), {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type(ID($assume), {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type(ID($live), {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type(ID($fair), {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type(ID($cover), {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type(ID($initstate), pool<RTLIL::IdString>(), {Y}, true);
- setup_type(ID($anyconst), pool<RTLIL::IdString>(), {Y}, true);
- setup_type(ID($anyseq), pool<RTLIL::IdString>(), {Y}, true);
- setup_type(ID($allconst), pool<RTLIL::IdString>(), {Y}, true);
- setup_type(ID($allseq), pool<RTLIL::IdString>(), {Y}, true);
- setup_type(ID($equiv), {A, B}, {Y}, true);
- setup_type(ID($specify2), {EN, SRC, DST}, pool<RTLIL::IdString>(), true);
- setup_type(ID($specify3), {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true);
- setup_type(ID($specrule), {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($tribuf), {ID::A, ID::EN}, {ID::Y}, true);
+
+ setup_type(ID($assert), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($assume), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($live), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($fair), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($cover), {ID::A, ID::EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($initstate), pool<RTLIL::IdString>(), {ID::Y}, true);
+ setup_type(ID($anyconst), pool<RTLIL::IdString>(), {ID::Y}, true);
+ setup_type(ID($anyseq), pool<RTLIL::IdString>(), {ID::Y}, true);
+ setup_type(ID($allconst), pool<RTLIL::IdString>(), {ID::Y}, true);
+ setup_type(ID($allseq), pool<RTLIL::IdString>(), {ID::Y}, true);
+ setup_type(ID($equiv), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
}
void setup_internals_eval()
@@ -121,134 +117,109 @@ struct CellTypes
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow),
ID($logic_and), ID($logic_or), ID($concat), ID($macc)
};
- IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;
- IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X);
- IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN);
for (auto type : unary_ops)
- setup_type(type, {A}, {Y}, true);
+ setup_type(type, {ID::A}, {ID::Y}, true);
for (auto type : binary_ops)
- setup_type(type, {A, B}, {Y}, true);
+ setup_type(type, {ID::A, ID::B}, {ID::Y}, true);
for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux)}))
- setup_type(type, {A, B, S}, {Y}, true);
+ setup_type(type, {ID::A, ID::B, ID::S}, {ID::Y}, true);
- setup_type(ID($lcu), {P, G, CI}, {CO}, true);
- setup_type(ID($alu), {A, B, CI, BI}, {X, Y, CO}, true);
- setup_type(ID($fa), {A, B, C}, {X, Y}, true);
+ setup_type(ID($lcu), {ID::P, ID::G, ID::CI}, {ID::CO}, true);
+ setup_type(ID($alu), {ID::A, ID::B, ID::CI, ID::BI}, {ID::X, ID::Y, ID::CO}, true);
+ setup_type(ID($fa), {ID::A, ID::B, ID::C}, {ID::X, ID::Y}, true);
}
void setup_internals_ff()
{
- IdString SET = ID(SET), CLR = ID(CLR), CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
- IdString Q = ID(Q), D = ID(D);
-
- setup_type(ID($sr), {SET, CLR}, {Q});
- setup_type(ID($ff), {D}, {Q});
- setup_type(ID($dff), {CLK, D}, {Q});
- setup_type(ID($dffe), {CLK, EN, D}, {Q});
- setup_type(ID($dffsr), {CLK, SET, CLR, D}, {Q});
- setup_type(ID($adff), {CLK, ARST, D}, {Q});
- setup_type(ID($dlatch), {EN, D}, {Q});
- setup_type(ID($dlatchsr), {EN, SET, CLR, D}, {Q});
-
+ setup_type(ID($sr), {ID::SET, ID::CLR}, {ID::Q});
+ setup_type(ID($ff), {ID::D}, {ID::Q});
+ setup_type(ID($dff), {ID::CLK, ID::D}, {ID::Q});
+ setup_type(ID($dffe), {ID::CLK, ID::EN, ID::D}, {ID::Q});
+ setup_type(ID($dffsr), {ID::CLK, ID::SET, ID::CLR, ID::D}, {ID::Q});
+ setup_type(ID($adff), {ID::CLK, ID::ARST, ID::D}, {ID::Q});
+ setup_type(ID($dlatch), {ID::EN, ID::D}, {ID::Q});
+ setup_type(ID($dlatchsr), {ID::EN, ID::SET, ID::CLR, ID::D}, {ID::Q});
}
void setup_internals_mem()
{
setup_internals_ff();
- IdString CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
- IdString ADDR = ID(ADDR), DATA = ID(DATA), RD_EN = ID(RD_EN);
- IdString RD_CLK = ID(RD_CLK), RD_ADDR = ID(RD_ADDR), WR_CLK = ID(WR_CLK), WR_EN = ID(WR_EN);
- IdString WR_ADDR = ID(WR_ADDR), WR_DATA = ID(WR_DATA), RD_DATA = ID(RD_DATA);
- IdString CTRL_IN = ID(CTRL_IN), CTRL_OUT = ID(CTRL_OUT);
-
- setup_type(ID($memrd), {CLK, EN, ADDR}, {DATA});
- setup_type(ID($memwr), {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
- setup_type(ID($meminit), {ADDR, DATA}, pool<RTLIL::IdString>());
- setup_type(ID($mem), {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
+ setup_type(ID($memrd), {ID::CLK, ID::EN, ID::ADDR}, {ID::DATA});
+ setup_type(ID($memwr), {ID::CLK, ID::EN, ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
+ setup_type(ID($meminit), {ID::ADDR, ID::DATA}, pool<RTLIL::IdString>());
+ setup_type(ID($mem), {ID::RD_CLK, ID::RD_EN, ID::RD_ADDR, ID::WR_CLK, ID::WR_EN, ID::WR_ADDR, ID::WR_DATA}, {ID::RD_DATA});
- setup_type(ID($fsm), {CLK, ARST, CTRL_IN}, {CTRL_OUT});
+ setup_type(ID($fsm), {ID::CLK, ID::ARST, ID::CTRL_IN}, {ID::CTRL_OUT});
}
void setup_stdcells()
{
setup_stdcells_eval();
- IdString A = ID::A, E = ID(E), Y = ID::Y;
-
- setup_type(ID($_TBUF_), {A, E}, {Y}, true);
+ setup_type(ID($_TBUF_), {ID::A, ID::E}, {ID::Y}, true);
}
void setup_stdcells_eval()
{
- IdString A = ID::A, B = ID::B, C = ID(C), D = ID(D);
- IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H);
- IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L);
- IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P);
- IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V);
- IdString Y = ID::Y;
-
- setup_type(ID($_BUF_), {A}, {Y}, true);
- setup_type(ID($_NOT_), {A}, {Y}, true);
- setup_type(ID($_AND_), {A, B}, {Y}, true);
- setup_type(ID($_NAND_), {A, B}, {Y}, true);
- setup_type(ID($_OR_), {A, B}, {Y}, true);
- setup_type(ID($_NOR_), {A, B}, {Y}, true);
- setup_type(ID($_XOR_), {A, B}, {Y}, true);
- setup_type(ID($_XNOR_), {A, B}, {Y}, true);
- setup_type(ID($_ANDNOT_), {A, B}, {Y}, true);
- setup_type(ID($_ORNOT_), {A, B}, {Y}, true);
- setup_type(ID($_MUX_), {A, B, S}, {Y}, true);
- setup_type(ID($_NMUX_), {A, B, S}, {Y}, true);
- setup_type(ID($_MUX4_), {A, B, C, D, S, T}, {Y}, true);
- setup_type(ID($_MUX8_), {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
- setup_type(ID($_MUX16_), {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true);
- setup_type(ID($_AOI3_), {A, B, C}, {Y}, true);
- setup_type(ID($_OAI3_), {A, B, C}, {Y}, true);
- setup_type(ID($_AOI4_), {A, B, C, D}, {Y}, true);
- setup_type(ID($_OAI4_), {A, B, C, D}, {Y}, true);
+ setup_type(ID($_BUF_), {ID::A}, {ID::Y}, true);
+ setup_type(ID($_NOT_), {ID::A}, {ID::Y}, true);
+ setup_type(ID($_AND_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_NAND_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_OR_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_NOR_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_XOR_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_XNOR_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_ANDNOT_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_ORNOT_), {ID::A, ID::B}, {ID::Y}, true);
+ setup_type(ID($_MUX_), {ID::A, ID::B, ID::S}, {ID::Y}, true);
+ setup_type(ID($_NMUX_), {ID::A, ID::B, ID::S}, {ID::Y}, true);
+ setup_type(ID($_MUX4_), {ID::A, ID::B, ID::C, ID::D, ID::S, ID::T}, {ID::Y}, true);
+ setup_type(ID($_MUX8_), {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::S, ID::T, ID::U}, {ID::Y}, true);
+ setup_type(ID($_MUX16_), {ID::A, ID::B, ID::C, ID::D, ID::E, ID::F, ID::G, ID::H, ID::I, ID::J, ID::K, ID::L, ID::M, ID::N, ID::O, ID::P, ID::S, ID::T, ID::U, ID::V}, {ID::Y}, true);
+ setup_type(ID($_AOI3_), {ID::A, ID::B, ID::C}, {ID::Y}, true);
+ setup_type(ID($_OAI3_), {ID::A, ID::B, ID::C}, {ID::Y}, true);
+ setup_type(ID($_AOI4_), {ID::A, ID::B, ID::C, ID::D}, {ID::Y}, true);
+ setup_type(ID($_OAI4_), {ID::A, ID::B, ID::C, ID::D}, {ID::Y}, true);
}
void setup_stdcells_mem()
{
- IdString S = ID(S), R = ID(R), C = ID(C);
- IdString D = ID(D), Q = ID(Q), E = ID(E);
-
std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
for (auto c1 : list_np)
for (auto c2 : list_np)
- setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q});
+ setup_type(stringf("$_SR_%c%c_", c1, c2), {ID::S, ID::R}, {ID::Q});
- setup_type(ID($_FF_), {D}, {Q});
+ setup_type(ID($_FF_), {ID::D}, {ID::Q});
for (auto c1 : list_np)
- setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q});
+ setup_type(stringf("$_DFF_%c_", c1), {ID::C, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
- setup_type(stringf("$_DFFE_%c%c_", c1, c2), {C, D, E}, {Q});
+ setup_type(stringf("$_DFFE_%c%c_", c1, c2), {ID::C, ID::D, ID::E}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_01)
- setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {C, R, D}, {Q});
+ setup_type(stringf("$_DFF_%c%c%c_", c1, c2, c3), {ID::C, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
- setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {C, S, R, D}, {Q});
+ setup_type(stringf("$_DFFSR_%c%c%c_", c1, c2, c3), {ID::C, ID::S, ID::R, ID::D}, {ID::Q});
for (auto c1 : list_np)
- setup_type(stringf("$_DLATCH_%c_", c1), {E, D}, {Q});
+ setup_type(stringf("$_DLATCH_%c_", c1), {ID::E, ID::D}, {ID::Q});
for (auto c1 : list_np)
for (auto c2 : list_np)
for (auto c3 : list_np)
- setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {E, S, R, D}, {Q});
+ setup_type(stringf("$_DLATCHSR_%c%c%c_", c1, c2, c3), {ID::E, ID::S, ID::R, ID::D}, {ID::Q});
}
void clear()
@@ -300,7 +271,7 @@ struct CellTypes
signed1 = false, signed2 = false;
}
-#define HANDLE_CELL_TYPE(_t) if (type == "$" #_t) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
+#define HANDLE_CELL_TYPE(_t) if (type == ID($##_t)) return const_ ## _t(arg1, arg2, signed1, signed2, result_len);
HANDLE_CELL_TYPE(not)
HANDLE_CELL_TYPE(and)
HANDLE_CELL_TYPE(or)
@@ -371,8 +342,8 @@ struct CellTypes
{
if (cell->type == ID($slice)) {
RTLIL::Const ret;
- int width = cell->parameters.at(ID(Y_WIDTH)).as_int();
- int offset = cell->parameters.at(ID(OFFSET)).as_int();
+ int width = cell->parameters.at(ID::Y_WIDTH).as_int();
+ int offset = cell->parameters.at(ID::OFFSET).as_int();
ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width);
return ret;
}
@@ -385,9 +356,9 @@ struct CellTypes
if (cell->type == ID($lut))
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
+ int width = cell->parameters.at(ID::WIDTH).as_int();
- std::vector<RTLIL::State> t = cell->parameters.at(ID(LUT)).bits;
+ std::vector<RTLIL::State> t = cell->parameters.at(ID::LUT).bits;
while (GetSize(t) < (1 << width))
t.push_back(State::S0);
t.resize(1 << width);
@@ -411,9 +382,9 @@ struct CellTypes
if (cell->type == ID($sop))
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- int depth = cell->parameters.at(ID(DEPTH)).as_int();
- std::vector<RTLIL::State> t = cell->parameters.at(ID(TABLE)).bits;
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ int depth = cell->parameters.at(ID::DEPTH).as_int();
+ std::vector<RTLIL::State> t = cell->parameters.at(ID::TABLE).bits;
while (GetSize(t) < width*depth*2)
t.push_back(State::S0);
@@ -447,9 +418,9 @@ struct CellTypes
return default_ret;
}
- bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool();
- bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool();
- int result_len = cell->parameters.count(ID(Y_WIDTH)) > 0 ? cell->parameters[ID(Y_WIDTH)].as_int() : -1;
+ bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
+ bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
+ int result_len = cell->parameters.count(ID::Y_WIDTH) > 0 ? cell->parameters[ID::Y_WIDTH].as_int() : -1;
return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
}
diff --git a/kernel/consteval.h b/kernel/consteval.h
index 7a83d28e7..ff8cf86d6 100644
--- a/kernel/consteval.h
+++ b/kernel/consteval.h
@@ -91,10 +91,10 @@ struct ConstEval
{
if (cell->type == ID($lcu))
{
- RTLIL::SigSpec sig_p = cell->getPort(ID(P));
- RTLIL::SigSpec sig_g = cell->getPort(ID(G));
- RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
- RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID(CO))));
+ RTLIL::SigSpec sig_p = cell->getPort(ID::P);
+ RTLIL::SigSpec sig_g = cell->getPort(ID::G);
+ RTLIL::SigSpec sig_ci = cell->getPort(ID::CI);
+ RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID::CO)));
if (sig_co.is_fully_const())
return true;
@@ -133,8 +133,8 @@ struct ConstEval
if (sig_y.is_fully_const())
return true;
- if (cell->hasPort(ID(S))) {
- sig_s = cell->getPort(ID(S));
+ if (cell->hasPort(ID::S)) {
+ sig_s = cell->getPort(ID::S);
if (!eval(sig_s, undef, cell))
return false;
}
@@ -200,8 +200,8 @@ struct ConstEval
}
else if (cell->type == ID($fa))
{
- RTLIL::SigSpec sig_c = cell->getPort(ID(C));
- RTLIL::SigSpec sig_x = cell->getPort(ID(X));
+ RTLIL::SigSpec sig_c = cell->getPort(ID::C);
+ RTLIL::SigSpec sig_x = cell->getPort(ID::X);
int width = GetSize(sig_c);
if (!eval(sig_a, undef, cell))
@@ -229,11 +229,11 @@ struct ConstEval
}
else if (cell->type == ID($alu))
{
- bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool();
- bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool();
+ bool signed_a = cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool();
+ bool signed_b = cell->parameters.count(ID::B_SIGNED) > 0 && cell->parameters[ID::B_SIGNED].as_bool();
- RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
- RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
+ RTLIL::SigSpec sig_ci = cell->getPort(ID::CI);
+ RTLIL::SigSpec sig_bi = cell->getPort(ID::BI);
if (!eval(sig_a, undef, cell))
return false;
@@ -247,8 +247,8 @@ struct ConstEval
if (!eval(sig_bi, undef, cell))
return false;
- RTLIL::SigSpec sig_x = cell->getPort(ID(X));
- RTLIL::SigSpec sig_co = cell->getPort(ID(CO));
+ RTLIL::SigSpec sig_x = cell->getPort(ID::X);
+ RTLIL::SigSpec sig_co = cell->getPort(ID::CO);
bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def());
sig_a.extend_u0(GetSize(sig_y), signed_a);
@@ -309,10 +309,10 @@ struct ConstEval
RTLIL::SigSpec sig_c, sig_d;
if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) {
- if (cell->hasPort(ID(C)))
- sig_c = cell->getPort(ID(C));
- if (cell->hasPort(ID(D)))
- sig_d = cell->getPort(ID(D));
+ if (cell->hasPort(ID::C))
+ sig_c = cell->getPort(ID::C);
+ if (cell->hasPort(ID::D))
+ sig_d = cell->getPort(ID::D);
}
if (sig_a.size() > 0 && !eval(sig_a, undef, cell))
diff --git a/kernel/constids.inc b/kernel/constids.inc
new file mode 100644
index 000000000..68a5782fd
--- /dev/null
+++ b/kernel/constids.inc
@@ -0,0 +1,213 @@
+X(A)
+X(abc9_box)
+X(abc9_box_id)
+X(abc9_box_seq)
+X(abc9_carry)
+X(abc9_flop)
+X(abc9_holes)
+X(abc9_init)
+X(abc9_lut)
+X(abc9_mergeability)
+X(abc9_scc)
+X(abc9_scc_id)
+X(abcgroup)
+X(ABITS)
+X(ADDR)
+X(allconst)
+X(allseq)
+X(always_comb)
+X(always_ff)
+X(always_latch)
+X(anyconst)
+X(anyseq)
+X(ARST)
+X(ARST_POLARITY)
+X(ARST_VALUE)
+X(A_SIGNED)
+X(A_WIDTH)
+X(B)
+X(BI)
+X(blackbox)
+X(B_SIGNED)
+X(B_WIDTH)
+X(C)
+X(cells_not_processed)
+X(CFG_ABITS)
+X(CFG_DBITS)
+X(CFG_INIT)
+X(CI)
+X(CLK)
+X(clkbuf_driver)
+X(clkbuf_inhibit)
+X(clkbuf_inv)
+X(clkbuf_sink)
+X(CLK_ENABLE)
+X(CLK_POLARITY)
+X(CLR)
+X(CLR_POLARITY)
+X(CO)
+X(CONFIG)
+X(CONFIG_WIDTH)
+X(CTRL_IN)
+X(CTRL_IN_WIDTH)
+X(CTRL_OUT)
+X(CTRL_OUT_WIDTH)
+X(D)
+X(DAT)
+X(DATA)
+X(DAT_DST_PEN)
+X(DAT_DST_POL)
+X(defaultvalue)
+X(DELAY)
+X(DEPTH)
+X(DST)
+X(DST_EN)
+X(DST_PEN)
+X(DST_POL)
+X(DST_WIDTH)
+X(dynports)
+X(E)
+X(EDGE_EN)
+X(EDGE_POL)
+X(EN)
+X(EN_DST)
+X(EN_POLARITY)
+X(EN_SRC)
+X(equiv_merged)
+X(equiv_region)
+X(extract_order)
+X(F)
+X(fsm_encoding)
+X(fsm_export)
+X(FULL)
+X(full_case)
+X(G)
+X(gclk)
+X(gentb_clock)
+X(gentb_constant)
+X(gentb_skip)
+X(H)
+X(hdlname)
+X(hierconn)
+X(I)
+X(INIT)
+X(init)
+X(initial_top)
+X(interface_modport)
+X(interfaces_replaced_in_module)
+X(interface_type)
+X(invertible_pin)
+X(iopad_external_pin)
+X(is_interface)
+X(J)
+X(K)
+X(keep)
+X(keep_hierarchy)
+X(L)
+X(lib_whitebox)
+X(localparam)
+X(LUT)
+X(lut_keep)
+X(M)
+X(maximize)
+X(mem2reg)
+X(MEMID)
+X(minimize)
+X(module_not_derived)
+X(N)
+X(NAME)
+X(noblackbox)
+X(nolatches)
+X(nomem2init)
+X(nomem2reg)
+X(nomeminit)
+X(nosync)
+X(O)
+X(OFFSET)
+X(onehot)
+X(P)
+X(parallel_case)
+X(parameter)
+X(PRIORITY)
+X(Q)
+X(qwp_position)
+X(R)
+X(RD_ADDR)
+X(RD_CLK)
+X(RD_CLK_ENABLE)
+X(RD_CLK_POLARITY)
+X(RD_DATA)
+X(RD_EN)
+X(RD_PORTS)
+X(RD_TRANSPARENT)
+X(reg)
+X(S)
+X(SET)
+X(SET_POLARITY)
+X(SIZE)
+X(SRC)
+X(src)
+X(SRC_DST_PEN)
+X(SRC_DST_POL)
+X(SRC_EN)
+X(SRC_PEN)
+X(SRC_POL)
+X(SRC_WIDTH)
+X(STATE_BITS)
+X(STATE_NUM)
+X(STATE_NUM_LOG2)
+X(STATE_RST)
+X(STATE_TABLE)
+X(submod)
+X(S_WIDTH)
+X(T)
+X(TABLE)
+X(techmap_autopurge)
+X(_TECHMAP_BITS_CONNMAP_)
+X(_TECHMAP_CELLTYPE_)
+X(techmap_celltype)
+X(techmap_maccmap)
+X(_TECHMAP_REPLACE_)
+X(techmap_simplemap)
+X(_techmap_special_)
+X(techmap_wrap)
+X(T_FALL_MAX)
+X(T_FALL_MIN)
+X(T_FALL_TYP)
+X(T_LIMIT)
+X(T_LIMIT2)
+X(T_LIMIT2_MAX)
+X(T_LIMIT2_MIN)
+X(T_LIMIT2_TYP)
+X(T_LIMIT_MAX)
+X(T_LIMIT_MIN)
+X(T_LIMIT_TYP)
+X(to_delete)
+X(top)
+X(TRANS_NUM)
+X(TRANSPARENT)
+X(TRANS_TABLE)
+X(T_RISE_MAX)
+X(T_RISE_MIN)
+X(T_RISE_TYP)
+X(TYPE)
+X(U)
+X(unique)
+X(unused_bits)
+X(V)
+X(wand)
+X(whitebox)
+X(WIDTH)
+X(wildcard_port_conns)
+X(wor)
+X(WORDS)
+X(WR_ADDR)
+X(WR_CLK)
+X(WR_CLK_ENABLE)
+X(WR_CLK_POLARITY)
+X(WR_DATA)
+X(WR_EN)
+X(WR_PORTS)
+X(X)
+X(Y)
+X(Y_WIDTH)
diff --git a/kernel/macc.h b/kernel/macc.h
index 371f6737d..e9f6f05e9 100644
--- a/kernel/macc.h
+++ b/kernel/macc.h
@@ -104,11 +104,11 @@ struct Macc
ports.clear();
bit_ports = cell->getPort(ID::B);
- std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits;
+ std::vector<RTLIL::State> config_bits = cell->getParam(ID::CONFIG).bits;
int config_cursor = 0;
#ifndef NDEBUG
- int config_width = cell->getParam(ID(CONFIG_WIDTH)).as_int();
+ int config_width = cell->getParam(ID::CONFIG_WIDTH).as_int();
log_assert(GetSize(config_bits) >= config_width);
#endif
@@ -193,10 +193,10 @@ struct Macc
cell->setPort(ID::A, port_a);
cell->setPort(ID::B, bit_ports);
- cell->setParam(ID(CONFIG), config_bits);
- cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits));
- cell->setParam(ID(A_WIDTH), GetSize(port_a));
- cell->setParam(ID(B_WIDTH), GetSize(bit_ports));
+ cell->setParam(ID::CONFIG, config_bits);
+ cell->setParam(ID::CONFIG_WIDTH, GetSize(config_bits));
+ cell->setParam(ID::A_WIDTH, GetSize(port_a));
+ cell->setParam(ID::B_WIDTH, GetSize(bit_ports));
}
bool eval(RTLIL::Const &result) const
diff --git a/kernel/modtools.h b/kernel/modtools.h
index 409562eb9..fbc5482ee 100644
--- a/kernel/modtools.h
+++ b/kernel/modtools.h
@@ -158,7 +158,7 @@ struct ModIndex : public RTLIL::Monitor
#endif
}
- void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
+ void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE
{
log_assert(module == cell->module);
@@ -380,22 +380,15 @@ struct ModWalker
}
}
- ModWalker() : design(NULL), module(NULL)
+ ModWalker(RTLIL::Design *design) : design(design), module(NULL)
{
+ ct.setup(design);
}
- ModWalker(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
+ void setup(RTLIL::Module *module, CellTypes *filter_ct = NULL)
{
- setup(design, module, filter_ct);
- }
-
- void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
- {
- this->design = design;
this->module = module;
- ct.clear();
- ct.setup(design);
sigmap.set(module);
signal_drivers.clear();
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 79e50cccd..d9003f28c 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -41,14 +41,59 @@ int RTLIL::IdString::last_created_idx_[8];
int RTLIL::IdString::last_created_idx_ptr_;
#endif
-IdString RTLIL::ID::A;
-IdString RTLIL::ID::B;
-IdString RTLIL::ID::Y;
-IdString RTLIL::ID::keep;
-IdString RTLIL::ID::whitebox;
-IdString RTLIL::ID::blackbox;
+#define X(_id) IdString RTLIL::ID::_id;
+#include "kernel/constids.inc"
+#undef X
+
dict<std::string, std::string> RTLIL::constpad;
+const pool<IdString> &RTLIL::builtin_ff_cell_types() {
+ static const pool<IdString> res = {
+ ID($sr),
+ ID($ff),
+ ID($dff),
+ ID($dffe),
+ ID($dffsr),
+ ID($adff),
+ ID($dlatch),
+ ID($dlatchsr),
+ ID($_DFFE_NN_),
+ ID($_DFFE_NP_),
+ ID($_DFFE_PN_),
+ ID($_DFFE_PP_),
+ ID($_DFFSR_NNN_),
+ ID($_DFFSR_NNP_),
+ ID($_DFFSR_NPN_),
+ ID($_DFFSR_NPP_),
+ ID($_DFFSR_PNN_),
+ ID($_DFFSR_PNP_),
+ ID($_DFFSR_PPN_),
+ ID($_DFFSR_PPP_),
+ ID($_DFF_NN0_),
+ ID($_DFF_NN1_),
+ ID($_DFF_NP0_),
+ ID($_DFF_NP1_),
+ ID($_DFF_N_),
+ ID($_DFF_PN0_),
+ ID($_DFF_PN1_),
+ ID($_DFF_PP0_),
+ ID($_DFF_PP1_),
+ ID($_DFF_P_),
+ ID($_DLATCHSR_NNN_),
+ ID($_DLATCHSR_NNP_),
+ ID($_DLATCHSR_NPN_),
+ ID($_DLATCHSR_NPP_),
+ ID($_DLATCHSR_PNN_),
+ ID($_DLATCHSR_PNP_),
+ ID($_DLATCHSR_PPN_),
+ ID($_DLATCHSR_PPP_),
+ ID($_DLATCH_N_),
+ ID($_DLATCH_P_),
+ ID($_FF_),
+ };
+ return res;
+}
+
RTLIL::Const::Const()
{
flags = RTLIL::CONST_FLAG_NONE;
@@ -85,14 +130,14 @@ RTLIL::Const::Const(RTLIL::State bit, int width)
RTLIL::Const::Const(const std::vector<bool> &bits)
{
flags = RTLIL::CONST_FLAG_NONE;
- for (auto b : bits)
- this->bits.push_back(b ? State::S1 : State::S0);
+ for (const auto &b : bits)
+ this->bits.emplace_back(b ? State::S1 : State::S0);
}
RTLIL::Const::Const(const RTLIL::Const &c)
{
flags = c.flags;
- for (auto b : c.bits)
+ for (const auto &b : c.bits)
this->bits.push_back(b);
}
@@ -139,6 +184,7 @@ int RTLIL::Const::as_int(bool is_signed) const
std::string RTLIL::Const::as_string() const
{
std::string ret;
+ ret.reserve(bits.size());
for (size_t i = bits.size(); i > 0; i--)
switch (bits[i-1]) {
case S0: ret += "0"; break;
@@ -151,9 +197,10 @@ std::string RTLIL::Const::as_string() const
return ret;
}
-RTLIL::Const RTLIL::Const::from_string(std::string str)
+RTLIL::Const RTLIL::Const::from_string(const std::string &str)
{
Const c;
+ c.bits.reserve(str.size());
for (auto it = str.rbegin(); it != str.rend(); it++)
switch (*it) {
case '0': c.bits.push_back(State::S0); break;
@@ -169,17 +216,16 @@ RTLIL::Const RTLIL::Const::from_string(std::string str)
std::string RTLIL::Const::decode_string() const
{
std::string string;
- std::vector<char> string_chars;
- for (int i = 0; i < int (bits.size()); i += 8) {
+ string.reserve(GetSize(bits)/8);
+ for (int i = 0; i < GetSize(bits); i += 8) {
char ch = 0;
for (int j = 0; j < 8 && i + j < int (bits.size()); j++)
if (bits[i + j] == RTLIL::State::S1)
ch |= 1 << j;
if (ch != 0)
- string_chars.push_back(ch);
+ string.append({ch});
}
- for (int i = int (string_chars.size()) - 1; i >= 0; i--)
- string += string_chars[i];
+ std::reverse(string.begin(), string.end());
return string;
}
@@ -187,7 +233,7 @@ bool RTLIL::Const::is_fully_zero() const
{
cover("kernel.rtlil.const.is_fully_zero");
- for (auto bit : bits)
+ for (const auto &bit : bits)
if (bit != RTLIL::State::S0)
return false;
@@ -198,7 +244,7 @@ bool RTLIL::Const::is_fully_ones() const
{
cover("kernel.rtlil.const.is_fully_ones");
- for (auto bit : bits)
+ for (const auto &bit : bits)
if (bit != RTLIL::State::S1)
return false;
@@ -209,7 +255,7 @@ bool RTLIL::Const::is_fully_def() const
{
cover("kernel.rtlil.const.is_fully_def");
- for (auto bit : bits)
+ for (const auto &bit : bits)
if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
return false;
@@ -220,7 +266,7 @@ bool RTLIL::Const::is_fully_undef() const
{
cover("kernel.rtlil.const.is_fully_undef");
- for (auto bit : bits)
+ for (const auto &bit : bits)
if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz)
return false;
@@ -231,11 +277,8 @@ void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value)
{
if (value)
attributes[id] = RTLIL::Const(1);
- else {
- const auto it = attributes.find(id);
- if (it != attributes.end())
- attributes.erase(it);
- }
+ else
+ attributes.erase(id);
}
bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const
@@ -249,7 +292,7 @@ bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const
void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<string> &data)
{
string attrval;
- for (auto &s : data) {
+ for (const auto &s : data) {
if (!attrval.empty())
attrval += "|";
attrval += s;
@@ -277,16 +320,17 @@ pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const
void RTLIL::AttrObject::set_src_attribute(const std::string &src)
{
if (src.empty())
- attributes.erase(ID(src));
+ attributes.erase(ID::src);
else
- attributes[ID(src)] = src;
+ attributes[ID::src] = src;
}
std::string RTLIL::AttrObject::get_src_attribute() const
{
std::string src;
- if (attributes.count(ID(src)))
- src = attributes.at(ID(src)).decode_string();
+ const auto it = attributes.find(ID::src);
+ if (it != attributes.end())
+ src = it->second.decode_string();
return src;
}
@@ -431,7 +475,7 @@ RTLIL::Module *RTLIL::Design::top_module()
int module_count = 0;
for (auto mod : selected_modules()) {
- if (mod->get_bool_attribute(ID(top)))
+ if (mod->get_bool_attribute(ID::top))
return mod;
module_count++;
module = mod;
@@ -477,32 +521,33 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
return module;
}
-void RTLIL::Design::scratchpad_unset(std::string varname)
+void RTLIL::Design::scratchpad_unset(const std::string &varname)
{
scratchpad.erase(varname);
}
-void RTLIL::Design::scratchpad_set_int(std::string varname, int value)
+void RTLIL::Design::scratchpad_set_int(const std::string &varname, int value)
{
scratchpad[varname] = stringf("%d", value);
}
-void RTLIL::Design::scratchpad_set_bool(std::string varname, bool value)
+void RTLIL::Design::scratchpad_set_bool(const std::string &varname, bool value)
{
scratchpad[varname] = value ? "true" : "false";
}
-void RTLIL::Design::scratchpad_set_string(std::string varname, std::string value)
+void RTLIL::Design::scratchpad_set_string(const std::string &varname, std::string value)
{
- scratchpad[varname] = value;
+ scratchpad[varname] = std::move(value);
}
-int RTLIL::Design::scratchpad_get_int(std::string varname, int default_value) const
+int RTLIL::Design::scratchpad_get_int(const std::string &varname, int default_value) const
{
- if (scratchpad.count(varname) == 0)
+ auto it = scratchpad.find(varname);
+ if (it == scratchpad.end())
return default_value;
- std::string str = scratchpad.at(varname);
+ const std::string &str = it->second;
if (str == "0" || str == "false")
return 0;
@@ -515,12 +560,13 @@ int RTLIL::Design::scratchpad_get_int(std::string varname, int default_value) co
return *endptr ? default_value : parsed_value;
}
-bool RTLIL::Design::scratchpad_get_bool(std::string varname, bool default_value) const
+bool RTLIL::Design::scratchpad_get_bool(const std::string &varname, bool default_value) const
{
- if (scratchpad.count(varname) == 0)
+ auto it = scratchpad.find(varname);
+ if (it == scratchpad.end())
return default_value;
- std::string str = scratchpad.at(varname);
+ const std::string &str = it->second;
if (str == "0" || str == "false")
return false;
@@ -531,11 +577,13 @@ bool RTLIL::Design::scratchpad_get_bool(std::string varname, bool default_value)
return default_value;
}
-std::string RTLIL::Design::scratchpad_get_string(std::string varname, std::string default_value) const
+std::string RTLIL::Design::scratchpad_get_string(const std::string &varname, const std::string &default_value) const
{
- if (scratchpad.count(varname) == 0)
+ auto it = scratchpad.find(varname);
+ if (it == scratchpad.end())
return default_value;
- return scratchpad.at(varname);
+
+ return it->second;
}
void RTLIL::Design::remove(RTLIL::Module *module)
@@ -723,12 +771,12 @@ void RTLIL::Module::makeblackbox()
set_bool_attribute(ID::blackbox);
}
-void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>)
+void RTLIL::Module::reprocess_module(RTLIL::Design *, const dict<RTLIL::IdString, RTLIL::Module *> &)
{
log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name));
}
-RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, bool mayfail)
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, bool mayfail)
{
if (mayfail)
return RTLIL::IdString();
@@ -736,7 +784,7 @@ RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLI
}
-RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, dict<RTLIL::IdString, RTLIL::Module*>, dict<RTLIL::IdString, RTLIL::IdString>, bool mayfail)
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict<RTLIL::IdString, RTLIL::Const> &, const dict<RTLIL::IdString, RTLIL::Module*> &, const dict<RTLIL::IdString, RTLIL::IdString> &, bool mayfail)
{
if (mayfail)
return RTLIL::IdString();
@@ -770,16 +818,17 @@ namespace {
int param(RTLIL::IdString name)
{
- if (cell->parameters.count(name) == 0)
+ auto it = cell->parameters.find(name);
+ if (it == cell->parameters.end())
error(__LINE__);
expected_params.insert(name);
- return cell->parameters.at(name).as_int();
+ return it->second.as_int();
}
int param_bool(RTLIL::IdString name)
{
int v = param(name);
- if (cell->parameters.at(name).bits.size() > 32)
+ if (GetSize(cell->parameters.at(name)) > 32)
error(__LINE__);
if (v != 0 && v != 1)
error(__LINE__);
@@ -797,20 +846,21 @@ namespace {
void param_bits(RTLIL::IdString name, int width)
{
param(name);
- if (int(cell->parameters.at(name).bits.size()) != width)
+ if (GetSize(cell->parameters.at(name).bits) != width)
error(__LINE__);
}
void port(RTLIL::IdString name, int width)
{
- if (!cell->hasPort(name))
+ auto it = cell->connections_.find(name);
+ if (it == cell->connections_.end())
error(__LINE__);
- if (cell->getPort(name).size() != width)
+ if (GetSize(it->second) != width)
error(__LINE__);
expected_ports.insert(name);
}
- void check_expected(bool check_matched_sign = true)
+ void check_expected(bool check_matched_sign = false)
{
for (auto &para : cell->parameters)
if (expected_params.count(para.first) == 0)
@@ -819,35 +869,15 @@ namespace {
if (expected_ports.count(conn.first) == 0)
error(__LINE__);
- if (expected_params.count(ID(A_SIGNED)) != 0 && expected_params.count(ID(B_SIGNED)) && check_matched_sign) {
- bool a_is_signed = param(ID(A_SIGNED)) != 0;
- bool b_is_signed = param(ID(B_SIGNED)) != 0;
+ if (check_matched_sign) {
+ log_assert(expected_params.count(ID::A_SIGNED) != 0 && expected_params.count(ID::B_SIGNED) != 0);
+ bool a_is_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
+ bool b_is_signed = cell->parameters.at(ID::B_SIGNED).as_bool();
if (a_is_signed != b_is_signed)
error(__LINE__);
}
}
- void check_gate(const char *ports)
- {
- if (cell->parameters.size() != 0)
- error(__LINE__);
-
- for (const char *p = ports; *p; p++) {
- char portname[3] = { '\\', *p, 0 };
- if (!cell->hasPort(portname))
- error(__LINE__);
- if (cell->getPort(portname).size() != 1)
- error(__LINE__);
- }
-
- for (auto &conn : cell->connections()) {
- if (conn.first.size() != 2 || conn.first[0] != '\\')
- error(__LINE__);
- if (strchr(ports, conn.first[1]) == NULL)
- error(__LINE__);
- }
- }
-
void check()
{
if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") ||
@@ -855,357 +885,357 @@ namespace {
return;
if (cell->type.in(ID($not), ID($pos), ID($neg))) {
- param_bool(ID(A_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param_bool(ID::A_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected();
return;
}
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
- check_expected();
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
+ check_expected(true);
return;
}
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) {
- param_bool(ID(A_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param_bool(ID::A_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected();
return;
}
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED), /*expected=*/false);
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED, /*expected=*/false);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected(/*check_matched_sign=*/false);
return;
}
if (cell->type.in(ID($shift), ID($shiftx))) {
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected(/*check_matched_sign=*/false);
return;
}
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
- check_expected();
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
+ check_expected(true);
return;
}
if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) {
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected(cell->type != ID($pow));
return;
}
if (cell->type == ID($fa)) {
- port(ID::A, param(ID(WIDTH)));
- port(ID::B, param(ID(WIDTH)));
- port(ID(C), param(ID(WIDTH)));
- port(ID(X), param(ID(WIDTH)));
- port(ID::Y, param(ID(WIDTH)));
+ port(ID::A, param(ID::WIDTH));
+ port(ID::B, param(ID::WIDTH));
+ port(ID::C, param(ID::WIDTH));
+ port(ID::X, param(ID::WIDTH));
+ port(ID::Y, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($lcu)) {
- port(ID(P), param(ID(WIDTH)));
- port(ID(G), param(ID(WIDTH)));
- port(ID(CI), 1);
- port(ID(CO), param(ID(WIDTH)));
+ port(ID::P, param(ID::WIDTH));
+ port(ID::G, param(ID::WIDTH));
+ port(ID::CI, 1);
+ port(ID::CO, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($alu)) {
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID(CI), 1);
- port(ID(BI), 1);
- port(ID(X), param(ID(Y_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
- port(ID(CO), param(ID(Y_WIDTH)));
- check_expected();
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::CI, 1);
+ port(ID::BI, 1);
+ port(ID::X, param(ID::Y_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
+ port(ID::CO, param(ID::Y_WIDTH));
+ check_expected(true);
return;
}
if (cell->type == ID($macc)) {
- param(ID(CONFIG));
- param(ID(CONFIG_WIDTH));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param(ID::CONFIG);
+ param(ID::CONFIG_WIDTH);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected();
Macc().from_cell(cell);
return;
}
if (cell->type == ID($logic_not)) {
- param_bool(ID(A_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param_bool(ID::A_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected();
return;
}
if (cell->type.in(ID($logic_and), ID($logic_or))) {
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
check_expected(/*check_matched_sign=*/false);
return;
}
if (cell->type == ID($slice)) {
- param(ID(OFFSET));
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::Y, param(ID(Y_WIDTH)));
- if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH)))
+ param(ID::OFFSET);
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::Y, param(ID::Y_WIDTH));
+ if (param(ID::OFFSET) + param(ID::Y_WIDTH) > param(ID::A_WIDTH))
error(__LINE__);
check_expected();
return;
}
if (cell->type == ID($concat)) {
- port(ID::A, param(ID(A_WIDTH)));
- port(ID::B, param(ID(B_WIDTH)));
- port(ID::Y, param(ID(A_WIDTH)) + param(ID(B_WIDTH)));
+ port(ID::A, param(ID::A_WIDTH));
+ port(ID::B, param(ID::B_WIDTH));
+ port(ID::Y, param(ID::A_WIDTH) + param(ID::B_WIDTH));
check_expected();
return;
}
if (cell->type == ID($mux)) {
- port(ID::A, param(ID(WIDTH)));
- port(ID::B, param(ID(WIDTH)));
- port(ID(S), 1);
- port(ID::Y, param(ID(WIDTH)));
+ port(ID::A, param(ID::WIDTH));
+ port(ID::B, param(ID::WIDTH));
+ port(ID::S, 1);
+ port(ID::Y, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($pmux)) {
- port(ID::A, param(ID(WIDTH)));
- port(ID::B, param(ID(WIDTH)) * param(ID(S_WIDTH)));
- port(ID(S), param(ID(S_WIDTH)));
- port(ID::Y, param(ID(WIDTH)));
+ port(ID::A, param(ID::WIDTH));
+ port(ID::B, param(ID::WIDTH) * param(ID::S_WIDTH));
+ port(ID::S, param(ID::S_WIDTH));
+ port(ID::Y, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($lut)) {
- param(ID(LUT));
- port(ID::A, param(ID(WIDTH)));
+ param(ID::LUT);
+ port(ID::A, param(ID::WIDTH));
port(ID::Y, 1);
check_expected();
return;
}
if (cell->type == ID($sop)) {
- param(ID(DEPTH));
- param(ID(TABLE));
- port(ID::A, param(ID(WIDTH)));
+ param(ID::DEPTH);
+ param(ID::TABLE);
+ port(ID::A, param(ID::WIDTH));
port(ID::Y, 1);
check_expected();
return;
}
if (cell->type == ID($sr)) {
- param_bool(ID(SET_POLARITY));
- param_bool(ID(CLR_POLARITY));
- port(ID(SET), param(ID(WIDTH)));
- port(ID(CLR), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ param_bool(ID::SET_POLARITY);
+ param_bool(ID::CLR_POLARITY);
+ port(ID::SET, param(ID::WIDTH));
+ port(ID::CLR, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($ff)) {
- port(ID(D), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ port(ID::D, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($dff)) {
- param_bool(ID(CLK_POLARITY));
- port(ID(CLK), 1);
- port(ID(D), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ param_bool(ID::CLK_POLARITY);
+ port(ID::CLK, 1);
+ port(ID::D, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($dffe)) {
- param_bool(ID(CLK_POLARITY));
- param_bool(ID(EN_POLARITY));
- port(ID(CLK), 1);
- port(ID(EN), 1);
- port(ID(D), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ param_bool(ID::CLK_POLARITY);
+ param_bool(ID::EN_POLARITY);
+ port(ID::CLK, 1);
+ port(ID::EN, 1);
+ port(ID::D, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($dffsr)) {
- param_bool(ID(CLK_POLARITY));
- param_bool(ID(SET_POLARITY));
- param_bool(ID(CLR_POLARITY));
- port(ID(CLK), 1);
- port(ID(SET), param(ID(WIDTH)));
- port(ID(CLR), param(ID(WIDTH)));
- port(ID(D), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ param_bool(ID::CLK_POLARITY);
+ param_bool(ID::SET_POLARITY);
+ param_bool(ID::CLR_POLARITY);
+ port(ID::CLK, 1);
+ port(ID::SET, param(ID::WIDTH));
+ port(ID::CLR, param(ID::WIDTH));
+ port(ID::D, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($adff)) {
- param_bool(ID(CLK_POLARITY));
- param_bool(ID(ARST_POLARITY));
- param_bits(ID(ARST_VALUE), param(ID(WIDTH)));
- port(ID(CLK), 1);
- port(ID(ARST), 1);
- port(ID(D), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ param_bool(ID::CLK_POLARITY);
+ param_bool(ID::ARST_POLARITY);
+ param_bits(ID::ARST_VALUE, param(ID::WIDTH));
+ port(ID::CLK, 1);
+ port(ID::ARST, 1);
+ port(ID::D, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($dlatch)) {
- param_bool(ID(EN_POLARITY));
- port(ID(EN), 1);
- port(ID(D), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ param_bool(ID::EN_POLARITY);
+ port(ID::EN, 1);
+ port(ID::D, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($dlatchsr)) {
- param_bool(ID(EN_POLARITY));
- param_bool(ID(SET_POLARITY));
- param_bool(ID(CLR_POLARITY));
- port(ID(EN), 1);
- port(ID(SET), param(ID(WIDTH)));
- port(ID(CLR), param(ID(WIDTH)));
- port(ID(D), param(ID(WIDTH)));
- port(ID(Q), param(ID(WIDTH)));
+ param_bool(ID::EN_POLARITY);
+ param_bool(ID::SET_POLARITY);
+ param_bool(ID::CLR_POLARITY);
+ port(ID::EN, 1);
+ port(ID::SET, param(ID::WIDTH));
+ port(ID::CLR, param(ID::WIDTH));
+ port(ID::D, param(ID::WIDTH));
+ port(ID::Q, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($fsm)) {
- param(ID(NAME));
- param_bool(ID(CLK_POLARITY));
- param_bool(ID(ARST_POLARITY));
- param(ID(STATE_BITS));
- param(ID(STATE_NUM));
- param(ID(STATE_NUM_LOG2));
- param(ID(STATE_RST));
- param_bits(ID(STATE_TABLE), param(ID(STATE_BITS)) * param(ID(STATE_NUM)));
- param(ID(TRANS_NUM));
- param_bits(ID(TRANS_TABLE), param(ID(TRANS_NUM)) * (2*param(ID(STATE_NUM_LOG2)) + param(ID(CTRL_IN_WIDTH)) + param(ID(CTRL_OUT_WIDTH))));
- port(ID(CLK), 1);
- port(ID(ARST), 1);
- port(ID(CTRL_IN), param(ID(CTRL_IN_WIDTH)));
- port(ID(CTRL_OUT), param(ID(CTRL_OUT_WIDTH)));
+ param(ID::NAME);
+ param_bool(ID::CLK_POLARITY);
+ param_bool(ID::ARST_POLARITY);
+ param(ID::STATE_BITS);
+ param(ID::STATE_NUM);
+ param(ID::STATE_NUM_LOG2);
+ param(ID::STATE_RST);
+ param_bits(ID::STATE_TABLE, param(ID::STATE_BITS) * param(ID::STATE_NUM));
+ param(ID::TRANS_NUM);
+ param_bits(ID::TRANS_TABLE, param(ID::TRANS_NUM) * (2*param(ID::STATE_NUM_LOG2) + param(ID::CTRL_IN_WIDTH) + param(ID::CTRL_OUT_WIDTH)));
+ port(ID::CLK, 1);
+ port(ID::ARST, 1);
+ port(ID::CTRL_IN, param(ID::CTRL_IN_WIDTH));
+ port(ID::CTRL_OUT, param(ID::CTRL_OUT_WIDTH));
check_expected();
return;
}
if (cell->type == ID($memrd)) {
- param(ID(MEMID));
- param_bool(ID(CLK_ENABLE));
- param_bool(ID(CLK_POLARITY));
- param_bool(ID(TRANSPARENT));
- port(ID(CLK), 1);
- port(ID(EN), 1);
- port(ID(ADDR), param(ID(ABITS)));
- port(ID(DATA), param(ID(WIDTH)));
+ param(ID::MEMID);
+ param_bool(ID::CLK_ENABLE);
+ param_bool(ID::CLK_POLARITY);
+ param_bool(ID::TRANSPARENT);
+ port(ID::CLK, 1);
+ port(ID::EN, 1);
+ port(ID::ADDR, param(ID::ABITS));
+ port(ID::DATA, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($memwr)) {
- param(ID(MEMID));
- param_bool(ID(CLK_ENABLE));
- param_bool(ID(CLK_POLARITY));
- param(ID(PRIORITY));
- port(ID(CLK), 1);
- port(ID(EN), param(ID(WIDTH)));
- port(ID(ADDR), param(ID(ABITS)));
- port(ID(DATA), param(ID(WIDTH)));
+ param(ID::MEMID);
+ param_bool(ID::CLK_ENABLE);
+ param_bool(ID::CLK_POLARITY);
+ param(ID::PRIORITY);
+ port(ID::CLK, 1);
+ port(ID::EN, param(ID::WIDTH));
+ port(ID::ADDR, param(ID::ABITS));
+ port(ID::DATA, param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($meminit)) {
- param(ID(MEMID));
- param(ID(PRIORITY));
- port(ID(ADDR), param(ID(ABITS)));
- port(ID(DATA), param(ID(WIDTH)) * param(ID(WORDS)));
+ param(ID::MEMID);
+ param(ID::PRIORITY);
+ port(ID::ADDR, param(ID::ABITS));
+ port(ID::DATA, param(ID::WIDTH) * param(ID::WORDS));
check_expected();
return;
}
if (cell->type == ID($mem)) {
- param(ID(MEMID));
- param(ID(SIZE));
- param(ID(OFFSET));
- param(ID(INIT));
- param_bits(ID(RD_CLK_ENABLE), max(1, param(ID(RD_PORTS))));
- param_bits(ID(RD_CLK_POLARITY), max(1, param(ID(RD_PORTS))));
- param_bits(ID(RD_TRANSPARENT), max(1, param(ID(RD_PORTS))));
- param_bits(ID(WR_CLK_ENABLE), max(1, param(ID(WR_PORTS))));
- param_bits(ID(WR_CLK_POLARITY), max(1, param(ID(WR_PORTS))));
- port(ID(RD_CLK), param(ID(RD_PORTS)));
- port(ID(RD_EN), param(ID(RD_PORTS)));
- port(ID(RD_ADDR), param(ID(RD_PORTS)) * param(ID(ABITS)));
- port(ID(RD_DATA), param(ID(RD_PORTS)) * param(ID(WIDTH)));
- port(ID(WR_CLK), param(ID(WR_PORTS)));
- port(ID(WR_EN), param(ID(WR_PORTS)) * param(ID(WIDTH)));
- port(ID(WR_ADDR), param(ID(WR_PORTS)) * param(ID(ABITS)));
- port(ID(WR_DATA), param(ID(WR_PORTS)) * param(ID(WIDTH)));
+ param(ID::MEMID);
+ param(ID::SIZE);
+ param(ID::OFFSET);
+ param(ID::INIT);
+ param_bits(ID::RD_CLK_ENABLE, max(1, param(ID::RD_PORTS)));
+ param_bits(ID::RD_CLK_POLARITY, max(1, param(ID::RD_PORTS)));
+ param_bits(ID::RD_TRANSPARENT, max(1, param(ID::RD_PORTS)));
+ param_bits(ID::WR_CLK_ENABLE, max(1, param(ID::WR_PORTS)));
+ param_bits(ID::WR_CLK_POLARITY, max(1, param(ID::WR_PORTS)));
+ port(ID::RD_CLK, param(ID::RD_PORTS));
+ port(ID::RD_EN, param(ID::RD_PORTS));
+ port(ID::RD_ADDR, param(ID::RD_PORTS) * param(ID::ABITS));
+ port(ID::RD_DATA, param(ID::RD_PORTS) * param(ID::WIDTH));
+ port(ID::WR_CLK, param(ID::WR_PORTS));
+ port(ID::WR_EN, param(ID::WR_PORTS) * param(ID::WIDTH));
+ port(ID::WR_ADDR, param(ID::WR_PORTS) * param(ID::ABITS));
+ port(ID::WR_DATA, param(ID::WR_PORTS) * param(ID::WIDTH));
check_expected();
return;
}
if (cell->type == ID($tribuf)) {
- port(ID::A, param(ID(WIDTH)));
- port(ID::Y, param(ID(WIDTH)));
- port(ID(EN), 1);
+ port(ID::A, param(ID::WIDTH));
+ port(ID::Y, param(ID::WIDTH));
+ port(ID::EN, 1);
check_expected();
return;
}
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
port(ID::A, 1);
- port(ID(EN), 1);
+ port(ID::EN, 1);
check_expected();
return;
}
@@ -1217,7 +1247,7 @@ namespace {
}
if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) {
- port(ID::Y, param(ID(WIDTH)));
+ port(ID::Y, param(ID::WIDTH));
check_expected();
return;
}
@@ -1231,115 +1261,115 @@ namespace {
}
if (cell->type.in(ID($specify2), ID($specify3))) {
- param_bool(ID(FULL));
- param_bool(ID(SRC_DST_PEN));
- param_bool(ID(SRC_DST_POL));
- param(ID(T_RISE_MIN));
- param(ID(T_RISE_TYP));
- param(ID(T_RISE_MAX));
- param(ID(T_FALL_MIN));
- param(ID(T_FALL_TYP));
- param(ID(T_FALL_MAX));
- port(ID(EN), 1);
- port(ID(SRC), param(ID(SRC_WIDTH)));
- port(ID(DST), param(ID(DST_WIDTH)));
+ param_bool(ID::FULL);
+ param_bool(ID::SRC_DST_PEN);
+ param_bool(ID::SRC_DST_POL);
+ param(ID::T_RISE_MIN);
+ param(ID::T_RISE_TYP);
+ param(ID::T_RISE_MAX);
+ param(ID::T_FALL_MIN);
+ param(ID::T_FALL_TYP);
+ param(ID::T_FALL_MAX);
+ port(ID::EN, 1);
+ port(ID::SRC, param(ID::SRC_WIDTH));
+ port(ID::DST, param(ID::DST_WIDTH));
if (cell->type == ID($specify3)) {
- param_bool(ID(EDGE_EN));
- param_bool(ID(EDGE_POL));
- param_bool(ID(DAT_DST_PEN));
- param_bool(ID(DAT_DST_POL));
- port(ID(DAT), param(ID(DST_WIDTH)));
+ param_bool(ID::EDGE_EN);
+ param_bool(ID::EDGE_POL);
+ param_bool(ID::DAT_DST_PEN);
+ param_bool(ID::DAT_DST_POL);
+ port(ID::DAT, param(ID::DST_WIDTH));
}
check_expected();
return;
}
if (cell->type == ID($specrule)) {
- param(ID(TYPE));
- param_bool(ID(SRC_PEN));
- param_bool(ID(SRC_POL));
- param_bool(ID(DST_PEN));
- param_bool(ID(DST_POL));
- param(ID(T_LIMIT_MIN));
- param(ID(T_LIMIT_TYP));
- param(ID(T_LIMIT_MAX));
- param(ID(T_LIMIT2_MIN));
- param(ID(T_LIMIT2_TYP));
- param(ID(T_LIMIT2_MAX));
- port(ID(SRC_EN), 1);
- port(ID(DST_EN), 1);
- port(ID(SRC), param(ID(SRC_WIDTH)));
- port(ID(DST), param(ID(DST_WIDTH)));
+ param(ID::TYPE);
+ param_bool(ID::SRC_PEN);
+ param_bool(ID::SRC_POL);
+ param_bool(ID::DST_PEN);
+ param_bool(ID::DST_POL);
+ param(ID::T_LIMIT_MIN);
+ param(ID::T_LIMIT_TYP);
+ param(ID::T_LIMIT_MAX);
+ param(ID::T_LIMIT2_MIN);
+ param(ID::T_LIMIT2_TYP);
+ param(ID::T_LIMIT2_MAX);
+ port(ID::SRC_EN, 1);
+ port(ID::DST_EN, 1);
+ port(ID::SRC, param(ID::SRC_WIDTH));
+ port(ID::DST, param(ID::DST_WIDTH));
check_expected();
return;
}
- if (cell->type == ID($_BUF_)) { check_gate("AY"); return; }
- if (cell->type == ID($_NOT_)) { check_gate("AY"); return; }
- if (cell->type == ID($_AND_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_NAND_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_OR_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_NOR_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_XOR_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_XNOR_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_ANDNOT_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_ORNOT_)) { check_gate("ABY"); return; }
- if (cell->type == ID($_MUX_)) { check_gate("ABSY"); return; }
- if (cell->type == ID($_NMUX_)) { check_gate("ABSY"); return; }
- if (cell->type == ID($_AOI3_)) { check_gate("ABCY"); return; }
- if (cell->type == ID($_OAI3_)) { check_gate("ABCY"); return; }
- if (cell->type == ID($_AOI4_)) { check_gate("ABCDY"); return; }
- if (cell->type == ID($_OAI4_)) { check_gate("ABCDY"); return; }
-
- if (cell->type == ID($_TBUF_)) { check_gate("AYE"); return; }
-
- if (cell->type == ID($_MUX4_)) { check_gate("ABCDSTY"); return; }
- if (cell->type == ID($_MUX8_)) { check_gate("ABCDEFGHSTUY"); return; }
- if (cell->type == ID($_MUX16_)) { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; }
-
- if (cell->type == ID($_SR_NN_)) { check_gate("SRQ"); return; }
- if (cell->type == ID($_SR_NP_)) { check_gate("SRQ"); return; }
- if (cell->type == ID($_SR_PN_)) { check_gate("SRQ"); return; }
- if (cell->type == ID($_SR_PP_)) { check_gate("SRQ"); return; }
-
- if (cell->type == ID($_FF_)) { check_gate("DQ"); return; }
- if (cell->type == ID($_DFF_N_)) { check_gate("DQC"); return; }
- if (cell->type == ID($_DFF_P_)) { check_gate("DQC"); return; }
-
- if (cell->type == ID($_DFFE_NN_)) { check_gate("DQCE"); return; }
- if (cell->type == ID($_DFFE_NP_)) { check_gate("DQCE"); return; }
- if (cell->type == ID($_DFFE_PN_)) { check_gate("DQCE"); return; }
- if (cell->type == ID($_DFFE_PP_)) { check_gate("DQCE"); return; }
-
- if (cell->type == ID($_DFF_NN0_)) { check_gate("DQCR"); return; }
- if (cell->type == ID($_DFF_NN1_)) { check_gate("DQCR"); return; }
- if (cell->type == ID($_DFF_NP0_)) { check_gate("DQCR"); return; }
- if (cell->type == ID($_DFF_NP1_)) { check_gate("DQCR"); return; }
- if (cell->type == ID($_DFF_PN0_)) { check_gate("DQCR"); return; }
- if (cell->type == ID($_DFF_PN1_)) { check_gate("DQCR"); return; }
- if (cell->type == ID($_DFF_PP0_)) { check_gate("DQCR"); return; }
- if (cell->type == ID($_DFF_PP1_)) { check_gate("DQCR"); return; }
-
- if (cell->type == ID($_DFFSR_NNN_)) { check_gate("CSRDQ"); return; }
- if (cell->type == ID($_DFFSR_NNP_)) { check_gate("CSRDQ"); return; }
- if (cell->type == ID($_DFFSR_NPN_)) { check_gate("CSRDQ"); return; }
- if (cell->type == ID($_DFFSR_NPP_)) { check_gate("CSRDQ"); return; }
- if (cell->type == ID($_DFFSR_PNN_)) { check_gate("CSRDQ"); return; }
- if (cell->type == ID($_DFFSR_PNP_)) { check_gate("CSRDQ"); return; }
- if (cell->type == ID($_DFFSR_PPN_)) { check_gate("CSRDQ"); return; }
- if (cell->type == ID($_DFFSR_PPP_)) { check_gate("CSRDQ"); return; }
-
- if (cell->type == ID($_DLATCH_N_)) { check_gate("EDQ"); return; }
- if (cell->type == ID($_DLATCH_P_)) { check_gate("EDQ"); return; }
-
- if (cell->type == ID($_DLATCHSR_NNN_)) { check_gate("ESRDQ"); return; }
- if (cell->type == ID($_DLATCHSR_NNP_)) { check_gate("ESRDQ"); return; }
- if (cell->type == ID($_DLATCHSR_NPN_)) { check_gate("ESRDQ"); return; }
- if (cell->type == ID($_DLATCHSR_NPP_)) { check_gate("ESRDQ"); return; }
- if (cell->type == ID($_DLATCHSR_PNN_)) { check_gate("ESRDQ"); return; }
- if (cell->type == ID($_DLATCHSR_PNP_)) { check_gate("ESRDQ"); return; }
- if (cell->type == ID($_DLATCHSR_PPN_)) { check_gate("ESRDQ"); return; }
- if (cell->type == ID($_DLATCHSR_PPP_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_BUF_)) { port(ID::A,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_NOT_)) { port(ID::A,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_AND_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_NAND_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_OR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_NOR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_XOR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_XNOR_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_ANDNOT_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_ORNOT_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_MUX_)) { port(ID::A,1); port(ID::B,1); port(ID::S,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_NMUX_)) { port(ID::A,1); port(ID::B,1); port(ID::S,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_AOI3_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_OAI3_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_AOI4_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_OAI4_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::Y,1); check_expected(); return; }
+
+ if (cell->type == ID($_TBUF_)) { port(ID::A,1); port(ID::Y,1); port(ID::E,1); check_expected(); return; }
+
+ if (cell->type == ID($_MUX4_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::S,1); port(ID::T,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_MUX8_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::Y,1); check_expected(); return; }
+ if (cell->type == ID($_MUX16_)) { port(ID::A,1); port(ID::B,1); port(ID::C,1); port(ID::D,1); port(ID::E,1); port(ID::F,1); port(ID::G,1); port(ID::H,1); port(ID::I,1); port(ID::J,1); port(ID::K,1); port(ID::L,1); port(ID::M,1); port(ID::N,1); port(ID::O,1); port(ID::P,1); port(ID::S,1); port(ID::T,1); port(ID::U,1); port(ID::V,1); port(ID::Y,1); check_expected(); return; }
+
+ if (cell->type == ID($_SR_NN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_SR_NP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_SR_PN_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_SR_PP_)) { port(ID::S,1); port(ID::R,1); port(ID::Q,1); check_expected(); return; }
+
+ if (cell->type == ID($_FF_)) { port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_N_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_P_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); check_expected(); return; }
+
+ if (cell->type == ID($_DFFE_NN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; }
+ if (cell->type == ID($_DFFE_NP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; }
+ if (cell->type == ID($_DFFE_PN_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; }
+ if (cell->type == ID($_DFFE_PP_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::E,1); check_expected(); return; }
+
+ if (cell->type == ID($_DFF_NN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_NN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_NP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_NP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_PN0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_PN1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_PP0_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+ if (cell->type == ID($_DFF_PP1_)) { port(ID::D,1); port(ID::Q,1); port(ID::C,1); port(ID::R,1); check_expected(); return; }
+
+ if (cell->type == ID($_DFFSR_NNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFFSR_NNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFFSR_NPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFFSR_NPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFFSR_PNN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFFSR_PNP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFFSR_PPN_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DFFSR_PPP_)) { port(ID::C,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+
+ if (cell->type == ID($_DLATCH_N_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCH_P_)) { port(ID::E,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+
+ if (cell->type == ID($_DLATCHSR_NNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCHSR_NNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCHSR_NPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCHSR_NPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCHSR_PNN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCHSR_PNP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCHSR_PPN_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
+ if (cell->type == ID($_DLATCHSR_PPP_)) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; }
error(__LINE__);
}
@@ -1494,11 +1524,10 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod) const
RTLIL::Module *mod;
void operator()(RTLIL::SigSpec &sig)
{
- std::vector<RTLIL::SigChunk> chunks = sig.chunks();
- for (auto &c : chunks)
+ sig.pack();
+ for (auto &c : sig.chunks_)
if (c.wire != NULL)
c.wire = mod->wires_.at(c.wire->name);
- sig = chunks;
}
};
@@ -1588,30 +1617,26 @@ void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
const pool<RTLIL::Wire*> *wires_p;
void operator()(RTLIL::SigSpec &sig) {
- std::vector<RTLIL::SigChunk> chunks = sig;
- for (auto &c : chunks)
+ sig.pack();
+ for (auto &c : sig.chunks_)
if (c.wire != NULL && wires_p->count(c.wire)) {
c.wire = module->addWire(NEW_ID, c.width);
c.offset = 0;
}
- sig = chunks;
}
void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) {
log_assert(GetSize(lhs) == GetSize(rhs));
- RTLIL::SigSpec new_lhs, new_rhs;
+ lhs.unpack();
+ rhs.unpack();
for (int i = 0; i < GetSize(lhs); i++) {
- RTLIL::SigBit lhs_bit = lhs[i];
- if (lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire))
- continue;
- RTLIL::SigBit rhs_bit = rhs[i];
- if (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))
- continue;
- new_lhs.append(lhs_bit);
- new_rhs.append(rhs_bit);
+ RTLIL::SigBit &lhs_bit = lhs.bits_[i];
+ RTLIL::SigBit &rhs_bit = rhs.bits_[i];
+ if ((lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire)) || (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))) {
+ lhs_bit = State::Sx;
+ rhs_bit = State::Sx;
+ }
}
- lhs = new_lhs;
- rhs = new_rhs;
}
};
@@ -1851,17 +1876,17 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth
}
#define DEF_METHOD(_func, _y_size, _type) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
- cell->parameters[ID(A_SIGNED)] = is_signed; \
- cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
- cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
+ cell->parameters[ID::A_SIGNED] = is_signed; \
+ cell->parameters[ID::A_WIDTH] = sig_a.size(); \
+ cell->parameters[ID::Y_WIDTH] = sig_y.size(); \
cell->setPort(ID::A, sig_a); \
cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed, const std::string &src) { \
+ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const std::string &src) { \
RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
add ## _func(name, sig_a, sig_y, is_signed, src); \
return sig_y; \
@@ -1878,20 +1903,20 @@ DEF_METHOD(LogicNot, 1, ID($logic_not))
#undef DEF_METHOD
#define DEF_METHOD(_func, _y_size, _type) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
- cell->parameters[ID(A_SIGNED)] = is_signed; \
- cell->parameters[ID(B_SIGNED)] = is_signed; \
- cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
- cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
- cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
+ cell->parameters[ID::A_SIGNED] = is_signed; \
+ cell->parameters[ID::B_SIGNED] = is_signed; \
+ cell->parameters[ID::A_WIDTH] = sig_a.size(); \
+ cell->parameters[ID::B_WIDTH] = sig_b.size(); \
+ cell->parameters[ID::Y_WIDTH] = sig_y.size(); \
cell->setPort(ID::A, sig_a); \
cell->setPort(ID::B, sig_b); \
cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \
+ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \
RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \
return sig_y; \
@@ -1920,20 +1945,20 @@ DEF_METHOD(LogicOr, 1, ID($logic_or))
#undef DEF_METHOD
#define DEF_METHOD(_func, _y_size, _type) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
- cell->parameters[ID(A_SIGNED)] = is_signed; \
- cell->parameters[ID(B_SIGNED)] = false; \
- cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
- cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
- cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
+ cell->parameters[ID::A_SIGNED] = is_signed; \
+ cell->parameters[ID::B_SIGNED] = false; \
+ cell->parameters[ID::A_WIDTH] = sig_a.size(); \
+ cell->parameters[ID::B_WIDTH] = sig_b.size(); \
+ cell->parameters[ID::Y_WIDTH] = sig_y.size(); \
cell->setPort(ID::A, sig_a); \
cell->setPort(ID::B, sig_b); \
cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \
+ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const std::string &src) { \
RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \
return sig_y; \
@@ -1945,18 +1970,18 @@ DEF_METHOD(Sshr, sig_a.size(), ID($sshr))
#undef DEF_METHOD
#define DEF_METHOD(_func, _type, _pmux) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
- cell->parameters[ID(WIDTH)] = sig_a.size(); \
- if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \
+ cell->parameters[ID::WIDTH] = sig_a.size(); \
+ if (_pmux) cell->parameters[ID::S_WIDTH] = sig_s.size(); \
cell->setPort(ID::A, sig_a); \
cell->setPort(ID::B, sig_b); \
- cell->setPort(ID(S), sig_s); \
+ cell->setPort(ID::S, sig_s); \
cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src) { \
+ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src) { \
RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \
add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \
return sig_y; \
@@ -1966,20 +1991,20 @@ DEF_METHOD(Pmux, ID($pmux), 1)
#undef DEF_METHOD
#define DEF_METHOD_2(_func, _type, _P1, _P2) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
cell->setPort("\\" #_P1, sig1); \
cell->setPort("\\" #_P2, sig2); \
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, const std::string &src) { \
+ RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const std::string &src) { \
RTLIL::SigBit sig2 = addWire(NEW_ID); \
add ## _func(name, sig1, sig2, src); \
return sig2; \
}
#define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
cell->setPort("\\" #_P1, sig1); \
cell->setPort("\\" #_P2, sig2); \
@@ -1987,13 +2012,13 @@ DEF_METHOD(Pmux, ID($pmux), 1)
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, const std::string &src) { \
+ RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \
RTLIL::SigBit sig3 = addWire(NEW_ID); \
add ## _func(name, sig1, sig2, sig3, src); \
return sig3; \
}
#define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
cell->setPort("\\" #_P1, sig1); \
cell->setPort("\\" #_P2, sig2); \
@@ -2002,13 +2027,13 @@ DEF_METHOD(Pmux, ID($pmux), 1)
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, const std::string &src) { \
+ RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const std::string &src) { \
RTLIL::SigBit sig4 = addWire(NEW_ID); \
add ## _func(name, sig1, sig2, sig3, sig4, src); \
return sig4; \
}
#define DEF_METHOD_5(_func, _type, _P1, _P2, _P3, _P4, _P5) \
- RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, RTLIL::SigBit sig5, const std::string &src) { \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SigBit &sig5, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
cell->setPort("\\" #_P1, sig1); \
cell->setPort("\\" #_P2, sig2); \
@@ -2018,7 +2043,7 @@ DEF_METHOD(Pmux, ID($pmux), 1)
cell->set_src_attribute(src); \
return cell; \
} \
- RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigBit sig1, RTLIL::SigBit sig2, RTLIL::SigBit sig3, RTLIL::SigBit sig4, const std::string &src) { \
+ RTLIL::SigBit RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const std::string &src) { \
RTLIL::SigBit sig5 = addWire(NEW_ID); \
add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \
return sig5; \
@@ -2044,14 +2069,14 @@ DEF_METHOD_5(Oai4Gate, ID($_OAI4_), A, B, C, D, Y)
#undef DEF_METHOD_4
#undef DEF_METHOD_5
-RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed, bool b_signed, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($pow));
- cell->parameters[ID(A_SIGNED)] = a_signed;
- cell->parameters[ID(B_SIGNED)] = b_signed;
- cell->parameters[ID(A_WIDTH)] = sig_a.size();
- cell->parameters[ID(B_WIDTH)] = sig_b.size();
- cell->parameters[ID(Y_WIDTH)] = sig_y.size();
+ cell->parameters[ID::A_SIGNED] = a_signed;
+ cell->parameters[ID::B_SIGNED] = b_signed;
+ cell->parameters[ID::A_WIDTH] = sig_a.size();
+ cell->parameters[ID::B_WIDTH] = sig_b.size();
+ cell->parameters[ID::Y_WIDTH] = sig_y.size();
cell->setPort(ID::A, sig_a);
cell->setPort(ID::B, sig_b);
cell->setPort(ID::Y, sig_y);
@@ -2059,23 +2084,23 @@ RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, R
return cell;
}
-RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($slice));
- cell->parameters[ID(A_WIDTH)] = sig_a.size();
- cell->parameters[ID(Y_WIDTH)] = sig_y.size();
- cell->parameters[ID(OFFSET)] = offset;
+ cell->parameters[ID::A_WIDTH] = sig_a.size();
+ cell->parameters[ID::Y_WIDTH] = sig_y.size();
+ cell->parameters[ID::OFFSET] = offset;
cell->setPort(ID::A, sig_a);
cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($concat));
- cell->parameters[ID(A_WIDTH)] = sig_a.size();
- cell->parameters[ID(B_WIDTH)] = sig_b.size();
+ cell->parameters[ID::A_WIDTH] = sig_a.size();
+ cell->parameters[ID::B_WIDTH] = sig_b.size();
cell->setPort(ID::A, sig_a);
cell->setPort(ID::B, sig_b);
cell->setPort(ID::Y, sig_y);
@@ -2083,74 +2108,74 @@ RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a
return cell;
}
-RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($lut));
- cell->parameters[ID(LUT)] = lut;
- cell->parameters[ID(WIDTH)] = sig_a.size();
+ cell->parameters[ID::LUT] = lut;
+ cell->parameters[ID::WIDTH] = sig_a.size();
cell->setPort(ID::A, sig_a);
cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($tribuf));
- cell->parameters[ID(WIDTH)] = sig_a.size();
+ cell->parameters[ID::WIDTH] = sig_a.size();
cell->setPort(ID::A, sig_a);
- cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID::EN, sig_en);
cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($assert));
cell->setPort(ID::A, sig_a);
- cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID::EN, sig_en);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($assume));
cell->setPort(ID::A, sig_a);
- cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID::EN, sig_en);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($live));
cell->setPort(ID::A, sig_a);
- cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID::EN, sig_en);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($fair));
cell->setPort(ID::A, sig_a);
- cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID::EN, sig_en);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($cover));
cell->setPort(ID::A, sig_a);
- cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID::EN, sig_en);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($equiv));
cell->setPort(ID::A, sig_a);
@@ -2160,191 +2185,191 @@ RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a,
return cell;
}
-RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($sr));
- cell->parameters[ID(SET_POLARITY)] = set_polarity;
- cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(SET), sig_set);
- cell->setPort(ID(CLR), sig_clr);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::SET_POLARITY] = set_polarity;
+ cell->parameters[ID::CLR_POLARITY] = clr_polarity;
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::SET, sig_set);
+ cell->setPort(ID::CLR, sig_clr);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($ff));
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($dff));
- cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(CLK), sig_clk);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::CLK_POLARITY] = clk_polarity;
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::CLK, sig_clk);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($dffe));
- cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
- cell->parameters[ID(EN_POLARITY)] = en_polarity;
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(CLK), sig_clk);
- cell->setPort(ID(EN), sig_en);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::CLK_POLARITY] = clk_polarity;
+ cell->parameters[ID::EN_POLARITY] = en_polarity;
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::CLK, sig_clk);
+ cell->setPort(ID::EN, sig_en);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($dffsr));
- cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
- cell->parameters[ID(SET_POLARITY)] = set_polarity;
- cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(CLK), sig_clk);
- cell->setPort(ID(SET), sig_set);
- cell->setPort(ID(CLR), sig_clr);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::CLK_POLARITY] = clk_polarity;
+ cell->parameters[ID::SET_POLARITY] = set_polarity;
+ cell->parameters[ID::CLR_POLARITY] = clr_polarity;
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::CLK, sig_clk);
+ cell->setPort(ID::SET, sig_set);
+ cell->setPort(ID::CLR, sig_clr);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
+RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($adff));
- cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
- cell->parameters[ID(ARST_POLARITY)] = arst_polarity;
- cell->parameters[ID(ARST_VALUE)] = arst_value;
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(CLK), sig_clk);
- cell->setPort(ID(ARST), sig_arst);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::CLK_POLARITY] = clk_polarity;
+ cell->parameters[ID::ARST_POLARITY] = arst_polarity;
+ cell->parameters[ID::ARST_VALUE] = arst_value;
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::CLK, sig_clk);
+ cell->setPort(ID::ARST, sig_arst);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($dlatch));
- cell->parameters[ID(EN_POLARITY)] = en_polarity;
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(EN), sig_en);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::EN_POLARITY] = en_polarity;
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::EN, sig_en);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($dlatchsr));
- cell->parameters[ID(EN_POLARITY)] = en_polarity;
- cell->parameters[ID(SET_POLARITY)] = set_polarity;
- cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
- cell->parameters[ID(WIDTH)] = sig_q.size();
- cell->setPort(ID(EN), sig_en);
- cell->setPort(ID(SET), sig_set);
- cell->setPort(ID(CLR), sig_clr);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->parameters[ID::EN_POLARITY] = en_polarity;
+ cell->parameters[ID::SET_POLARITY] = set_polarity;
+ cell->parameters[ID::CLR_POLARITY] = clr_polarity;
+ cell->parameters[ID::WIDTH] = sig_q.size();
+ cell->setPort(ID::EN, sig_en);
+ cell->setPort(ID::SET, sig_set);
+ cell->setPort(ID::CLR, sig_clr);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, ID($_FF_));
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'));
- cell->setPort(ID(C), sig_clk);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::C, sig_clk);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
- cell->setPort(ID(C), sig_clk);
- cell->setPort(ID(E), sig_en);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::C, sig_clk);
+ cell->setPort(ID::E, sig_en);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
- cell->setPort(ID(C), sig_clk);
- cell->setPort(ID(S), sig_set);
- cell->setPort(ID(R), sig_clr);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::C, sig_clk);
+ cell->setPort(ID::S, sig_set);
+ cell->setPort(ID::R, sig_clr);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
+RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'));
- cell->setPort(ID(C), sig_clk);
- cell->setPort(ID(R), sig_arst);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::C, sig_clk);
+ cell->setPort(ID::R, sig_arst);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'));
- cell->setPort(ID(E), sig_en);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::E, sig_en);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
-RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
+RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
- cell->setPort(ID(E), sig_en);
- cell->setPort(ID(S), sig_set);
- cell->setPort(ID(R), sig_clr);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::E, sig_en);
+ cell->setPort(ID::S, sig_set);
+ cell->setPort(ID::R, sig_clr);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2353,7 +2378,7 @@ RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const st
{
RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($anyconst));
- cell->setParam(ID(WIDTH), width);
+ cell->setParam(ID::WIDTH, width);
cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
return sig;
@@ -2363,7 +2388,7 @@ RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std:
{
RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($anyseq));
- cell->setParam(ID(WIDTH), width);
+ cell->setParam(ID::WIDTH, width);
cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
return sig;
@@ -2373,7 +2398,7 @@ RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const st
{
RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($allconst));
- cell->setParam(ID(WIDTH), width);
+ cell->setParam(ID::WIDTH, width);
cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
return sig;
@@ -2383,7 +2408,7 @@ RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std:
{
RTLIL::SigSpec sig = addWire(NEW_ID, width);
Cell *cell = addCell(name, ID($allseq));
- cell->setParam(ID(WIDTH), width);
+ cell->setParam(ID::WIDTH, width);
cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
return sig;
@@ -2505,14 +2530,9 @@ void RTLIL::Cell::unsetPort(RTLIL::IdString portname)
void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
{
- auto conn_it = connections_.find(portname);
-
- if (conn_it == connections_.end()) {
- connections_[portname] = RTLIL::SigSpec();
- conn_it = connections_.find(portname);
- log_assert(conn_it != connections_.end());
- } else
- if (conn_it->second == signal)
+ auto r = connections_.insert(portname);
+ auto conn_it = r.first;
+ if (!r.second && conn_it->second == signal)
return;
for (auto mon : module->monitors)
@@ -2527,7 +2547,7 @@ void RTLIL::Cell::setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
log_backtrace("-X- ", yosys_xtrace-1);
}
- conn_it->second = signal;
+ conn_it->second = std::move(signal);
}
const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const
@@ -2585,7 +2605,7 @@ void RTLIL::Cell::unsetParam(RTLIL::IdString paramname)
void RTLIL::Cell::setParam(RTLIL::IdString paramname, RTLIL::Const value)
{
- parameters[paramname] = value;
+ parameters[paramname] = std::move(value);
}
const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const
@@ -2615,25 +2635,25 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
return;
if (type == ID($mux) || type == ID($pmux)) {
- parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
+ parameters[ID::WIDTH] = GetSize(connections_[ID::Y]);
if (type == ID($pmux))
- parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]);
+ parameters[ID::S_WIDTH] = GetSize(connections_[ID::S]);
check();
return;
}
if (type == ID($lut) || type == ID($sop)) {
- parameters[ID(WIDTH)] = GetSize(connections_[ID::A]);
+ parameters[ID::WIDTH] = GetSize(connections_[ID::A]);
return;
}
if (type == ID($fa)) {
- parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
+ parameters[ID::WIDTH] = GetSize(connections_[ID::Y]);
return;
}
if (type == ID($lcu)) {
- parameters[ID(WIDTH)] = GetSize(connections_[ID(CO)]);
+ parameters[ID::WIDTH] = GetSize(connections_[ID::CO]);
return;
}
@@ -2642,28 +2662,28 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
if (connections_.count(ID::A)) {
if (signedness_ab) {
if (set_a_signed)
- parameters[ID(A_SIGNED)] = true;
- else if (parameters.count(ID(A_SIGNED)) == 0)
- parameters[ID(A_SIGNED)] = false;
+ parameters[ID::A_SIGNED] = true;
+ else if (parameters.count(ID::A_SIGNED) == 0)
+ parameters[ID::A_SIGNED] = false;
}
- parameters[ID(A_WIDTH)] = GetSize(connections_[ID::A]);
+ parameters[ID::A_WIDTH] = GetSize(connections_[ID::A]);
}
if (connections_.count(ID::B)) {
if (signedness_ab) {
if (set_b_signed)
- parameters[ID(B_SIGNED)] = true;
- else if (parameters.count(ID(B_SIGNED)) == 0)
- parameters[ID(B_SIGNED)] = false;
+ parameters[ID::B_SIGNED] = true;
+ else if (parameters.count(ID::B_SIGNED) == 0)
+ parameters[ID::B_SIGNED] = false;
}
- parameters[ID(B_WIDTH)] = GetSize(connections_[ID::B]);
+ parameters[ID::B_WIDTH] = GetSize(connections_[ID::B]);
}
if (connections_.count(ID::Y))
- parameters[ID(Y_WIDTH)] = GetSize(connections_[ID::Y]);
+ parameters[ID::Y_WIDTH] = GetSize(connections_[ID::Y]);
- if (connections_.count(ID(Q)))
- parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]);
+ if (connections_.count(ID::Q))
+ parameters[ID::WIDTH] = GetSize(connections_[ID::Q]);
check();
}
@@ -2723,7 +2743,7 @@ RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width)
offset = 0;
}
-RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
+RTLIL::SigChunk::SigChunk(const RTLIL::SigBit &bit)
{
wire = bit.wire;
offset = 0;
@@ -2734,12 +2754,9 @@ RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
width = 1;
}
-RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) : data(sigchunk.data)
+RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk)
{
- wire = sigchunk.wire;
- data = sigchunk.data;
- width = sigchunk.width;
- offset = sigchunk.offset;
+ *this = sigchunk;
}
RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
@@ -2805,45 +2822,21 @@ RTLIL::SigSpec::SigSpec(std::initializer_list<RTLIL::SigSpec> parts)
width_ = 0;
hash_ = 0;
- std::vector<RTLIL::SigSpec> parts_vec(parts.begin(), parts.end());
- for (auto it = parts_vec.rbegin(); it != parts_vec.rend(); it++)
- append(*it);
+ log_assert(parts.size() > 0);
+ auto ie = parts.begin();
+ auto it = ie + parts.size() - 1;
+ while (it >= ie)
+ append(*it--);
}
-const RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other)
+RTLIL::SigSpec &RTLIL::SigSpec::operator=(const RTLIL::SigSpec &other)
{
cover("kernel.rtlil.sigspec.assign");
width_ = other.width_;
hash_ = other.hash_;
chunks_ = other.chunks_;
- bits_.clear();
-
- if (!other.bits_.empty())
- {
- RTLIL::SigChunk *last = NULL;
- int last_end_offset = 0;
-
- for (auto &bit : other.bits_) {
- if (last && bit.wire == last->wire) {
- if (bit.wire == NULL) {
- last->data.push_back(bit.data);
- last->width++;
- continue;
- } else if (last_end_offset == bit.offset) {
- last_end_offset++;
- last->width++;
- continue;
- }
- }
- chunks_.push_back(bit);
- last = &chunks_.back();
- last_end_offset = bit.offset + 1;
- }
-
- check();
- }
-
+ bits_ = other.bits_;
return *this;
}
@@ -2851,7 +2844,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::Const &value)
{
cover("kernel.rtlil.sigspec.init.const");
- chunks_.push_back(RTLIL::SigChunk(value));
+ chunks_.emplace_back(value);
width_ = chunks_.back().width;
hash_ = 0;
check();
@@ -2861,7 +2854,7 @@ RTLIL::SigSpec::SigSpec(const RTLIL::SigChunk &chunk)
{
cover("kernel.rtlil.sigspec.init.chunk");
- chunks_.push_back(chunk);
+ chunks_.emplace_back(chunk);
width_ = chunks_.back().width;
hash_ = 0;
check();
@@ -2871,7 +2864,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire)
{
cover("kernel.rtlil.sigspec.init.wire");
- chunks_.push_back(RTLIL::SigChunk(wire));
+ chunks_.emplace_back(wire);
width_ = chunks_.back().width;
hash_ = 0;
check();
@@ -2881,7 +2874,7 @@ RTLIL::SigSpec::SigSpec(RTLIL::Wire *wire, int offset, int width)
{
cover("kernel.rtlil.sigspec.init.wire_part");
- chunks_.push_back(RTLIL::SigChunk(wire, offset, width));
+ chunks_.emplace_back(wire, offset, width);
width_ = chunks_.back().width;
hash_ = 0;
check();
@@ -2891,7 +2884,7 @@ RTLIL::SigSpec::SigSpec(const std::string &str)
{
cover("kernel.rtlil.sigspec.init.str");
- chunks_.push_back(RTLIL::SigChunk(str));
+ chunks_.emplace_back(str);
width_ = chunks_.back().width;
hash_ = 0;
check();
@@ -2901,7 +2894,7 @@ RTLIL::SigSpec::SigSpec(int val, int width)
{
cover("kernel.rtlil.sigspec.init.int");
- chunks_.push_back(RTLIL::SigChunk(val, width));
+ chunks_.emplace_back(val, width);
width_ = width;
hash_ = 0;
check();
@@ -2911,18 +2904,18 @@ RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
{
cover("kernel.rtlil.sigspec.init.state");
- chunks_.push_back(RTLIL::SigChunk(bit, width));
+ chunks_.emplace_back(bit, width);
width_ = width;
hash_ = 0;
check();
}
-RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
+RTLIL::SigSpec::SigSpec(const RTLIL::SigBit &bit, int width)
{
cover("kernel.rtlil.sigspec.init.bit");
if (bit.wire == NULL)
- chunks_.push_back(RTLIL::SigChunk(bit.data, width));
+ chunks_.emplace_back(bit.data, width);
else
for (int i = 0; i < width; i++)
chunks_.push_back(bit);
@@ -2931,47 +2924,47 @@ RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
check();
}
-RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigChunk> chunks)
+RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigChunk> &chunks)
{
cover("kernel.rtlil.sigspec.init.stdvec_chunks");
width_ = 0;
hash_ = 0;
- for (auto &c : chunks)
+ for (const auto &c : chunks)
append(c);
check();
}
-RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
+RTLIL::SigSpec::SigSpec(const std::vector<RTLIL::SigBit> &bits)
{
cover("kernel.rtlil.sigspec.init.stdvec_bits");
width_ = 0;
hash_ = 0;
- for (auto &bit : bits)
- append_bit(bit);
+ for (const auto &bit : bits)
+ append(bit);
check();
}
-RTLIL::SigSpec::SigSpec(pool<RTLIL::SigBit> bits)
+RTLIL::SigSpec::SigSpec(const pool<RTLIL::SigBit> &bits)
{
cover("kernel.rtlil.sigspec.init.pool_bits");
width_ = 0;
hash_ = 0;
- for (auto &bit : bits)
- append_bit(bit);
+ for (const auto &bit : bits)
+ append(bit);
check();
}
-RTLIL::SigSpec::SigSpec(std::set<RTLIL::SigBit> bits)
+RTLIL::SigSpec::SigSpec(const std::set<RTLIL::SigBit> &bits)
{
cover("kernel.rtlil.sigspec.init.stdset_bits");
width_ = 0;
hash_ = 0;
- for (auto &bit : bits)
- append_bit(bit);
+ for (const auto &bit : bits)
+ append(bit);
check();
}
@@ -2981,7 +2974,7 @@ RTLIL::SigSpec::SigSpec(bool bit)
width_ = 0;
hash_ = 0;
- append_bit(bit);
+ append(SigBit(bit));
check();
}
@@ -3034,7 +3027,7 @@ void RTLIL::SigSpec::unpack() const
that->bits_.reserve(that->width_);
for (auto &c : that->chunks_)
for (int i = 0; i < c.width; i++)
- that->bits_.push_back(RTLIL::SigBit(c, i));
+ that->bits_.emplace_back(c, i);
that->chunks_.clear();
that->hash_ = 0;
@@ -3299,14 +3292,14 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLI
bits_match[i].wire == pattern_chunk.wire &&
bits_match[i].offset >= pattern_chunk.offset &&
bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width)
- ret.append_bit(bits_other[i]);
+ ret.append(bits_other[i]);
} else {
for (int i = 0; i < width_; i++)
if (bits_match[i].wire &&
bits_match[i].wire == pattern_chunk.wire &&
bits_match[i].offset >= pattern_chunk.offset &&
bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width)
- ret.append_bit(bits_match[i]);
+ ret.append(bits_match[i]);
}
}
@@ -3330,11 +3323,11 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(const pool<RTLIL::SigBit> &pattern, const
std::vector<RTLIL::SigBit> bits_other = other->to_sigbit_vector();
for (int i = 0; i < width_; i++)
if (bits_match[i].wire && pattern.count(bits_match[i]))
- ret.append_bit(bits_other[i]);
+ ret.append(bits_other[i]);
} else {
for (int i = 0; i < width_; i++)
if (bits_match[i].wire && pattern.count(bits_match[i]))
- ret.append_bit(bits_match[i]);
+ ret.append(bits_match[i]);
}
ret.check();
@@ -3456,7 +3449,7 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
check();
}
-void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
+void RTLIL::SigSpec::append(const RTLIL::SigBit &bit)
{
if (packed())
{
@@ -3529,7 +3522,7 @@ void RTLIL::SigSpec::check() const
int w = 0;
for (size_t i = 0; i < chunks_.size(); i++) {
- const RTLIL::SigChunk chunk = chunks_[i];
+ const RTLIL::SigChunk &chunk = chunks_[i];
if (chunk.wire == NULL) {
if (i > 0)
log_assert(chunks_[i-1].wire != NULL);
@@ -3768,11 +3761,11 @@ std::string RTLIL::SigSpec::as_string() const
pack();
std::string str;
+ str.reserve(size());
for (size_t i = chunks_.size(); i > 0; i--) {
const RTLIL::SigChunk &chunk = chunks_[i-1];
if (chunk.wire != NULL)
- for (int j = 0; j < chunk.width; j++)
- str += "?";
+ str.append(chunk.width, '?');
else
str += RTLIL::Const(chunk.data).as_string();
}
@@ -3819,24 +3812,30 @@ RTLIL::SigBit RTLIL::SigSpec::as_bit() const
return bits_[0];
}
-bool RTLIL::SigSpec::match(std::string pattern) const
+bool RTLIL::SigSpec::match(const char* pattern) const
{
cover("kernel.rtlil.sigspec.match");
- pack();
- std::string str = as_string();
- log_assert(pattern.size() == str.size());
+ unpack();
+ log_assert(int(strlen(pattern)) == GetSize(bits_));
- for (size_t i = 0; i < pattern.size(); i++) {
- if (pattern[i] == ' ')
+ for (auto it = bits_.rbegin(); it != bits_.rend(); it++, pattern++) {
+ if (*pattern == ' ')
continue;
- if (pattern[i] == '*') {
- if (str[i] != 'z' && str[i] != 'x')
+ if (*pattern == '*') {
+ if (*it != State::Sz && *it != State::Sx)
return false;
continue;
}
- if (pattern[i] != str[i])
- return false;
+ if (*pattern == '0') {
+ if (*it != State::S0)
+ return false;
+ } else
+ if (*pattern == '1') {
+ if (*it != State::S1)
+ return false;
+ } else
+ log_abort();
}
return true;
@@ -3860,6 +3859,7 @@ pool<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_pool() const
pack();
pool<RTLIL::SigBit> sigbits;
+ sigbits.reserve(size());
for (auto &c : chunks_)
for (int i = 0; i < c.width; i++)
sigbits.insert(RTLIL::SigBit(c, i));
@@ -3900,6 +3900,7 @@ dict<RTLIL::SigBit, RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_dict(const RTLIL::S
log_assert(width_ == other.width_);
dict<RTLIL::SigBit, RTLIL::SigBit> new_map;
+ new_map.reserve(size());
for (int i = 0; i < width_; i++)
new_map[bits_[i]] = other.bits_[i];
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 4afe4304f..17f038e36 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -235,7 +235,10 @@ namespace RTLIL
return;
log_assert(refcount == 0);
-
+ free_reference(idx);
+ }
+ static inline void free_reference(int idx)
+ {
if (yosys_xtrace) {
log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx);
log_backtrace("-X- ", yosys_xtrace-1);
@@ -358,34 +361,37 @@ namespace RTLIL
// often one needs to check if a given IdString is part of a list (for example a list
// of cell types). the following functions helps with that.
- template<typename T, typename... Args>
- bool in(T first, Args... rest) const {
- return in(first) || in(rest...);
+ template<typename... Args>
+ bool in(Args... args) const {
+ // Credit: https://articles.emptycrate.com/2016/05/14/folds_in_cpp11_ish.html
+ bool result = false;
+ (void) std::initializer_list<int>{ (result = result || in(args), 0)... };
+ return result;
}
- bool in(IdString rhs) const { return *this == rhs; }
+ bool in(const IdString &rhs) const { return *this == rhs; }
bool in(const char *rhs) const { return *this == rhs; }
bool in(const std::string &rhs) const { return *this == rhs; }
bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; }
};
namespace ID {
- // defined in rtlil.cc, initialized in yosys.cc
- extern IdString A, B, Y;
- extern IdString keep;
- extern IdString whitebox;
- extern IdString blackbox;
+#define X(_id) extern IdString _id;
+#include "kernel/constids.inc"
+#undef X
};
extern dict<std::string, std::string> constpad;
- static inline std::string escape_id(std::string str) {
+ const pool<IdString> &builtin_ff_cell_types();
+
+ static inline std::string escape_id(const std::string &str) {
if (str.size() > 0 && str[0] != '\\' && str[0] != '$')
return "\\" + str;
return str;
}
- static inline std::string unescape_id(std::string str) {
+ static inline std::string unescape_id(const std::string &str) {
if (str.size() < 2)
return str;
if (str[0] != '\\')
@@ -401,7 +407,7 @@ namespace RTLIL
return unescape_id(str.str());
}
- static inline const char *id2cstr(const RTLIL::IdString &str) {
+ static inline const char *id2cstr(RTLIL::IdString str) {
return log_id(str);
}
@@ -606,7 +612,7 @@ struct RTLIL::Const
bool as_bool() const;
int as_int(bool is_signed = false) const;
std::string as_string() const;
- static Const from_string(std::string str);
+ static Const from_string(const std::string &str);
std::string decode_string() const;
@@ -678,7 +684,7 @@ struct RTLIL::SigChunk
SigChunk(const std::string &str);
SigChunk(int val, int width = 32);
SigChunk(RTLIL::State bit, int width = 1);
- SigChunk(RTLIL::SigBit bit);
+ SigChunk(const RTLIL::SigBit &bit);
SigChunk(const RTLIL::SigChunk &sigchunk);
RTLIL::SigChunk &operator =(const RTLIL::SigChunk &other) = default;
@@ -758,11 +764,15 @@ private:
unpack();
}
+ // Only used by Module::remove(const pool<Wire*> &wires)
+ // but cannot be more specific as it isn't yet declared
+ friend struct RTLIL::Module;
+
public:
SigSpec();
SigSpec(const RTLIL::SigSpec &other);
SigSpec(std::initializer_list<RTLIL::SigSpec> parts);
- const RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other);
+ RTLIL::SigSpec &operator=(const RTLIL::SigSpec &other);
SigSpec(const RTLIL::Const &value);
SigSpec(const RTLIL::SigChunk &chunk);
@@ -771,11 +781,11 @@ public:
SigSpec(const std::string &str);
SigSpec(int val, int width = 32);
SigSpec(RTLIL::State bit, int width = 1);
- SigSpec(RTLIL::SigBit bit, int width = 1);
- SigSpec(std::vector<RTLIL::SigChunk> chunks);
- SigSpec(std::vector<RTLIL::SigBit> bits);
- SigSpec(pool<RTLIL::SigBit> bits);
- SigSpec(std::set<RTLIL::SigBit> bits);
+ SigSpec(const RTLIL::SigBit &bit, int width = 1);
+ SigSpec(const std::vector<RTLIL::SigChunk> &chunks);
+ SigSpec(const std::vector<RTLIL::SigBit> &bits);
+ SigSpec(const pool<RTLIL::SigBit> &bits);
+ SigSpec(const std::set<RTLIL::SigBit> &bits);
SigSpec(bool bit);
SigSpec(RTLIL::SigSpec &&other) {
@@ -845,7 +855,13 @@ public:
RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); }
void append(const RTLIL::SigSpec &signal);
- void append_bit(const RTLIL::SigBit &bit);
+ inline void append(Wire *wire) { append(RTLIL::SigSpec(wire)); }
+ inline void append(const RTLIL::SigChunk &chunk) { append(RTLIL::SigSpec(chunk)); }
+ inline void append(const RTLIL::Const &const_) { append(RTLIL::SigSpec(const_)); }
+
+ void append(const RTLIL::SigBit &bit);
+ inline void append(RTLIL::State state) { append(RTLIL::SigBit(state)); }
+ inline void append(bool bool_) { append(RTLIL::SigBit(bool_)); }
void extend_u0(int width, bool is_signed = false);
@@ -877,7 +893,7 @@ public:
RTLIL::SigChunk as_chunk() const;
RTLIL::SigBit as_bit() const;
- bool match(std::string pattern) const;
+ bool match(const char* pattern) const;
std::set<RTLIL::SigBit> to_sigbit_set() const;
pool<RTLIL::SigBit> to_sigbit_pool() const;
@@ -891,7 +907,7 @@ public:
operator std::vector<RTLIL::SigChunk>() const { return chunks(); }
operator std::vector<RTLIL::SigBit>() const { return bits(); }
- RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }
+ const RTLIL::SigBit &at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }
unsigned int hash() const { if (!hash_) updhash(); return hash_; };
@@ -946,7 +962,7 @@ struct RTLIL::Monitor
virtual ~Monitor() { }
virtual void notify_module_add(RTLIL::Module*) { }
virtual void notify_module_del(RTLIL::Module*) { }
- virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, RTLIL::SigSpec&) { }
+ virtual void notify_connect(RTLIL::Cell*, const RTLIL::IdString&, const RTLIL::SigSpec&, const RTLIL::SigSpec&) { }
virtual void notify_connect(RTLIL::Module*, const RTLIL::SigSig&) { }
virtual void notify_connect(RTLIL::Module*, const std::vector<RTLIL::SigSig>&) { }
virtual void notify_blackout(RTLIL::Module*) { }
@@ -988,15 +1004,15 @@ struct RTLIL::Design
void remove(RTLIL::Module *module);
void rename(RTLIL::Module *module, RTLIL::IdString new_name);
- void scratchpad_unset(std::string varname);
+ void scratchpad_unset(const std::string &varname);
- void scratchpad_set_int(std::string varname, int value);
- void scratchpad_set_bool(std::string varname, bool value);
- void scratchpad_set_string(std::string varname, std::string value);
+ void scratchpad_set_int(const std::string &varname, int value);
+ void scratchpad_set_bool(const std::string &varname, bool value);
+ void scratchpad_set_string(const std::string &varname, std::string value);
- int scratchpad_get_int(std::string varname, int default_value = 0) const;
- bool scratchpad_get_bool(std::string varname, bool default_value = false) const;
- std::string scratchpad_get_string(std::string varname, std::string default_value = std::string()) const;
+ int scratchpad_get_int(const std::string &varname, int default_value = 0) const;
+ bool scratchpad_get_bool(const std::string &varname, bool default_value = false) const;
+ std::string scratchpad_get_string(const std::string &varname, const std::string &default_value = std::string()) const;
void sort();
void check();
@@ -1072,10 +1088,10 @@ public:
Module();
virtual ~Module();
- virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail = false);
- virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail = false);
+ virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, bool mayfail = false);
+ virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
virtual size_t count_id(RTLIL::IdString id);
- virtual void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces);
+ virtual void reprocess_module(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
virtual void sort();
virtual void check();
@@ -1136,166 +1152,166 @@ public:
// The add* methods create a cell and return the created cell. All signals must exist in advance.
- RTLIL::Cell* addNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addPos (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addNeg (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
-
- RTLIL::Cell* addAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
-
- RTLIL::Cell* addReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
-
- RTLIL::Cell* addShl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addShr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addSshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addSshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addShift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addShiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
-
- RTLIL::Cell* addLt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addLe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addEq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addNe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addEqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addNex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addGe (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addGt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
-
- RTLIL::Cell* addAdd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addSub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addMul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addDiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addMod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addPow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = "");
-
- RTLIL::Cell* addLogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addLogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
- RTLIL::Cell* addLogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed = false, const std::string &src = "");
-
- RTLIL::Cell* addMux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src = "");
- RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src = "");
-
- RTLIL::Cell* addSlice (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src = "");
- RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src = "");
- RTLIL::Cell* addLut (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src = "");
- RTLIL::Cell* addTribuf (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src = "");
- RTLIL::Cell* addAssert (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
- RTLIL::Cell* addAssume (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
- RTLIL::Cell* addLive (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
- RTLIL::Cell* addFair (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
- RTLIL::Cell* addCover (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src = "");
- RTLIL::Cell* addEquiv (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src = "");
-
- RTLIL::Cell* addSr (RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
- RTLIL::Cell* addFf (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src = "");
- RTLIL::Cell* addDff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDffe (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDffsr (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
- RTLIL::Cell* addAdff (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
+ RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addPos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addNeg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::Cell* addAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::Cell* addReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::Cell* addShl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addShr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addSshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addSshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addShift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addShiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::Cell* addLt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addLe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addEq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addNe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addEqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addNex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addGe (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addGt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::Cell* addAdd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addSub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addMul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addDiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addMod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addPow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = "");
+
+ RTLIL::Cell* addLogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addLogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+ RTLIL::Cell* addLogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::Cell* addMux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
+ RTLIL::Cell* addPmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
+
+ RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src = "");
+ RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
+ RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src = "");
+ RTLIL::Cell* addTribuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src = "");
+ RTLIL::Cell* addAssert (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
+ RTLIL::Cell* addAssume (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
+ RTLIL::Cell* addLive (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
+ RTLIL::Cell* addFair (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
+ RTLIL::Cell* addCover (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
+ RTLIL::Cell* addEquiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
+
+ RTLIL::Cell* addSr (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
+ RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDlatch (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDlatchsr (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
-
- RTLIL::Cell* addBufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addNotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addAndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addNandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addOrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addNorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addXorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addXnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addNmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = "");
- RTLIL::Cell* addOai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = "");
-
- RTLIL::Cell* addFfGate (RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src = "");
- RTLIL::Cell* addDffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDffeGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDffsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
- RTLIL::Cell* addAdffGate (RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
+ RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
+
+ RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addNandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addOrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addNorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addXorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addXnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addAndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addOrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addMuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addNmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addOai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
+ RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
+
+ RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
+ RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDffsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addAdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDlatchGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, const std::string &src = "");
- RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
- RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
+ RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
+ RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
// The methods without the add* prefix create a cell and an output signal. They return the newly created output signal.
- RTLIL::SigSpec Not (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Pos (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Bu0 (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Neg (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
-
- RTLIL::SigSpec And (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Or (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Xor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Xnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
-
- RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec ReduceOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec ReduceXor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec ReduceBool (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
-
- RTLIL::SigSpec Shl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Shr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Sshl (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Sshr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Shift (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Shiftx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
-
- RTLIL::SigSpec Lt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Le (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Eq (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Ne (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Eqx (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Nex (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Ge (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Gt (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
-
- RTLIL::SigSpec Add (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Sub (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Mul (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Div (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Mod (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec Pow (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = "");
-
- RTLIL::SigSpec LogicNot (RTLIL::IdString name, RTLIL::SigSpec sig_a, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec LogicAnd (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
- RTLIL::SigSpec LogicOr (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed = false, const std::string &src = "");
-
- RTLIL::SigSpec Mux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src = "");
- RTLIL::SigSpec Pmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, const std::string &src = "");
-
- RTLIL::SigBit BufGate (RTLIL::IdString name, RTLIL::SigBit sig_a, const std::string &src = "");
- RTLIL::SigBit NotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, const std::string &src = "");
- RTLIL::SigBit AndGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit NandGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit OrGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit NorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit XorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit XnorGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit OrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
- RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
- RTLIL::SigBit NmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
- RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
- RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
- RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = "");
- RTLIL::SigBit Oai4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = "");
+ RTLIL::SigSpec Not (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Pos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Bu0 (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Neg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::SigSpec And (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Or (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Xor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Xnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec ReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec ReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec ReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::SigSpec Shl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Shr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Sshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Sshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Shift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Shiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::SigSpec Lt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Le (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Eq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Ne (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Eqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Nex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Ge (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Gt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::SigSpec Add (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Sub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Mul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Div (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Mod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec Pow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = "");
+
+ RTLIL::SigSpec LogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec LogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+ RTLIL::SigSpec LogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
+
+ RTLIL::SigSpec Mux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
+ RTLIL::SigSpec Pmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
+
+ RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
+ RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
+ RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit NandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit OrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit NorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit XorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit XnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit AndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit OrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
+ RTLIL::SigBit MuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
+ RTLIL::SigBit NmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
+ RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
+ RTLIL::SigBit Oai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
+ RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
+ RTLIL::SigBit Oai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
@@ -1468,7 +1484,7 @@ inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_as
inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; }
-inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){if(wire) offset = sigbit.offset;}
+inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){ if (wire) offset = sigbit.offset; }
inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const {
if (wire == other.wire)
diff --git a/kernel/satgen.h b/kernel/satgen.h
index 133389eee..88b84b7e6 100644
--- a/kernel/satgen.h
+++ b/kernel/satgen.h
@@ -224,8 +224,8 @@ struct SatGen
void extendSignalWidth(std::vector<int> &vec_a, std::vector<int> &vec_b, RTLIL::Cell *cell, size_t y_width = 0, bool forced_signed = false)
{
bool is_signed = forced_signed;
- if (!forced_signed && cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters.count(ID(B_SIGNED)) > 0)
- is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool();
+ if (!forced_signed && cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters.count(ID::B_SIGNED) > 0)
+ is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool();
while (vec_a.size() < vec_b.size() || vec_a.size() < y_width)
vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);
while (vec_b.size() < vec_a.size() || vec_b.size() < y_width)
@@ -241,7 +241,7 @@ struct SatGen
void extendSignalWidthUnary(std::vector<int> &vec_a, std::vector<int> &vec_y, RTLIL::Cell *cell, bool forced_signed = false)
{
- bool is_signed = forced_signed || (cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool());
+ bool is_signed = forced_signed || (cell->parameters.count(ID::A_SIGNED) > 0 && cell->parameters[ID::A_SIGNED].as_bool());
while (vec_a.size() < vec_y.size())
vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);
while (vec_y.size() < vec_a.size())
@@ -397,8 +397,8 @@ struct SatGen
int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0);
int b = importDefSigSpec(cell->getPort(ID::B), timestep).at(0);
- int c = importDefSigSpec(cell->getPort(ID(C)), timestep).at(0);
- int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID(D)), timestep).at(0);
+ int c = importDefSigSpec(cell->getPort(ID::C), timestep).at(0);
+ int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID::D), timestep).at(0);
int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
int yy = model_undef ? ez->literal() : y;
@@ -411,8 +411,8 @@ struct SatGen
{
int undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep).at(0);
int undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep).at(0);
- int undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep).at(0);
- int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID(D)), timestep).at(0);
+ int undef_c = importUndefSigSpec(cell->getPort(ID::C), timestep).at(0);
+ int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID::D), timestep).at(0);
int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);
if (aoi_mode)
@@ -479,7 +479,7 @@ struct SatGen
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
- std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@@ -492,7 +492,7 @@ struct SatGen
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
- std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
@@ -508,7 +508,7 @@ struct SatGen
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
- std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> s = importDefSigSpec(cell->getPort(ID::S), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@@ -524,7 +524,7 @@ struct SatGen
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
- std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID::S), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int maybe_a = ez->CONST_TRUE;
@@ -684,7 +684,7 @@ struct SatGen
if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt)))
{
- bool is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool();
+ bool is_signed = cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool();
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
@@ -774,7 +774,7 @@ struct SatGen
int extend_bit = ez->CONST_FALSE;
- if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())
+ if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID::A_SIGNED].as_bool())
extend_bit = a.back();
while (y.size() < a.size())
@@ -792,10 +792,10 @@ struct SatGen
shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($sshr))
- shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
+ shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type.in(ID($shift), ID($shiftx)))
- shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
+ shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
ez->assume(ez->vec_eq(shifted_a, yy));
@@ -807,7 +807,7 @@ struct SatGen
std::vector<int> undef_a_shifted;
extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE;
- if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())
+ if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID::A_SIGNED].as_bool())
extend_bit = undef_a.back();
while (undef_y.size() < undef_a.size())
@@ -822,13 +822,13 @@ struct SatGen
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($sshr))
- undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
+ undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID::A_SIGNED].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shift))
- undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
+ undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
if (cell->type == ID($shiftx))
- undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
+ undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID::B_SIGNED].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
std::vector<int> undef_all_y_bits(undef_y.size(), undef_any_b);
@@ -945,7 +945,7 @@ struct SatGen
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> a_u, b_u;
- if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) {
+ if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) {
a_u = ez->vec_ite(a.back(), ez->vec_neg(a), a);
b_u = ez->vec_ite(b.back(), ez->vec_neg(b), b);
} else {
@@ -971,12 +971,12 @@ struct SatGen
std::vector<int> y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size());
if (cell->type == ID($div)) {
- if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())
+ if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));
else
ez->assume(ez->vec_eq(y_tmp, y_u));
} else {
- if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())
+ if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf)));
else
ez->assume(ez->vec_eq(y_tmp, chain_buf));
@@ -987,7 +987,7 @@ struct SatGen
} else {
std::vector<int> div_zero_result;
if (cell->type == ID($div)) {
- if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) {
+ if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool()) {
std::vector<int> all_ones(y.size(), ez->CONST_TRUE);
std::vector<int> only_first_one(y.size(), ez->CONST_FALSE);
only_first_one.at(0) = ez->CONST_TRUE;
@@ -999,7 +999,7 @@ struct SatGen
} else {
int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size());
div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits);
- if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())
+ if (cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool())
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back());
else
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
@@ -1021,7 +1021,7 @@ struct SatGen
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> lut;
- for (auto bit : cell->getParam(ID(LUT)).bits)
+ for (auto bit : cell->getParam(ID::LUT).bits)
lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE);
while (GetSize(lut) < (1 << GetSize(a)))
lut.push_back(ez->CONST_FALSE);
@@ -1070,10 +1070,10 @@ struct SatGen
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
- int width = cell->getParam(ID(WIDTH)).as_int();
- int depth = cell->getParam(ID(DEPTH)).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int depth = cell->getParam(ID::DEPTH).as_int();
- vector<State> table_raw = cell->getParam(ID(TABLE)).bits;
+ vector<State> table_raw = cell->getParam(ID::TABLE).bits;
while (GetSize(table_raw) < 2*width*depth)
table_raw.push_back(State::S0);
@@ -1151,9 +1151,9 @@ struct SatGen
{
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
- std::vector<int> c = importDefSigSpec(cell->getPort(ID(C)), timestep);
+ std::vector<int> c = importDefSigSpec(cell->getPort(ID::C), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
- std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);
+ std::vector<int> x = importDefSigSpec(cell->getPort(ID::X), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> xx = model_undef ? ez->vec_var(x.size()) : x;
@@ -1169,10 +1169,10 @@ struct SatGen
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
- std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep);
+ std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID::C), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
- std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep);
+ std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID::X), timestep);
ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c)));
ez->assume(ez->vec_eq(undef_x, undef_y));
@@ -1185,10 +1185,10 @@ struct SatGen
if (cell->type == ID($lcu))
{
- std::vector<int> p = importDefSigSpec(cell->getPort(ID(P)), timestep);
- std::vector<int> g = importDefSigSpec(cell->getPort(ID(G)), timestep);
- std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep);
- std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);
+ std::vector<int> p = importDefSigSpec(cell->getPort(ID::P), timestep);
+ std::vector<int> g = importDefSigSpec(cell->getPort(ID::G), timestep);
+ std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep);
+ std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(co.size()) : co;
@@ -1197,10 +1197,10 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID(P)), timestep);
- std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID(G)), timestep);
- std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep);
- std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);
+ std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID::P), timestep);
+ std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID::G), timestep);
+ std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID::CI), timestep);
+ std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep);
int undef_any_p = ez->expression(ezSAT::OpOr, undef_p);
int undef_any_g = ez->expression(ezSAT::OpOr, undef_g);
@@ -1220,10 +1220,10 @@ struct SatGen
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
- std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);
- std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep);
- std::vector<int> bi = importDefSigSpec(cell->getPort(ID(BI)), timestep);
- std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);
+ std::vector<int> x = importDefSigSpec(cell->getPort(ID::X), timestep);
+ std::vector<int> ci = importDefSigSpec(cell->getPort(ID::CI), timestep);
+ std::vector<int> bi = importDefSigSpec(cell->getPort(ID::BI), timestep);
+ std::vector<int> co = importDefSigSpec(cell->getPort(ID::CO), timestep);
extendSignalWidth(a, b, y, cell);
extendSignalWidth(a, b, x, cell);
@@ -1250,12 +1250,12 @@ struct SatGen
{
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
- std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep);
- std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), timestep);
+ std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID::CI), timestep);
+ std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID::BI), timestep);
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
- std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep);
- std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);
+ std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID::X), timestep);
+ std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID::CO), timestep);
extendSignalWidth(undef_a, undef_b, undef_y, cell);
extendSignalWidth(undef_a, undef_b, undef_x, cell);
@@ -1285,7 +1285,7 @@ struct SatGen
{
RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec y = cell->getPort(ID::Y);
- ez->assume(signals_eq(a.extract(cell->parameters.at(ID(OFFSET)).as_int(), y.size()), y, timestep));
+ ez->assume(signals_eq(a.extract(cell->parameters.at(ID::OFFSET).as_int(), y.size()), y, timestep));
return true;
}
@@ -1306,20 +1306,20 @@ struct SatGen
{
if (timestep == 1)
{
- initial_state.add((*sigmap)(cell->getPort(ID(Q))));
+ initial_state.add((*sigmap)(cell->getPort(ID::Q)));
}
else
{
- std::vector<int> d = importDefSigSpec(cell->getPort(ID(D)), timestep-1);
- std::vector<int> q = importDefSigSpec(cell->getPort(ID(Q)), timestep);
+ std::vector<int> d = importDefSigSpec(cell->getPort(ID::D), timestep-1);
+ std::vector<int> q = importDefSigSpec(cell->getPort(ID::Q), timestep);
std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;
ez->assume(ez->vec_eq(d, qq));
if (model_undef)
{
- std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID(D)), timestep-1);
- std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID(Q)), timestep);
+ std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::D), timestep-1);
+ std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Q), timestep);
ez->assume(ez->vec_eq(undef_d, undef_q));
undefGating(q, qq, undef_q);
@@ -1397,7 +1397,7 @@ struct SatGen
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
asserts_a[pf].append((*sigmap)(cell->getPort(ID::A)));
- asserts_en[pf].append((*sigmap)(cell->getPort(ID(EN))));
+ asserts_en[pf].append((*sigmap)(cell->getPort(ID::EN)));
return true;
}
@@ -1405,7 +1405,7 @@ struct SatGen
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
assumes_a[pf].append((*sigmap)(cell->getPort(ID::A)));
- assumes_en[pf].append((*sigmap)(cell->getPort(ID(EN))));
+ assumes_en[pf].append((*sigmap)(cell->getPort(ID::EN)));
return true;
}
diff --git a/kernel/sigtools.h b/kernel/sigtools.h
index 2517d6de3..c631fa481 100644
--- a/kernel/sigtools.h
+++ b/kernel/sigtools.h
@@ -39,7 +39,7 @@ struct SigPool
bits.clear();
}
- void add(RTLIL::SigSpec sig)
+ void add(const RTLIL::SigSpec &sig)
{
for (auto &bit : sig)
if (bit.wire != NULL)
@@ -52,7 +52,7 @@ struct SigPool
bits.insert(bit);
}
- void del(RTLIL::SigSpec sig)
+ void del(const RTLIL::SigSpec &sig)
{
for (auto &bit : sig)
if (bit.wire != NULL)
@@ -65,7 +65,7 @@ struct SigPool
bits.erase(bit);
}
- void expand(RTLIL::SigSpec from, RTLIL::SigSpec to)
+ void expand(const RTLIL::SigSpec &from, const RTLIL::SigSpec &to)
{
log_assert(GetSize(from) == GetSize(to));
for (int i = 0; i < GetSize(from); i++) {
@@ -75,16 +75,16 @@ struct SigPool
}
}
- RTLIL::SigSpec extract(RTLIL::SigSpec sig)
+ RTLIL::SigSpec extract(const RTLIL::SigSpec &sig) const
{
RTLIL::SigSpec result;
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit))
- result.append_bit(bit);
+ result.append(bit);
return result;
}
- RTLIL::SigSpec remove(RTLIL::SigSpec sig)
+ RTLIL::SigSpec remove(const RTLIL::SigSpec &sig) const
{
RTLIL::SigSpec result;
for (auto &bit : sig)
@@ -93,12 +93,12 @@ struct SigPool
return result;
}
- bool check(RTLIL::SigBit bit)
+ bool check(const RTLIL::SigBit &bit) const
{
return bit.wire != NULL && bits.count(bit);
}
- bool check_any(RTLIL::SigSpec sig)
+ bool check_any(const RTLIL::SigSpec &sig) const
{
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit))
@@ -106,7 +106,7 @@ struct SigPool
return false;
}
- bool check_all(RTLIL::SigSpec sig)
+ bool check_all(const RTLIL::SigSpec &sig) const
{
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit) == 0)
@@ -114,14 +114,14 @@ struct SigPool
return true;
}
- RTLIL::SigSpec export_one()
+ RTLIL::SigSpec export_one() const
{
for (auto &bit : bits)
return RTLIL::SigSpec(bit.first, bit.second);
return RTLIL::SigSpec();
}
- RTLIL::SigSpec export_all()
+ RTLIL::SigSpec export_all() const
{
pool<RTLIL::SigBit> sig;
for (auto &bit : bits)
@@ -153,67 +153,67 @@ struct SigSet
bits.clear();
}
- void insert(RTLIL::SigSpec sig, T data)
+ void insert(const RTLIL::SigSpec &sig, T data)
{
- for (auto &bit : sig)
+ for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].insert(data);
}
- void insert(RTLIL::SigSpec sig, const std::set<T> &data)
+ void insert(const RTLIL::SigSpec& sig, const std::set<T> &data)
{
- for (auto &bit : sig)
+ for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].insert(data.begin(), data.end());
}
- void erase(RTLIL::SigSpec sig)
+ void erase(const RTLIL::SigSpec& sig)
{
- for (auto &bit : sig)
+ for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].clear();
}
- void erase(RTLIL::SigSpec sig, T data)
+ void erase(const RTLIL::SigSpec &sig, T data)
{
- for (auto &bit : sig)
+ for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].erase(data);
}
- void erase(RTLIL::SigSpec sig, const std::set<T> &data)
+ void erase(const RTLIL::SigSpec &sig, const std::set<T> &data)
{
- for (auto &bit : sig)
+ for (const auto &bit : sig)
if (bit.wire != NULL)
bits[bit].erase(data.begin(), data.end());
}
- void find(RTLIL::SigSpec sig, std::set<T> &result)
+ void find(const RTLIL::SigSpec &sig, std::set<T> &result)
{
- for (auto &bit : sig)
+ for (const auto &bit : sig)
if (bit.wire != NULL) {
auto &data = bits[bit];
result.insert(data.begin(), data.end());
}
}
- void find(RTLIL::SigSpec sig, pool<T> &result)
+ void find(const RTLIL::SigSpec &sig, pool<T> &result)
{
- for (auto &bit : sig)
+ for (const auto &bit : sig)
if (bit.wire != NULL) {
auto &data = bits[bit];
result.insert(data.begin(), data.end());
}
}
- std::set<T> find(RTLIL::SigSpec sig)
+ std::set<T> find(const RTLIL::SigSpec &sig)
{
std::set<T> result;
find(sig, result);
return result;
}
- bool has(RTLIL::SigSpec sig)
+ bool has(const RTLIL::SigSpec &sig)
{
for (auto &bit : sig)
if (bit.wire != NULL && bits.count(bit))
@@ -262,7 +262,7 @@ struct SigMap
add(it.first, it.second);
}
- void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
+ void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to)
{
log_assert(GetSize(from) == GetSize(to));
@@ -287,15 +287,21 @@ struct SigMap
}
}
- void add(RTLIL::SigSpec sig)
+ void add(const RTLIL::SigBit &bit)
{
- for (auto &bit : sig) {
- RTLIL::SigBit b = database.find(bit);
- if (b.wire != nullptr)
- database.promote(bit);
- }
+ const auto &b = database.find(bit);
+ if (b.wire != nullptr)
+ database.promote(bit);
+ }
+
+ void add(const RTLIL::SigSpec &sig)
+ {
+ for (const auto &bit : sig)
+ add(bit);
}
+ inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); }
+
void apply(RTLIL::SigBit &bit) const
{
bit = database.find(bit);
@@ -329,7 +335,7 @@ struct SigMap
RTLIL::SigSpec allbits() const
{
RTLIL::SigSpec sig;
- for (auto &bit : database)
+ for (const auto &bit : database)
if (bit.wire != nullptr)
sig.append(bit);
return sig;
diff --git a/kernel/timinginfo.h b/kernel/timinginfo.h
index 4b77c02e8..fb4e0930d 100644
--- a/kernel/timinginfo.h
+++ b/kernel/timinginfo.h
@@ -82,20 +82,20 @@ struct TimingInfo
for (auto cell : module->cells()) {
if (cell->type == ID($specify2)) {
- auto src = cell->getPort(ID(SRC));
- auto dst = cell->getPort(ID(DST));
+ auto src = cell->getPort(ID::SRC);
+ auto dst = cell->getPort(ID::DST);
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dst.chunks())
if (!c.wire->port_output)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst));
- int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
- int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
+ int rise_max = cell->getParam(ID::T_RISE_MAX).as_int();
+ int fall_max = cell->getParam(ID::T_FALL_MAX).as_int();
int max = std::max(rise_max,fall_max);
if (max < 0)
log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell));
- if (cell->getParam(ID(FULL)).as_bool()) {
+ if (cell->getParam(ID::FULL).as_bool()) {
for (const auto &s : src)
for (const auto &d : dst) {
auto r = t.comb.insert(BitBit(s,d));
@@ -117,16 +117,16 @@ struct TimingInfo
}
}
else if (cell->type == ID($specify3)) {
- auto src = cell->getPort(ID(SRC));
- auto dst = cell->getPort(ID(DST));
+ auto src = cell->getPort(ID::SRC);
+ auto dst = cell->getPort(ID::DST);
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dst.chunks())
if (!c.wire->port_output)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst));
- int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int();
- int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int();
+ int rise_max = cell->getParam(ID::T_RISE_MAX).as_int();
+ int fall_max = cell->getParam(ID::T_FALL_MAX).as_int();
int max = std::max(rise_max,fall_max);
if (max < 0)
log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
@@ -140,18 +140,18 @@ struct TimingInfo
}
}
else if (cell->type == ID($specrule)) {
- auto type = cell->getParam(ID(TYPE)).decode_string();
+ auto type = cell->getParam(ID::TYPE).decode_string();
if (type != "$setup" && type != "$setuphold")
continue;
- auto src = cell->getPort(ID(SRC));
- auto dst = cell->getPort(ID(DST));
+ auto src = cell->getPort(ID::SRC);
+ auto dst = cell->getPort(ID::DST);
for (const auto &c : src.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src));
for (const auto &c : dst.chunks())
if (!c.wire->port_input)
log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dst));
- int max = cell->getParam(ID(T_LIMIT_MAX)).as_int();
+ int max = cell->getParam(ID::T_LIMIT_MAX).as_int();
if (max < 0)
log_warning("Module '%s' contains specify cell '%s' with T_LIMIT_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell));
if (max <= 0) {
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 4cb53f05d..01131601f 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -515,12 +515,9 @@ void yosys_setup()
return;
already_setup = true;
- RTLIL::ID::A = "\\A";
- RTLIL::ID::B = "\\B";
- RTLIL::ID::Y = "\\Y";
- RTLIL::ID::keep = "\\keep";
- RTLIL::ID::whitebox = "\\whitebox";
- RTLIL::ID::blackbox = "\\blackbox";
+#define X(_id) RTLIL::ID::_id = "\\" # _id;
+#include "kernel/constids.inc"
+#undef X
#ifdef WITH_PYTHON
PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
@@ -838,7 +835,7 @@ std::string proc_share_dirname()
std::string proc_share_path = proc_self_path + "share/";
if (check_file_exists(proc_share_path, true))
return proc_share_path;
- proc_share_path = proc_self_path + "../share/yosys/";
+ proc_share_path = proc_self_path + "../share/" + proc_program_prefix()+ "yosys/";
if (check_file_exists(proc_share_path, true))
return proc_share_path;
# ifdef YOSYS_DATDIR
@@ -851,6 +848,15 @@ std::string proc_share_dirname()
}
#endif
+std::string proc_program_prefix()
+{
+ std::string program_prefix;
+#ifdef YOSYS_PROGRAM_PREFIX
+ program_prefix = YOSYS_PROGRAM_PREFIX;
+#endif
+ return program_prefix;
+}
+
bool fgetline(FILE *f, std::string &buffer)
{
buffer = "";
@@ -1037,6 +1043,8 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
command = "verilog";
else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0)
command = "ilang";
+ else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".cc") == 0)
+ command = "cxxrtl";
else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0)
command = "aiger";
else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".blif") == 0)
@@ -1098,30 +1106,29 @@ static char *readline_obj_generator(const char *text, int state)
if (design->selected_active_module.empty())
{
- for (auto &it : design->modules_)
- if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
- obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+ for (auto mod : design->modules())
+ if (RTLIL::unescape_id(mod->name).compare(0, len, text) == 0)
+ obj_names.push_back(strdup(log_id(mod->name)));
}
- else
- if (design->modules_.count(design->selected_active_module) > 0)
+ else if (design->module(design->selected_active_module) != nullptr)
{
- RTLIL::Module *module = design->modules_.at(design->selected_active_module);
+ RTLIL::Module *module = design->module(design->selected_active_module);
- for (auto &it : module->wires_)
- if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
- obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+ for (auto w : module->wires())
+ if (RTLIL::unescape_id(w->name).compare(0, len, text) == 0)
+ obj_names.push_back(strdup(log_id(w->name)));
for (auto &it : module->memories)
if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
- obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+ obj_names.push_back(strdup(log_id(it.first)));
- for (auto &it : module->cells_)
- if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
- obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+ for (auto cell : module->cells())
+ if (RTLIL::unescape_id(cell->name).compare(0, len, text) == 0)
+ obj_names.push_back(strdup(log_id(cell->name)));
for (auto &it : module->processes)
if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
- obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
+ obj_names.push_back(strdup(log_id(it.first)));
}
std::sort(obj_names.begin(), obj_names.end());
diff --git a/kernel/yosys.h b/kernel/yosys.h
index 179bfe07a..5ad47054c 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -207,6 +207,7 @@ namespace RTLIL {
struct SigSpec;
struct Wire;
struct Cell;
+ struct Memory;
struct Module;
struct Design;
struct Monitor;
@@ -229,6 +230,7 @@ using RTLIL::Design;
namespace hashlib {
template<> struct hash_ops<RTLIL::Wire*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Cell*> : hash_obj_ops {};
+ template<> struct hash_ops<RTLIL::Memory*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Module*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Design*> : hash_obj_ops {};
template<> struct hash_ops<RTLIL::Monitor*> : hash_obj_ops {};
@@ -236,6 +238,7 @@ namespace hashlib {
template<> struct hash_ops<const RTLIL::Wire*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Cell*> : hash_obj_ops {};
+ template<> struct hash_ops<const RTLIL::Memory*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Module*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Design*> : hash_obj_ops {};
template<> struct hash_ops<const RTLIL::Monitor*> : hash_obj_ops {};
@@ -306,9 +309,9 @@ RTLIL::IdString new_id(std::string file, int line, std::string func);
#define NEW_ID \
YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__)
-// Create a statically allocated IdString object, using for example ID(A) or ID($add).
+// Create a statically allocated IdString object, using for example ID::A or ID($add).
//
-// Recipe for Converting old code that is using conversion of strings like "\\A" and
+// Recipe for Converting old code that is using conversion of strings like ID::A and
// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
//
@@ -321,6 +324,7 @@ namespace ID = RTLIL::ID;
RTLIL::Design *yosys_get_design();
std::string proc_self_dirname();
std::string proc_share_dirname();
+std::string proc_program_prefix();
const char *create_prompt(RTLIL::Design *design, int recursion_counter);
std::vector<std::string> glob_filename(const std::string &filename_pattern);
void rewrite_filename(std::string &filename);
diff --git a/libs/ezsat/ezsat.cc b/libs/ezsat/ezsat.cc
index 177bcd8a3..8c666ca1f 100644
--- a/libs/ezsat/ezsat.cc
+++ b/libs/ezsat/ezsat.cc
@@ -1371,24 +1371,39 @@ int ezSAT::onehot(const std::vector<int> &vec, bool max_only)
if (max_only == false)
formula.push_back(expression(OpOr, vec));
- // create binary vector
- int num_bits = clog2(vec.size());
- std::vector<int> bits;
- for (int k = 0; k < num_bits; k++)
- bits.push_back(literal());
-
- // add at-most-one clauses using binary encoding
- for (size_t i = 0; i < vec.size(); i++)
- for (int k = 0; k < num_bits; k++) {
- std::vector<int> clause;
- clause.push_back(NOT(vec[i]));
- clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k]));
- formula.push_back(expression(OpOr, clause));
- }
+ if (vec.size() < 8)
+ {
+ // fall-back to simple O(n^2) solution for small cases
+ for (size_t i = 0; i < vec.size(); i++)
+ for (size_t j = i+1; j < vec.size(); j++) {
+ std::vector<int> clause;
+ clause.push_back(NOT(vec[i]));
+ clause.push_back(NOT(vec[j]));
+ formula.push_back(expression(OpOr, clause));
+ }
+ }
+ else
+ {
+ // create binary vector
+ int num_bits = clog2(vec.size());
+ std::vector<int> bits;
+ for (int k = 0; k < num_bits; k++)
+ bits.push_back(literal());
+
+ // add at-most-one clauses using binary encoding
+ for (size_t i = 0; i < vec.size(); i++)
+ for (int k = 0; k < num_bits; k++) {
+ std::vector<int> clause;
+ clause.push_back(NOT(vec[i]));
+ clause.push_back((i & (1 << k)) != 0 ? bits[k] : NOT(bits[k]));
+ formula.push_back(expression(OpOr, clause));
+ }
+ }
return expression(OpAnd, formula);
}
+#if 0
int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot)
{
// many-hot encoding using a simple sorting network
@@ -1426,6 +1441,123 @@ int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot)
return expression(OpAnd, formula);
}
+#else
+static std::vector<int> lfsr_sym(ezSAT *that, const std::vector<int> &vec, int poly)
+{
+ std::vector<int> out;
+
+ for (int i = 0; i < int(vec.size()); i++)
+ if ((poly & (1 << (i+1))) != 0) {
+ if (out.empty())
+ out.push_back(vec.at(i));
+ else
+ out.at(0) = that->XOR(out.at(0), vec.at(i));
+ }
+
+ for (int i = 0; i+1 < int(vec.size()); i++)
+ out.push_back(vec.at(i));
+
+ return out;
+}
+
+static int lfsr_num(int vec, int poly, int cnt = 1)
+{
+ int mask = poly >> 1;
+ mask |= mask >> 1;
+ mask |= mask >> 2;
+ mask |= mask >> 4;
+ mask |= mask >> 8;
+ mask |= mask >> 16;
+
+ while (cnt-- > 0) {
+ int bits = vec & (poly >> 1);
+ bits = ((bits & 0xAAAAAAAA) >> 1) ^ (bits & 0x55555555);
+ bits = ((bits & 0x44444444) >> 2) ^ (bits & 0x11111111);
+ bits = ((bits & 0x10101010) >> 4) ^ (bits & 0x01010101);
+ bits = ((bits & 0x01000100) >> 8) ^ (bits & 0x00010001);
+ bits = ((bits & 0x00010000) >> 16) ^ (bits & 0x00000001);
+ vec = ((vec << 1) | bits) & mask;
+ }
+
+ return vec;
+}
+
+int ezSAT::manyhot(const std::vector<int> &vec, int min_hot, int max_hot)
+{
+ // many-hot encoding using LFSR as counter
+
+ int poly = 0;
+ int nbits = 0;
+
+ if (vec.size() < 3) {
+ poly = (1 << 2) | (1 << 1) | 1;
+ nbits = 2;
+ } else
+ if (vec.size() < 7) {
+ poly = (1 << 3) | (1 << 2) | 1;
+ nbits = 3;
+ } else
+ if (vec.size() < 15) {
+ poly = (1 << 4) | (1 << 3) | 1;
+ nbits = 4;
+ } else
+ if (vec.size() < 31) {
+ poly = (1 << 5) | (1 << 3) | 1;
+ nbits = 5;
+ } else
+ if (vec.size() < 63) {
+ poly = (1 << 6) | (1 << 5) | 1;
+ nbits = 6;
+ } else
+ if (vec.size() < 127) {
+ poly = (1 << 7) | (1 << 6) | 1;
+ nbits = 7;
+ } else
+ // if (vec.size() < 255) {
+ // poly = (1 << 8) | (1 << 6) | (1 << 5) | (1 << 4) | 1;
+ // nbits = 8;
+ // } else
+ if (vec.size() < 511) {
+ poly = (1 << 9) | (1 << 5) | 1;
+ nbits = 9;
+ } else {
+ assert(0);
+ }
+
+ std::vector<int> min_val;
+ std::vector<int> max_val;
+
+ if (min_hot > 1)
+ min_val = vec_const_unsigned(lfsr_num(1, poly, min_hot), nbits);
+
+ if (max_hot >= 0)
+ max_val = vec_const_unsigned(lfsr_num(1, poly, max_hot+1), nbits);
+
+ std::vector<int> state = vec_const_unsigned(1, nbits);
+
+ std::vector<int> match_min;
+ std::vector<int> match_max;
+
+ if (min_hot == 1)
+ match_min = vec;
+
+ for (int i = 0; i < int(vec.size()); i++)
+ {
+ state = vec_ite(vec[i], lfsr_sym(this, state, poly), state);
+
+ if (!min_val.empty() && i+1 >= min_hot)
+ match_min.push_back(vec_eq(min_val, state));
+
+ if (!max_val.empty() && i >= max_hot)
+ match_max.push_back(vec_eq(max_val, state));
+ }
+
+ int min_matched = min_hot ? vec_reduce_or(match_min) : CONST_TRUE;
+ int max_matched = vec_reduce_or(match_max);
+
+ return AND(min_matched, NOT(max_matched));
+}
+#endif
int ezSAT::ordered(const std::vector<int> &vec1, const std::vector<int> &vec2, bool allow_equal)
{
diff --git a/manual/command-reference-manual.tex b/manual/command-reference-manual.tex
index 4925defe3..988f034b4 100644
--- a/manual/command-reference-manual.tex
+++ b/manual/command-reference-manual.tex
@@ -116,20 +116,26 @@ library to a target architecture.
-g type1,type2,...
Map to the specified list of gate types. Supported gates types are:
- AND, NAND, OR, NOR, XOR, XNOR, ANDNOT, ORNOT, MUX, AOI3, OAI3, AOI4, OAI4.
+ AND, NAND, OR, NOR, XOR, XNOR, ANDNOT, ORNOT, MUX,
+ NMUX, AOI3, OAI3, AOI4, OAI4.
(The NOT gate is always added to this list automatically.)
The following aliases can be used to reference common sets of gate types:
simple: AND OR XOR MUX
- cmos2: NAND NOR
- cmos3: NAND NOR AOI3 OAI3
- cmos4: NAND NOR AOI3 OAI3 AOI4 OAI4
- gates: AND NAND OR NOR XOR XNOR ANDNOT ORNOT
- aig: AND NAND OR NOR ANDNOT ORNOT
+ cmos2: NAND NOR
+ cmos3: NAND NOR AOI3 OAI3
+ cmos4: NAND NOR AOI3 OAI3 AOI4 OAI4
+ cmos: NAND NOR AOI3 OAI3 AOI4 OAI4 NMUX MUX XOR XNOR
+ gates: AND NAND OR NOR XOR XNOR ANDNOT ORNOT
+ aig: AND NAND OR NOR ANDNOT ORNOT
+
+ The alias 'all' represent the full set of all gate types.
Prefix a gate type with a '-' to remove it from the list. For example
the arguments 'AND,OR,XOR' and 'simple,-MUX' are equivalent.
+ The default is 'all,-NMUX,-AOI3,-OAI3,-AOI4,-OAI4'.
+
-dff
also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many
clock domains are automatically partitioned in clock domains and each
@@ -156,6 +162,11 @@ library to a target architecture.
this attribute is a unique integer for each ABC process started. This
is useful for debugging the partitioning of clock domains.
+ -dress
+ run the 'dress' command after all other ABC commands. This aims to
+ preserve naming by an equivalence check between the original and post-ABC
+ netlists (experimental).
+
When neither -liberty nor -lut is used, the Yosys standard cell library is
loaded into ABC before the ABC script is executed.
@@ -163,12 +174,251 @@ Note that this is a logic optimization pass within Yosys that is calling ABC
internally. This is not going to "run ABC on your design". It will instead run
ABC on logic snippets extracted from your design. You will not get any useful
output when passing an ABC script that writes a file. Instead write your full
-design as BLIF file with write_blif and the load that into ABC externally if
+design as BLIF file with write_blif and then load that into ABC externally if
+you want to use ABC to convert your design into another format.
+
+[1] http://www.eecs.berkeley.edu/~alanmi/abc/
+\end{lstlisting}
+
+\section{abc9 -- use ABC9 for technology mapping}
+\label{cmd:abc9}
+\begin{lstlisting}[numbers=left,frame=single]
+ abc9 [options] [selection]
+
+This script pass performs a sequence of commands to facilitate the use of the ABC
+tool [1] for technology mapping of the current design to a target FPGA
+architecture. Only fully-selected modules are supported.
+
+ -run <from_label>:<to_label>
+ only run the commands between the labels (see below). an empty
+ from label is synonymous to 'begin', and empty to label is
+ synonymous to the end of the command list.
+
+ -exe <command>
+ use the specified command instead of "<yosys-bindir>/yosys-abc" to execute ABC.
+ This can e.g. be used to call a specific version of ABC or a wrapper.
+
+ -script <file>
+ use the specified ABC script file instead of the default script.
+
+ if <file> starts with a plus sign (+), then the rest of the filename
+ string is interpreted as the command string to be passed to ABC. The
+ leading plus sign is removed and all commas (,) in the string are
+ replaced with blanks before the string is passed to ABC.
+
+ if no -script parameter is given, the following scripts are used:
+ &scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs
+
+ -fast
+ use different default scripts that are slightly faster (at the cost
+ of output quality):
+ &if {C} {W} {D} {R} -v
+
+ -D <picoseconds>
+ set delay target. the string {D} in the default scripts above is
+ replaced by this option when used, and an empty string otherwise
+ (indicating best possible delay).
+
+ -lut <width>
+ generate netlist using luts of (max) the specified width.
+
+ -lut <w1>:<w2>
+ generate netlist using luts of (max) the specified width <w2>. All
+ luts with width <= <w1> have constant cost. for luts larger than <w1>
+ the area cost doubles with each additional input bit. the delay cost
+ is still constant for all lut widths.
+
+ -lut <file>
+ pass this file with lut library to ABC.
+
+ -luts <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..
+ generate netlist using luts. Use the specified costs for luts with 1,
+ 2, 3, .. inputs.
+
+ -maxlut <width>
+ when auto-generating the lut library, discard all luts equal to or
+ greater than this size (applicable when neither -lut nor -luts is
+ specified).
+
+ -dff
+ also pass $_ABC9_FF_ cells through to ABC. modules with many clock
+ domains are marked as such and automatically partitioned by ABC.
+
+ -nocleanup
+ when this option is used, the temporary files created by this pass
+ are not removed. this is useful for debugging.
+
+ -showtmp
+ print the temp dir name in log. usually this is suppressed so that the
+ command output is identical across runs.
+
+ -box <file>
+ pass this file with box library to ABC.
+
+Note that this is a logic optimization pass within Yosys that is calling ABC
+internally. This is not going to "run ABC on your design". It will instead run
+ABC on logic snippets extracted from your design. You will not get any useful
+output when passing an ABC script that writes a file. Instead write your full
+design as an XAIGER file with `write_xaiger' and then load that into ABC
+externally if you want to use ABC to convert your design into another format.
+
+[1] http://www.eecs.berkeley.edu/~alanmi/abc/
+
+
+ pre:
+ abc9_ops -check
+ scc -set_attr abc9_scc_id {}
+ abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff] (option for -dff)
+ abc9_ops -prep_lut <maxlut> (skip if -lut or -luts)
+ abc9_ops -prep_box [-dff] (skip if -box)
+ select -set abc9_holes A:abc9_holes
+ flatten -wb @abc9_holes
+ techmap @abc9_holes
+ abc9_ops -prep_dff (only if -dff)
+ opt -purge @abc9_holes
+ aigmap
+ wbflip @abc9_holes
+
+ map:
+ foreach module in selection
+ abc9_ops -write_lut <abc-temp-dir>/input.lut (skip if '-lut' or '-luts')
+ abc9_ops -write_box <abc-temp-dir>/input.box
+ write_xaiger -map <abc-temp-dir>/input.sym <abc-temp-dir>/input.xaig
+ abc9_exe [options] -cwd <abc-temp-dir> [-lut <abc-temp-dir>/input.lut] -box <abc-temp-dir>/input.box
+ read_aiger -xaiger -wideports -module_name <module-name>$abc9 -map <abc-temp-dir>/input.sym <abc-temp-dir>/output.aig
+ abc9_ops -reintegrate
+\end{lstlisting}
+
+\section{abc9\_exe -- use ABC9 for technology mapping}
+\label{cmd:abc9_exe}
+\begin{lstlisting}[numbers=left,frame=single]
+ abc9_exe [options]
+
+
+This pass uses the ABC tool [1] for technology mapping of the top module
+(according to the (* top *) attribute or if only one module is currently selected)
+to a target FPGA architecture.
+
+ -exe <command>
+ use the specified command instead of "<yosys-bindir>/yosys-abc" to execute ABC.
+ This can e.g. be used to call a specific version of ABC or a wrapper.
+
+ -script <file>
+ use the specified ABC script file instead of the default script.
+
+ if <file> starts with a plus sign (+), then the rest of the filename
+ string is interpreted as the command string to be passed to ABC. The
+ leading plus sign is removed and all commas (,) in the string are
+ replaced with blanks before the string is passed to ABC.
+
+ if no -script parameter is given, the following scripts are used:
+ &scorr; &sweep; &dc2; &dch -f; &ps; &if {C} {W} {D} {R} -v; &mfs
+
+ -fast
+ use different default scripts that are slightly faster (at the cost
+ of output quality):
+ &if {C} {W} {D} {R} -v
+
+ -D <picoseconds>
+ set delay target. the string {D} in the default scripts above is
+ replaced by this option when used, and an empty string otherwise
+ (indicating best possible delay).
+
+ -lut <width>
+ generate netlist using luts of (max) the specified width.
+
+ -lut <w1>:<w2>
+ generate netlist using luts of (max) the specified width <w2>. All
+ luts with width <= <w1> have constant cost. for luts larger than <w1>
+ the area cost doubles with each additional input bit. the delay cost
+ is still constant for all lut widths.
+
+ -lut <file>
+ pass this file with lut library to ABC.
+
+ -luts <cost1>,<cost2>,<cost3>,<sizeN>:<cost4-N>,..
+ generate netlist using luts. Use the specified costs for luts with 1,
+ 2, 3, .. inputs.
+
+ -showtmp
+ print the temp dir name in log. usually this is suppressed so that the
+ command output is identical across runs.
+
+ -box <file>
+ pass this file with box library to ABC.
+
+ -cwd <dir>
+ use this as the current working directory, inside which the 'input.xaig'
+ file is expected. temporary files will be created in this directory, and
+ the mapped result will be written to 'output.aig'.
+
+Note that this is a logic optimization pass within Yosys that is calling ABC
+internally. This is not going to "run ABC on your design". It will instead run
+ABC on logic snippets extracted from your design. You will not get any useful
+output when passing an ABC script that writes a file. Instead write your full
+design as BLIF file with write_blif and then load that into ABC externally if
you want to use ABC to convert your design into another format.
[1] http://www.eecs.berkeley.edu/~alanmi/abc/
\end{lstlisting}
+\section{abc9\_ops -- helper functions for ABC9}
+\label{cmd:abc9_ops}
+\begin{lstlisting}[numbers=left,frame=single]
+ abc9_ops [options] [selection]
+
+This pass contains a set of supporting operations for use during ABC technology
+mapping, and is expected to be called in conjunction with other operations from
+the `abc9' script pass. Only fully-selected modules are supported.
+
+ -check
+ check that the design is valid, e.g. (* abc9_box_id *) values are unique,
+ (* abc9_carry *) is only given for one input/output port, etc.
+
+ -prep_delays
+ insert `$__ABC9_DELAY' blackbox cells into the design to account for
+ certain required times.
+
+ -mark_scc
+ for an arbitrarily chosen cell in each unique SCC of each selected module
+ (tagged with an (* abc9_scc_id = <int> *) attribute), temporarily mark all
+ wires driven by this cell's outputs with a (* keep *) attribute in order
+ to break the SCC. this temporary attribute will be removed on -reintegrate.
+
+ -prep_xaiger
+ prepare the design for XAIGER output. this includes computing the
+ topological ordering of ABC9 boxes, as well as preparing the
+ '<module-name>$holes' module that contains the logic behaviour of ABC9
+ whiteboxes.
+
+ -dff
+ consider flop cells (those instantiating modules marked with (* abc9_flop *))
+ during -prep_{delays,xaiger,box}.
+
+ -prep_dff
+ compute the clock domain and initial value of each flop in the design.
+ process the '$holes' module to support clock-enable functionality.
+
+ -prep_lut <maxlut>
+ pre-compute the lut library by analysing all modules marked with
+ (* abc9_lut=<area> *).
+
+ -write_lut <dst>
+ write the pre-computed lut library to <dst>.
+
+ -prep_box
+ pre-compute the box library by analysing all modules marked with
+ (* abc9_box *).
+
+ -write_box <dst>
+ write the pre-computed box library to <dst>.
+
+ -reintegrate
+ for each selected module, re-intergrate the module '<module-name>$abc9'
+ by first recovering ABC9 boxes, and then stitching in the remaining primary
+ inputs and outputs.
+\end{lstlisting}
+
\section{add -- add objects to the design}
\label{cmd:add}
\begin{lstlisting}[numbers=left,frame=single]
@@ -189,6 +439,17 @@ than the object to be created.
Like 'add -input', but also connect the signal between instances of the
selected modules.
+
+
+ add {-assert|-assume|-live|-fair|-cover} <name1> [-if <name2>]
+
+Add an $assert, $assume, etc. cell connected to a wire named name1, with its
+enable signal optionally connected to a wire named name2 (default: 1'b1).
+
+
+ add -mod <name[s]>
+
+Add module[s] with the specified name[s].
\end{lstlisting}
\section{aigmap -- map logic to and-inverter-graph circuit}
@@ -201,6 +462,10 @@ $_NOT_ cells.
-nand
Enable creation of $_NAND_ cells
+
+ -select
+ Overwrite replaced cells in the current selection with new $_AND_,
+ $_NOT_, and $_NAND_, cells
\end{lstlisting}
\section{alumacc -- extract ALU and MACC cells}
@@ -212,7 +477,23 @@ This pass translates arithmetic operations like $add, $mul, $lt, etc. to $alu
and $macc cells.
\end{lstlisting}
-\section{assertpmux -- convert internal signals to module ports}
+\section{anlogic\_eqn -- Anlogic: Calculate equations for luts}
+\label{cmd:anlogic_eqn}
+\begin{lstlisting}[numbers=left,frame=single]
+ anlogic_eqn [selection]
+
+Calculate equations for luts since bitstream generator depends on it.
+\end{lstlisting}
+
+\section{anlogic\_fixcarry -- Anlogic: fix carry chain}
+\label{cmd:anlogic_fixcarry}
+\begin{lstlisting}[numbers=left,frame=single]
+ anlogic_fixcarry [options] [selection]
+
+Add Anlogic adders to fix carry chain if needed.
+\end{lstlisting}
+
+\section{assertpmux -- adds asserts for parallel muxes}
\label{cmd:assertpmux}
\begin{lstlisting}[numbers=left,frame=single]
assertpmux [options] [selection]
@@ -225,8 +506,8 @@ This command adds asserts to the design that assert that all parallel muxes
-always
usually the $pmux condition is only checked when the $pmux output
- is used be the mux tree it drives. this option will deactivate this
- additional constrained and check the $pmux condition always.
+ is used by the mux tree it drives. this option will deactivate this
+ additional constraint and check the $pmux condition always.
\end{lstlisting}
\section{async2sync -- convert async FF inputs to sync circuits}
@@ -242,7 +523,7 @@ a reset deasserts with the clock edge, then the FF output will still drive the
reset value in the next cycle regardless of the data-in value at the time of
the clock edge.
-Currently only $adff cells are supported by this pass.
+Currently only $adff, $dffsr, and $dlatch cells are supported by this pass.
\end{lstlisting}
\section{attrmap -- renaming attributes}
@@ -250,7 +531,7 @@ Currently only $adff cells are supported by this pass.
\begin{lstlisting}[numbers=left,frame=single]
attrmap [options] [selection]
-This command renames attributes and/or mapps key/value pairs to
+This command renames attributes and/or maps key/value pairs to
other key/value pairs.
-tocase <name>
@@ -307,7 +588,16 @@ Move or copy attributes on wires to the cells driving them.
multiple times.
\end{lstlisting}
-\section{blackbox -- change type of cells in the design}
+\section{autoname -- automatically assign names to objects}
+\label{cmd:autoname}
+\begin{lstlisting}[numbers=left,frame=single]
+ autoname [selection]
+
+Assign auto-generated public names to objects with private names (the ones
+with $-prefix).
+\end{lstlisting}
+
+\section{blackbox -- convert modules into blackbox modules}
\label{cmd:blackbox}
\begin{lstlisting}[numbers=left,frame=single]
blackbox [options] [selection]
@@ -316,6 +606,58 @@ Convert modules into blackbox modules (remove contents and set the blackbox
module attribute).
\end{lstlisting}
+\section{bugpoint -- minimize testcases}
+\label{cmd:bugpoint}
+\begin{lstlisting}[numbers=left,frame=single]
+ bugpoint [options]
+
+This command minimizes testcases that crash Yosys. It removes an arbitrary part
+of the design and recursively invokes Yosys with a given script, repeating these
+steps while it can find a smaller design that still causes a crash. Once this
+command finishes, it replaces the current design with the smallest testcase it
+was able to produce.
+
+It is possible to specify the kinds of design part that will be removed. If none
+are specified, all parts of design will be removed.
+
+ -yosys <filename>
+ use this Yosys binary. if not specified, `yosys` is used.
+
+ -script <filename>
+ use this script to crash Yosys. required.
+
+ -grep <string>
+ only consider crashes that place this string in the log file.
+
+ -fast
+ run `proc_clean; clean -purge` after each minimization step. converges
+ faster, but produces larger testcases, and may fail to produce any
+ testcase at all if the crash is related to dangling wires.
+
+ -clean
+ run `proc_clean; clean -purge` before checking testcase and after
+ finishing. produces smaller and more useful testcases, but may fail to
+ produce any testcase at all if the crash is related to dangling wires.
+
+ -modules
+ try to remove modules.
+
+ -ports
+ try to remove module ports.
+
+ -cells
+ try to remove cells.
+
+ -connections
+ try to reconnect ports to 'x.
+
+ -assigns
+ try to remove process assigns from cases.
+
+ -updates
+ try to remove process updates from syncs.
+\end{lstlisting}
+
\section{cd -- a shortcut for 'select -module <name>'}
\label{cmd:cd}
\begin{lstlisting}[numbers=left,frame=single]
@@ -354,14 +696,24 @@ This pass identifies the following problems in the current design:
- used wires that do not have a driver
-When called with -noinit then this command also checks for wires which have
-the 'init' attribute set.
+Options:
+
+ -noinit
+ Also check for wires which have the 'init' attribute set.
-When called with -initdrv then this command also checks for wires which have
-the 'init' attribute set and aren't driven by a FF cell type.
+ -initdrv
+ Also check for wires that have the 'init' attribute set and are not
+ driven by an FF cell type.
-When called with -assert then the command will produce an error if any
-problems are found in the current design.
+ -mapped
+ Also check for internal cells that have not been mapped to cells of the
+ target architecture.
+
+ -allow-tbuf
+ Modify the -mapped behavior to still allow $_TBUF_ cells.
+
+ -assert
+ Produce a runtime error if any problems are found in the current design.
\end{lstlisting}
\section{chformal -- change formal constraints of the design}
@@ -370,7 +722,7 @@ problems are found in the current design.
chformal [types] [mode] [options] [selection]
Make changes to the formal constraints of the design. The [types] options
-the type of constraint to operate on. If none of the folling options is given,
+the type of constraint to operate on. If none of the following options are given,
the command will operate on all constraint types:
-assert $assert cells, representing assert(...) constraints
@@ -397,7 +749,7 @@ Exactly one of the following modes must be specified:
-assume2assert
-live2fair
-fair2live
- change the roles of cells as indicated. this options can be combined
+ change the roles of cells as indicated. these options can be combined
\end{lstlisting}
\section{chparam -- re-evaluate modules with new parameters}
@@ -452,6 +804,32 @@ implicit global clock. This is useful for formal verification of designs with
multiple clocks.
\end{lstlisting}
+\section{clkbufmap -- insert global buffers on clock networks}
+\label{cmd:clkbufmap}
+\begin{lstlisting}[numbers=left,frame=single]
+ clkbufmap [options] [selection]
+
+Inserts global buffers between nets connected to clock inputs and their drivers.
+
+In the absence of any selection, all wires without the 'clkbuf_inhibit'
+attribute will be considered for global buffer insertion.
+Alternatively, to consider all wires without the 'buffer_type' attribute set to
+'none' or 'bufr' one would specify:
+ 'w:* a:buffer_type=none a:buffer_type=bufr %u %d'
+as the selection.
+
+ -buf <celltype> <portname_out>:<portname_in>
+ Specifies the cell type to use for the global buffers
+ and its port names. The first port will be connected to
+ the clock network sinks, and the second will be connected
+ to the actual clock source. This option is required.
+
+ -inpad <celltype> <portname_out>:<portname_in>
+ If specified, a PAD cell of the given type is inserted on
+ clock nets that are also top module's inputs (in addition
+ to the global buffer).
+\end{lstlisting}
+
\section{connect -- create or remove connections}
\label{cmd:connect}
\begin{lstlisting}[numbers=left,frame=single]
@@ -483,6 +861,50 @@ be selected or an active module must be set using the 'cd' command.
This command does not operate on module with processes.
\end{lstlisting}
+\section{connect\_rpc -- connect to RPC frontend}
+\label{cmd:connect_rpc}
+\begin{lstlisting}[numbers=left,frame=single]
+ connect_rpc -exec <command> [args...]
+ connect_rpc -path <path>
+
+Load modules using an out-of-process frontend.
+
+ -exec <command> [args...]
+ run <command> with arguments [args...]. send requests on stdin, read
+ responses from stdout.
+
+ -path <path>
+ connect to Unix domain socket at <path>. (Unix)
+ connect to bidirectional byte-type named pipe at <path>. (Windows)
+
+A simple JSON-based, newline-delimited protocol is used for communicating with
+the frontend. Yosys requests data from the frontend by sending exactly 1 line
+of JSON. Frontend responds with data or error message by replying with exactly
+1 line of JSON as well.
+
+ -> {"method": "modules"}
+ <- {"modules": ["<module-name>", ...]}
+ <- {"error": "<error-message>"}
+ request for the list of modules that can be derived by this frontend.
+ the 'hierarchy' command will call back into this frontend if a cell
+ with type <module-name> is instantiated in the design.
+
+ -> {"method": "derive", "module": "<module-name">, "parameters": {
+ "<param-name>": {"type": "[unsigned|signed|string|real]",
+ "value": "<param-value>"}, ...}}
+ <- {"frontend": "[ilang|verilog|...]","source": "<source>"}}
+ <- {"error": "<error-message>"}
+ request for the module <module-name> to be derived for a specific set of
+ parameters. <param-name> starts with \ for named parameters, and with $
+ for unnamed parameters, which are numbered starting at 1.<param-value>
+ for integer parameters is always specified as a binary string of unlimited
+ precision. the <source> returned by the frontend is hygienically parsed
+ by a built-in Yosys <frontend>, allowing the RPC frontend to return any
+ convenient representation of the module. the derived module is cached,
+ so the response should be the same whenever the same set of parameters
+ is provided.
+\end{lstlisting}
+
\section{connwrappers -- match width of input-output port pairs}
\label{cmd:connwrappers}
\begin{lstlisting}[numbers=left,frame=single]
@@ -504,6 +926,14 @@ the driving cell.
The options -signed, -unsigned, and -port can be specified multiple times.
\end{lstlisting}
+\section{coolrunner2\_fixup -- insert necessary buffer cells for CoolRunner-II architecture}
+\label{cmd:coolrunner2_fixup}
+\begin{lstlisting}[numbers=left,frame=single]
+ coolrunner2_fixup [options] [selection]
+
+Insert necessary buffer cells for CoolRunner-II architecture.
+\end{lstlisting}
+
\section{coolrunner2\_sop -- break \$sop cells into ANDTERM/ORTERM cells}
\label{cmd:coolrunner2_sop}
\begin{lstlisting}[numbers=left,frame=single]
@@ -568,6 +998,26 @@ Hint: Use the following AWK command to consolidate Yosys coverage files:
Coverage counters are only available in Yosys for Linux.
\end{lstlisting}
+\section{cutpoint -- adds formal cut points to the design}
+\label{cmd:cutpoint}
+\begin{lstlisting}[numbers=left,frame=single]
+ cutpoint [options] [selection]
+
+This command adds formal cut points to the design.
+
+ -undef
+ set cupoint nets to undef (x). the default behavior is to create a
+ $anyseq cell and drive the cutpoint net from that
+\end{lstlisting}
+
+\section{debug -- run command with debug log messages enabled}
+\label{cmd:debug}
+\begin{lstlisting}[numbers=left,frame=single]
+ debug cmd
+
+Execute the specified command with debug log messages enabled
+\end{lstlisting}
+
\section{delete -- delete objects in the design}
\label{cmd:delete}
\begin{lstlisting}[numbers=left,frame=single]
@@ -614,6 +1064,11 @@ Save the current design under the given name and then clear the current design.
Push the current design to the stack and then clear the current design.
+ design -push-copy
+
+Push the current design to the stack without clearing the current design.
+
+
design -pop
Reset the current design and pop the last design from the stack.
@@ -649,6 +1104,14 @@ The Verilog front-end remembers defined macros and top-level declarations
between calls to 'read_verilog'. This command resets this memory.
\end{lstlisting}
+\section{determine\_init -- Determine the init value of cells}
+\label{cmd:determine_init}
+\begin{lstlisting}[numbers=left,frame=single]
+ determine_init [selection]
+
+Determine the init value of cells that doesn't allow unknown init value.
+\end{lstlisting}
+
\section{dff2dffe -- transform \$dff cells to \$dffe cells}
\label{cmd:dff2dffe}
\begin{lstlisting}[numbers=left,frame=single]
@@ -660,7 +1123,11 @@ $_DFF_P_, $_DFF_N_ and $_MUX_.
-unmap
operate in the opposite direction: replace $dffe cells with combinations
- of $dff and $mux cells. the options below are ignore in unmap mode.
+ of $dff and $mux cells. the options below are ignored in unmap mode.
+
+ -unmap-mince N
+ Same as -unmap but only unmap $dffe where the clock enable port
+ signal is used by less $dffe than the specified number
-direct <internal_gate_type> <external_gate_type>
map directly to external gate type. <internal_gate_type> can
@@ -686,6 +1153,10 @@ $_DFF_P_, $_DFF_N_ and $_MUX_.
Merge synchronous set/reset $_MUX_ cells to create $__DFFS_[NP][NP][01], to be run before
dff2dffe for SR over CE priority.
+
+ -match-init
+ Disallow merging synchronous set/reset that has polarity opposite of the
+ output wire's init attribute (if any).
\end{lstlisting}
\section{dffinit -- set INIT param on FF cells}
@@ -704,6 +1175,16 @@ drives. (This is primarily used in FPGA flows.)
use the string values "high" and "low" to represent a single-bit
initial value of 1 or 0. (multi-bit values are not supported in this
mode.)
+
+ -strinit <string for high> <string for low>
+ use string values in the command line to represent a single-bit
+ initial value of 1 or 0. (multi-bit values are not supported in this
+ mode.)
+
+ -noreinit
+ fail if the FF cell has already a defined initial value set in other
+ passes and the initial value of the net it drives is not equal to
+ the already defined initial value.
\end{lstlisting}
\section{dfflibmap -- technology mapping of flip-flops}
@@ -722,15 +1203,6 @@ to the internal cell types that best match the cells found in the given
liberty file.
\end{lstlisting}
-\section{dffsr2dff -- convert DFFSR cells to simpler FF cell types}
-\label{cmd:dffsr2dff}
-\begin{lstlisting}[numbers=left,frame=single]
- dffsr2dff [options] [selection]
-
-This pass converts DFFSR cells ($dffsr, $_DFFSR_???_) and ADFF cells ($adff,
-$_DFF_???_) to simpler FF cell types when any of the set/reset inputs is unused.
-\end{lstlisting}
-
\section{dump -- print parts of the design in ilang format}
\label{cmd:dump}
\begin{lstlisting}[numbers=left,frame=single]
@@ -766,6 +1238,29 @@ Print all commands to log before executing them.
Do not print all commands to log before executing them. (default)
\end{lstlisting}
+\section{ecp5\_ffinit -- ECP5: handle FF init values}
+\label{cmd:ecp5_ffinit}
+\begin{lstlisting}[numbers=left,frame=single]
+ ecp5_ffinit [options] [selection]
+
+Remove init values for FF output signals when equal to reset value.
+If reset is not used, set the reset value to the init value, otherwise
+unmap out the reset (if not an async reset).
+\end{lstlisting}
+
+\section{ecp5\_gsr -- ECP5: handle GSR}
+\label{cmd:ecp5_gsr}
+\begin{lstlisting}[numbers=left,frame=single]
+ ecp5_gsr [options] [selection]
+
+Trim active low async resets connected to GSR and resolve GSR parameter,
+if a GSR or SGSR primitive is used in the design.
+
+If any cell has the GSR parameter set to "AUTO", this will be resolved
+to "ENABLED" if a GSR primitive is present and the (* nogsr *) attribute
+is not set, otherwise it will be resolved to "DISABLED".
+\end{lstlisting}
+
\section{edgetypes -- list all types of edges in selection}
\label{cmd:edgetypes}
\begin{lstlisting}[numbers=left,frame=single]
@@ -775,6 +1270,22 @@ This command lists all unique types of 'edges' found in the selection. An 'edge'
is a 4-tuple of source and sink cell type and port name.
\end{lstlisting}
+\section{efinix\_fixcarry -- Efinix: fix carry chain}
+\label{cmd:efinix_fixcarry}
+\begin{lstlisting}[numbers=left,frame=single]
+ efinix_fixcarry [options] [selection]
+
+Add Efinix adders to fix carry chain if needed.
+\end{lstlisting}
+
+\section{efinix\_gbuf -- Efinix: insert global clock buffers}
+\label{cmd:efinix_gbuf}
+\begin{lstlisting}[numbers=left,frame=single]
+ efinix_gbuf [options] [selection]
+
+Add Efinix global clock buffers to top module as needed.
+\end{lstlisting}
+
\section{equiv\_add -- add a \$equiv cell}
\label{cmd:equiv_add}
\begin{lstlisting}[numbers=left,frame=single]
@@ -872,6 +1383,65 @@ This creates a miter module for further analysis of the selected $equiv cells.
Create compare logic that handles undefs correctly
\end{lstlisting}
+\section{equiv\_opt -- prove equivalence for optimized circuit}
+\label{cmd:equiv_opt}
+\begin{lstlisting}[numbers=left,frame=single]
+ equiv_opt [options] [command]
+
+This command uses temporal induction to check circuit equivalence before and
+after an optimization pass.
+
+ -run <from_label>:<to_label>
+ only run the commands between the labels (see below). an empty
+ from label is synonymous to the start of the command list, and empty to
+ label is synonymous to the end of the command list.
+
+ -map <filename>
+ expand the modules in this file before proving equivalence. this is
+ useful for handling architecture-specific primitives.
+
+ -blacklist <file>
+ Do not match cells or signals that match the names in the file
+ (passed to equiv_make).
+
+ -assert
+ produce an error if the circuits are not equivalent.
+
+ -multiclock
+ run clk2fflogic before equivalence checking.
+
+ -async2sync
+ run async2sync before equivalence checking.
+
+ -undef
+ enable modelling of undef states during equiv_induct.
+
+The following commands are executed by this verification command:
+
+ run_pass:
+ hierarchy -auto-top
+ design -save preopt
+ [command]
+ design -stash postopt
+
+ prepare:
+ design -copy-from preopt -as gold A:top
+ design -copy-from postopt -as gate A:top
+
+ techmap: (only with -map)
+ techmap -wb -D EQUIV -autoproc -map <filename> ...
+
+ prove:
+ clk2fflogic (only with -multiclock)
+ async2sync (only with -async2sync)
+ equiv_make -blacklist <filename> ... gold gate equiv
+ equiv_induct [-undef] equiv
+ equiv_status [-assert] equiv
+
+ restore:
+ design -load preopt
+\end{lstlisting}
+
\section{equiv\_purge -- purge equivalence checking module}
\label{cmd:equiv_purge}
\begin{lstlisting}[numbers=left,frame=single]
@@ -984,6 +1554,37 @@ inputs.
then all output ports of the current module are used.
\end{lstlisting}
+\section{exec -- execute commands in the operating system shell}
+\label{cmd:exec}
+\begin{lstlisting}[numbers=left,frame=single]
+ exec [options] -- [command]
+
+Execute a command in the operating system shell. All supplied arguments are
+concatenated and passed as a command to popen(3). Whitespace is not guaranteed
+to be preserved, even if quoted. stdin and stderr are not connected, while stdout is
+logged unless the "-q" option is specified.
+
+
+ -q
+ Suppress stdout and stderr from subprocess
+
+ -expect-return <int>
+ Generate an error if popen() does not return specified value.
+ May only be specified once; the final specified value is controlling
+ if specified multiple times.
+
+ -expect-stdout <regex>
+ Generate an error if the specified regex does not match any line
+ in subprocess's stdout. May be specified multiple times.
+
+ -not-expect-stdout <regex>
+ Generate an error if the specified regex matches any line
+ in subprocess's stdout. May be specified multiple times.
+
+
+ Example: exec -q -expect-return 0 -- echo "bananapie" | grep "nana"
+\end{lstlisting}
+
\section{expose -- convert internal signals to module ports}
\label{cmd:expose}
\begin{lstlisting}[numbers=left,frame=single]
@@ -1117,7 +1718,16 @@ counter cells. Use a target-specific 'techmap' map file to convert those cells
to the actual target cells.
-maxwidth N
- Only extract counters up to N bits wide
+ Only extract counters up to N bits wide (default 64)
+
+ -minwidth N
+ Only extract counters at least N bits wide (default 2)
+
+ -allow_arst yes|no
+ Allow counters to have async reset (default yes)
+
+ -dir up|down|both
+ Look for up-counters, down-counters, or both (default down)
-pout X,Y,...
Only allow parallel output from the counter to the listed cell types
@@ -1165,10 +1775,30 @@ parts of the design to AND/OR/XOR cells, and run extract_reduce a second time.
cell will remain, driving its original loads.
\end{lstlisting}
+\section{extractinv -- extract explicit inverter cells for invertible cell pins}
+\label{cmd:extractinv}
+\begin{lstlisting}[numbers=left,frame=single]
+ extractinv [options] [selection]
+
+Searches the design for all cells with invertible pins controlled by a cell
+parameter (eg. IS_CLK_INVERTED on many Xilinx cells) and removes the parameter.
+If the parameter was set to 1, inserts an explicit inverter cell in front of
+the pin instead. Normally used for output to ISE, which does not support the
+inversion parameters.
+
+To mark a cell port as invertible, use (* invertible_pin = "param_name" *)
+on the wire in the blackbox module. The parameter value should have
+the same width as the port, and will be effectively XORed with it.
+
+ -inv <celltype> <portname_out>:<portname_in>
+ Specifies the cell type to use for the inverters and its port names.
+ This option is required.
+\end{lstlisting}
+
\section{flatten -- flatten design}
\label{cmd:flatten}
\begin{lstlisting}[numbers=left,frame=single]
- flatten [selection]
+ flatten [options] [selection]
This pass flattens the design by replacing cells by their implementation. This
pass is very similar to the 'techmap' pass. The only difference is that this
@@ -1176,6 +1806,105 @@ pass is using the current design as mapping library.
Cells and/or modules with the 'keep_hierarchy' attribute set will not be
flattened by this command.
+
+ -wb
+ Ignore the 'whitebox' attribute on cell implementations.
+\end{lstlisting}
+
+\section{flowmap -- pack LUTs with FlowMap}
+\label{cmd:flowmap}
+\begin{lstlisting}[numbers=left,frame=single]
+ flowmap [options] [selection]
+
+This pass uses the FlowMap technology mapping algorithm to pack logic gates
+into k-LUTs with optimal depth. It allows mapping any circuit elements that can
+be evaluated with the `eval` pass, including cells with multiple output ports
+and multi-bit input and output ports.
+
+ -maxlut k
+ perform technology mapping for a k-LUT architecture. if not specified,
+ defaults to 3.
+
+ -minlut n
+ only produce n-input or larger LUTs. if not specified, defaults to 1.
+
+ -cells <cell>[,<cell>,...]
+ map specified cells. if not specified, maps $_NOT_, $_AND_, $_OR_,
+ $_XOR_ and $_MUX_, which are the outputs of the `simplemap` pass.
+
+ -relax
+ perform depth relaxation and area minimization.
+
+ -r-alpha n, -r-beta n, -r-gamma n
+ parameters of depth relaxation heuristic potential function.
+ if not specified, alpha=8, beta=2, gamma=1.
+
+ -optarea n
+ optimize for area by trading off at most n logic levels for fewer LUTs.
+ n may be zero, to optimize for area without increasing depth.
+ implies -relax.
+
+ -debug
+ dump intermediate graphs.
+
+ -debug-relax
+ explain decisions performed during depth relaxation.
+\end{lstlisting}
+
+\section{fmcombine -- combine two instances of a cell into one}
+\label{cmd:fmcombine}
+\begin{lstlisting}[numbers=left,frame=single]
+ fmcombine [options] module_name gold_cell gate_cell
+
+This pass takes two cells, which are instances of the same module, and replaces
+them with one instance of a special 'combined' module, that effectively
+contains two copies of the original module, plus some formal properties.
+
+This is useful for formal test benches that check what differences in behavior
+a slight difference in input causes in a module.
+
+ -initeq
+ Insert assumptions that initially all FFs in both circuits have the
+ same initial values.
+
+ -anyeq
+ Do not duplicate $anyseq/$anyconst cells.
+
+ -fwd
+ Insert forward hint assumptions into the combined module.
+
+ -bwd
+ Insert backward hint assumptions into the combined module.
+ (Backward hints are logically equivalend to fordward hits, but
+ some solvers are faster with bwd hints, or even both -bwd and -fwd.)
+
+ -nop
+ Don't insert hint assumptions into the combined module.
+ (This should not provide any speedup over the original design, but
+ strangely sometimes it does.)
+
+If none of -fwd, -bwd, and -nop is given, then -fwd is used as default.
+\end{lstlisting}
+
+\section{fminit -- set init values/sequences for formal}
+\label{cmd:fminit}
+\begin{lstlisting}[numbers=left,frame=single]
+ fminit [options] <selection>
+
+This pass creates init constraints (for example for reset sequences) in a formal
+model.
+
+ -seq <signal> <sequence>
+ Set sequence using comma-separated list of values, use 'z for
+ unconstrained bits. The last value is used for the remainder of the
+ trace.
+
+ -set <signal> <value>
+ Add constant value constraint
+
+ -posedge <signal>
+ -negedge <signal>
+ Set clock for init sequences
\end{lstlisting}
\section{freduce -- perform functional reduction}
@@ -1393,15 +2122,16 @@ Merge GP_INV cells with GP_DFF* and GP_DLATCH* cells.
In parametric designs, a module might exists in several variations with
different parameter values. This pass looks at all modules in the current
design an re-runs the language frontends for the parametric modules as
-needed.
+needed. It also resolves assignments to wired logic data types (wand/wor),
+resolves positional module parameters, unroll array instances, and more.
-check
also check the design hierarchy. this generates an error when
an unknown module is used as cell type.
-simcheck
- like -check, but also thow an error if blackbox modules are
- instantiated, and throw an error if the design has no top module
+ like -check, but also throw an error if blackbox modules are
+ instantiated, and throw an error if the design has no top module.
-purge_lib
by default the hierarchy command will not remove library (blackbox)
@@ -1414,20 +2144,23 @@ needed.
-keep_positionals
per default this pass also converts positional arguments in cells
- to arguments using port names. this option disables this behavior.
+ to arguments using port names. This option disables this behavior.
-keep_portwidths
per default this pass adjusts the port width on cells that are
- module instances when the width does not match the module port. this
+ module instances when the width does not match the module port. This
option disables this behavior.
+ -nodefaults
+ do not resolve input port default values
+
-nokeep_asserts
per default this pass sets the "keep" attribute on all modules
- that directly or indirectly contain one or more $assert cells. this
- option disables this behavior.
+ that directly or indirectly contain one or more formal properties.
+ This option disables this behavior.
-top <module>
- use the specified top module to built a design hierarchy. modules
+ use the specified top module to build the design hierarchy. Modules
outside this tree (unused modules) are removed.
when the -top option is used, the 'top' attribute will be set on the
@@ -1437,6 +2170,12 @@ needed.
-auto-top
automatically determine the top of the design hierarchy and mark it.
+ -chparam name value
+ elaborate the top module using this parameter value. Modules on which
+ this parameter does not exist may cause a warning message to be output.
+ This option can be specified multiple times to override multiple
+ parameters. String values must be passed in double quotes (").
+
In -generate mode this pass generates blackbox modules for the given cell
types (wildcards supported). For this the design is searched for cells that
match the given types and then the given port declarations are used to
@@ -1483,6 +2222,33 @@ all commands executed in an interactive session, but not the commands
from executed scripts.
\end{lstlisting}
+\section{ice40\_braminit -- iCE40: perform SB\_RAM40\_4K initialization from file}
+\label{cmd:ice40_braminit}
+\begin{lstlisting}[numbers=left,frame=single]
+ ice40_braminit
+
+This command processes all SB_RAM40_4K blocks with a non-empty INIT_FILE
+parameter and converts it into the required INIT_x attributes
+\end{lstlisting}
+
+\section{ice40\_dsp -- iCE40: map multipliers}
+\label{cmd:ice40_dsp}
+\begin{lstlisting}[numbers=left,frame=single]
+ ice40_dsp [options] [selection]
+
+Map multipliers ($mul/SB_MAC16) and multiply-accumulate ($mul/SB_MAC16 + $add)
+cells into iCE40 DSP resources.
+Currently, only the 16x16 multiply mode is supported and not the 2 x 8x8 mode.
+
+Pack input registers (A, B, {C,D}; with optional hold), pipeline registers
+({F,J,K,G}, H), output registers (O -- full 32-bits or lower 16-bits only; with
+optional hold), and post-adder into into the SB_MAC16 resource.
+
+Multiply-accumulate operations using the post-adder with feedback on the {C,D}
+input will be folded into the DSP. In this scenario only, resetting the
+the accumulator to an arbitrary value can be inferred to use the {C,D} input.
+\end{lstlisting}
+
\section{ice40\_ffinit -- iCE40: handle FF init values}
\label{cmd:ice40_ffinit}
\begin{lstlisting}[numbers=left,frame=single]
@@ -1514,9 +2280,24 @@ This command executes the following script:
opt_rmdff
opt_clean
while <changed design>
+\end{lstlisting}
+
+\section{ice40\_wrapcarry -- iCE40: wrap carries}
+\label{cmd:ice40_wrapcarry}
+\begin{lstlisting}[numbers=left,frame=single]
+ ice40_wrapcarry [selection]
-When called with the option -unlut, this command will transform all already
-mapped SB_LUT4 cells back to logic.
+Wrap manually instantiated SB_CARRY cells, along with their associated SB_LUT4s,
+into an internal $__ICE40_CARRY_WRAPPER cell for preservation across technology
+mapping.
+
+Attributes on both cells will have their names prefixed with 'SB_CARRY.' or
+'SB_LUT4.' and attached to the wrapping cell.
+A (* keep *) attribute on either cell will be logically OR-ed together.
+
+ -unwrap
+ unwrap $__ICE40_CARRY_WRAPPER cells back into SB_CARRYs and SB_LUT4s,
+ including restoring their attributes.
\end{lstlisting}
\section{insbuf -- insert buffer cells for connected wires}
@@ -1561,6 +2342,11 @@ the resulting cells to more sophisticated PAD cells.
of the tristate driver and the 2nd portname is the internal output
buffering the external signal.
+ -ignore <celltype> <portname>[:<portname>]*
+ Skips mapping inputs/outputs that are already connected to given
+ ports of the given cell. Can be used multiple times. This is in
+ addition to the cells specified as mapping targets.
+
-widthparam <param_name>
Use the specified parameter name to set the port width.
@@ -1588,6 +2374,10 @@ Write a JSON netlist of all selected objects.
-aig
also include AIG models for the different gate types
+ -compat-int
+ emit 32-bit or smaller fully-defined parameter values directly
+ as JSON numbers (for compatibility with old parsers)
+
See 'help write_json' for a description of the JSON format used.
\end{lstlisting}
@@ -1615,6 +2405,44 @@ logfiles.
do not append a newline
\end{lstlisting}
+\section{logger -- set logger properties}
+\label{cmd:logger}
+\begin{lstlisting}[numbers=left,frame=single]
+ logger [options]
+
+This command sets global logger properties, also available using command line
+options.
+
+ -[no]time
+ enable/disable display of timestamp in log output.
+
+ -[no]stderr
+ enable/disable logging errors to stderr.
+
+ -warn regex
+ print a warning for all log messages matching the regex.
+
+ -nowarn regex
+ if a warning message matches the regex, it is printed as regular
+ message instead.
+
+ -werror regex
+ if a warning message matches the regex, it is printed as error
+ message instead and the tool terminates with a nonzero return code.
+
+ -[no]debug
+ globally enable/disable debug log messages.
+
+ -experimental <feature>
+ do not print warnings for the specified experimental feature
+
+ -expect <type> <regex> <expected_count>
+ expect log,warning or error to appear. In case of error return code is 0.
+
+ -expect-no-warnings
+ gives error in case there is at least one warning that is not expected.
+\end{lstlisting}
+
\section{ls -- list modules or objects in modules}
\label{cmd:ls}
\begin{lstlisting}[numbers=left,frame=single]
@@ -1661,6 +2489,7 @@ is used then the $macc cell is mapped to $add, $sub, etc. cells instead.
This pass calls all the other memory_* passes in a useful order:
+ opt_mem
memory_dff [-nordff] (-memx implies -nordff)
opt_clean
memory_share
@@ -1683,8 +2512,13 @@ This pass converts the multi-port $mem memory cells into block ram instances.
The given rules file describes the available resources and how they should be
used.
-The rules file contains a set of block ram description and a sequence of match
-rules. A block ram description looks like this:
+The rules file contains configuration options, a set of block ram description
+and a sequence of match rules.
+
+The option 'attr_icase' configures how attribute values are matched. The value 0
+means case-sensitive, 1 means case-insensitive.
+
+A block ram description looks like this:
bram RAMB1024X32 # name of BRAM cell
init 1 # set to '1' if BRAM can be initialized
@@ -1745,6 +2579,13 @@ It is possible to match against the following values with min/max rules:
dcells ....... number of cells in 'data-direction'
cells ........ total number of cells (acells*dcells*dups)
+A match containing the command 'attribute' followed by a list of space
+separated 'name[=string_value]' values requires that the memory contains any
+one of the given attribute name and string values (where specified), or name
+and integer 1 value (if no string_value given, since Verilog will interpret
+'(* attr *)' as '(* attr=1 *)').
+A name prefixed with '!' indicates that the attribute must not exist.
+
The interface for the created bram instances is derived from the bram
description. Use 'techmap' to convert the created bram instances into
instances of the actual bram cells of your target architecture.
@@ -1788,10 +2629,22 @@ interface and yields a synchronous memory port.
\section{memory\_map -- translate multiport memories to basic cells}
\label{cmd:memory_map}
\begin{lstlisting}[numbers=left,frame=single]
- memory_map [selection]
+ memory_map [options] [selection]
This pass converts multiport memory cells as generated by the memory_collect
pass to word-wide DFFs and address decoders.
+
+ -attr !<name>
+ do not map memories that have attribute <name> set.
+
+ -attr <name>[=<value>]
+ for memories that have attribute <name> set, only map them if its value
+ is a string <value> (if specified), or an integer 1 (otherwise). if this
+ option is specified multiple times, map the memory if the attribute is
+ to any of the values.
+
+ -iattr
+ for -attr, ignore case of <value>.
\end{lstlisting}
\section{memory\_memx -- emulate vlog sim behavior for mem ports}
@@ -1872,7 +2725,7 @@ detected.
also create an 'assert' cell that checks if trigger is always low.
-flatten
- call 'flatten; opt_expr -keepdc -undriven;;' on the miter circuit.
+ call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.
miter -assert [options] module [miter_name]
@@ -1886,7 +2739,70 @@ module is modified.
keep module output ports.
-flatten
- call 'flatten; opt_expr -keepdc -undriven;;' on the miter circuit.
+ call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.
+\end{lstlisting}
+
+\section{mutate -- generate or apply design mutations}
+\label{cmd:mutate}
+\begin{lstlisting}[numbers=left,frame=single]
+ mutate -list N [options] [selection]
+
+Create a list of N mutations using an even sampling.
+
+ -o filename
+ Write list to this file instead of console output
+
+ -s filename
+ Write a list of all src tags found in the design to the specified file
+
+ -seed N
+ RNG seed for selecting mutations
+
+ -none
+ Include a "none" mutation in the output
+
+ -ctrl name width value
+ Add -ctrl options to the output. Use 'value' for first mutation, then
+ simply count up from there.
+
+ -mode name
+ -module name
+ -cell name
+ -port name
+ -portbit int
+ -ctrlbit int
+ -wire name
+ -wirebit int
+ -src string
+ Filter list of mutation candidates to those matching
+ the given parameters.
+
+ -cfg option int
+ Set a configuration option. Options available:
+ weight_pq_w weight_pq_b weight_pq_c weight_pq_s
+ weight_pq_mw weight_pq_mb weight_pq_mc weight_pq_ms
+ weight_cover pick_cover_prcnt
+
+
+ mutate -mode MODE [options]
+
+Apply the given mutation.
+
+ -ctrl name width value
+ Add a control signal with the given name and width. The mutation is
+ activated if the control signal equals the given value.
+
+ -module name
+ -cell name
+ -port name
+ -portbit int
+ -ctrlbit int
+ Mutation parameters, as generated by 'mutate -list N'.
+
+ -wire name
+ -wirebit int
+ -src string
+ Ignored. (They are generated by -list for documentation purposes.)
\end{lstlisting}
\section{muxcover -- cover trees of MUX cells with wider MUXes}
@@ -1896,14 +2812,43 @@ module is modified.
Cover trees of $_MUX_ cells with $_MUX{4,8,16}_ cells
- -mux4, -mux8, -mux16
- Use the specified types of MUXes. If none of those options are used,
- the effect is the same as if all of them where used.
+ -mux4[=cost], -mux8[=cost], -mux16[=cost]
+ Cover $_MUX_ trees using the specified types of MUXes (with optional
+ integer costs). If none of these options are given, the effect is the
+ same as if all of them are.
+ Default costs: $_MUX4_ = 220, $_MUX8_ = 460,
+ $_MUX16_ = 940
+
+ -mux2=cost
+ Use the specified cost for $_MUX_ cells when making covering decisions.
+ Default cost: $_MUX_ = 100
+
+ -dmux=cost
+ Use the specified cost for $_MUX_ cells used in decoders.
+ Default cost: 90
-nodecode
Do not insert decoder logic. This reduces the number of possible
substitutions, but guarantees that the resulting circuit is not
less efficient than the original circuit.
+
+ -nopartial
+ Do not consider mappings that use $_MUX<N>_ to select from less
+ than <N> different signals.
+\end{lstlisting}
+
+\section{muxpack -- \$mux/\$pmux cascades to \$pmux}
+\label{cmd:muxpack}
+\begin{lstlisting}[numbers=left,frame=single]
+ muxpack [selection]
+
+This pass converts cascaded chains of $pmux cells (e.g. those create from case
+constructs) and $mux cells (e.g. those created by if-else constructs) into
+$pmux cells.
+
+This optimisation is conservative --- it will only pack $mux or $pmux cells
+whose select lines are driven by '$eq' cells with other such cells if it can be
+certain that their select inputs are mutually exclusive.
\end{lstlisting}
\section{nlutmap -- map to LUTs of different sizes}
@@ -1925,6 +2870,17 @@ Excess logic that does not fit into the specified LUTs is mapped back
to generic logic gates ($_AND_, etc.).
\end{lstlisting}
+\section{onehot -- optimize \$eq cells for onehot signals}
+\label{cmd:onehot}
+\begin{lstlisting}[numbers=left,frame=single]
+ onehot [options] [selection]
+
+This pass optimizes $eq cells that compare one-hot signals against constants
+
+ -v, -vv
+ verbose output
+\end{lstlisting}
+
\section{opt -- perform simple optimizations}
\label{cmd:opt}
\begin{lstlisting}[numbers=left,frame=single]
@@ -1941,7 +2897,8 @@ passes in the following order:
opt_muxtree
opt_reduce [-fine] [-full]
opt_merge [-share_all]
- opt_rmdff [-keepdc]
+ opt_share (-full only)
+ opt_rmdff [-keepdc] [-sat]
opt_clean [-purge]
opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]
while <changed design>
@@ -1951,7 +2908,7 @@ When called with -fast the following script is used instead:
do
opt_expr [-mux_undef] [-mux_bool] [-undriven] [-clkinv] [-fine] [-full] [-keepdc]
opt_merge [-share_all]
- opt_rmdff [-keepdc]
+ opt_rmdff [-keepdc] [-sat]
opt_clean [-purge]
while <changed design in opt_rmdff>
@@ -1990,7 +2947,7 @@ overall gate count of the circuit
opt_expr [options] [selection]
This pass performs const folding on internal cell types with constant inputs.
-It also performs some simple expression rewritring.
+It also performs some simple expression rewriting.
-mux_undef
remove 'undef' inputs from $mux, $pmux and $_MUX_ cells
@@ -2017,6 +2974,47 @@ It also performs some simple expression rewritring.
replaced by 'a'. the -keepdc option disables all such optimizations.
\end{lstlisting}
+\section{opt\_lut -- optimize LUT cells}
+\label{cmd:opt_lut}
+\begin{lstlisting}[numbers=left,frame=single]
+ opt_lut [options] [selection]
+
+This pass combines cascaded $lut cells with unused inputs.
+
+ -dlogic <type>:<cell-port>=<LUT-input>[:<cell-port>=<LUT-input>...]
+ preserve connections to dedicated logic cell <type> that has ports
+ <cell-port> connected to LUT inputs <LUT-input>. this includes
+ the case where both LUT and dedicated logic input are connected to
+ the same constant.
+
+ -limit N
+ only perform the first N combines, then stop. useful for debugging.
+\end{lstlisting}
+
+\section{opt\_lut\_ins -- discard unused LUT inputs}
+\label{cmd:opt_lut_ins}
+\begin{lstlisting}[numbers=left,frame=single]
+ opt_lut_ins [options] [selection]
+
+This pass removes unused inputs from LUT cells (that is, inputs that can not
+influence the output signal given this LUT's value). While such LUTs cannot
+be directly emitted by ABC, they can be a result of various post-ABC
+transformations, such as mapping wide LUTs (not all sub-LUTs will use the
+full set of inputs) or optimizations such as xilinx_dffopt.
+
+ -tech <technology>
+ Instead of generic $lut cells, operate on LUT cells specific
+ to the given technology. Valid values are: xilinx, ecp5, gowin.
+\end{lstlisting}
+
+\section{opt\_mem -- optimize memories}
+\label{cmd:opt_mem}
+\begin{lstlisting}[numbers=left,frame=single]
+ opt_mem [options] [selection]
+
+This pass performs various optimizations on memories in the design.
+\end{lstlisting}
+
\section{opt\_merge -- consolidate identical cells}
\label{cmd:opt_merge}
\begin{lstlisting}[numbers=left,frame=single]
@@ -2067,10 +3065,65 @@ input with the original control signals OR'ed together.
\section{opt\_rmdff -- remove DFFs with constant inputs}
\label{cmd:opt_rmdff}
\begin{lstlisting}[numbers=left,frame=single]
- opt_rmdff [-keepdc] [selection]
+ opt_rmdff [-keepdc] [-sat] [selection]
This pass identifies flip-flops with constant inputs and replaces them with
a constant driver.
+
+ -sat
+ additionally invoke SAT solver to detect and remove flip-flops (with
+ non-constant inputs) that can also be replaced with a constant driver
+\end{lstlisting}
+
+\section{opt\_share -- merge mutually exclusive cells of the same type that share an input signal}
+\label{cmd:opt_share}
+\begin{lstlisting}[numbers=left,frame=single]
+ opt_share [selection]
+
+This pass identifies mutually exclusive cells of the same type that:
+ (a) share an input signal,
+ (b) drive the same $mux, $_MUX_, or $pmux multiplexing cell,
+
+allowing the cell to be merged and the multiplexer to be moved from
+multiplexing its output to multiplexing the non-shared input signals.
+\end{lstlisting}
+
+\section{paramap -- renaming cell parameters}
+\label{cmd:paramap}
+\begin{lstlisting}[numbers=left,frame=single]
+ paramap [options] [selection]
+
+This command renames cell parameters and/or maps key/value pairs to
+other key/value pairs.
+
+ -tocase <name>
+ Match attribute names case-insensitively and set it to the specified
+ name.
+
+ -rename <old_name> <new_name>
+ Rename attributes as specified
+
+ -map <old_name>=<old_value> <new_name>=<new_value>
+ Map key/value pairs as indicated.
+
+ -imap <old_name>=<old_value> <new_name>=<new_value>
+ Like -map, but use case-insensitive match for <old_value> when
+ it is a string value.
+
+ -remove <name>=<value>
+ Remove attributes matching this pattern.
+
+For example, mapping Diamond-style ECP5 "init" attributes to Yosys-style:
+
+ paramap -tocase INIT t:LUT4
+\end{lstlisting}
+
+\section{peepopt -- collection of peephole optimizers}
+\label{cmd:peepopt}
+\begin{lstlisting}[numbers=left,frame=single]
+ peepopt [options] [selection]
+
+This pass applies a collection of peephole optimizers to the current design.
\end{lstlisting}
\section{plugin -- load and list loaded plugins}
@@ -2090,12 +3143,51 @@ Load and list loaded plugins.
List loaded plugins
\end{lstlisting}
+\section{pmux2shiftx -- transform \$pmux cells to \$shiftx cells}
+\label{cmd:pmux2shiftx}
+\begin{lstlisting}[numbers=left,frame=single]
+ pmux2shiftx [options] [selection]
+
+This pass transforms $pmux cells to $shiftx cells.
+
+ -v, -vv
+ verbose output
+
+ -min_density <percentage>
+ specifies the minimum density for the shifter
+ default: 50
+
+ -min_choices <int>
+ specified the minimum number of choices for a control signal
+ default: 3
+
+ -onehot ignore|pmux|shiftx
+ select strategy for one-hot encoded control signals
+ default: pmux
+
+ -norange
+ disable $sub inference for "range decoders"
+\end{lstlisting}
+
\section{pmuxtree -- transform \$pmux cells to trees of \$mux cells}
\label{cmd:pmuxtree}
\begin{lstlisting}[numbers=left,frame=single]
- pmuxtree [options] [selection]
+ pmuxtree [selection]
+
+This pass transforms $pmux cells to trees of $mux cells.
+\end{lstlisting}
+
+\section{portlist -- list (top-level) ports}
+\label{cmd:portlist}
+\begin{lstlisting}[numbers=left,frame=single]
+ portlist [options] [selection]
+
+This command lists all module ports found in the selected modules.
-This pass transforms $pmux cells to a trees of $mux cells.
+If no selection is provided then it lists the ports on the top module.
+
+ -m
+ print verilog blackbox module definitions instead of port lists
\end{lstlisting}
\section{prep -- generic synthesis script}
@@ -2153,7 +3245,7 @@ The following commands are executed by this synthesis command:
opt_clean
check
opt -keepdc
- wreduce [-memx]
+ wreduce -keepdc [-memx]
memory_dff [-nordff]
memory_memx (if -memx)
opt_clean
@@ -2174,6 +3266,7 @@ This pass calls all the other proc_* passes in the most common order.
proc_clean
proc_rmdead
+ proc_prune
proc_init
proc_arst
proc_mux
@@ -2214,7 +3307,10 @@ flip-flop cells with asynchronous resets.
\section{proc\_clean -- remove empty parts of processes}
\label{cmd:proc_clean}
\begin{lstlisting}[numbers=left,frame=single]
- proc_clean [selection]
+ proc_clean [options] [selection]
+
+ -quiet
+ do not print any messages.
This pass removes empty parts of processes and ultimately removes a process
if it contains only empty structures.
@@ -2261,6 +3357,15 @@ and case statements) to trees of multiplexer cells.
'case' expressions and 'if' conditions.
\end{lstlisting}
+\section{proc\_prune -- remove redundant assignments}
+\label{cmd:proc_prune}
+\begin{lstlisting}[numbers=left,frame=single]
+ proc_prune [selection]
+
+This pass identifies assignments in processes that are always overwritten by
+a later assignment to the same signal and removes them.
+\end{lstlisting}
+
\section{proc\_rmdead -- eliminate dead trees in decision trees}
\label{cmd:proc_rmdead}
\begin{lstlisting}[numbers=left,frame=single]
@@ -2328,12 +3433,45 @@ Unset global Verilog/SystemVerilog defines.
read -incdir <directory>
Add directory to global Verilog/SystemVerilog include directories.
+
+
+ read -verific
+ read -noverific
+
+Subsequent calls to 'read' will either use or not use Verific. Calling 'read'
+with -verific will result in an error on Yosys binaries that are built without
+Verific support. The default is to use Verific if it is available.
+\end{lstlisting}
+
+\section{read\_aiger -- read AIGER file}
+\label{cmd:read_aiger}
+\begin{lstlisting}[numbers=left,frame=single]
+ read_aiger [options] [filename]
+
+Load module from an AIGER file into the current design.
+
+ -module_name <module_name>
+ name of module to be created (default: <filename>)
+
+ -clk_name <wire_name>
+ if specified, AIGER latches to be transformed into $_DFF_P_ cells
+ clocked by wire of this name. otherwise, $_FF_ cells will be used
+
+ -map <filename>
+ read file with port and latch symbols
+
+ -wideports
+ merge ports that match the pattern 'name[int]' into a single
+ multi-bit port 'name'
+
+ -xaiger
+ read XAIGER extensions
\end{lstlisting}
\section{read\_blif -- read BLIF file}
\label{cmd:read_blif}
\begin{lstlisting}[numbers=left,frame=single]
- read_blif [filename]
+ read_blif [options] [filename]
Load modules from a BLIF file into the current design.
@@ -2352,6 +3490,17 @@ Load modules from a BLIF file into the current design.
Load modules from an ilang file to the current design. (ilang is a text
representation of a design in yosys's internal format.)
+
+ -nooverwrite
+ ignore re-definitions of modules. (the default behavior is to
+ create an error message if the existing module is not a blackbox
+ module, and overwrite the existing module if it is a blackbox module.)
+
+ -overwrite
+ overwrite existing modules with the same name
+
+ -lib
+ only create empty blackbox modules
\end{lstlisting}
\section{read\_json -- read JSON file}
@@ -2411,12 +3560,24 @@ Verilog-2005 is supported.
enable support for SystemVerilog assertions and some Yosys extensions
replace the implicit -D SYNTHESIS with -D FORMAL
+ -noassert
+ ignore assert() statements
+
+ -noassume
+ ignore assume() statements
+
-norestrict
- ignore restrict() assertions
+ ignore restrict() statements
-assume-asserts
treat all assert() statements like assume() statements
+ -assert-assumes
+ treat all assume() statements like assert() statements
+
+ -debug
+ alias for -dump_ast1 -dump_ast2 -dump_vlog1 -dump_vlog2 -yydebug
+
-dump_ast1
dump abstract syntax tree (before simplification)
@@ -2426,7 +3587,10 @@ Verilog-2005 is supported.
-no_dump_ptr
do not include hex memory addresses in dump (easier to diff dumps)
- -dump_vlog
+ -dump_vlog1
+ dump ast as Verilog code (before simplification)
+
+ -dump_vlog2
dump ast as Verilog code (after simplification)
-dump_rtlil
@@ -2475,8 +3639,21 @@ Verilog-2005 is supported.
-nodpi
disable DPI-C support
+ -noblackbox
+ do not automatically add a (* blackbox *) attribute to an
+ empty module.
+
-lib
only create empty blackbox modules. This implies -DBLACKBOX.
+ modules with the (* whitebox *) attribute will be preserved.
+ (* lib_whitebox *) will be treated like (* whitebox *).
+
+ -nowb
+ delete (* whitebox *) and (* lib_whitebox *) attributes from
+ all modules.
+
+ -specify
+ parse and import specify blocks
-noopt
don't perform basic optimizations (such as const folding) in the
@@ -2485,6 +3662,9 @@ Verilog-2005 is supported.
-icells
interpret cell types starting with '$' as internal cell types
+ -pwires
+ add a wire for each module parameter
+
-nooverwrite
ignore re-definitions of modules. (the default behavior is to
create an error message if the existing module is not a black box
@@ -2537,6 +3717,25 @@ Rename the specified object. Note that selection patterns are not supported
by this command.
+
+ rename -output old_name new_name
+
+Like above, but also make the wire an output. This will fail if the object is
+not a wire.
+
+
+ rename -src [selection]
+
+Assign names auto-generated from the src attribute to all selected wires and
+cells with private names.
+
+
+ rename -wire [selection]
+
+Assign auto-generated names based on the wires they drive to all selected
+cells with private names. Ignores cells driving privatly named wires.
+
+
rename -enumerate [-pattern <pattern>] [selection]
Assign short auto-generated names to all selected wires and cells with private
@@ -2544,11 +3743,13 @@ names. The -pattern option can be used to set the pattern for the new names.
The character % in the pattern is replaced with a integer number. The default
pattern is '_%_'.
+
rename -hide [selection]
Assign private names (the ones with $-prefix) to all selected wires and cells
with public names. This ignores all selected ports.
+
rename -top new_name
Rename top module.
@@ -2778,20 +3979,61 @@ design.
that are part of a found logic loop
\end{lstlisting}
-\section{script -- execute commands from script file}
+\section{scratchpad -- get/set values in the scratchpad}
+\label{cmd:scratchpad}
+\begin{lstlisting}[numbers=left,frame=single]
+ scratchpad [options]
+
+This pass allows to read and modify values from the scratchpad of the current
+design. Options:
+
+ -get <identifier>
+ print the value saved in the scratchpad under the given identifier.
+
+ -set <identifier> <value>
+ save the given value in the scratchpad under the given identifier.
+
+ -unset <identifier>
+ remove the entry for the given identifier from the scratchpad.
+
+ -copy <identifier_from> <identifier_to>
+ copy the value of the first identifier to the second identifier.
+
+ -assert <identifier> <value>
+ assert that the entry for the given identifier is set to the given value.
+
+ -assert-set <identifier>
+ assert that the entry for the given identifier exists.
+
+ -assert-unset <identifier>
+ assert that the entry for the given identifier does not exist.
+
+The identifier may not contain whitespace. By convention, it is usually prefixed
+by the name of the pass that uses it, e.g. 'opt.did_something'. If the value
+contains whitespace, it must be enclosed in double quotes.
+\end{lstlisting}
+
+\section{script -- execute commands from file or wire}
\label{cmd:script}
\begin{lstlisting}[numbers=left,frame=single]
script <filename> [<from_label>:<to_label>]
+ script -scriptwire [selection]
-This command executes the yosys commands in the specified file.
+This command executes the yosys commands in the specified file (default
+behaviour), or commands embedded in the constant text value connected to the
+selected wires.
-The 2nd argument can be used to only execute the section of the
-file between the specified labels. An empty from label is synonymous
-for the beginning of the file and an empty to label is synonymous
-for the end of the file.
+In the default (file) case, the 2nd argument can be used to only execute the
+section of the file between the specified labels. An empty from label is
+synonymous with the beginning of the file and an empty to label is synonymous
+with the end of the file.
If only one label is specified (without ':') then only the block
marked with that label (until the next label) is executed.
+
+In "-scriptwire" mode, the commands on the selected wire(s) will be executed
+in the scope of (and thus, relative to) the wires' owning module(s). This
+'-module' mode can be exited by using the 'cd' command.
\end{lstlisting}
\section{select -- modify and view the list of selected objects}
@@ -2807,7 +4049,7 @@ of the design to operate on. This command can be used to modify and view this
list of selected objects.
Note that many commands support an optional [selection] argument that can be
-used to YS_OVERRIDE the global selection for the command. The syntax of this
+used to override the global selection for the command. The syntax of this
optional argument is identical to the syntax of the <selection> argument
described here.
@@ -2897,6 +4139,10 @@ matching module names, or one of the following:
all modules with an attribute matching the given pattern
in addition to = also <, <=, >=, and > are supported
+ N:<pattern>
+ all modules with a name matching the given pattern
+ (i.e. 'N:' is optional as it is the default matching rule)
+
An <obj_pattern> can be an object name, wildcard expression, or one of
the following:
@@ -3062,11 +4308,25 @@ This command replaces undef (x) constants with defined (0/1) constants.
replace with $anyconst drivers (for formal)
-random <seed>
- replace with random bits using the specified integer als seed
+ replace with random bits using the specified integer as seed
value for the random number generator.
-init
also create/update init values for flip-flops
+
+ -params
+ replace undef in cell parameters
+\end{lstlisting}
+
+\section{sf2\_iobs -- SF2: insert IO buffers}
+\label{cmd:sf2_iobs}
+\begin{lstlisting}[numbers=left,frame=single]
+ sf2_iobs [options] [selection]
+
+Add SF2 I/O buffers and global buffers to top module as needed.
+
+ -clkbuf
+ Insert PAD->global_net clock buffers
\end{lstlisting}
\section{share -- perform sat-based resource sharing}
@@ -3182,7 +4442,7 @@ to a graphics file (usually SVG or PostScript).
assigned to each unique value of this attribute.
-width
- annotate busses with a label indicating the width of the bus.
+ annotate buses with a label indicating the width of the bus.
-signed
mark ports (A, B) that are declared as signed (using the [AB]_SIGNED
@@ -3204,6 +4464,10 @@ to a graphics file (usually SVG or PostScript).
-notitle
do not add the module name as graph title to the dot file
+ -nobg
+ don't run viewer in the background, IE wait for the viewer tool to
+ exit before returning
+
When no <format> is specified, 'dot' is used. When no <format> and <viewer> is
specified, 'xdot' is used to display the schematic (POSIX systems only).
@@ -3404,6 +4668,10 @@ design.
-liberty <liberty_file>
use cell area information from the provided liberty file
+ -tech <technology>
+ print area estemate for the specified technology. Currently supported
+ values for <technology>: xilinx, cmos
+
-width
annotate internal cell types with their word width.
e.g. $add_8 for an 8 bit wide $add cell.
@@ -3412,7 +4680,7 @@ design.
\section{submod -- moving part of a module to a new submodule}
\label{cmd:submod}
\begin{lstlisting}[numbers=left,frame=single]
- submod [-copy] [selection]
+ submod [options] [selection]
This pass identifies all cells with the 'submod' attribute and moves them to
a newly created module. The value of the attribute is used as name for the
@@ -3424,16 +4692,29 @@ be useful for analyzing or reverse-engineering a design.
This pass only operates on completely selected modules with no processes
or memories.
+ -copy
+ by default the cells are 'moved' from the source module and the source
+ module will use an instance of the new module after this command is
+ finished. call with -copy to not modify the source module.
+
+ -name <name>
+ don't use the 'submod' attribute but instead use the selection. only
+ objects from one module might be selected. the value of the -name option
+ is used as the value of the 'submod' attribute instead.
- submod -name <name> [-copy] [selection]
+ -hidden
+ instead of creating submodule ports with public names, create ports with
+ private names so that a subsequent 'flatten; clean' call will restore the
+ original module with original public names.
+\end{lstlisting}
-As above, but don't use the 'submod' attribute but instead use the selection.
-Only objects from one module might be selected. The value of the -name option
-is used as the value of the 'submod' attribute above.
+\section{supercover -- add hi/lo cover cells for each wire bit}
+\label{cmd:supercover}
+\begin{lstlisting}[numbers=left,frame=single]
+ supercover [options] [selection]
-By default the cells are 'moved' from the source module and the source module
-will use an instance of the new module after this command is finished. Call
-with -copy to not modify the source module.
+This command adds two cover cells for each bit of each selected wire, one
+checking for a hi signal level and one checking for lo level.
\end{lstlisting}
\section{synth -- generic synthesis script}
@@ -3457,6 +4738,9 @@ on partly selected designs.
-encfile <file>
passed to 'fsm_recode' via 'fsm'
+ -lut <k>
+ perform synthesis for a k-LUT architecture.
+
-nofsm
do not run FSM optimization
@@ -3478,6 +4762,12 @@ on partly selected designs.
from label is synonymous to 'begin', and empty to label is
synonymous to the end of the command list.
+ -abc9
+ use new ABC9 flow (EXPERIMENTAL)
+
+ -flowmap
+ use FlowMap LUT techmapping instead of ABC
+
The following commands are executed by this synthesis command:
@@ -3486,16 +4776,19 @@ The following commands are executed by this synthesis command:
coarse:
proc
- flatten (if -flatten)
+ flatten (if -flatten)
opt_expr
opt_clean
check
opt
wreduce
- alumacc
- share
+ peepopt
+ opt_clean
+ techmap -map +/cmp2lut.v -map +/cmp2lcu.v (if -lut)
+ alumacc (unless -noalumacc)
+ share (unless -noshare)
opt
- fsm
+ fsm (unless -nofsm)
opt -fast
memory -nomap
opt_clean
@@ -3505,9 +4798,13 @@ The following commands are executed by this synthesis command:
memory_map
opt -full
techmap
+ techmap -map +/gate2lut.v (if -noabc and -lut)
+ clean; opt_lut (if -noabc and -lut)
+ flowmap -maxlut K (if -flowmap and -lut)
opt -fast
- abc -fast
- opt -fast
+ abc -fast (unless -noabc, unless -lut)
+ abc -fast -lut k (unless -noabc, if -lut)
+ opt -fast (unless -noabc)
check:
hierarchy -check
@@ -3538,7 +4835,7 @@ This command runs synthesis for Achronix Speedster eFPGAs. This work is still ex
do not flatten design before synthesis
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
The following commands are executed by this synthesis command:
@@ -3560,14 +4857,13 @@ The following commands are executed by this synthesis command:
opt -fast -mux_undef -undriven -fine -full
memory_map
opt -undriven -fine
- dffsr2dff
dff2dffe -direct-match $_DFF_*
opt -fine
techmap -map +/techmap.v
opt -full
clean -purge
setundef -undriven -zero
- abc -markgroups -dff (only if -retime)
+ abc -markgroups -dff -D 1 (only if -retime)
map_luts:
abc -lut 4
@@ -3587,6 +4883,99 @@ The following commands are executed by this synthesis command:
write_verilog -nodec -attr2comment -defparam -renameprefix syn_ <file-name>
\end{lstlisting}
+\section{synth\_anlogic -- synthesis for Anlogic FPGAs}
+\label{cmd:synth_anlogic}
+\begin{lstlisting}[numbers=left,frame=single]
+ synth_anlogic [options]
+
+This command runs synthesis for Anlogic FPGAs.
+
+ -top <module>
+ use the specified module as top module
+
+ -edif <file>
+ write the design to the specified EDIF file. writing of an output file
+ is omitted if this parameter is not specified.
+
+ -json <file>
+ write the design to the specified JSON file. writing of an output file
+ is omitted if this parameter is not specified.
+
+ -run <from_label>:<to_label>
+ only run the commands between the labels (see below). an empty
+ from label is synonymous to 'begin', and empty to label is
+ synonymous to the end of the command list.
+
+ -noflatten
+ do not flatten design before synthesis
+
+ -retime
+ run 'abc' with '-dff -D 1' options
+
+ -nolutram
+ do not use EG_LOGIC_DRAM16X4 cells in output netlist
+
+
+The following commands are executed by this synthesis command:
+
+ begin:
+ read_verilog -lib +/anlogic/cells_sim.v +/anlogic/eagle_bb.v
+ hierarchy -check -top <top>
+
+ flatten: (unless -noflatten)
+ proc
+ flatten
+ tribuf -logic
+ deminout
+
+ coarse:
+ synth -run coarse
+
+ map_lutram: (skip if -nolutram)
+ memory_bram -rules +/anlogic/lutrams.txt
+ techmap -map +/anlogic/lutrams_map.v
+ setundef -zero -params t:EG_LOGIC_DRAM16X4
+
+ map_ffram:
+ opt -fast -mux_undef -undriven -fine
+ memory_map
+ opt -undriven -fine
+
+ map_gates:
+ techmap -map +/techmap.v -map +/anlogic/arith_map.v
+ opt -fast
+ abc -dff -D 1 (only if -retime)
+
+ map_ffs:
+ techmap -D NO_LUT -map +/anlogic/cells_map.v
+ dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit
+ opt_expr -mux_undef
+ simplemap
+
+ map_luts:
+ abc -lut 4:6
+ clean
+
+ map_cells:
+ techmap -map +/anlogic/cells_map.v
+ clean
+
+ map_anlogic:
+ anlogic_fixcarry
+ anlogic_eqn
+
+ check:
+ hierarchy -check
+ stat
+ check -noinit
+
+ edif:
+ write_edif <file-name>
+
+ json:
+ write_json <file-name>
+\end{lstlisting}
+
\section{synth\_coolrunner2 -- synthesis for Xilinx Coolrunner-II CPLDs}
\label{cmd:synth_coolrunner2}
\begin{lstlisting}[numbers=left,frame=single]
@@ -3612,7 +5001,7 @@ place-and-route.
do not flatten design before synthesis
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
The following commands are executed by this synthesis command:
@@ -3630,9 +5019,12 @@ The following commands are executed by this synthesis command:
synth -run coarse
fine:
+ extract_counter -dir up -allow_arst no
+ techmap -map +/coolrunner2/cells_counter_map.v
+ clean
opt -fast -full
- techmap
- techmap -map +/coolrunner2/cells_latch.v
+ techmap -map +/techmap.v -map +/coolrunner2/cells_latch.v
+ opt -fast
dfflibmap -prepare -liberty +/coolrunner2/xc2_dff.lib
map_tff:
@@ -3653,9 +5045,11 @@ The following commands are executed by this synthesis command:
dffinit -ff LDCP Q INIT
dffinit -ff LDCP_N Q INIT
coolrunner2_sop
+ clean
iopadmap -bits -inpad IBUF O:I -outpad IOBUFE I:IO -inoutpad IOBUFE O:IO -toutpad IOBUFE E:I:IO -tinoutpad IOBUFE E:O:I:IO
attrmvcp -attr src -attr LOC t:IOBUFE n:*
attrmvcp -attr src -attr LOC -driven t:IBUF n:*
+ coolrunner2_fixup
splitnets
clean
@@ -3694,7 +5088,7 @@ This command runs synthesis for eASIC platform.
do not flatten design before synthesis
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
The following commands are executed by this synthesis command:
@@ -3717,7 +5111,7 @@ The following commands are executed by this synthesis command:
opt -undriven -fine
techmap
opt -fast
- abc -dff (only if -retime)
+ abc -dff -D 1 (only if -retime)
opt_clean (only if -retime)
map:
@@ -3765,7 +5159,7 @@ This command runs synthesis for ECP5 FPGAs.
do not flatten design before synthesis
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
-noccu2
do not use CCU2 cells in output netlist
@@ -3774,69 +5168,105 @@ This command runs synthesis for ECP5 FPGAs.
do not use flipflops with CE in output netlist
-nobram
- do not use BRAM cells in output netlist
+ do not use block RAM cells in output netlist
- -nodram
- do not use distributed RAM cells in output netlist
+ -nolutram
+ do not use LUT RAM cells in output netlist
- -nomux
+ -nowidelut
do not use PFU muxes to implement LUTs larger than LUT4s
+ -asyncprld
+ use async PRLD mode to implement DLATCH and DFFSR (EXPERIMENTAL)
+
-abc2
run two passes of 'abc' for slightly improved logic density
+ -abc9
+ use new ABC9 flow (EXPERIMENTAL)
+
-vpr
generate an output netlist (and BLIF file) suitable for VPR
(this feature is experimental and incomplete)
+ -nodsp
+ do not map multipliers to MULT18X18D
+
The following commands are executed by this synthesis command:
begin:
- read_verilog -lib +/ecp5/cells_sim.v
+ read_verilog -lib -specify +/ecp5/cells_sim.v +/ecp5/cells_bb.v
hierarchy -check -top <top>
- flatten: (unless -noflatten)
+ coarse:
proc
flatten
tribuf -logic
deminout
+ opt_expr
+ opt_clean
+ check
+ opt
+ wreduce
+ peepopt
+ opt_clean
+ share
+ techmap -map +/cmp2lut.v -D LUT_WIDTH=4
+ opt_expr
+ opt_clean
+ techmap -map +/mul2dsp.v -map +/ecp5/dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=$__MUL18X18 (unless -nodsp)
+ chtype -set $mul t:$__soft_mul (unless -nodsp)
+ alumacc
+ opt
+ fsm
+ opt -fast
+ memory -nomap
+ opt_clean
- coarse:
- synth -run coarse
-
- bram: (skip if -nobram)
+ map_bram: (skip if -nobram)
+ memory_bram -rules +/ecp5/brams.txt
+ techmap -map +/ecp5/brams_map.v
- dram: (skip if -nodram)
- memory_bram -rules +/ecp5/dram.txt
- techmap -map +/ecp5/drams_map.v
+ map_lutram: (skip if -nolutram)
+ memory_bram -rules +/ecp5/lutrams.txt
+ techmap -map +/ecp5/lutrams_map.v
- fine:
+ map_ffram:
opt -fast -mux_undef -undriven -fine
- memory_map
+ memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block -attr syn_ramstyle=auto -attr syn_ramstyle=registers -attr syn_romstyle=auto -attr syn_romstyle=logic
opt -undriven -fine
+
+ map_gates:
techmap -map +/techmap.v -map +/ecp5/arith_map.v
- abc -dff (only if -retime)
+ opt -fast
+ abc -dff -D 1 (only if -retime)
map_ffs:
- dffsr2dff
dff2dffs
opt_clean
dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*
- techmap -D NO_LUT -map +/ecp5/cells_map.v
- opt_expr -mux_undef
+ techmap -D NO_LUT [-D ASYNC_PRLD] -map +/ecp5/cells_map.v
+ opt_expr -undriven -mux_undef
simplemap
+ ecp5_ffinit
+ ecp5_gsr
+ attrmvcp -copy -attr syn_useioff
+ opt_clean
map_luts:
abc (only if -abc2)
- abc -lut 4:7
+ techmap -map +/ecp5/latches_map.v
+ abc -lut 4:7 -dress
clean
map_cells:
techmap -map +/ecp5/cells_map.v (with -D NO_LUT in vpr mode)
+ opt_lut_ins -tech ecp5
clean
check:
+ autoname
hierarchy -check
stat
check -noinit
@@ -3853,6 +5283,98 @@ The following commands are executed by this synthesis command:
write_json <file-name>
\end{lstlisting}
+\section{synth\_efinix -- synthesis for Efinix FPGAs}
+\label{cmd:synth_efinix}
+\begin{lstlisting}[numbers=left,frame=single]
+ synth_efinix [options]
+
+This command runs synthesis for Efinix FPGAs.
+
+ -top <module>
+ use the specified module as top module
+
+ -edif <file>
+ write the design to the specified EDIF file. writing of an output file
+ is omitted if this parameter is not specified.
+
+ -json <file>
+ write the design to the specified JSON file. writing of an output file
+ is omitted if this parameter is not specified.
+
+ -run <from_label>:<to_label>
+ only run the commands between the labels (see below). an empty
+ from label is synonymous to 'begin', and empty to label is
+ synonymous to the end of the command list.
+
+ -noflatten
+ do not flatten design before synthesis
+
+ -retime
+ run 'abc' with '-dff -D 1' options
+
+ -nobram
+ do not use EFX_RAM_5K cells in output netlist
+
+
+The following commands are executed by this synthesis command:
+
+ begin:
+ read_verilog -lib +/efinix/cells_sim.v
+ hierarchy -check -top <top>
+
+ flatten: (unless -noflatten)
+ proc
+ flatten
+ tribuf -logic
+ deminout
+
+ coarse:
+ synth -run coarse
+ memory_bram -rules +/efinix/brams.txt
+ techmap -map +/efinix/brams_map.v
+ setundef -zero -params t:EFX_RAM_5K
+
+ map_ffram:
+ opt -fast -mux_undef -undriven -fine
+ memory_map
+ opt -undriven -fine
+
+ map_gates:
+ techmap -map +/techmap.v -map +/efinix/arith_map.v
+ opt -fast
+ abc -dff -D 1 (only if -retime)
+
+ map_ffs:
+ techmap -D NO_LUT -map +/efinix/cells_map.v
+ dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit
+ opt_expr -mux_undef
+ simplemap
+
+ map_luts:
+ abc -lut 4
+ clean
+
+ map_cells:
+ techmap -map +/efinix/cells_map.v
+ clean
+
+ map_gbuf:
+ efinix_gbuf
+ efinix_fixcarry
+ clean
+
+ check:
+ hierarchy -check
+ stat
+ check -noinit
+
+ edif:
+ write_edif <file-name>
+
+ json:
+ write_json <file-name>
+\end{lstlisting}
+
\section{synth\_gowin -- synthesis for Gowin FPGAs}
\label{cmd:synth_gowin}
\begin{lstlisting}[numbers=left,frame=single]
@@ -3872,8 +5394,26 @@ This command runs synthesis for Gowin FPGAs. This work is experimental.
from label is synonymous to 'begin', and empty to label is
synonymous to the end of the command list.
+ -nodffe
+ do not use flipflops with CE in output netlist
+
+ -nobram
+ do not use BRAM cells in output netlist
+
+ -nolutram
+ do not use distributed RAM cells in output netlist
+
+ -noflatten
+ do not flatten design before synthesis
+
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
+
+ -nowidelut
+ do not use muxes to implement LUTs larger than LUT4s
+
+ -noiopads
+ do not emit IOB at top level ports
The following commands are executed by this synthesis command:
@@ -3882,7 +5422,7 @@ The following commands are executed by this synthesis command:
read_verilog -lib +/gowin/cells_sim.v
hierarchy -check -top <top>
- flatten:
+ flatten: (unless -noflatten)
proc
flatten
tribuf -logic
@@ -3891,25 +5431,45 @@ The following commands are executed by this synthesis command:
coarse:
synth -run coarse
- fine:
+ map_bram: (skip if -nobram)
+ memory_bram -rules +/gowin/brams.txt
+ techmap -map +/gowin/brams_map.v
+
+ map_lutram: (skip if -nolutram)
+ memory_bram -rules +/gowin/lutrams.txt
+ techmap -map +/gowin/lutrams_map.v
+ determine_init
+
+ map_ffram:
opt -fast -mux_undef -undriven -fine
memory_map
opt -undriven -fine
- techmap
- clean -purge
- splitnets -ports
- setundef -undriven -zero
- abc -dff (only if -retime)
+
+ map_gates:
+ techmap -map +/techmap.v -map +/gowin/arith_map.v
+ opt -fast
+ abc -dff -D 1 (only if -retime)
+ splitnets
+
+ map_ffs:
+ dff2dffs -match-init
+ opt_clean
+ dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*
+ techmap -map +/gowin/cells_map.v
+ opt_expr -mux_undef
+ simplemap
map_luts:
- abc -lut 4
+ abc -lut 4:8
clean
map_cells:
techmap -map +/gowin/cells_map.v
- hilomap -hicell VCC V -locell GND G
- iopadmap -inpad IBUF O:I -outpad OBUF I:O
- clean -purge
+ opt_lut_ins -tech gowin
+ setundef -undriven -params -zero
+ hilomap -singleton -hicell VCC V -locell GND G
+ iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O -toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO (unless -noiopads)
+ clean
check:
hierarchy -check
@@ -3917,7 +5477,7 @@ The following commands are executed by this synthesis command:
check -noinit
vout:
- write_verilog -nodec -attr2comment -defparam -renameprefix gen <file-name>
+ write_verilog -decimal -attr2comment -defparam -renameprefix gen <file-name>
\end{lstlisting}
\section{synth\_greenpak4 -- synthesis for GreenPAK4 FPGAs}
@@ -3949,7 +5509,7 @@ place-and-route.
do not flatten design before synthesis
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
The following commands are executed by this synthesis command:
@@ -3972,11 +5532,10 @@ The following commands are executed by this synthesis command:
opt -fast -mux_undef -undriven -fine
memory_map
opt -undriven -fine
- techmap
- techmap -map +/greenpak4/cells_latch.v
+ techmap -map +/techmap.v -map +/greenpak4/cells_latch.v
dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib
opt -fast
- abc -dff (only if -retime)
+ abc -dff -D 1 (only if -retime)
map_luts:
nlutmap -assert -luts 0,6,8,2 (for -part SLG46140V)
@@ -4014,6 +5573,10 @@ The following commands are executed by this synthesis command:
This command runs synthesis for iCE40 FPGAs.
+ -device < hx | lp | u >
+ relevant only for '-abc9' flow, optimise timing for the specified device.
+ default: hx
+
-top <module>
use the specified module as top module
@@ -4038,7 +5601,7 @@ This command runs synthesis for iCE40 FPGAs.
do not flatten design before synthesis
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
-nocarry
do not use SB_CARRY cells in output netlist
@@ -4046,9 +5609,19 @@ This command runs synthesis for iCE40 FPGAs.
-nodffe
do not use SB_DFFE* cells in output netlist
+ -dffe_min_ce_use <min_ce_use>
+ do not use SB_DFFE* cells if the resulting CE line would go to less
+ than min_ce_use SB_DFFE* in output netlist
+
-nobram
do not use SB_RAM40_4K* cells in output netlist
+ -dsp
+ use iCE40 UltraPlus DSP cells for large arithmetic
+
+ -noabc
+ use built-in Yosys LUT techmapping instead of abc
+
-abc2
run two passes of 'abc' for slightly improved logic density
@@ -4056,38 +5629,74 @@ This command runs synthesis for iCE40 FPGAs.
generate an output netlist (and BLIF file) suitable for VPR
(this feature is experimental and incomplete)
+ -abc9
+ use new ABC9 flow (EXPERIMENTAL)
+
+ -flowmap
+ use FlowMap LUT techmapping instead of abc (EXPERIMENTAL)
+
The following commands are executed by this synthesis command:
begin:
- read_verilog -lib +/ice40/cells_sim.v
+ read_verilog -D ICE40_HX -lib -specify +/ice40/cells_sim.v
hierarchy -check -top <top>
+ proc
flatten: (unless -noflatten)
- proc
flatten
tribuf -logic
deminout
coarse:
- synth -run coarse
+ opt_expr
+ opt_clean
+ check
+ opt
+ wreduce
+ peepopt
+ opt_clean
+ share
+ techmap -map +/cmp2lut.v -D LUT_WIDTH=4
+ opt_expr
+ opt_clean
+ memory_dff
+ wreduce t:$mul
+ techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 -D DSP_NAME=$__MUL16X16 (if -dsp)
+ select a:mul2dsp (if -dsp)
+ setattr -unset mul2dsp (if -dsp)
+ opt_expr -fine (if -dsp)
+ wreduce (if -dsp)
+ select -clear (if -dsp)
+ ice40_dsp (if -dsp)
+ chtype -set $mul t:$__soft_mul (if -dsp)
+ alumacc
+ opt
+ fsm
+ opt -fast
+ memory -nomap
+ opt_clean
- bram: (skip if -nobram)
+ map_bram: (skip if -nobram)
memory_bram -rules +/ice40/brams.txt
techmap -map +/ice40/brams_map.v
+ ice40_braminit
- fine:
+ map_ffram:
opt -fast -mux_undef -undriven -fine
- memory_map
+ memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block -attr syn_ramstyle=auto -attr syn_ramstyle=registers -attr syn_romstyle=auto -attr syn_romstyle=logic
opt -undriven -fine
+
+ map_gates:
+ ice40_wrapcarry
techmap -map +/techmap.v -map +/ice40/arith_map.v
- abc -dff (only if -retime)
+ opt -fast
+ abc -dff -D 1 (only if -retime)
ice40_opt
map_ffs:
- dffsr2dff
dff2dffe -direct-match $_DFF_*
- techmap -D NO_LUT -map +/ice40/cells_map.v
+ techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v
opt_expr -mux_undef
simplemap
ice40_ffinit
@@ -4098,14 +5707,21 @@ The following commands are executed by this synthesis command:
abc (only if -abc2)
ice40_opt (only if -abc2)
techmap -map +/ice40/latches_map.v
- abc -lut 4
+ simplemap (if -noabc or -flowmap)
+ techmap -map +/gate2lut.v -D LUT_WIDTH=4 (only if -noabc)
+ flowmap -maxlut 4 (only if -flowmap)
+ abc -dress -lut 4 (skip if -noabc)
+ ice40_wrapcarry -unwrap
+ techmap -D NO_LUT -map +/ice40/cells_map.v
clean
+ opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0
map_cells:
techmap -map +/ice40/cells_map.v (with -D NO_LUT in vpr mode)
clean
check:
+ autoname
hierarchy -check
stat
check -noinit
@@ -4129,11 +5745,11 @@ The following commands are executed by this synthesis command:
This command runs synthesis for Intel FPGAs.
- -family < max10 | a10gx | cyclone10 | cyclonev | cycloneiv | cycloneive>
+ -family <max10 | arria10gx | cyclone10lp | cyclonev | cycloneiv | cycloneive>
generate the synthesis netlist for the specified family.
- MAX10 is the default target if not family argument specified.
- For Cyclone GX devices, use cycloneiv argument; For Cyclone E, use cycloneive.
- Cyclone V and Arria 10 GX devices are experimental, use it with a10gx argument.
+ MAX10 is the default target if no family argument specified.
+ For Cyclone IV GX devices, use cycloneiv argument; for Cyclone IV E, use cycloneive.
+ Cyclone V and Arria 10 GX devices are experimental.
-top <module>
use the specified module as top module (default='top')
@@ -4141,6 +5757,8 @@ This command runs synthesis for Intel FPGAs.
-vqm <file>
write the design to the specified Verilog Quartus Mapping File. Writing of an
output file is omitted if this parameter is not specified.
+ Note that this backend has not been tested and is likely incompatible
+ with recent versions of Quartus.
-vpr <file>
write BLIF files for VPR flow experiments. The synthesized BLIF output file is not
@@ -4152,17 +5770,17 @@ This command runs synthesis for Intel FPGAs.
from label is synonymous to 'begin', and empty to label is
synonymous to the end of the command list.
- -noiopads
- do not use altsyncram cells in output netlist
+ -iopads
+ use IO pad cells in output netlist
-nobram
- do not use altsyncram cells in output netlist
+ do not use block RAM cells in output netlist
-noflatten
do not flatten design before synthesis
-retime
- run 'abc' with -dff option
+ run 'abc' with '-dff -D 1' options
The following commands are executed by this synthesis command:
@@ -4183,29 +5801,28 @@ The following commands are executed by this synthesis command:
coarse:
synth -run coarse
- bram: (skip if -nobram)
- memory_bram -rules +/intel/common/brams.txt
- techmap -map +/intel/common/brams_map.v
+ map_bram: (skip if -nobram)
+ memory_bram -rules +/intel/common/brams_m9k.txt (if applicable for family)
+ techmap -map +/intel/common/brams_map_m9k.v (if applicable for family)
- fine:
+ map_ffram:
opt -fast -mux_undef -undriven -fine -full
memory_map
opt -undriven -fine
- dffsr2dff
dff2dffe -direct-match $_DFF_*
opt -fine
techmap -map +/techmap.v
opt -full
clean -purge
setundef -undriven -zero
- abc -markgroups -dff (only if -retime)
+ abc -markgroups -dff -D 1 (only if -retime)
map_luts:
abc -lut 4
clean
map_cells:
- iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I (unless -noiopads)
+ iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I (if -iopads)
techmap -map +/intel/max10/cells_map.v
dffinit -highlow -ff dffeas q power_up
clean -purge
@@ -4221,6 +5838,104 @@ The following commands are executed by this synthesis command:
vpr:
opt_clean -purge
write_blif <file-name>
+
+
+WARNING: THE 'synth_intel' COMMAND IS EXPERIMENTAL.
+\end{lstlisting}
+
+\section{synth\_sf2 -- synthesis for SmartFusion2 and IGLOO2 FPGAs}
+\label{cmd:synth_sf2}
+\begin{lstlisting}[numbers=left,frame=single]
+ synth_sf2 [options]
+
+This command runs synthesis for SmartFusion2 and IGLOO2 FPGAs.
+
+ -top <module>
+ use the specified module as top module
+
+ -edif <file>
+ write the design to the specified EDIF file. writing of an output file
+ is omitted if this parameter is not specified.
+
+ -vlog <file>
+ write the design to the specified Verilog file. writing of an output file
+ is omitted if this parameter is not specified.
+
+ -json <file>
+ write the design to the specified JSON file. writing of an output file
+ is omitted if this parameter is not specified.
+
+ -run <from_label>:<to_label>
+ only run the commands between the labels (see below). an empty
+ from label is synonymous to 'begin', and empty to label is
+ synonymous to the end of the command list.
+
+ -noflatten
+ do not flatten design before synthesis
+
+ -noiobs
+ run synthesis in "block mode", i.e. do not insert IO buffers
+
+ -clkbuf
+ insert direct PAD->global_net buffers
+
+ -retime
+ run 'abc' with '-dff -D 1' options
+
+
+The following commands are executed by this synthesis command:
+
+ begin:
+ read_verilog -lib +/sf2/cells_sim.v
+ hierarchy -check -top <top>
+
+ flatten: (unless -noflatten)
+ proc
+ flatten
+ tribuf -logic
+ deminout
+
+ coarse:
+ synth -run coarse
+
+ fine:
+ opt -fast -mux_undef -undriven -fine
+ memory_map
+ opt -undriven -fine
+ techmap -map +/techmap.v -map +/sf2/arith_map.v
+ opt -fast
+ abc -dff -D 1 (only if -retime)
+
+ map_ffs:
+ techmap -D NO_LUT -map +/sf2/cells_map.v
+ opt_expr -mux_undef
+ simplemap
+
+ map_luts:
+ abc -lut 4
+ clean
+
+ map_cells:
+ techmap -map +/sf2/cells_map.v
+ clean
+
+ map_iobs:
+ sf2_iobs [-clkbuf] (unless -noiobs)
+ clean
+
+ check:
+ hierarchy -check
+ stat
+ check -noinit
+
+ edif:
+ write_edif -gndvccy <file-name>
+
+ vlog:
+ write_verilog <file-name>
+
+ json:
+ write_json <file-name>
\end{lstlisting}
\section{synth\_xilinx -- synthesis for Xilinx FPGAs}
@@ -4235,6 +5950,26 @@ compatible with 7-Series Xilinx devices.
-top <module>
use the specified module as top module
+ -family <family>
+ run synthesis for the specified Xilinx architecture
+ generate the synthesis netlist for the specified family.
+ supported values:
+ - xcup: Ultrascale Plus
+ - xcu: Ultrascale
+ - xc7: Series 7 (default)
+ - xc6s: Spartan 6
+ - xc6v: Virtex 6
+ - xc5v: Virtex 5 (EXPERIMENTAL)
+ - xc4v: Virtex 4 (EXPERIMENTAL)
+ - xc3sda: Spartan 3A DSP (EXPERIMENTAL)
+ - xc3sa: Spartan 3A (EXPERIMENTAL)
+ - xc3se: Spartan 3E (EXPERIMENTAL)
+ - xc3s: Spartan 3 (EXPERIMENTAL)
+ - xc2vp: Virtex 2 Pro (EXPERIMENTAL)
+ - xc2v: Virtex 2 (EXPERIMENTAL)
+ - xcve: Virtex E, Spartan 2E (EXPERIMENTAL)
+ - xcv: Virtex, Spartan 2 (EXPERIMENTAL)
+
-edif <file>
write the design to the specified edif file. writing of an output file
is omitted if this parameter is not specified.
@@ -4247,6 +5982,42 @@ compatible with 7-Series Xilinx devices.
generate an output netlist (and BLIF file) suitable for VPR
(this feature is experimental and incomplete)
+ -ise
+ generate an output netlist suitable for ISE
+
+ -nobram
+ do not use block RAM cells in output netlist
+
+ -nolutram
+ do not use distributed RAM cells in output netlist
+
+ -nosrl
+ do not use distributed SRL cells in output netlist
+
+ -nocarry
+ do not use XORCY/MUXCY/CARRY4 cells in output netlist
+
+ -nowidelut
+ do not use MUXF[5-9] resources to implement LUTs larger than native for the target
+
+ -nodsp
+ do not use DSP48*s to implement multipliers and associated logic
+
+ -noiopad
+ disable I/O buffer insertion (useful for hierarchical or
+ out-of-context flows)
+
+ -noclkbuf
+ disable automatic clock buffer insertion
+
+ -uram
+ infer URAM288s for large memories (xcup only)
+
+ -widemux <int>
+ enable inference of hard multiplexer resources (MUXF[78]) for muxes at or
+ above this number of inputs (minimum value 2, recommended value >= 5).
+ default: 0 (no inference)
+
-run <from_label>:<to_label>
only run the commands between the labels (see below). an empty
from label is synonymous to 'begin', and empty to label is
@@ -4255,67 +6026,125 @@ compatible with 7-Series Xilinx devices.
-flatten
flatten design before synthesis
+ -dff
+ run 'abc'/'abc9' with -dff option
+
-retime
- run 'abc' with -dff option
+ run 'abc' with '-D 1' option to enable flip-flop retiming.
+ implies -dff.
+
+ -abc9
+ use new ABC9 flow (EXPERIMENTAL)
The following commands are executed by this synthesis command:
begin:
- read_verilog -lib +/xilinx/cells_sim.v
+ read_verilog -lib -specify +/xilinx/cells_sim.v
read_verilog -lib +/xilinx/cells_xtra.v
- read_verilog -lib +/xilinx/brams_bb.v
- hierarchy -check -top <top>
+ hierarchy -check -auto-top
- flatten: (only if -flatten)
+ prepare:
proc
- flatten
+ flatten (with '-flatten')
+ tribuf -logic
+ deminout
+ opt_expr
+ opt_clean
+ check
+ opt
+ wreduce [-keepdc] (option for '-widemux')
+ peepopt
+ opt_clean
+ muxpack ('-widemux' only)
+ pmux2shiftx (skip if '-nosrl' and '-widemux=0')
+ clean (skip if '-nosrl' and '-widemux=0')
+
+ map_dsp: (skip if '-nodsp')
+ memory_dff
+ techmap -map +/mul2dsp.v -map +/xilinx/{family}_dsp_map.v {options}
+ select a:mul2dsp
+ setattr -unset mul2dsp
+ opt_expr -fine
+ wreduce
+ select -clear
+ xilinx_dsp -family <family>
+ chtype -set $mul t:$__soft_mul
coarse:
- synth -run coarse
+ techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=[46]
+ alumacc
+ share
+ opt
+ fsm
+ opt -fast
+ memory -nomap
+ opt_clean
- bram:
- memory_bram -rules +/xilinx/brams.txt
- techmap -map +/xilinx/brams_map.v
+ map_uram: (only if '-uram')
+ memory_bram -rules +/xilinx/{family}_urams.txt
+ techmap -map +/xilinx/{family}_urams_map.v
- dram:
- memory_bram -rules +/xilinx/drams.txt
- techmap -map +/xilinx/drams_map.v
+ map_bram: (skip if '-nobram')
+ memory_bram -rules +/xilinx/{family}_brams.txt
+ techmap -map +/xilinx/{family}_brams_map.v
- fine:
+ map_lutram: (skip if '-nolutram')
+ memory_bram -rules +/xilinx/lut[46]_lutrams.txt
+ techmap -map +/xilinx/lutrams_map.v
+
+ map_ffram:
+ simplemap t:$dff t:$adff t:$mux
+ dff2dffs [-match-init] (-match-init for xc6s only)
opt -fast -full
memory_map
- dffsr2dff
- dff2dffe
+
+ fine:
+ dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*
+ muxcover <internal options> ('-widemux' only)
opt -full
- techmap -map +/techmap.v -map +/xilinx/arith_map.v
+ xilinx_srl -variable -minlen 3 (skip if '-nosrl')
+ techmap -map +/techmap.v -D LUT_SIZE=[46] [-map +/xilinx/mux_map.v] -map +/xilinx/arith_map.v
opt -fast
- map_luts:
- abc -luts 2:2,3,6:5,10,20 [-dff]
+ map_cells:
+ iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top (skip if '-noiopad')
+ techmap -map +/techmap.v -map +/xilinx/cells_map.v
clean
- map_cells:
- techmap -map +/xilinx/cells_map.v (with -D NO_LUT in vpr mode)
- dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT
+ map_ffs:
+ techmap -map +/xilinx/{family}_ff_map.v ('-abc9' only)
+
+ map_luts:
+ opt_expr -mux_undef
+ abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1] (option for 'nowidelut', '-dff', '-retime')
+ clean
+ xilinx_srl -fixed -minlen 3 (skip if '-nosrl')
+ techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -map +/xilinx/{family}_ff_map.v -D LUT_WIDTH=[46]
+ xilinx_dffopt [-lut4]
+ opt_lut_ins -tech xilinx
+
+ finalize:
+ clkbufmap -buf BUFG O:I (skip if '-noclkbuf')
+ extractinv -inv INV O:I (only if '-ise')
clean
check:
hierarchy -check
- stat
+ stat -tech xilinx
check -noinit
- edif: (only if -edif)
- write_edif <file-name>
+ edif:
+ write_edif -pvector bra
- blif: (only if -blif)
- write_blif <file-name>
+ blif:
+ write_blif
\end{lstlisting}
\section{tcl -- execute a TCL script file}
\label{cmd:tcl}
\begin{lstlisting}[numbers=left,frame=single]
- tcl <filename>
+ tcl <filename> [args]
This command executes the tcl commands in the specified file.
Use 'yosys cmd' to run the yosys command 'cmd' from tcl.
@@ -4324,6 +6153,9 @@ The tcl command 'yosys -import' can be used to import all yosys
commands directly as tcl commands to the tcl shell. Yosys commands
'proc' and 'rename' are wrapped to tcl commands 'procs' and 'renames'
in order to avoid a name collision with the built in commands.
+
+If any arguments are specified, these arguments are provided to the script via
+the standard $argc and $argv variables.
\end{lstlisting}
\section{techmap -- generic technology mapper}
@@ -4349,7 +6181,8 @@ file.
instead of inlining them.
-max_iter <number>
- only run the specified number of iterations.
+ only run the specified number of iterations on each module.
+ default: unlimited
-recursive
instead of the iterative breadth-first algorithm use a recursive
@@ -4359,6 +6192,9 @@ file.
-autoproc
Automatically call "proc" on implementations that contain processes.
+ -wb
+ Ignore the 'whitebox' attribute on cell implementations.
+
-assert
this option will cause techmap to exit with an error if it can't map
a selected cell. only cell types that end on an underscore are accepted
@@ -4383,6 +6219,11 @@ When a module in the map file has the 'techmap_wrap' attribute set, techmap
will create a wrapper for the cell and then run the command string that the
attribute is set to on the wrapper module.
+When a port on a module in the map file has the 'techmap_autopurge' attribute
+set, and that port is not connected in the instantiation that is mapped, then
+then a cell port connected only to such wires will be omitted in the mapped
+version of the circuit.
+
All wires in the modules from the map file matching the pattern _TECHMAP_*
or *._TECHMAP_* are special wires that are used to pass instructions from
the mapping module to the techmap command. At the moment the following special
@@ -4421,6 +6262,13 @@ wires are supported:
It is possible to combine both prefixes to 'RECURSION; CONSTMAP; '.
+ _TECHMAP_REMOVEINIT_<port-name>_
+ When this wire is set to a constant value, the init attribute of the wire(s)
+ connected to this port will be consumed. This wire must have the same
+ width as the given port, and for every bit that is set to 1 in the value,
+ the corresponding init attribute bit will be changed to 1'bx. If all
+ bits of an init attribute are left as x, it will be removed.
+
In addition to this special wires, techmap also supports special parameters in
modules in the map file:
@@ -4434,6 +6282,13 @@ modules in the map file:
former has a 1-bit for each constant input bit and the latter has the
value for this bit. The unused bits of the latter are set to undef (x).
+ _TECHMAP_WIREINIT_<port-name>_
+ When a parameter with this name exists, it will be set to the initial
+ value of the wire(s) connected to the given port, as specified by the init
+ attribute. If the attribute doesn't exist, x will be filled for the
+ missing bits. To remove the init attribute bits used, use the
+ _TECHMAP_REMOVEINIT_*_ wires.
+
_TECHMAP_BITS_CONNMAP_
_TECHMAP_CONNMAP_<port-name>_
For an N-bit port, the _TECHMAP_CONNMAP_<port-name>_ parameter, if it
@@ -4449,6 +6304,12 @@ constant value.
A cell with the name _TECHMAP_REPLACE_ in the map file will inherit the name
and attributes of the cell that is being replaced.
+A cell with a name of the form `_TECHMAP_REPLACE_.<suffix>` in the map file will
+be named thus but with the `_TECHMAP_REPLACE_' prefix substituted with the name
+of the cell being replaced.
+Similarly, a wire named in the form `_TECHMAP_REPLACE_.<suffix>` will cause a
+new wire alias to be created and named as above but with the `_TECHMAP_REPLACE_'
+prefix also substituted.
See 'help extract' for a pass that does the opposite thing.
@@ -4465,7 +6326,7 @@ Execute the specified command, optionally writing the commands output to the
specified logfile(s).
-q
- Do not print output to the normal destination (console and/or log file)
+ Do not print output to the normal destination (console and/or log file).
-o logfile
Write output to this file, truncate if exists.
@@ -4474,7 +6335,7 @@ specified logfile(s).
Write output to this file, append if exists.
+INT, -INT
- Add/subract INT from the -v setting for this command.
+ Add/subtract INT from the -v setting for this command.
\end{lstlisting}
\section{test\_abcloop -- automatically test handling of loops in abc command}
@@ -4511,8 +6372,16 @@ The attribute 'gentb_constant' can be used to force a signal to a constant
value after initialization. This can e.g. be used to force a reset signal
low in order to explore more inner states in a state machine.
+The attribute 'gentb_skip' can be attached to modules to suppress testbench
+generation.
+
-n <int>
number of iterations the test bench should run (default = 1000)
+
+ -seed <int>
+ seed used for pseudo-random number generation (default = 0).
+ a value of 0 will cause an arbitrary seed to be chosen, based on
+ the current system time.
\end{lstlisting}
\section{test\_cell -- automatically test the implementation of a cell type}
@@ -4574,6 +6443,29 @@ cell types. Use for example 'all /$add' for all cell types except $add.
create a Verilog test bench to test simlib and write_verilog
\end{lstlisting}
+\section{test\_pmgen -- test pass for pmgen}
+\label{cmd:test_pmgen}
+\begin{lstlisting}[numbers=left,frame=single]
+ test_pmgen -reduce_chain [options] [selection]
+
+Demo for recursive pmgen patterns. Map chains of AND/OR/XOR to $reduce_*.
+
+
+ test_pmgen -reduce_tree [options] [selection]
+
+Demo for recursive pmgen patterns. Map trees of AND/OR/XOR to $reduce_*.
+
+
+ test_pmgen -eqpmux [options] [selection]
+
+Demo for recursive pmgen patterns. Optimize EQ/NE/PMUX circuits.
+
+
+ test_pmgen -generate [options] <pattern_name>
+
+Create modules that match the specified pattern.
+\end{lstlisting}
+
\section{torder -- print cells in topological order}
\label{cmd:torder}
\begin{lstlisting}[numbers=left,frame=single]
@@ -4656,12 +6548,18 @@ Like -sv, but define FORMAL instead of SYNTHESIS.
Load the specified VHDL files into Verific.
- verific -work <libname> {-sv|-vhdl|...} <hdl-file>
+ verific [-work <libname>] {-sv|-vhdl|...} <hdl-file>
Load the specified Verilog/SystemVerilog/VHDL file into the specified library.
(default library when -work is not present: "work")
+ verific [-L <libname>] {-sv|-vhdl|...} <hdl-file>
+
+Look up external definitions in the specified library.
+(-L may be used more than once)
+
+
verific -vlog-incdir <directory>..
Add Verilog include directories.
@@ -4715,6 +6613,16 @@ Import options:
-autocover
Generate automatic cover statements for all asserts
+ -fullinit
+ Keep all register initializations, even those for non-FF registers.
+
+ -chparam name value
+ Elaborate the specified top modules (all modules when -all given) using
+ this parameter value. Modules on which this parameter does not exist will
+ cause Verific to produce a VERI-1928 or VHDL-1676 message. This option
+ can be specified multiple times to override multiple parameters.
+ String values must be passed in double quotes (").
+
-v, -vv
Verbose log messages. (-vv is even more verbose than -v.)
@@ -4743,7 +6651,12 @@ bindings (for Yosys and/or Verific developers):
-d <dump_file>
Dump the Verific netlist as a verilog file.
-Visit http://verific.com/ for more information on Verific.
+
+Use Symbiotic EDA Suite if you need Yosys+Verifc.
+https://www.symbioticeda.com/seda-suite
+
+Contact office@symbioticeda.com for free evaluation
+binaries of Symbiotic EDA Suite.
\end{lstlisting}
\section{verilog\_defaults -- set default options for read\_verilog}
@@ -4779,6 +6692,21 @@ Define and undefine verilog preprocessor macros.
-Uname[=definition]
undefine the preprocessor symbol 'name'
+
+ -reset
+ clear list of defined preprocessor symbols
+
+ -list
+ list currently defined preprocessor symbols
+\end{lstlisting}
+
+\section{wbflip -- flip the whitebox attribute}
+\label{cmd:wbflip}
+\begin{lstlisting}[numbers=left,frame=single]
+ wbflip [selection]
+
+Flip the whitebox attribute on selected cells. I.e. if it's set, unset it, and
+vice-versa. Blackbox cells are not effected by this command.
\end{lstlisting}
\section{wreduce -- reduce the word size of operations if possible}
@@ -4798,6 +6726,9 @@ Options:
-memx
Do not change the width of memory address ports. Use this options in
flows that use the 'memory_memx' pass.
+
+ -keepdc
+ Do not optimize explicit don't-care values.
\end{lstlisting}
\section{write\_aiger -- write design to AIGER file}
@@ -4813,7 +6744,7 @@ $assert and $assume cells are converted to AIGER bad state properties and
invariant constraints.
-ascii
- write ASCII version of AGIER format
+ write ASCII version of AIGER format
-zinit
convert FFs to zero-initialized FFs, adding additional inputs for
@@ -4830,6 +6761,11 @@ invariant constraints.
-vmap <filename>
like -map, but more verbose
+
+ -I, -O, -B, -L
+ If the design contains no input/output/assert/flip-flop then create one
+ dummy input/output/bad_state-pin or latch to make the tools reading the
+ AIGER file happy.
\end{lstlisting}
\section{write\_blif -- write design to BLIF file}
@@ -4913,6 +6849,58 @@ Write a BTOR description of the current design.
-s
Output only a single bad property for all asserts
+
+ -c
+ Output cover properties using 'bad' statements instead of asserts
+
+ -i <filename>
+ Create additional info file with auxiliary information
+\end{lstlisting}
+
+\section{write\_cxxrtl -- convert design to C++ RTL simulation}
+\label{cmd:write_cxxrtl}
+\begin{lstlisting}[numbers=left,frame=single]
+ write_cxxrtl [options] [filename]
+
+Write C++ code for simulating the design. The generated code requires a driver;
+the following simple driver is provided as an example:
+
+ #include "top.cc"
+
+ int main() {
+ cxxrtl_design::p_top top;
+ while (1) {
+ top.p_clk.next = value<1> {1u};
+ top.step();
+ top.p_clk.next = value<1> {0u};
+ top.step();
+ }
+ }
+
+The following options are supported by this backend:
+
+ -O <level>
+ set the optimization level. the default is -O5. higher optimization
+ levels dramatically decrease compile and run time, and highest level
+ possible for a design should be used.
+
+ -O0
+ no optimization.
+
+ -O1
+ elide internal wires if possible.
+
+ -O2
+ like -O1, and localize internal wires if possible.
+
+ -O3
+ like -O2, and elide public wires not marked (*keep*) if possible.
+
+ -O4
+ like -O3, and localize public wires not marked (*keep*) if possible.
+
+ -O5
+ like -O4, and run `splitnets -driver; opt_clean -purge` first.
\end{lstlisting}
\section{write\_edif -- write design to EDIF netlist file}
@@ -4930,6 +6918,13 @@ Write the current design to an EDIF netlist file.
if the design contains constant nets. use "hilomap" to map to custom
constant drivers first)
+ -gndvccy
+ create "GND" and "VCC" cells with "Y" outputs. (the default is "G"
+ for "GND" and "P" for "VCC".)
+
+ -attrprop
+ create EDIF properties for cell attributes
+
-pvector {par|bra|ang}
sets the delimiting character for module port rename clauses to
parentheses, square brackets, or angle brackets.
@@ -4964,6 +6959,8 @@ Inside a script the input file can also can a here-document:
write_firrtl [options] [filename]
Write a FIRRTL netlist of the current design.
+The following commands are executed by this command:
+ pmuxtree
\end{lstlisting}
\section{write\_ilang -- write design to ilang file}
@@ -5012,6 +7009,10 @@ Write a JSON netlist of the current design.
-aig
include AIG models for the different gate types
+ -compat-int
+ emit 32-bit or smaller fully-defined parameter values directly
+ as JSON numbers (for compatibility with old parsers)
+
The general syntax of the JSON output created by this command is as follows:
@@ -5083,12 +7084,10 @@ interface is known.
Module and cell ports and nets can be single bit wide or vectors of multiple
bits. Each individual signal bit is assigned a unique integer. The <bit_vector>
values referenced above are vectors of this integers. Signal bits that are
-connected to a constant driver are denoted as string "0" or "1" instead of
-a number.
+connected to a constant driver are denoted as string "0", "1", "x", or
+"z" instead of a number.
-Numeric parameter and attribute values up to 32 bits are written as decimal
-values. Numbers larger than that are written as string holding the binary
-representation of the value.
+Bit vectors (including integers) are written as string holding the binaryrepresentation of the value. Strings are written as strings, with an appendedblank in cases of strings of the form /[01xz]* */.
For example the following Verilog code:
@@ -5214,7 +7213,7 @@ format. A program processing this format must ignore all unknown fields.
\begin{lstlisting}[numbers=left,frame=single]
write_simplec [options] [filename]
-Write simple C code for simulating the design. The C code writen can be used to
+Write simple C code for simulating the design. The C code written can be used to
simulate the design in a C environment, but the purpose of this command is to
generate code that works well with C-based formal verification.
@@ -5471,6 +7470,10 @@ Write the current design to a Verilog file.
without this option all internal cells are converted to Verilog
expressions.
+ -siminit
+ add initial statements with hierarchical refs to initialize FFs when
+ in -noexpr mode.
+
-nodec
32-bit constant values are by default dumped as decimal numbers,
not bit pattern. This option deactivates this feature and instead
@@ -5490,8 +7493,16 @@ Write the current design to a Verilog file.
deactivates this feature and instead will write string constants
as binary numbers.
+ -extmem
+ instead of initializing memories using assignments to individual
+ elements, use the '$readmemh' function to read initialization data
+ from a file. This data is written to a file named by appending
+ a sequential index to the Verilog filename and replacing the extension
+ with '.mem', e.g. 'write_verilog -extmem foo.v' writes 'foo-1.mem',
+ 'foo-2.mem' and so on.
+
-defparam
- Use 'defparam' statements instead of the Verilog-2001 syntax for
+ use 'defparam' statements instead of the Verilog-2001 syntax for
cell parameters.
-blackboxes
@@ -5513,6 +7524,97 @@ processes to logic networks and registers. A warning is generated when
this command is called on a design with RTLIL processes.
\end{lstlisting}
+\section{write\_xaiger -- write design to XAIGER file}
+\label{cmd:write_xaiger}
+\begin{lstlisting}[numbers=left,frame=single]
+ write_xaiger [options] [filename]
+
+Write the top module (according to the (* top *) attribute or if only one module
+is currently selected) to an XAIGER file. Any non $_NOT_, $_AND_, $_ABC9_FF_, ornon (* abc9_box_id *) cells will be converted into psuedo-inputs and
+pseudo-outputs. Whitebox contents will be taken from the '<module-name>$holes'
+module, if it exists.
+
+ -ascii
+ write ASCII version of AIGER format
+
+ -map <filename>
+ write an extra file with port and box symbols
+\end{lstlisting}
+
+\section{xilinx\_dffopt -- Xilinx: optimize FF control signal usage}
+\label{cmd:xilinx_dffopt}
+\begin{lstlisting}[numbers=left,frame=single]
+ xilinx_dffopt [options] [selection]
+
+Converts hardware clock enable and set/reset signals on FFs to emulation
+using LUTs, if doing so would improve area. Operates on post-techmap Xilinx
+cells (LUT*, FD*).
+
+ -lut4
+ Assume a LUT4-based device (instead of a LUT6-based device).
+\end{lstlisting}
+
+\section{xilinx\_dsp -- Xilinx: pack resources into DSPs}
+\label{cmd:xilinx_dsp}
+\begin{lstlisting}[numbers=left,frame=single]
+ xilinx_dsp [options] [selection]
+
+Pack input registers (A2, A1, B2, B1, C, D, AD; with optional enable/reset),
+pipeline registers (M; with optional enable/reset), output registers (P; with
+optional enable/reset), pre-adder and/or post-adder into Xilinx DSP resources.
+
+Multiply-accumulate operations using the post-adder with feedback on the 'C'
+input will be folded into the DSP. In this scenario only, the 'C' input can be
+used to override the current accumulation result with a new value, which will
+be added to the multiplier result to form the next accumulation result.
+
+Use of the dedicated 'PCOUT' -> 'PCIN' cascade path is detected for 'P' -> 'C'
+connections (optionally, where 'P' is right-shifted by 17-bits and used as an
+input to the post-adder -- a pattern common for summing partial products to
+implement wide multipliers). Limited support also exists for similar cascading
+for A and B using '[AB]COUT' -> '[AB]CIN'. Currently, cascade chains are limited
+to a maximum length of 20 cells, corresponding to the smallest Xilinx 7 Series
+device.
+
+This pass is a no-op if the scratchpad variable 'xilinx_dsp.multonly' is set
+to 1.
+
+
+Experimental feature: addition/subtractions less than 12 or 24 bits with the
+'(* use_dsp="simd" *)' attribute attached to the output wire or attached to
+the add/subtract operator will cause those operations to be implemented using
+the 'SIMD' feature of DSPs.
+
+Experimental feature: the presence of a `$ge' cell attached to the registered
+P output implementing the operation "(P >= <power-of-2>)" will be transformed
+into using the DSP48E1's pattern detector feature for overflow detection.
+
+ -family {xcup|xcu|xc7|xc6v|xc5v|xc4v|xc6s|xc3sda}
+ select the family to target
+ default: xc7
+\end{lstlisting}
+
+\section{xilinx\_srl -- Xilinx shift register extraction}
+\label{cmd:xilinx_srl}
+\begin{lstlisting}[numbers=left,frame=single]
+ xilinx_srl [options] [selection]
+
+This pass converts chains of built-in flops (bit-level: $_DFF_[NP]_, $_DFFE_*
+and word-level: $dff, $dffe) as well as Xilinx flops (FDRE, FDRE_1) into a
+$__XILINX_SHREG cell. Chains must be of the same cell type, clock, clock polarity,
+enable, and enable polarity (where relevant).
+Flops with resets cannot be mapped to Xilinx devices and will not be inferred.
+ -minlen N
+ min length of shift register (default = 3)
+
+ -fixed
+ infer fixed-length shift registers.
+
+ -variable
+ infer variable-length shift registers (i.e. fixed-length shifts where
+ each element also fans-out to a $shiftx cell).
+\end{lstlisting}
+
\section{zinit -- add inverters so all FF are zero-initialized}
\label{cmd:zinit}
\begin{lstlisting}[numbers=left,frame=single]
diff --git a/misc/yosys-config.in b/misc/yosys-config.in
index 1473948cf..370835f8f 100644
--- a/misc/yosys-config.in
+++ b/misc/yosys-config.in
@@ -18,21 +18,21 @@ help() {
echo ""
echo "Use --exec to call a command instead of generating output. Example usage:"
echo ""
- echo " yosys-config --exec --cxx --cxxflags --ldflags -o plugin.so -shared plugin.cc --ldlibs"
+ echo " $0 --exec --cxx --cxxflags --ldflags -o plugin.so -shared plugin.cc --ldlibs"
echo ""
echo "The above command can be abbreviated as:"
echo ""
- echo " yosys-config --build plugin.so plugin.cc"
+ echo " $0 --build plugin.so plugin.cc"
echo ""
echo "Use --prefix to change the prefix for the special args from '--' to"
echo "something else. Example:"
echo ""
- echo " yosys-config --prefix @ bindir: @bindir"
+ echo " $0 --prefix @ bindir: @bindir"
echo ""
echo "The args --bindir and --datdir can be directly followed by a slash and"
echo "additional text. Example:"
echo ""
- echo " yosys-config --datdir/simlib.v"
+ echo " $0 --datdir/simlib.v"
echo ""
} >&2
exit 1
diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc
index c49b8bf5d..91f8c2add 100644
--- a/passes/cmds/add.cc
+++ b/passes/cmds/add.cc
@@ -42,9 +42,9 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
}
else {
RTLIL::Cell *formal_cell = module->addCell(NEW_ID, "$" + celltype);
- formal_cell->setPort(ID(A), wire);
+ formal_cell->setPort(ID::A, wire);
if(enable_name == "") {
- formal_cell->setPort(ID(EN), State::S1);
+ formal_cell->setPort(ID::EN, State::S1);
log("Added $%s cell for wire \"%s.%s\"\n", celltype.c_str(), module->name.str().c_str(), name.c_str());
}
else {
@@ -52,7 +52,7 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
if(enable_wire == nullptr)
log_error("Could not find enable wire with name \"%s\".\n", enable_name.c_str());
- formal_cell->setPort(ID(EN), enable_wire);
+ formal_cell->setPort(ID::EN, enable_wire);
log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype.c_str(), module->name.str().c_str(), name.c_str(), module->name.str().c_str(), enable_name.c_str());
}
}
@@ -212,7 +212,7 @@ struct AddPass : public Pass {
log_assert(module != nullptr);
if (!design->selected_whole_module(module->name))
continue;
- if (module->get_bool_attribute("\\blackbox"))
+ if (module->get_bool_attribute(ID::blackbox))
continue;
selected_anything = true;
diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc
index d09ed872e..5c0405f15 100644
--- a/passes/cmds/blackbox.cc
+++ b/passes/cmds/blackbox.cc
@@ -73,7 +73,7 @@ struct BlackboxPass : public Pass {
module->remove(remove_wires);
- module->set_bool_attribute("\\blackbox");
+ module->set_bool_attribute(ID::blackbox);
}
}
} BlackboxPass;
diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc
index 5a47988ec..ad6a07fa0 100644
--- a/passes/cmds/bugpoint.cc
+++ b/passes/cmds/bugpoint.cc
@@ -114,8 +114,8 @@ struct BugpointPass : public Pass {
return design;
RTLIL::Design *design_copy = new RTLIL::Design;
- for (auto &it : design->modules_)
- design_copy->add(it.second->clone());
+ for (auto module : design->modules())
+ design_copy->add(module->clone());
Pass::call(design_copy, "proc_clean -quiet");
Pass::call(design_copy, "clean -purge");
@@ -127,21 +127,21 @@ struct BugpointPass : public Pass {
RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool assigns, bool updates)
{
RTLIL::Design *design_copy = new RTLIL::Design;
- for (auto &it : design->modules_)
- design_copy->add(it.second->clone());
+ for (auto module : design->modules())
+ design_copy->add(module->clone());
int index = 0;
if (modules)
{
- for (auto &it : design_copy->modules_)
+ for (auto module : design_copy->modules())
{
- if (it.second->get_blackbox_attribute())
+ if (module->get_blackbox_attribute())
continue;
if (index++ == seed)
{
- log("Trying to remove module %s.\n", it.first.c_str());
- design_copy->remove(it.second);
+ log("Trying to remove module %s.\n", module->name.c_str());
+ design_copy->remove(module);
return design_copy;
}
}
@@ -155,7 +155,7 @@ struct BugpointPass : public Pass {
for (auto wire : mod->wires())
{
- if (!stage2 && wire->get_bool_attribute("$bugpoint"))
+ if (!stage2 && wire->get_bool_attribute(ID($bugpoint)))
continue;
if (wire->port_input || wire->port_output)
@@ -178,12 +178,12 @@ struct BugpointPass : public Pass {
if (mod->get_blackbox_attribute())
continue;
- for (auto &it : mod->cells_)
+ for (auto cell : mod->cells())
{
if (index++ == seed)
{
- log("Trying to remove cell %s.%s.\n", mod->name.c_str(), it.first.c_str());
- mod->remove(it.second);
+ log("Trying to remove cell %s.%s.\n", mod->name.c_str(), cell->name.c_str());
+ mod->remove(cell);
return design_copy;
}
}
@@ -220,7 +220,7 @@ struct BugpointPass : public Pass {
{
log("Trying to expose cell port %s.%s.%s as module port.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str());
RTLIL::Wire *wire = mod->addWire(NEW_ID, port.size());
- wire->set_bool_attribute("$bugpoint");
+ wire->set_bool_attribute(ID($bugpoint));
wire->port_input = cell->input(it.first);
wire->port_output = cell->output(it.first);
cell->unsetPort(it.first);
@@ -285,7 +285,7 @@ struct BugpointPass : public Pass {
}
}
}
- return NULL;
+ return nullptr;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -433,8 +433,8 @@ struct BugpointPass : public Pass {
{
Pass::call(design, "design -reset");
crashing_design = clean_design(crashing_design, clean, /*do_delete=*/true);
- for (auto &it : crashing_design->modules_)
- design->add(it.second->clone());
+ for (auto module : crashing_design->modules())
+ design->add(module->clone());
delete crashing_design;
}
}
diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc
index 820ecac7b..ba29e6f4b 100644
--- a/passes/cmds/check.cc
+++ b/passes/cmds/check.cc
@@ -98,49 +98,6 @@ struct CheckPass : public Pass {
log_header(design, "Executing CHECK pass (checking for obvious problems).\n");
- pool<IdString> fftypes;
- fftypes.insert("$sr");
- fftypes.insert("$ff");
- fftypes.insert("$dff");
- fftypes.insert("$dffe");
- fftypes.insert("$dffsr");
- fftypes.insert("$adff");
- fftypes.insert("$dlatch");
- fftypes.insert("$dlatchsr");
- fftypes.insert("$_DFFE_NN_");
- fftypes.insert("$_DFFE_NP_");
- fftypes.insert("$_DFFE_PN_");
- fftypes.insert("$_DFFE_PP_");
- fftypes.insert("$_DFFSR_NNN_");
- fftypes.insert("$_DFFSR_NNP_");
- fftypes.insert("$_DFFSR_NPN_");
- fftypes.insert("$_DFFSR_NPP_");
- fftypes.insert("$_DFFSR_PNN_");
- fftypes.insert("$_DFFSR_PNP_");
- fftypes.insert("$_DFFSR_PPN_");
- fftypes.insert("$_DFFSR_PPP_");
- fftypes.insert("$_DFF_NN0_");
- fftypes.insert("$_DFF_NN1_");
- fftypes.insert("$_DFF_NP0_");
- fftypes.insert("$_DFF_NP1_");
- fftypes.insert("$_DFF_N_");
- fftypes.insert("$_DFF_PN0_");
- fftypes.insert("$_DFF_PN1_");
- fftypes.insert("$_DFF_PP0_");
- fftypes.insert("$_DFF_PP1_");
- fftypes.insert("$_DFF_P_");
- fftypes.insert("$_DLATCHSR_NNN_");
- fftypes.insert("$_DLATCHSR_NNP_");
- fftypes.insert("$_DLATCHSR_NPN_");
- fftypes.insert("$_DLATCHSR_NPP_");
- fftypes.insert("$_DLATCHSR_PNN_");
- fftypes.insert("$_DLATCHSR_PNP_");
- fftypes.insert("$_DLATCHSR_PPN_");
- fftypes.insert("$_DLATCHSR_PPP_");
- fftypes.insert("$_DLATCH_N_");
- fftypes.insert("$_DLATCH_P_");
- fftypes.insert("$_FF_");
-
for (auto module : design->selected_whole_modules_warn())
{
if (module->has_processes_warn())
@@ -202,8 +159,8 @@ struct CheckPass : public Pass {
if (wire->port_input && !wire->port_output)
for (auto bit : sigmap(wire))
if (bit.wire) wire_drivers_count[bit]++;
- if (wire->attributes.count("\\init")) {
- Const initval = wire->attributes.at("\\init");
+ if (wire->attributes.count(ID::init)) {
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
init_bits.insert(sigmap(SigBit(wire, i)));
@@ -242,10 +199,10 @@ struct CheckPass : public Pass {
{
for (auto cell : module->cells())
{
- if (fftypes.count(cell->type) == 0)
+ if (RTLIL::builtin_ff_cell_types().count(cell->type) == 0)
continue;
- for (auto bit : sigmap(cell->getPort("\\Q")))
+ for (auto bit : sigmap(cell->getPort(ID::Q)))
init_bits.erase(bit);
}
diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc
index 7e32da65f..d6e7f2ccf 100644
--- a/passes/cmds/chformal.cc
+++ b/passes/cmds/chformal.cc
@@ -77,23 +77,23 @@ struct ChformalPass : public Pass {
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-assert") {
- constr_types.insert("$assert");
+ constr_types.insert(ID($assert));
continue;
}
if (args[argidx] == "-assume") {
- constr_types.insert("$assume");
+ constr_types.insert(ID($assume));
continue;
}
if (args[argidx] == "-live") {
- constr_types.insert("$live");
+ constr_types.insert(ID($live));
continue;
}
if (args[argidx] == "-fair") {
- constr_types.insert("$fair");
+ constr_types.insert(ID($fair));
continue;
}
if (args[argidx] == "-cover") {
- constr_types.insert("$cover");
+ constr_types.insert(ID($cover));
continue;
}
if (mode == 0 && args[argidx] == "-remove") {
@@ -139,11 +139,11 @@ struct ChformalPass : public Pass {
extra_args(args, argidx, design);
if (constr_types.empty()) {
- constr_types.insert("$assert");
- constr_types.insert("$assume");
- constr_types.insert("$live");
- constr_types.insert("$fair");
- constr_types.insert("$cover");
+ constr_types.insert(ID($assert));
+ constr_types.insert(ID($assume));
+ constr_types.insert(ID($live));
+ constr_types.insert(ID($fair));
+ constr_types.insert(ID($cover));
}
if (mode == 0)
@@ -171,11 +171,11 @@ struct ChformalPass : public Pass {
for (auto wire : module->wires())
{
- if (wire->attributes.count("\\init") == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec initsig = sigmap(wire);
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) {
if (initval[i] == State::S0)
@@ -187,17 +187,17 @@ struct ChformalPass : public Pass {
for (auto cell : module->selected_cells())
{
- if (cell->type == "$ff") {
- SigSpec D = sigmap(cell->getPort("\\D"));
- SigSpec Q = sigmap(cell->getPort("\\Q"));
+ if (cell->type == ID($ff)) {
+ SigSpec D = sigmap(cell->getPort(ID::D));
+ SigSpec Q = sigmap(cell->getPort(ID::Q));
for (int i = 0; i < GetSize(D); i++)
ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false));
}
- if (cell->type == "$dff") {
- SigSpec D = sigmap(cell->getPort("\\D"));
- SigSpec Q = sigmap(cell->getPort("\\Q"));
- SigSpec C = sigmap(cell->getPort("\\CLK"));
- bool clockpol = cell->getParam("\\CLK_POLARITY").as_bool();
+ if (cell->type == ID($dff)) {
+ SigSpec D = sigmap(cell->getPort(ID::D));
+ SigSpec Q = sigmap(cell->getPort(ID::Q));
+ SigSpec C = sigmap(cell->getPort(ID::CLK));
+ bool clockpol = cell->getParam(ID::CLK_POLARITY).as_bool();
for (int i = 0; i < GetSize(D); i++)
ffmap[Q[i]] = make_pair(D[i], make_pair(C, clockpol));
}
@@ -206,15 +206,15 @@ struct ChformalPass : public Pass {
for (auto cell : constr_cells)
while (true)
{
- SigSpec A = sigmap(cell->getPort("\\A"));
- SigSpec EN = sigmap(cell->getPort("\\EN"));
+ SigSpec A = sigmap(cell->getPort(ID::A));
+ SigSpec EN = sigmap(cell->getPort(ID::EN));
if (ffmap.count(A) == 0 || ffmap.count(EN) == 0)
break;
if (!init_zero.count(EN)) {
- if (cell->type == "$cover") break;
- if (cell->type.in("$assert", "$assume") && !init_one.count(A)) break;
+ if (cell->type == ID($cover)) break;
+ if (cell->type.in(ID($assert), ID($assume)) && !init_one.count(A)) break;
}
const auto &A_map = ffmap.at(A);
@@ -223,8 +223,8 @@ struct ChformalPass : public Pass {
if (A_map.second != EN_map.second)
break;
- cell->setPort("\\A", A_map.first);
- cell->setPort("\\EN", EN_map.first);
+ cell->setPort(ID::A, A_map.first);
+ cell->setPort(ID::EN, EN_map.first);
}
}
else
@@ -233,18 +233,18 @@ struct ChformalPass : public Pass {
for (auto cell : constr_cells)
for (int i = 0; i < mode_arg; i++)
{
- SigSpec orig_a = cell->getPort("\\A");
- SigSpec orig_en = cell->getPort("\\EN");
+ SigSpec orig_a = cell->getPort(ID::A);
+ SigSpec orig_en = cell->getPort(ID::EN);
Wire *new_a = module->addWire(NEW_ID);
Wire *new_en = module->addWire(NEW_ID);
- new_en->attributes["\\init"] = State::S0;
+ new_en->attributes[ID::init] = State::S0;
module->addFf(NEW_ID, orig_a, new_a);
module->addFf(NEW_ID, orig_en, new_en);
- cell->setPort("\\A", new_a);
- cell->setPort("\\EN", new_en);
+ cell->setPort(ID::A, new_a);
+ cell->setPort(ID::EN, new_en);
}
}
else
@@ -254,26 +254,26 @@ struct ChformalPass : public Pass {
for (int i = 0; i < mode_arg; i++) {
Wire *w = module->addWire(NEW_ID);
- w->attributes["\\init"] = State::S0;
+ w->attributes[ID::init] = State::S0;
module->addFf(NEW_ID, en, w);
en = w;
}
for (auto cell : constr_cells)
- cell->setPort("\\EN", module->LogicAnd(NEW_ID, en, cell->getPort("\\EN")));
+ cell->setPort(ID::EN, module->LogicAnd(NEW_ID, en, cell->getPort(ID::EN)));
}
else
if (mode == 'c')
{
for (auto cell : constr_cells)
- if (assert2assume && cell->type == "$assert")
- cell->type = "$assume";
- else if (assume2assert && cell->type == "$assume")
- cell->type = "$assert";
- else if (live2fair && cell->type == "$live")
- cell->type = "$fair";
- else if (fair2live && cell->type == "$fair")
- cell->type = "$live";
+ if (assert2assume && cell->type == ID($assert))
+ cell->type = ID($assume);
+ else if (assume2assert && cell->type == ID($assume))
+ cell->type = ID($assert);
+ else if (live2fair && cell->type == ID($live))
+ cell->type = ID($fair);
+ else if (fair2live && cell->type == ID($fair))
+ cell->type = ID($live);
}
}
}
diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc
index f93bada27..0b0868dfb 100644
--- a/passes/cmds/connect.cc
+++ b/passes/cmds/connect.cc
@@ -32,9 +32,9 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap &
RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size());
- for (auto &it : module->cells_)
- for (auto &port : it.second->connections_)
- if (ct.cell_output(it.second->type, port.first))
+ for (auto cell : module->cells())
+ for (auto &port : cell->connections_)
+ if (ct.cell_output(cell->type, port.first))
sigmap(port.second).replace(sig, dummy_wire, &port.second);
for (auto &conn : module->connections_)
@@ -77,15 +77,13 @@ struct ConnectPass : public Pass {
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- RTLIL::Module *module = NULL;
- for (auto &it : design->modules_) {
- if (!design->selected(it.second))
- continue;
- if (module != NULL)
- log_cmd_error("Multiple modules selected: %s, %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it.first));
- module = it.second;
+ RTLIL::Module *module = nullptr;
+ for (auto mod : design->selected_modules()) {
+ if (module != nullptr)
+ log_cmd_error("Multiple modules selected: %s, %s\n", log_id(module->name), log_id(mod->name));
+ module = mod;
}
- if (module == NULL)
+ if (module == nullptr)
log_cmd_error("No modules selected.\n");
if (!module->processes.empty())
log_cmd_error("Found processes in selected module.\n");
@@ -130,7 +128,7 @@ struct ConnectPass : public Pass {
std::vector<RTLIL::SigBit> lhs = it.first.to_sigbit_vector();
std::vector<RTLIL::SigBit> rhs = it.first.to_sigbit_vector();
for (size_t i = 0; i < lhs.size(); i++)
- if (rhs[i].wire != NULL)
+ if (rhs[i].wire != nullptr)
sigmap.add(lhs[i], rhs[i]);
}
@@ -172,14 +170,14 @@ struct ConnectPass : public Pass {
if (flag_nounset)
log_cmd_error("Can't use -port together with -nounset.\n");
- if (module->cells_.count(RTLIL::escape_id(port_cell)) == 0)
+ if (module->cell(RTLIL::escape_id(port_cell)) == nullptr)
log_cmd_error("Can't find cell %s.\n", port_cell.c_str());
RTLIL::SigSpec sig;
if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr))
log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str());
- module->cells_.at(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig));
+ module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig));
}
else
log_cmd_error("Expected -set, -unset, or -port.\n");
diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc
index 5a15cbbaf..6ae7c9304 100644
--- a/passes/cmds/connwrappers.cc
+++ b/passes/cmds/connwrappers.cc
@@ -65,15 +65,13 @@ struct ConnwrappersWorker
decls[key] = decl;
}
- void work(RTLIL::Design *design, RTLIL::Module *module)
+ void work(RTLIL::Module *module)
{
std::map<RTLIL::SigBit, std::pair<bool, RTLIL::SigSpec>> extend_map;
SigMap sigmap(module);
- for (auto &it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = it.second;
-
if (!decl_celltypes.count(cell->type))
continue;
@@ -105,13 +103,8 @@ struct ConnwrappersWorker
}
}
- for (auto &it : module->cells_)
+ for (auto cell : module->selected_cells())
{
- RTLIL::Cell *cell = it.second;
-
- if (!design->selected(module, cell))
- continue;
-
for (auto &conn : cell->connections_)
{
std::vector<RTLIL::SigBit> sigbits = sigmap(conn.second).to_sigbit_vector();
@@ -141,8 +134,8 @@ struct ConnwrappersWorker
}
if (old_sig.size())
- log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name),
- RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second));
+ log("Connected extended bits of %s.%s:%s: %s -> %s\n", log_id(module->name), log_id(cell->name),
+ log_id(conn.first), log_signal(old_sig), log_signal(conn.second));
}
}
}
@@ -200,9 +193,8 @@ struct ConnwrappersPass : public Pass {
log_header(design, "Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n");
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
- worker.work(design, mod_it.second);
+ for (auto module : design->selected_modules())
+ worker.work(module);
}
} ConnwrappersPass;
diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc
index acd2dba52..99f1f69cf 100644
--- a/passes/cmds/copy.cc
+++ b/passes/cmds/copy.cc
@@ -44,10 +44,10 @@ struct CopyPass : public Pass {
std::string src_name = RTLIL::escape_id(args[1]);
std::string trg_name = RTLIL::escape_id(args[2]);
- if (design->modules_.count(src_name) == 0)
+ if (design->module(src_name) == nullptr)
log_cmd_error("Can't find source module %s.\n", src_name.c_str());
- if (design->modules_.count(trg_name) != 0)
+ if (design->module(trg_name) != nullptr)
log_cmd_error("Target module name %s already exists.\n", trg_name.c_str());
RTLIL::Module *new_mod = design->module(src_name)->clone();
diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc
index 5822c09f8..b124e3b0f 100644
--- a/passes/cmds/delete.cc
+++ b/passes/cmds/delete.cc
@@ -65,27 +65,24 @@ struct DeletePass : public Pass {
}
extra_args(args, argidx, design);
- std::vector<RTLIL::IdString> delete_mods;
-
- for (auto &mod_it : design->modules_)
+ std::vector<RTLIL::Module *> delete_mods;
+ for (auto module : design->modules())
{
- if (design->selected_whole_module(mod_it.first) && !flag_input && !flag_output) {
- delete_mods.push_back(mod_it.first);
+ if (design->selected_whole_module(module->name) && !flag_input && !flag_output) {
+ delete_mods.push_back(module);
continue;
}
- if (!design->selected_module(mod_it.first))
+ if (!design->selected_module(module->name))
continue;
- RTLIL::Module *module = mod_it.second;
-
if (flag_input || flag_output) {
- for (auto &it : module->wires_)
- if (design->selected(module, it.second)) {
+ for (auto wire : module->wires())
+ if (design->selected(module, wire)) {
if (flag_input)
- it.second->port_input = false;
+ wire->port_input = false;
if (flag_output)
- it.second->port_output = false;
+ wire->port_output = false;
}
module->fixup_ports();
continue;
@@ -96,20 +93,19 @@ struct DeletePass : public Pass {
pool<RTLIL::IdString> delete_procs;
pool<RTLIL::IdString> delete_mems;
- for (auto &it : module->wires_)
- if (design->selected(module, it.second))
- delete_wires.insert(it.second);
+ for (auto wire : module->selected_wires())
+ delete_wires.insert(wire);
for (auto &it : module->memories)
if (design->selected(module, it.second))
delete_mems.insert(it.first);
- for (auto &it : module->cells_) {
- if (design->selected(module, it.second))
- delete_cells.insert(it.second);
- if (it.second->type.in("$memrd", "$memwr") &&
- delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0)
- delete_cells.insert(it.second);
+ for (auto cell : module->cells()) {
+ if (design->selected(module, cell))
+ delete_cells.insert(cell);
+ if (cell->type.in(ID($memrd), ID($memwr)) &&
+ delete_mems.count(cell->parameters.at(ID::MEMID).decode_string()) != 0)
+ delete_cells.insert(cell);
}
for (auto &it : module->processes)
@@ -134,9 +130,8 @@ struct DeletePass : public Pass {
module->fixup_ports();
}
- for (auto &it : delete_mods) {
- delete design->modules_.at(it);
- design->modules_.erase(it);
+ for (auto mod : delete_mods) {
+ design->remove(mod);
}
}
} DeletePass;
diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc
index 9ee613b1f..4612760cc 100644
--- a/passes/cmds/design.cc
+++ b/passes/cmds/design.cc
@@ -218,7 +218,7 @@ struct DesignPass : public Pass {
if (import_mode) {
for (auto module : copy_src_modules)
{
- if (module->get_bool_attribute("\\top")) {
+ if (module->get_bool_attribute(ID::top)) {
copy_src_modules.clear();
copy_src_modules.push_back(module);
break;
@@ -255,7 +255,7 @@ struct DesignPass : public Pass {
RTLIL::Module *t = mod->clone();
t->name = prefix;
t->design = copy_to_design;
- t->attributes.erase("\\top");
+ t->attributes.erase(ID::top);
copy_to_design->add(t);
queue.insert(t);
@@ -287,7 +287,7 @@ struct DesignPass : public Pass {
RTLIL::Module *t = fmod->clone();
t->name = trg_name;
t->design = copy_to_design;
- t->attributes.erase("\\top");
+ t->attributes.erase(ID::top);
copy_to_design->add(t);
queue.insert(t);
diff --git a/passes/cmds/qwp.cc b/passes/cmds/qwp.cc
index adbe89e31..b178ef951 100644
--- a/passes/cmds/qwp.cc
+++ b/passes/cmds/qwp.cc
@@ -737,7 +737,7 @@ struct QwpWorker
for (auto &node : nodes)
if (node.cell != nullptr)
- node.cell->attributes["\\qwp_position"] = stringf("%f %f", node.pos, node.alt_pos);
+ node.cell->attributes[ID::qwp_position] = stringf("%f %f", node.pos, node.alt_pos);
vector<double> edge_lengths;
vector<double> weighted_edge_lengths;
diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc
index 1ccfc2e86..515f5a4ef 100644
--- a/passes/cmds/setattr.cc
+++ b/passes/cmds/setattr.cc
@@ -38,7 +38,7 @@ struct setunset_t
value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2));
} else {
RTLIL::SigSpec sig_value;
- if (!RTLIL::SigSpec::parse(sig_value, NULL, set_value))
+ if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value))
log_cmd_error("Can't decode value '%s'!\n", set_value.c_str());
value = sig_value.as_const();
}
@@ -96,10 +96,8 @@ struct SetattrPass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &mod : design->modules_)
+ for (auto module : design->modules())
{
- RTLIL::Module *module = mod.second;
-
if (flag_mod) {
if (design->selected_whole_module(module->name))
do_setunset(module->attributes, setunset_list);
@@ -109,17 +107,17 @@ struct SetattrPass : public Pass {
if (!design->selected(module))
continue;
- for (auto &it : module->wires_)
- if (design->selected(module, it.second))
- do_setunset(it.second->attributes, setunset_list);
+ for (auto wire : module->wires())
+ if (design->selected(module, wire))
+ do_setunset(wire->attributes, setunset_list);
for (auto &it : module->memories)
if (design->selected(module, it.second))
do_setunset(it.second->attributes, setunset_list);
- for (auto &it : module->cells_)
- if (design->selected(module, it.second))
- do_setunset(it.second->attributes, setunset_list);
+ for (auto cell : module->cells())
+ if (design->selected(module, cell))
+ do_setunset(cell->attributes, setunset_list);
for (auto &it : module->processes)
if (design->selected(module, it.second))
@@ -159,10 +157,10 @@ struct WbflipPass : public Pass {
if (!design->selected(module))
continue;
- if (module->get_bool_attribute("\\blackbox"))
+ if (module->get_bool_attribute(ID::blackbox))
continue;
- module->set_bool_attribute("\\whitebox", !module->get_bool_attribute("\\whitebox"));
+ module->set_bool_attribute(ID::whitebox, !module->get_bool_attribute(ID::whitebox));
}
}
} WbflipPass;
@@ -208,19 +206,13 @@ struct SetparamPass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &mod : design->modules_)
+ for (auto module : design->selected_modules())
{
- RTLIL::Module *module = mod.second;
-
- if (!design->selected(module))
- continue;
-
- for (auto &it : module->cells_)
- if (design->selected(module, it.second)) {
- if (!new_cell_type.empty())
- it.second->type = new_cell_type;
- do_setunset(it.second->parameters, setunset_list);
- }
+ for (auto cell : module->selected_cells()) {
+ if (!new_cell_type.empty())
+ cell->type = new_cell_type;
+ do_setunset(cell->parameters, setunset_list);
+ }
}
}
} SetparamPass;
diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc
index 3eedc86b8..8d973869e 100644
--- a/passes/cmds/setundef.cc
+++ b/passes/cmds/setundef.cc
@@ -149,7 +149,7 @@ struct SetundefPass : public Pass {
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- bool got_value = false;
+ int got_value = 0;
bool undriven_mode = false;
bool expose_mode = false;
bool init_mode = false;
@@ -170,31 +170,31 @@ struct SetundefPass : public Pass {
continue;
}
if (args[argidx] == "-zero") {
- got_value = true;
+ got_value++;
worker.next_bit_mode = MODE_ZERO;
worker.next_bit_state = 0;
continue;
}
if (args[argidx] == "-one") {
- got_value = true;
+ got_value++;
worker.next_bit_mode = MODE_ONE;
worker.next_bit_state = 0;
continue;
}
if (args[argidx] == "-anyseq") {
- got_value = true;
+ got_value++;
worker.next_bit_mode = MODE_ANYSEQ;
worker.next_bit_state = 0;
continue;
}
if (args[argidx] == "-anyconst") {
- got_value = true;
+ got_value++;
worker.next_bit_mode = MODE_ANYCONST;
worker.next_bit_state = 0;
continue;
}
if (args[argidx] == "-undef") {
- got_value = true;
+ got_value++;
worker.next_bit_mode = MODE_UNDEF;
worker.next_bit_state = 0;
continue;
@@ -207,8 +207,8 @@ struct SetundefPass : public Pass {
params_mode = true;
continue;
}
- if (args[argidx] == "-random" && !got_value && argidx+1 < args.size()) {
- got_value = true;
+ if (args[argidx] == "-random" && argidx+1 < args.size()) {
+ got_value++;
worker.next_bit_mode = MODE_RANDOM;
worker.next_bit_state = atoi(args[++argidx].c_str()) + 1;
for (int i = 0; i < 10; i++)
@@ -221,7 +221,7 @@ struct SetundefPass : public Pass {
if (!got_value && expose_mode) {
log("Using default as -undef with -expose.\n");
- got_value = true;
+ got_value++;
worker.next_bit_mode = MODE_UNDEF;
worker.next_bit_state = 0;
}
@@ -229,7 +229,9 @@ struct SetundefPass : public Pass {
if (expose_mode && !undriven_mode)
log_cmd_error("Option -expose must be used with option -undriven.\n");
if (!got_value)
- log_cmd_error("One of the options -zero, -one, -anyseq, -anyconst, or -random <seed> must be specified.\n");
+ log_cmd_error("One of the options -zero, -one, -anyseq, -anyconst, -random <seed>, or -expose must be specified.\n");
+ else if (got_value > 1)
+ log_cmd_error("Only one of the options -zero, -one, -anyseq, -anyconst, or -random <seed> can be specified.\n");
if (init_mode && (worker.next_bit_mode == MODE_ANYSEQ || worker.next_bit_mode == MODE_ANYCONST))
log_cmd_error("The options -init and -anyseq / -anyconst are exclusive.\n");
@@ -359,37 +361,12 @@ struct SetundefPass : public Pass {
pool<SigBit> ffbits;
pool<Wire*> initwires;
- pool<IdString> fftypes;
- fftypes.insert("$dff");
- fftypes.insert("$dffe");
- fftypes.insert("$dffsr");
- fftypes.insert("$adff");
-
- std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
-
- for (auto c1 : list_np)
- fftypes.insert(stringf("$_DFF_%c_", c1));
-
- for (auto c1 : list_np)
- for (auto c2 : list_np)
- fftypes.insert(stringf("$_DFFE_%c%c_", c1, c2));
-
- for (auto c1 : list_np)
- for (auto c2 : list_np)
- for (auto c3 : list_01)
- fftypes.insert(stringf("$_DFF_%c%c%c_", c1, c2, c3));
-
- for (auto c1 : list_np)
- for (auto c2 : list_np)
- for (auto c3 : list_np)
- fftypes.insert(stringf("$_DFFSR_%c%c%c_", c1, c2, c3));
-
for (auto cell : module->cells())
{
- if (!fftypes.count(cell->type))
+ if (!RTLIL::builtin_ff_cell_types().count(cell->type))
continue;
- for (auto bit : sigmap(cell->getPort("\\Q")))
+ for (auto bit : sigmap(cell->getPort(ID::Q)))
ffbits.insert(bit);
}
@@ -411,7 +388,7 @@ struct SetundefPass : public Pass {
for (auto wire : initwires)
{
- Const &initval = wire->attributes["\\init"];
+ Const &initval = wire->attributes[ID::init];
initval.bits.resize(GetSize(wire), State::Sx);
for (int i = 0; i < GetSize(wire); i++) {
@@ -423,7 +400,7 @@ struct SetundefPass : public Pass {
}
if (initval.is_fully_undef())
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
initwires.clear();
@@ -439,14 +416,14 @@ struct SetundefPass : public Pass {
if (wire->name[0] == (wire_types ? '\\' : '$'))
continue;
- if (!wire->attributes.count("\\init"))
+ if (!wire->attributes.count(ID::init))
continue;
- Const &initval = wire->attributes["\\init"];
+ Const &initval = wire->attributes[ID::init];
initval.bits.resize(GetSize(wire), State::Sx);
if (initval.is_fully_undef()) {
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
continue;
}
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index e0d428811..155ed0fcd 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -41,8 +41,6 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-using RTLIL::id2cstr;
-
#undef CLUSTER_CELLS_AND_PORTBOXES
struct ShowWorker
@@ -101,7 +99,7 @@ struct ShowWorker
{
sig.sort_and_unify();
for (auto &c : sig.chunks()) {
- if (c.wire != NULL)
+ if (c.wire != nullptr)
for (auto &s : color_selections)
if (s.second.selected_members.count(module->name) > 0 && s.second.selected_members.at(module->name).count(c.wire->name) > 0)
return stringf("color=\"%s\"", s.first.c_str());
@@ -218,7 +216,7 @@ struct ShowWorker
if (sig.is_chunk()) {
const RTLIL::SigChunk &c = sig.as_chunk();
- if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) {
+ if (c.wire != nullptr && design->selected_member(module->name, c.wire->name)) {
if (!range_check || c.wire->width == c.width)
return stringf("n%d", id2num(c.wire->name));
} else {
@@ -230,7 +228,7 @@ struct ShowWorker
return std::string();
}
- std::string gen_portbox(std::string port, RTLIL::SigSpec sig, bool driver, std::string *node = NULL)
+ std::string gen_portbox(std::string port, RTLIL::SigSpec sig, bool driver, std::string *node = nullptr)
{
std::string code;
std::string net = gen_signode_simple(sig);
@@ -287,7 +285,7 @@ struct ShowWorker
else
code += stringf("x%d:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", idx, port.c_str(), nextColor(sig).c_str(), widthLabel(sig.size()).c_str());
}
- if (node != NULL)
+ if (node != nullptr)
*node = stringf("x%d", idx);
}
else
@@ -300,7 +298,7 @@ struct ShowWorker
net_conn_map[net].bits = sig.size();
net_conn_map[net].color = nextColor(sig, net_conn_map[net].color);
}
- if (node != NULL)
+ if (node != nullptr)
*node = net;
}
return code;
@@ -366,22 +364,20 @@ struct ShowWorker
std::set<std::string> all_sources, all_sinks;
std::map<std::string, std::string> wires_on_demand;
- for (auto &it : module->wires_) {
- if (!design->selected_member(module->name, it.first))
- continue;
+ for (auto wire : module->selected_wires()) {
const char *shape = "diamond";
- if (it.second->port_input || it.second->port_output)
+ if (wire->port_input || wire->port_output)
shape = "octagon";
- if (it.first[0] == '\\') {
+ if (wire->name[0] == '\\') {
fprintf(f, "n%d [ shape=%s, label=\"%s\", %s, fontcolor=\"black\" ];\n",
- id2num(it.first), shape, findLabel(it.first.str()),
- nextColor(RTLIL::SigSpec(it.second), "color=\"black\"").c_str());
- if (it.second->port_input)
- all_sources.insert(stringf("n%d", id2num(it.first)));
- else if (it.second->port_output)
- all_sinks.insert(stringf("n%d", id2num(it.first)));
+ id2num(wire->name), shape, findLabel(wire->name.str()),
+ nextColor(RTLIL::SigSpec(wire), "color=\"black\"").c_str());
+ if (wire->port_input)
+ all_sources.insert(stringf("n%d", id2num(wire->name)));
+ else if (wire->port_output)
+ all_sinks.insert(stringf("n%d", id2num(wire->name)));
} else {
- wires_on_demand[stringf("n%d", id2num(it.first))] = it.first.str();
+ wires_on_demand[stringf("n%d", id2num(wire->name))] = wire->name.str();
}
}
@@ -398,15 +394,12 @@ struct ShowWorker
fprintf(f, "}\n");
}
- for (auto &it : module->cells_)
+ for (auto cell : module->selected_cells())
{
- if (!design->selected_member(module->name, it.first))
- continue;
-
std::vector<RTLIL::IdString> in_ports, out_ports;
- for (auto &conn : it.second->connections()) {
- if (!ct.cell_output(it.second->type, conn.first))
+ for (auto &conn : cell->connections()) {
+ if (!ct.cell_output(cell->type, conn.first))
in_ports.push_back(conn.first);
else
out_ports.push_back(conn.first);
@@ -419,12 +412,12 @@ struct ShowWorker
for (auto &p : in_ports)
label_string += stringf("<p%d> %s%s|", id2num(p), escape(p.str()),
- genSignedLabels && it.second->hasParam(p.str() + "_SIGNED") &&
- it.second->getParam(p.str() + "_SIGNED").as_bool() ? "*" : "");
+ genSignedLabels && cell->hasParam(p.str() + "_SIGNED") &&
+ cell->getParam(p.str() + "_SIGNED").as_bool() ? "*" : "");
if (label_string[label_string.size()-1] == '|')
label_string = label_string.substr(0, label_string.size()-1);
- label_string += stringf("}|%s\\n%s|{", findLabel(it.first.str()), escape(it.second->type.str()));
+ label_string += stringf("}|%s\\n%s|{", findLabel(cell->name.str()), escape(cell->type.str()));
for (auto &p : out_ports)
label_string += stringf("<p%d> %s|", id2num(p), escape(p.str()));
@@ -434,19 +427,19 @@ struct ShowWorker
label_string += "}}";
std::string code;
- for (auto &conn : it.second->connections()) {
- code += gen_portbox(stringf("c%d:p%d", id2num(it.first), id2num(conn.first)),
- conn.second, ct.cell_output(it.second->type, conn.first));
+ for (auto &conn : cell->connections()) {
+ code += gen_portbox(stringf("c%d:p%d", id2num(cell->name), id2num(conn.first)),
+ conn.second, ct.cell_output(cell->type, conn.first));
}
#ifdef CLUSTER_CELLS_AND_PORTBOXES
if (!code.empty())
fprintf(f, "subgraph cluster_c%d {\nc%d [ shape=record, label=\"%s\"%s ];\n%s}\n",
- id2num(it.first), id2num(it.first), label_string.c_str(), findColor(it.first), code.c_str());
+ id2num(cell->name), id2num(cell->name), label_string.c_str(), findColor(cell->name), code.c_str());
else
#endif
fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s",
- id2num(it.first), label_string.c_str(), findColor(it.first.str()), code.c_str());
+ id2num(cell->name), label_string.c_str(), findColor(cell->name.str()), code.c_str());
}
for (auto &it : module->processes)
@@ -482,8 +475,8 @@ struct ShowWorker
}
std::string proc_src = RTLIL::unescape_id(proc->name);
- if (proc->attributes.count("\\src") > 0)
- proc_src = proc->attributes.at("\\src").decode_string();
+ if (proc->attributes.count(ID::src) > 0)
+ proc_src = proc->attributes.at(ID::src).decode_string();
fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name.str()), proc_src.c_str());
}
@@ -491,12 +484,12 @@ struct ShowWorker
{
bool found_lhs_wire = false;
for (auto &c : conn.first.chunks()) {
- if (c.wire == NULL || design->selected_member(module->name, c.wire->name))
+ if (c.wire == nullptr || design->selected_member(module->name, c.wire->name))
found_lhs_wire = true;
}
bool found_rhs_wire = false;
for (auto &c : conn.second.chunks()) {
- if (c.wire == NULL || design->selected_member(module->name, c.wire->name))
+ if (c.wire == nullptr || design->selected_member(module->name, c.wire->name))
found_rhs_wire = true;
}
if (!found_lhs_wire || !found_rhs_wire)
@@ -572,23 +565,21 @@ struct ShowWorker
design->optimize();
page_counter = 0;
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->selected_modules())
{
- module = mod_it.second;
- if (!design->selected_module(module->name))
- continue;
+ module = mod;
if (design->selected_whole_module(module->name)) {
if (module->get_blackbox_attribute()) {
- // log("Skipping blackbox module %s.\n", id2cstr(module->name));
+ // log("Skipping blackbox module %s.\n", log_id(module->name));
continue;
} else
- if (module->cells_.empty() && module->connections().empty() && module->processes.empty()) {
- log("Skipping empty module %s.\n", id2cstr(module->name));
+ if (module->cells().size() == 0 && module->connections().empty() && module->processes.empty()) {
+ log("Skipping empty module %s.\n", log_id(module->name));
continue;
} else
- log("Dumping module %s to page %d.\n", id2cstr(module->name), ++page_counter);
+ log("Dumping module %s to page %d.\n", log_id(module->name), ++page_counter);
} else
- log("Dumping selected parts of module %s to page %d.\n", id2cstr(module->name), ++page_counter);
+ log("Dumping selected parts of module %s to page %d.\n", log_id(module->name), ++page_counter);
handle_module();
}
}
@@ -802,13 +793,12 @@ struct ShowPass : public Pass {
if (format != "ps" && format != "dot") {
int modcount = 0;
- for (auto &mod_it : design->modules_) {
- if (mod_it.second->get_blackbox_attribute())
+ for (auto module : design->selected_modules()) {
+ if (module->get_blackbox_attribute())
continue;
- if (mod_it.second->cells_.empty() && mod_it.second->connections().empty())
+ if (module->cells().size() == 0 && module->connections().empty())
continue;
- if (design->selected_module(mod_it.first))
- modcount++;
+ modcount++;
}
if (modcount > 1)
log_cmd_error("For formats different than 'ps' or 'dot' only one module must be selected.\n");
@@ -835,7 +825,7 @@ struct ShowPass : public Pass {
FILE *f = fopen(dot_file.c_str(), "w");
if (custom_prefix)
yosys_output_files.insert(dot_file);
- if (f == NULL) {
+ if (f == nullptr) {
for (auto lib : libs)
delete lib;
log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str());
@@ -889,8 +879,8 @@ struct ShowPass : public Pass {
if (flag_pause) {
#ifdef YOSYS_ENABLE_READLINE
- char *input = NULL;
- while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) {
+ char *input = nullptr;
+ while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != nullptr) {
if (input[strspn(input, " \t\r\n")] == 0)
break;
char *p = input + strspn(input, " \t\r\n");
diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc
index bafafca4e..ea9e06979 100644
--- a/passes/cmds/splice.cc
+++ b/passes/cmds/splice.cc
@@ -75,13 +75,13 @@ struct SpliceWorker
RTLIL::SigSpec new_sig = sig;
if (sig_a.size() != sig.size()) {
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$slice");
- cell->parameters["\\OFFSET"] = offset;
- cell->parameters["\\A_WIDTH"] = sig_a.size();
- cell->parameters["\\Y_WIDTH"] = sig.size();
- cell->setPort("\\A", sig_a);
- cell->setPort("\\Y", module->addWire(NEW_ID, sig.size()));
- new_sig = cell->getPort("\\Y");
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($slice));
+ cell->parameters[ID::OFFSET] = offset;
+ cell->parameters[ID::A_WIDTH] = sig_a.size();
+ cell->parameters[ID::Y_WIDTH] = sig.size();
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID::Y, module->addWire(NEW_ID, sig.size()));
+ new_sig = cell->getPort(ID::Y);
}
sliced_signals_cache[sig] = new_sig;
@@ -102,7 +102,7 @@ struct SpliceWorker
for (auto &bit : sig.to_sigbit_vector())
{
- if (bit.wire == NULL)
+ if (bit.wire == nullptr)
{
if (last_bit == 0)
chunks.back().append(bit);
@@ -132,13 +132,13 @@ struct SpliceWorker
RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front());
for (size_t i = 1; i < chunks.size(); i++) {
RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]);
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat");
- cell->parameters["\\A_WIDTH"] = new_sig.size();
- cell->parameters["\\B_WIDTH"] = sig2.size();
- cell->setPort("\\A", new_sig);
- cell->setPort("\\B", sig2);
- cell->setPort("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size()));
- new_sig = cell->getPort("\\Y");
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($concat));
+ cell->parameters[ID::A_WIDTH] = new_sig.size();
+ cell->parameters[ID::B_WIDTH] = sig2.size();
+ cell->setPort(ID::A, new_sig);
+ cell->setPort(ID::B, sig2);
+ cell->setPort(ID::Y, module->addWire(NEW_ID, new_sig.size() + sig2.size()));
+ new_sig = cell->getPort(ID::Y);
}
spliced_signals_cache[sig] = new_sig;
@@ -149,23 +149,23 @@ struct SpliceWorker
void run()
{
- log("Splicing signals in module %s:\n", RTLIL::id2cstr(module->name));
+ log("Splicing signals in module %s:\n", log_id(module->name));
driven_bits.push_back(RTLIL::State::Sm);
driven_bits.push_back(RTLIL::State::Sm);
- for (auto &it : module->wires_)
- if (it.second->port_input) {
- RTLIL::SigSpec sig = sigmap(it.second);
+ for (auto wire : module->wires())
+ if (wire->port_input) {
+ RTLIL::SigSpec sig = sigmap(wire);
driven_chunks.insert(sig);
for (auto &bit : sig.to_sigbit_vector())
driven_bits.push_back(bit);
driven_bits.push_back(RTLIL::State::Sm);
}
- for (auto &it : module->cells_)
- for (auto &conn : it.second->connections())
- if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) {
+ for (auto cell : module->cells())
+ for (auto &conn : cell->connections())
+ if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) {
RTLIL::SigSpec sig = sigmap(conn.second);
driven_chunks.insert(sig);
for (auto &bit : sig.to_sigbit_vector())
@@ -180,9 +180,8 @@ struct SpliceWorker
SigPool selected_bits;
if (!sel_by_cell)
- for (auto &it : module->wires_)
- if (design->selected(module, it.second))
- selected_bits.add(sigmap(it.second));
+ for (auto wire : module->selected_wires())
+ selected_bits.add(sigmap(wire));
std::vector<Cell*> mod_cells = module->cells();
@@ -343,17 +342,14 @@ struct SplicePass : public Pass {
log_header(design, "Executing SPLICE pass (creating cells for signal splicing).\n");
- for (auto &mod_it : design->modules_)
+ for (auto module : design->selected_modules())
{
- if (!design->selected(mod_it.second))
- continue;
-
- if (mod_it.second->processes.size()) {
- log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str());
+ if (module->processes.size()) {
+ log("Skipping module %s as it contains processes.\n", module->name.c_str());
continue;
}
- SpliceWorker worker(design, mod_it.second);
+ SpliceWorker worker(design, module);
worker.sel_by_cell = sel_by_cell;
worker.sel_by_wire = sel_by_wire;
worker.sel_any_bit = sel_any_bit;
diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc
index f5a1f17b3..1e7dedd70 100644
--- a/passes/cmds/splitnets.cc
+++ b/passes/cmds/splitnets.cc
@@ -60,17 +60,17 @@ struct SplitnetsWorker
new_wire->port_input = wire->port_input;
new_wire->port_output = wire->port_output;
- if (wire->attributes.count("\\src"))
- new_wire->attributes["\\src"] = wire->attributes.at("\\src");
+ if (wire->attributes.count(ID::src))
+ new_wire->attributes[ID::src] = wire->attributes.at(ID::src);
- if (wire->attributes.count("\\keep"))
- new_wire->attributes["\\keep"] = wire->attributes.at("\\keep");
+ if (wire->attributes.count(ID::keep))
+ new_wire->attributes[ID::keep] = wire->attributes.at(ID::keep);
- if (wire->attributes.count("\\init")) {
- Const old_init = wire->attributes.at("\\init"), new_init;
+ if (wire->attributes.count(ID::init)) {
+ Const old_init = wire->attributes.at(ID::init), new_init;
for (int i = offset; i < offset+width; i++)
new_init.bits.push_back(i < GetSize(old_init) ? old_init.bits.at(i) : State::Sx);
- new_wire->attributes["\\init"] = new_init;
+ new_wire->attributes[ID::init] = new_init;
}
std::vector<RTLIL::SigBit> sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector();
@@ -141,6 +141,9 @@ struct SplitnetsPass : public Pass {
for (auto module : design->selected_modules())
{
+ if (module->has_processes_warn())
+ continue;
+
SplitnetsWorker worker;
if (flag_ports)
diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc
index c8e4f3981..6c4bc0e5b 100644
--- a/passes/cmds/stat.cc
+++ b/passes/cmds/stat.cc
@@ -79,18 +79,15 @@ struct statdata_t
STAT_NUMERIC_MEMBERS
#undef X
- for (auto &it : mod->wires_)
+ for (auto wire : mod->selected_wires())
{
- if (!design->selected(mod, it.second))
- continue;
-
- if (it.first[0] == '\\') {
+ if (wire->name[0] == '\\') {
num_pub_wires++;
- num_pub_wire_bits += it.second->width;
+ num_pub_wire_bits += wire->width;
}
num_wires++;
- num_wire_bits += it.second->width;
+ num_wire_bits += wire->width;
}
for (auto &it : mod->memories) {
@@ -100,31 +97,28 @@ struct statdata_t
num_memory_bits += it.second->width * it.second->size;
}
- for (auto &it : mod->cells_)
+ for (auto cell : mod->selected_cells())
{
- if (!design->selected(mod, it.second))
- continue;
-
- RTLIL::IdString cell_type = it.second->type;
+ RTLIL::IdString cell_type = cell->type;
if (width_mode)
{
- if (cell_type.in("$not", "$pos", "$neg",
- "$logic_not", "$logic_and", "$logic_or",
- "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
- "$lut", "$and", "$or", "$xor", "$xnor",
- "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
- "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
- "$add", "$sub", "$mul", "$div", "$mod", "$pow", "$alu")) {
- int width_a = it.second->hasPort("\\A") ? GetSize(it.second->getPort("\\A")) : 0;
- int width_b = it.second->hasPort("\\B") ? GetSize(it.second->getPort("\\B")) : 0;
- int width_y = it.second->hasPort("\\Y") ? GetSize(it.second->getPort("\\Y")) : 0;
+ if (cell_type.in(ID($not), ID($pos), ID($neg),
+ ID($logic_not), ID($logic_and), ID($logic_or),
+ ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
+ ID($lut), ID($and), ID($or), ID($xor), ID($xnor),
+ ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
+ ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
+ ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), ID($alu))) {
+ int width_a = cell->hasPort(ID::A) ? GetSize(cell->getPort(ID::A)) : 0;
+ int width_b = cell->hasPort(ID::B) ? GetSize(cell->getPort(ID::B)) : 0;
+ int width_y = cell->hasPort(ID::Y) ? GetSize(cell->getPort(ID::Y)) : 0;
cell_type = stringf("%s_%d", cell_type.c_str(), max<int>({width_a, width_b, width_y}));
}
- else if (cell_type.in("$mux", "$pmux"))
- cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Y")));
- else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr"))
- cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Q")));
+ else if (cell_type.in(ID($mux), ID($pmux)))
+ cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y)));
+ else if (cell_type.in(ID($sr), ID($dff), ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr)))
+ cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q)));
}
if (!cell_area.empty()) {
@@ -157,7 +151,7 @@ struct statdata_t
log(" Number of cells: %6d\n", num_cells);
for (auto &it : num_cells_by_type)
if (it.second)
- log(" %-26s %6d\n", RTLIL::id2cstr(it.first), it.second);
+ log(" %-26s %6d\n", log_id(it.first), it.second);
if (!unknown_cell_area.empty()) {
log("\n");
@@ -172,12 +166,12 @@ struct statdata_t
if (tech == "xilinx")
{
- int lut6_cnt = num_cells_by_type["\\LUT6"];
- int lut5_cnt = num_cells_by_type["\\LUT5"];
- int lut4_cnt = num_cells_by_type["\\LUT4"];
- int lut3_cnt = num_cells_by_type["\\LUT3"];
- int lut2_cnt = num_cells_by_type["\\LUT2"];
- int lut1_cnt = num_cells_by_type["\\LUT1"];
+ int lut6_cnt = num_cells_by_type[ID(LUT6)];
+ int lut5_cnt = num_cells_by_type[ID(LUT5)];
+ int lut4_cnt = num_cells_by_type[ID(LUT4)];
+ int lut3_cnt = num_cells_by_type[ID(LUT3)];
+ int lut2_cnt = num_cells_by_type[ID(LUT2)];
+ int lut1_cnt = num_cells_by_type[ID(LUT1)];
int lc_cnt = 0;
lc_cnt += lut6_cnt;
@@ -235,7 +229,7 @@ struct statdata_t
if (gate_costs.count(ctype))
tran_cnt += cnum * gate_costs.at(ctype);
- else if (ctype.in("$_DFF_P_", "$_DFF_N_"))
+ else if (ctype.in(ID($_DFF_P_), ID($_DFF_N_)))
tran_cnt += cnum * 16;
else
tran_cnt_exact = false;
@@ -255,7 +249,7 @@ statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTL
for (auto &it : num_cells_by_type)
if (mod_stat.count(it.first) > 0) {
- log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, RTLIL::id2cstr(it.first), it.second);
+ log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, log_id(it.first), it.second);
mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1) * it.second;
mod_data.num_cells -= it.second;
} else {
@@ -281,7 +275,7 @@ void read_liberty_cellarea(dict<IdString, double> &cell_area, string liberty_fil
continue;
LibertyAst *ar = cell->find("area");
- if (ar != NULL && !ar->value.empty())
+ if (ar != nullptr && !ar->value.empty())
cell_area["\\" + cell->args[0]] = atof(ar->value.c_str());
}
}
@@ -319,7 +313,7 @@ struct StatPass : public Pass {
log_header(design, "Printing statistics.\n");
bool width_mode = false;
- RTLIL::Module *top_mod = NULL;
+ RTLIL::Module *top_mod = nullptr;
std::map<RTLIL::IdString, statdata_t> mod_stat;
dict<IdString, double> cell_area;
string techname;
@@ -342,9 +336,9 @@ struct StatPass : public Pass {
continue;
}
if (args[argidx] == "-top" && argidx+1 < args.size()) {
- if (design->modules_.count(RTLIL::escape_id(args[argidx+1])) == 0)
+ if (design->module(RTLIL::escape_id(args[argidx+1])) == nullptr)
log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str());
- top_mod = design->modules_.at(RTLIL::escape_id(args[++argidx]));
+ top_mod = design->module(RTLIL::escape_id(args[++argidx]));
continue;
}
break;
@@ -357,25 +351,25 @@ struct StatPass : public Pass {
for (auto mod : design->selected_modules())
{
if (!top_mod && design->full_selection())
- if (mod->get_bool_attribute("\\top"))
+ if (mod->get_bool_attribute(ID::top))
top_mod = mod;
statdata_t data(design, mod, width_mode, cell_area, techname);
mod_stat[mod->name] = data;
log("\n");
- log("=== %s%s ===\n", RTLIL::id2cstr(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)");
+ log("=== %s%s ===\n", log_id(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)");
log("\n");
data.log_data(mod->name, false);
}
- if (top_mod != NULL && GetSize(mod_stat) > 1)
+ if (top_mod != nullptr && GetSize(mod_stat) > 1)
{
log("\n");
log("=== design hierarchy ===\n");
log("\n");
- log(" %-28s %6d\n", RTLIL::id2cstr(top_mod->name), 1);
+ log(" %-28s %6d\n", log_id(top_mod->name), 1);
statdata_t data = hierarchy_worker(mod_stat, top_mod->name, 0);
log("\n");
diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc
index 3c0eac8de..5748ff7f0 100644
--- a/passes/cmds/torder.cc
+++ b/passes/cmds/torder.cc
@@ -81,9 +81,9 @@ struct TorderPass : public Pass {
continue;
if (!noautostop && yosys_celltypes.cell_known(cell->type)) {
- if (conn.first.in("\\Q", "\\CTRL_OUT", "\\RD_DATA"))
+ if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA))
continue;
- if (cell->type == "$memrd" && conn.first == "\\DATA")
+ if (cell->type == ID($memrd) && conn.first == ID::DATA)
continue;
}
diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc
index cf3e46ace..8446e27b3 100644
--- a/passes/cmds/trace.cc
+++ b/passes/cmds/trace.cc
@@ -35,7 +35,7 @@ struct TraceMonitor : public RTLIL::Monitor
log("#TRACE# Module delete: %s\n", log_id(module));
}
- void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
+ void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE
{
log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig));
}
diff --git a/passes/equiv/equiv_add.cc b/passes/equiv/equiv_add.cc
index 71599f46e..cdc74b0b2 100644
--- a/passes/equiv/equiv_add.cc
+++ b/passes/equiv/equiv_add.cc
@@ -152,7 +152,7 @@ struct EquivAddPass : public Pass {
for (int i = 0; i < GetSize(gold_signal); i++) {
Cell *equiv_cell = module->addEquiv(NEW_ID, gold_signal[i], gate_signal[i], equiv_signal[i]);
- equiv_cell->set_bool_attribute("\\keep");
+ equiv_cell->set_bool_attribute(ID::keep);
to_equiv_bits[gold_signal[i]] = equiv_signal[i];
to_equiv_bits[gate_signal[i]] = equiv_signal[i];
added_equiv_cells.insert(equiv_cell);
diff --git a/passes/equiv/equiv_induct.cc b/passes/equiv/equiv_induct.cc
index bcc68d6d2..ec651193e 100644
--- a/passes/equiv/equiv_induct.cc
+++ b/passes/equiv/equiv_induct.cc
@@ -58,9 +58,9 @@ struct EquivInductWorker
log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type));
cell_warn_cache.insert(cell);
}
- if (cell->type == "$equiv") {
- SigBit bit_a = sigmap(cell->getPort("\\A")).as_bit();
- SigBit bit_b = sigmap(cell->getPort("\\B")).as_bit();
+ if (cell->type == ID($equiv)) {
+ SigBit bit_a = sigmap(cell->getPort(ID::A)).as_bit();
+ SigBit bit_b = sigmap(cell->getPort(ID::B)).as_bit();
if (bit_a != bit_b) {
int ez_a = satgen.importSigBit(bit_a, step);
int ez_b = satgen.importSigBit(bit_b, step);
@@ -125,7 +125,7 @@ struct EquivInductWorker
if (!ez->solve(new_step_not_consistent)) {
log(" Proof for induction step holds. Entire workset of %d cells proven!\n", GetSize(workset));
for (auto cell : workset)
- cell->setPort("\\B", cell->getPort("\\A"));
+ cell->setPort(ID::B, cell->getPort(ID::A));
success_counter += GetSize(workset);
return;
}
@@ -137,10 +137,10 @@ struct EquivInductWorker
for (auto cell : workset)
{
- SigBit bit_a = sigmap(cell->getPort("\\A")).as_bit();
- SigBit bit_b = sigmap(cell->getPort("\\B")).as_bit();
+ SigBit bit_a = sigmap(cell->getPort(ID::A)).as_bit();
+ SigBit bit_b = sigmap(cell->getPort(ID::B)).as_bit();
- log(" Trying to prove $equiv for %s:", log_signal(sigmap(cell->getPort("\\Y"))));
+ log(" Trying to prove $equiv for %s:", log_signal(sigmap(cell->getPort(ID::Y))));
int ez_a = satgen.importSigBit(bit_a, max_seq+1);
int ez_b = satgen.importSigBit(bit_b, max_seq+1);
@@ -151,7 +151,7 @@ struct EquivInductWorker
if (!ez->solve(cond)) {
log(" success!\n");
- cell->setPort("\\B", cell->getPort("\\A"));
+ cell->setPort(ID::B, cell->getPort(ID::A));
success_counter++;
} else {
log(" failed.\n");
@@ -219,8 +219,8 @@ struct EquivInductPass : public Pass {
pool<Cell*> unproven_equiv_cells;
for (auto cell : module->selected_cells())
- if (cell->type == "$equiv") {
- if (cell->getPort("\\A") != cell->getPort("\\B"))
+ if (cell->type == ID($equiv)) {
+ if (cell->getPort(ID::A) != cell->getPort(ID::B))
unproven_equiv_cells.insert(cell);
}
diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc
index 4855ce29e..50572ae5c 100644
--- a/passes/equiv/equiv_make.cc
+++ b/passes/equiv/equiv_make.cc
@@ -406,7 +406,7 @@ struct EquivMakeWorker
void init_bit2driven()
{
for (auto cell : equiv_mod->cells()) {
- if (!ct.cell_known(cell->type) && !cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_"))
+ if (!ct.cell_known(cell->type) && !cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_)))
continue;
for (auto &conn : cell->connections())
{
diff --git a/passes/equiv/equiv_mark.cc b/passes/equiv/equiv_mark.cc
index 135eaf145..737de25d9 100644
--- a/passes/equiv/equiv_mark.cc
+++ b/passes/equiv/equiv_mark.cc
@@ -48,7 +48,7 @@ struct EquivMarkWorker
{
for (auto cell : module->cells())
{
- if (cell->type == "$equiv")
+ if (cell->type == ID($equiv))
equiv_cells.insert(cell->name);
for (auto &port : cell->connections())
@@ -122,8 +122,8 @@ struct EquivMarkWorker
{
auto cell = module->cell(cell_name);
- SigSpec sig_a = sigmap(cell->getPort("\\A"));
- SigSpec sig_b = sigmap(cell->getPort("\\B"));
+ SigSpec sig_a = sigmap(cell->getPort(ID::A));
+ SigSpec sig_b = sigmap(cell->getPort(ID::B));
if (sig_a == sig_b) {
for (auto bit : sig_a)
@@ -139,11 +139,11 @@ struct EquivMarkWorker
for (auto cell : module->cells())
{
- if (cell_regions.count(cell->name) || cell->type != "$equiv")
+ if (cell_regions.count(cell->name) || cell->type != ID($equiv))
continue;
- SigSpec sig_a = sigmap(cell->getPort("\\A"));
- SigSpec sig_b = sigmap(cell->getPort("\\B"));
+ SigSpec sig_a = sigmap(cell->getPort(ID::A));
+ SigSpec sig_b = sigmap(cell->getPort(ID::B));
log_assert(sig_a != sig_b);
@@ -176,10 +176,10 @@ struct EquivMarkWorker
{
if (cell_regions.count(cell->name)) {
int r = final_region_map.at(cell_regions.at(cell->name));
- cell->attributes["\\equiv_region"] = Const(r);
+ cell->attributes[ID::equiv_region] = Const(r);
region_cell_count[r]++;
} else
- cell->attributes.erase("\\equiv_region");
+ cell->attributes.erase(ID::equiv_region);
}
for (auto wire : module->wires())
@@ -191,10 +191,10 @@ struct EquivMarkWorker
if (GetSize(regions) == 1) {
int r = final_region_map.at(*regions.begin());
- wire->attributes["\\equiv_region"] = Const(r);
+ wire->attributes[ID::equiv_region] = Const(r);
region_wire_count[r]++;
} else
- wire->attributes.erase("\\equiv_region");
+ wire->attributes.erase(ID::equiv_region);
}
for (int i = 0; i < next_final_region; i++)
diff --git a/passes/equiv/equiv_miter.cc b/passes/equiv/equiv_miter.cc
index e06f9515b..085970189 100644
--- a/passes/equiv/equiv_miter.cc
+++ b/passes/equiv/equiv_miter.cc
@@ -47,7 +47,7 @@ struct EquivMiterWorker
if (cone.count(c))
return;
- if (c->type == "$equiv" && !seed_cells.count(c)) {
+ if (c->type == ID($equiv) && !seed_cells.count(c)) {
leaves.insert(c);
return;
}
@@ -57,7 +57,7 @@ struct EquivMiterWorker
for (auto &conn : c->connections()) {
if (!ct.cell_input(c->type, conn.first))
continue;
- if (c->type == "$equiv" && (conn.first == "\\A") != gold_mode)
+ if (c->type == ID($equiv) && (conn.first == ID::A) != gold_mode)
continue;
for (auto bit : sigmap(conn.second))
if (bit_to_driver.count(bit))
@@ -81,7 +81,7 @@ struct EquivMiterWorker
// find seed cells
for (auto c : source_module->selected_cells())
- if (c->type == "$equiv") {
+ if (c->type == ID($equiv)) {
log("Seed $equiv cell: %s\n", log_id(c));
seed_cells.insert(c);
}
@@ -213,18 +213,18 @@ struct EquivMiterWorker
vector<Cell*> equiv_cells;
for (auto c : miter_module->cells())
- if (c->type == "$equiv" && c->getPort("\\A") != c->getPort("\\B"))
+ if (c->type == ID($equiv) && c->getPort(ID::A) != c->getPort(ID::B))
equiv_cells.push_back(c);
for (auto c : equiv_cells)
{
SigSpec cmp = mode_undef ?
- miter_module->LogicOr(NEW_ID, miter_module->Eqx(NEW_ID, c->getPort("\\A"), State::Sx),
- miter_module->Eqx(NEW_ID, c->getPort("\\A"), c->getPort("\\B"))) :
- miter_module->Eq(NEW_ID, c->getPort("\\A"), c->getPort("\\B"));
+ miter_module->LogicOr(NEW_ID, miter_module->Eqx(NEW_ID, c->getPort(ID::A), State::Sx),
+ miter_module->Eqx(NEW_ID, c->getPort(ID::A), c->getPort(ID::B))) :
+ miter_module->Eq(NEW_ID, c->getPort(ID::A), c->getPort(ID::B));
if (mode_cmp) {
- string cmp_name = string("\\cmp") + log_signal(c->getPort("\\Y"));
+ string cmp_name = stringf("\\cmp%s", log_signal(c->getPort(ID::Y)));
for (int i = 1; i < GetSize(cmp_name); i++)
if (cmp_name[i] == '\\')
cmp_name[i] = '_';
@@ -242,7 +242,7 @@ struct EquivMiterWorker
}
if (mode_trigger) {
- auto w = miter_module->addWire("\\trigger");
+ auto w = miter_module->addWire(ID(trigger));
w->port_output = true;
miter_module->addReduceOr(NEW_ID, trigger_signals, w);
}
diff --git a/passes/equiv/equiv_purge.cc b/passes/equiv/equiv_purge.cc
index 18b3e7d36..688c20f43 100644
--- a/passes/equiv/equiv_purge.cc
+++ b/passes/equiv/equiv_purge.cc
@@ -102,7 +102,7 @@ struct EquivPurgeWorker
for (auto cell : module->cells())
{
- if (cell->type != "$equiv") {
+ if (cell->type != ID($equiv)) {
for (auto &port : cell->connections()) {
if (cell->input(port.first))
for (auto bit : sigmap(port.second))
@@ -114,9 +114,9 @@ struct EquivPurgeWorker
continue;
}
- SigSpec sig_a = sigmap(cell->getPort("\\A"));
- SigSpec sig_b = sigmap(cell->getPort("\\B"));
- SigSpec sig_y = sigmap(cell->getPort("\\Y"));
+ SigSpec sig_a = sigmap(cell->getPort(ID::A));
+ SigSpec sig_b = sigmap(cell->getPort(ID::B));
+ SigSpec sig_y = sigmap(cell->getPort(ID::Y));
if (sig_a == sig_b)
continue;
@@ -130,7 +130,7 @@ struct EquivPurgeWorker
for (auto bit : sig_y)
visited.insert(bit);
- cell->setPort("\\Y", make_output(sig_y, cell->name));
+ cell->setPort(ID::Y, make_output(sig_y, cell->name));
}
SigSpec srcsig;
@@ -167,8 +167,8 @@ struct EquivPurgeWorker
rewrite_sigmap.add(chunk, make_input(chunk));
for (auto cell : module->cells())
- if (cell->type == "$equiv")
- cell->setPort("\\Y", rewrite_sigmap(sigmap(cell->getPort("\\Y"))));
+ if (cell->type == ID($equiv))
+ cell->setPort(ID::Y, rewrite_sigmap(sigmap(cell->getPort(ID::Y))));
module->fixup_ports();
}
diff --git a/passes/equiv/equiv_remove.cc b/passes/equiv/equiv_remove.cc
index c5c28c7d9..6daa112b5 100644
--- a/passes/equiv/equiv_remove.cc
+++ b/passes/equiv/equiv_remove.cc
@@ -68,9 +68,9 @@ struct EquivRemovePass : public Pass {
for (auto module : design->selected_modules())
{
for (auto cell : module->selected_cells())
- if (cell->type == "$equiv" && (mode_gold || mode_gate || cell->getPort("\\A") == cell->getPort("\\B"))) {
- log("Removing $equiv cell %s.%s (%s).\n", log_id(module), log_id(cell), log_signal(cell->getPort("\\Y")));
- module->connect(cell->getPort("\\Y"), mode_gate ? cell->getPort("\\B") : cell->getPort("\\A"));
+ if (cell->type == ID($equiv) && (mode_gold || mode_gate || cell->getPort(ID::A) == cell->getPort(ID::B))) {
+ log("Removing $equiv cell %s.%s (%s).\n", log_id(module), log_id(cell), log_signal(cell->getPort(ID::Y)));
+ module->connect(cell->getPort(ID::Y), mode_gate ? cell->getPort(ID::B) : cell->getPort(ID::A));
module->remove(cell);
remove_count++;
}
diff --git a/passes/equiv/equiv_simple.cc b/passes/equiv/equiv_simple.cc
index c2fab26f2..4d2839f4d 100644
--- a/passes/equiv/equiv_simple.cc
+++ b/passes/equiv/equiv_simple.cc
@@ -60,8 +60,8 @@ struct EquivSimpleWorker
for (auto &conn : cell->connections())
if (yosys_celltypes.cell_input(cell->type, conn.first))
for (auto bit : sigmap(conn.second)) {
- if (cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_")) {
- if (!conn.first.in("\\CLK", "\\C"))
+ if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_))) {
+ if (!conn.first.in(ID::CLK, ID::C))
next_seed.insert(bit);
} else
find_input_cone(next_seed, cells_cone, bits_cone, cells_stop, bits_stop, input_bits, bit);
@@ -90,8 +90,8 @@ struct EquivSimpleWorker
bool run_cell()
{
- SigBit bit_a = sigmap(equiv_cell->getPort("\\A")).as_bit();
- SigBit bit_b = sigmap(equiv_cell->getPort("\\B")).as_bit();
+ SigBit bit_a = sigmap(equiv_cell->getPort(ID::A)).as_bit();
+ SigBit bit_b = sigmap(equiv_cell->getPort(ID::B)).as_bit();
int ez_context = ez->frozen_literal();
if (satgen.model_undef)
@@ -115,9 +115,9 @@ struct EquivSimpleWorker
if (verbose) {
log(" Trying to prove $equiv cell %s:\n", log_id(equiv_cell));
- log(" A = %s, B = %s, Y = %s\n", log_signal(bit_a), log_signal(bit_b), log_signal(equiv_cell->getPort("\\Y")));
+ log(" A = %s, B = %s, Y = %s\n", log_signal(bit_a), log_signal(bit_b), log_signal(equiv_cell->getPort(ID::Y)));
} else {
- log(" Trying to prove $equiv for %s:", log_signal(equiv_cell->getPort("\\Y")));
+ log(" Trying to prove $equiv for %s:", log_signal(equiv_cell->getPort(ID::Y)));
}
int step = max_seq;
@@ -199,7 +199,7 @@ struct EquivSimpleWorker
if (!ez->solve(ez_context)) {
log(verbose ? " Proved equivalence! Marking $equiv cell as proven.\n" : " success!\n");
- equiv_cell->setPort("\\B", equiv_cell->getPort("\\A"));
+ equiv_cell->setPort(ID::B, equiv_cell->getPort(ID::A));
ez->assume(ez->NOT(ez_context));
return true;
}
@@ -256,7 +256,7 @@ struct EquivSimpleWorker
if (GetSize(equiv_cells) > 1) {
SigSpec sig;
for (auto c : equiv_cells)
- sig.append(sigmap(c->getPort("\\Y")));
+ sig.append(sigmap(c->getPort(ID::Y)));
log(" Grouping SAT models for %s:\n", log_signal(sig));
}
@@ -344,8 +344,8 @@ struct EquivSimplePass : public Pass {
int unproven_cells_counter = 0;
for (auto cell : module->selected_cells())
- if (cell->type == "$equiv" && cell->getPort("\\A") != cell->getPort("\\B")) {
- auto bit = sigmap(cell->getPort("\\Y").as_bit());
+ if (cell->type == ID($equiv) && cell->getPort(ID::A) != cell->getPort(ID::B)) {
+ auto bit = sigmap(cell->getPort(ID::Y).as_bit());
auto bit_group = bit;
if (!nogroup && bit_group.wire)
bit_group.offset = 0;
@@ -360,7 +360,7 @@ struct EquivSimplePass : public Pass {
unproven_cells_counter, GetSize(unproven_equiv_cells), log_id(module));
for (auto cell : module->cells()) {
- if (!ct.cell_known(cell->type) && !cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_"))
+ if (!ct.cell_known(cell->type) && !cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_)))
continue;
for (auto &conn : cell->connections())
if (yosys_celltypes.cell_output(cell->type, conn.first))
diff --git a/passes/equiv/equiv_status.cc b/passes/equiv/equiv_status.cc
index b4a93ccf5..258e2e45b 100644
--- a/passes/equiv/equiv_status.cc
+++ b/passes/equiv/equiv_status.cc
@@ -59,8 +59,8 @@ struct EquivStatusPass : public Pass {
int proven_equiv_cells = 0;
for (auto cell : module->selected_cells())
- if (cell->type == "$equiv") {
- if (cell->getPort("\\A") != cell->getPort("\\B"))
+ if (cell->type == ID($equiv)) {
+ if (cell->getPort(ID::A) != cell->getPort(ID::B))
unproven_equiv_cells.push_back(cell);
else
proven_equiv_cells++;
@@ -77,7 +77,7 @@ struct EquivStatusPass : public Pass {
log(" Equivalence successfully proven!\n");
} else {
for (auto cell : unproven_equiv_cells)
- log(" Unproven $equiv %s: %s %s\n", log_id(cell), log_signal(cell->getPort("\\A")), log_signal(cell->getPort("\\B")));
+ log(" Unproven $equiv %s: %s %s\n", log_id(cell), log_signal(cell->getPort(ID::A)), log_signal(cell->getPort(ID::B)));
}
unproven_count += GetSize(unproven_equiv_cells);
diff --git a/passes/equiv/equiv_struct.cc b/passes/equiv/equiv_struct.cc
index 6672948b9..1b7bf96a8 100644
--- a/passes/equiv/equiv_struct.cc
+++ b/passes/equiv/equiv_struct.cc
@@ -110,9 +110,9 @@ struct EquivStructWorker
module->connect(sig_b, sig_a);
}
- auto merged_attr = cell_b->get_strpool_attribute("\\equiv_merged");
+ auto merged_attr = cell_b->get_strpool_attribute(ID::equiv_merged);
merged_attr.insert(log_id(cell_b));
- cell_a->add_strpool_attribute("\\equiv_merged", merged_attr);
+ cell_a->add_strpool_attribute(ID::equiv_merged, merged_attr);
module->remove(cell_b);
}
@@ -126,9 +126,9 @@ struct EquivStructWorker
pool<IdString> cells;
for (auto cell : module->selected_cells())
- if (cell->type == "$equiv") {
- SigBit sig_a = sigmap(cell->getPort("\\A").as_bit());
- SigBit sig_b = sigmap(cell->getPort("\\B").as_bit());
+ if (cell->type == ID($equiv)) {
+ SigBit sig_a = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit sig_b = sigmap(cell->getPort(ID::B).as_bit());
equiv_bits.add(sig_b, sig_a);
equiv_inputs.insert(sig_a);
equiv_inputs.insert(sig_b);
@@ -139,10 +139,10 @@ struct EquivStructWorker
}
for (auto cell : module->selected_cells())
- if (cell->type == "$equiv") {
- SigBit sig_a = sigmap(cell->getPort("\\A").as_bit());
- SigBit sig_b = sigmap(cell->getPort("\\B").as_bit());
- SigBit sig_y = sigmap(cell->getPort("\\Y").as_bit());
+ if (cell->type == ID($equiv)) {
+ SigBit sig_a = sigmap(cell->getPort(ID::A).as_bit());
+ SigBit sig_b = sigmap(cell->getPort(ID::B).as_bit());
+ SigBit sig_y = sigmap(cell->getPort(ID::Y).as_bit());
if (sig_a == sig_b && equiv_inputs.count(sig_y)) {
log(" Purging redundant $equiv cell %s.\n", log_id(cell));
module->connect(sig_y, sig_a);
@@ -316,7 +316,7 @@ struct EquivStructPass : public Pass {
}
void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE
{
- pool<IdString> fwonly_cells({ "$equiv" });
+ pool<IdString> fwonly_cells({ ID($equiv) });
bool mode_icells = false;
bool mode_fwd = false;
int max_iter = -1;
diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc
index a1c8067b4..30e9e4dad 100644
--- a/passes/fsm/fsm_detect.cc
+++ b/passes/fsm/fsm_detect.cc
@@ -55,7 +55,7 @@ ret_false:
sig2driver.find(sig, cellport_list);
for (auto &cellport : cellport_list)
{
- if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux") || cellport.second != "\\Y") {
+ if ((cellport.first->type != ID($mux) && cellport.first->type != ID($pmux)) || cellport.second != ID::Y) {
goto ret_false;
}
@@ -67,8 +67,8 @@ ret_false:
recursion_monitor.insert(cellport.first);
- RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A"));
- RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B"));
+ RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort(ID::A));
+ RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort(ID::B));
if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor, mux_tree_cache)) {
recursion_monitor.erase(cellport.first);
@@ -99,18 +99,18 @@ static bool check_state_users(RTLIL::SigSpec sig)
RTLIL::Cell *cell = cellport.first;
if (muxtree_cells.count(cell) > 0)
continue;
- if (cell->type == "$logic_not" && assign_map(cell->getPort("\\A")) == sig)
+ if (cell->type == ID($logic_not) && assign_map(cell->getPort(ID::A)) == sig)
continue;
- if (cellport.second != "\\A" && cellport.second != "\\B")
+ if (cellport.second != ID::A && cellport.second != ID::B)
return false;
- if (!cell->hasPort("\\A") || !cell->hasPort("\\B") || !cell->hasPort("\\Y"))
+ if (!cell->hasPort(ID::A) || !cell->hasPort(ID::B) || !cell->hasPort(ID::Y))
return false;
for (auto &port_it : cell->connections())
- if (port_it.first != "\\A" && port_it.first != "\\B" && port_it.first != "\\Y")
+ if (port_it.first != ID::A && port_it.first != ID::B && port_it.first != ID::Y)
return false;
- if (assign_map(cell->getPort("\\A")) == sig && cell->getPort("\\B").is_fully_const())
+ if (assign_map(cell->getPort(ID::A)) == sig && cell->getPort(ID::B).is_fully_const())
continue;
- if (assign_map(cell->getPort("\\B")) == sig && cell->getPort("\\A").is_fully_const())
+ if (assign_map(cell->getPort(ID::B)) == sig && cell->getPort(ID::A).is_fully_const())
continue;
return false;
}
@@ -120,9 +120,9 @@ static bool check_state_users(RTLIL::SigSpec sig)
static void detect_fsm(RTLIL::Wire *wire)
{
- bool has_fsm_encoding_attr = wire->attributes.count("\\fsm_encoding") > 0 && wire->attributes.at("\\fsm_encoding").decode_string() != "none";
- bool has_fsm_encoding_none = wire->attributes.count("\\fsm_encoding") > 0 && wire->attributes.at("\\fsm_encoding").decode_string() == "none";
- bool has_init_attr = wire->attributes.count("\\init") > 0;
+ bool has_fsm_encoding_attr = wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes.at(ID::fsm_encoding).decode_string() != "none";
+ bool has_fsm_encoding_none = wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes.at(ID::fsm_encoding).decode_string() == "none";
+ bool has_init_attr = wire->attributes.count(ID::init) > 0;
bool is_module_port = sig_at_port.check_any(assign_map(RTLIL::SigSpec(wire)));
bool looks_like_state_reg = false, looks_like_good_state_reg = false;
bool is_self_resetting = false;
@@ -133,7 +133,7 @@ static void detect_fsm(RTLIL::Wire *wire)
if (wire->width <= 1) {
if (has_fsm_encoding_attr) {
log_warning("Removing fsm_encoding attribute from 1-bit net: %s.%s\n", log_id(wire->module), log_id(wire));
- wire->attributes.erase("\\fsm_encoding");
+ wire->attributes.erase(ID::fsm_encoding);
}
return;
}
@@ -143,13 +143,13 @@ static void detect_fsm(RTLIL::Wire *wire)
for (auto &cellport : cellport_list)
{
- if ((cellport.first->type != "$dff" && cellport.first->type != "$adff") || cellport.second != "\\Q")
+ if ((cellport.first->type != ID($dff) && cellport.first->type != ID($adff)) || cellport.second != ID::Q)
continue;
muxtree_cells.clear();
pool<Cell*> recursion_monitor;
- RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort("\\Q"));
- RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort("\\D"));
+ RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort(ID::Q));
+ RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort(ID::D));
dict<RTLIL::SigSpec, bool> mux_tree_cache;
if (sig_q != assign_map(wire))
@@ -173,10 +173,10 @@ static void detect_fsm(RTLIL::Wire *wire)
RTLIL::Cell *cell = cellport.first;
bool set_output = false, clr_output = false;
- if (cell->type.in("$ne", "$reduce_or", "$reduce_bool"))
+ if (cell->type.in(ID($ne), ID($reduce_or), ID($reduce_bool)))
set_output = true;
- if (cell->type.in("$eq", "$logic_not", "$reduce_and"))
+ if (cell->type.in(ID($eq), ID($logic_not), ID($reduce_and)))
clr_output = true;
if (set_output || clr_output) {
@@ -234,7 +234,7 @@ static void detect_fsm(RTLIL::Wire *wire)
if (looks_like_state_reg && looks_like_good_state_reg && !has_init_attr && !is_module_port && !is_self_resetting)
{
log("Found FSM state register %s.%s.\n", log_id(wire->module), log_id(wire));
- wire->attributes["\\fsm_encoding"] = RTLIL::Const("auto");
+ wire->attributes[ID::fsm_encoding] = RTLIL::Const("auto");
}
else
if (looks_like_state_reg)
@@ -284,38 +284,34 @@ struct FsmDetectPass : public Pass {
ct.setup_stdcells();
ct.setup_stdcells_mem();
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->selected_modules())
{
- if (!design->selected(mod_it.second))
- continue;
-
- module = mod_it.second;
+ module = mod;
assign_map.set(module);
sig2driver.clear();
sig2user.clear();
sig_at_port.clear();
- for (auto &cell_it : module->cells_)
- for (auto &conn_it : cell_it.second->connections()) {
- if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) {
+ for (auto cell : module->cells())
+ for (auto &conn_it : cell->connections()) {
+ if (ct.cell_output(cell->type, conn_it.first) || !ct.cell_known(cell->type)) {
RTLIL::SigSpec sig = conn_it.second;
assign_map.apply(sig);
- sig2driver.insert(sig, sig2driver_entry_t(cell_it.second, conn_it.first));
+ sig2driver.insert(sig, sig2driver_entry_t(cell, conn_it.first));
}
- if (!ct.cell_known(cell_it.second->type) || ct.cell_input(cell_it.second->type, conn_it.first)) {
+ if (!ct.cell_known(cell->type) || ct.cell_input(cell->type, conn_it.first)) {
RTLIL::SigSpec sig = conn_it.second;
assign_map.apply(sig);
- sig2user.insert(sig, sig2driver_entry_t(cell_it.second, conn_it.first));
+ sig2user.insert(sig, sig2driver_entry_t(cell, conn_it.first));
}
}
- for (auto &wire_it : module->wires_)
- if (wire_it.second->port_id != 0)
- sig_at_port.add(assign_map(RTLIL::SigSpec(wire_it.second)));
+ for (auto wire : module->wires())
+ if (wire->port_id != 0)
+ sig_at_port.add(assign_map(wire));
- for (auto &wire_it : module->wires_)
- if (design->selected(module, wire_it.second))
- detect_fsm(wire_it.second);
+ for (auto wire : module->selected_wires())
+ detect_fsm(wire);
}
assign_map.clear();
diff --git a/passes/fsm/fsm_expand.cc b/passes/fsm/fsm_expand.cc
index 1610ec751..ade6c17f5 100644
--- a/passes/fsm/fsm_expand.cc
+++ b/passes/fsm/fsm_expand.cc
@@ -47,42 +47,42 @@ struct FsmExpand
bool is_cell_merge_candidate(RTLIL::Cell *cell)
{
- if (full_mode || cell->type == "$_MUX_")
+ if (full_mode || cell->type == ID($_MUX_))
return true;
- if (cell->type.in("$mux", "$pmux"))
- if (cell->getPort("\\A").size() < 2)
+ if (cell->type.in(ID($mux), ID($pmux)))
+ if (cell->getPort(ID::A).size() < 2)
return true;
int in_bits = 0;
RTLIL::SigSpec new_signals;
- if (cell->hasPort("\\A")) {
- in_bits += GetSize(cell->getPort("\\A"));
- new_signals.append(assign_map(cell->getPort("\\A")));
+ if (cell->hasPort(ID::A)) {
+ in_bits += GetSize(cell->getPort(ID::A));
+ new_signals.append(assign_map(cell->getPort(ID::A)));
}
- if (cell->hasPort("\\B")) {
- in_bits += GetSize(cell->getPort("\\B"));
- new_signals.append(assign_map(cell->getPort("\\B")));
+ if (cell->hasPort(ID::B)) {
+ in_bits += GetSize(cell->getPort(ID::B));
+ new_signals.append(assign_map(cell->getPort(ID::B)));
}
- if (cell->hasPort("\\S")) {
- in_bits += GetSize(cell->getPort("\\S"));
- new_signals.append(assign_map(cell->getPort("\\S")));
+ if (cell->hasPort(ID::S)) {
+ in_bits += GetSize(cell->getPort(ID::S));
+ new_signals.append(assign_map(cell->getPort(ID::S)));
}
if (in_bits > 8)
return false;
- if (cell->hasPort("\\Y"))
- new_signals.append(assign_map(cell->getPort("\\Y")));
+ if (cell->hasPort(ID::Y))
+ new_signals.append(assign_map(cell->getPort(ID::Y)));
new_signals.sort_and_unify();
new_signals.remove_const();
- new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_IN")));
- new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_OUT")));
+ new_signals.remove(assign_map(fsm_cell->getPort(ID::CTRL_IN)));
+ new_signals.remove(assign_map(fsm_cell->getPort(ID::CTRL_OUT)));
if (new_signals.size() > 3)
return false;
@@ -94,10 +94,10 @@ struct FsmExpand
{
std::vector<RTLIL::Cell*> cell_list;
- for (auto c : sig2driver.find(assign_map(fsm_cell->getPort("\\CTRL_IN"))))
+ for (auto c : sig2driver.find(assign_map(fsm_cell->getPort(ID::CTRL_IN))))
cell_list.push_back(c);
- for (auto c : sig2user.find(assign_map(fsm_cell->getPort("\\CTRL_OUT"))))
+ for (auto c : sig2user.find(assign_map(fsm_cell->getPort(ID::CTRL_OUT))))
cell_list.push_back(c);
current_set.clear();
@@ -106,7 +106,7 @@ struct FsmExpand
if (merged_set.count(c) > 0 || current_set.count(c) > 0 || no_candidate_set.count(c) > 0)
continue;
for (auto &p : c->connections()) {
- if (p.first != "\\A" && p.first != "\\B" && p.first != "\\S" && p.first != "\\Y")
+ if (p.first != ID::A && p.first != ID::B && p.first != ID::S && p.first != ID::Y)
goto next_cell;
}
if (!is_cell_merge_candidate(c)) {
@@ -123,14 +123,14 @@ struct FsmExpand
if (already_optimized)
return;
- int trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
+ int trans_num = fsm_cell->parameters[ID::TRANS_NUM].as_int();
if (trans_num > limit_transitions)
{
log(" grown transition table to %d entries -> optimize.\n", trans_num);
FsmData::optimize_fsm(fsm_cell, module);
already_optimized = true;
- trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
+ trans_num = fsm_cell->parameters[ID::TRANS_NUM].as_int();
log(" transition table size after optimizaton: %d\n", trans_num);
limit_transitions = 16 * trans_num;
}
@@ -159,12 +159,12 @@ struct FsmExpand
for (int i = 0; i < (1 << input_sig.size()); i++) {
RTLIL::Const in_val(i, input_sig.size());
RTLIL::SigSpec A, B, S;
- if (cell->hasPort("\\A"))
- A = assign_map(cell->getPort("\\A"));
- if (cell->hasPort("\\B"))
- B = assign_map(cell->getPort("\\B"));
- if (cell->hasPort("\\S"))
- S = assign_map(cell->getPort("\\S"));
+ if (cell->hasPort(ID::A))
+ A = assign_map(cell->getPort(ID::A));
+ if (cell->hasPort(ID::B))
+ B = assign_map(cell->getPort(ID::B));
+ if (cell->hasPort(ID::S))
+ S = assign_map(cell->getPort(ID::S));
A.replace(input_sig, RTLIL::SigSpec(in_val));
B.replace(input_sig, RTLIL::SigSpec(in_val));
S.replace(input_sig, RTLIL::SigSpec(in_val));
@@ -178,14 +178,14 @@ struct FsmExpand
fsm_data.copy_from_cell(fsm_cell);
fsm_data.num_inputs += input_sig.size();
- RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort("\\CTRL_IN");
+ RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort(ID::CTRL_IN);
new_ctrl_in.append(input_sig);
- fsm_cell->setPort("\\CTRL_IN", new_ctrl_in);
+ fsm_cell->setPort(ID::CTRL_IN, new_ctrl_in);
fsm_data.num_outputs += output_sig.size();
- RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort("\\CTRL_OUT");
+ RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort(ID::CTRL_OUT);
new_ctrl_out.append(output_sig);
- fsm_cell->setPort("\\CTRL_OUT", new_ctrl_out);
+ fsm_cell->setPort(ID::CTRL_OUT, new_ctrl_out);
if (GetSize(input_sig) > 10)
log_warning("Cell %s.%s (%s) has %d input bits, merging into FSM %s.%s might be problematic.\n",
@@ -246,7 +246,7 @@ struct FsmExpand
log("Expanding FSM `%s' from module `%s':\n", fsm_cell->name.c_str(), module->name.c_str());
already_optimized = false;
- limit_transitions = 16 * fsm_cell->parameters["\\TRANS_NUM"].as_int();
+ limit_transitions = 16 * fsm_cell->parameters[ID::TRANS_NUM].as_int();
for (create_current_set(); current_set.size() > 0; create_current_set()) {
for (auto c : current_set)
@@ -295,15 +295,13 @@ struct FsmExpandPass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &mod_it : design->modules_) {
- if (!design->selected(mod_it.second))
- continue;
+ for (auto mod : design->selected_modules()) {
std::vector<RTLIL::Cell*> fsm_cells;
- for (auto &cell_it : mod_it.second->cells_)
- if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
- fsm_cells.push_back(cell_it.second);
+ for (auto cell : mod->selected_cells())
+ if (cell->type == ID($fsm))
+ fsm_cells.push_back(cell);
for (auto c : fsm_cells) {
- FsmExpand fsm_expand(c, design, mod_it.second, full_mode);
+ FsmExpand fsm_expand(c, design, mod, full_mode);
fsm_expand.execute();
}
}
diff --git a/passes/fsm/fsm_export.cc b/passes/fsm/fsm_export.cc
index 8eb1872f0..c02a54ea2 100644
--- a/passes/fsm/fsm_export.cc
+++ b/passes/fsm/fsm_export.cc
@@ -57,7 +57,7 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st
std::string kiss_name;
size_t i;
- attr_it = cell->attributes.find("\\fsm_export");
+ attr_it = cell->attributes.find(ID::fsm_export);
if (!filename.empty()) {
kiss_name.assign(filename);
} else if (attr_it != cell->attributes.end() && attr_it->second.decode_string() != "") {
@@ -173,16 +173,15 @@ struct FsmExportPass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
- for (auto &cell_it : mod_it.second->cells_)
- if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) {
- attr_it = cell_it.second->attributes.find("\\fsm_export");
- if (!flag_noauto || (attr_it != cell_it.second->attributes.end())) {
- write_kiss2(mod_it.second, cell_it.second, filename, flag_origenc);
- filename.clear();
- }
+ for (auto mod : design->selected_modules())
+ for (auto cell : mod->selected_cells())
+ if (cell->type == ID($fsm)) {
+ attr_it = cell->attributes.find(ID::fsm_export);
+ if (!flag_noauto || (attr_it != cell->attributes.end())) {
+ write_kiss2(mod, cell, filename, flag_origenc);
+ filename.clear();
}
+ }
}
} FsmExportPass;
diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc
index 0f7b4d106..3840aabc8 100644
--- a/passes/fsm/fsm_extract.cc
+++ b/passes/fsm/fsm_extract.cc
@@ -70,15 +70,15 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL
for (auto &cellport : cellport_list)
{
RTLIL::Cell *cell = module->cells_.at(cellport.first);
- if ((cell->type != "$mux" && cell->type != "$pmux") || cellport.second != "\\Y") {
+ if ((cell->type != ID($mux) && cell->type != ID($pmux)) || cellport.second != ID::Y) {
log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str());
return false;
}
- RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
- RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B"));
- RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S"));
- RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y"));
+ RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
+ RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
+ RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID::S));
+ RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
RTLIL::SigSpec sig_aa = sig;
sig_aa.replace(sig_y, sig_a);
@@ -272,17 +272,17 @@ static void extract_fsm(RTLIL::Wire *wire)
sig2driver.find(dff_out, cellport_list);
for (auto &cellport : cellport_list) {
RTLIL::Cell *cell = module->cells_.at(cellport.first);
- if ((cell->type != "$dff" && cell->type != "$adff") || cellport.second != "\\Q")
+ if ((cell->type != ID($dff) && cell->type != ID($adff)) || cellport.second != ID::Q)
continue;
log(" found %s cell for state register: %s\n", cell->type.c_str(), cell->name.c_str());
- RTLIL::SigSpec sig_q = assign_map(cell->getPort("\\Q"));
- RTLIL::SigSpec sig_d = assign_map(cell->getPort("\\D"));
- clk = cell->getPort("\\CLK");
- clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
- if (cell->type == "$adff") {
- arst = cell->getPort("\\ARST");
- arst_polarity = cell->parameters["\\ARST_POLARITY"].as_bool();
- reset_state = cell->parameters["\\ARST_VALUE"];
+ RTLIL::SigSpec sig_q = assign_map(cell->getPort(ID::Q));
+ RTLIL::SigSpec sig_d = assign_map(cell->getPort(ID::D));
+ clk = cell->getPort(ID::CLK);
+ clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool();
+ if (cell->type == ID($adff)) {
+ arst = cell->getPort(ID::ARST);
+ arst_polarity = cell->parameters[ID::ARST_POLARITY].as_bool();
+ reset_state = cell->parameters[ID::ARST_VALUE];
}
sig_q.replace(dff_out, sig_d, &dff_in);
break;
@@ -320,14 +320,14 @@ static void extract_fsm(RTLIL::Wire *wire)
sig2trigger.find(dff_out, cellport_list);
for (auto &cellport : cellport_list) {
RTLIL::Cell *cell = module->cells_.at(cellport.first);
- RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
+ RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b;
- if (cell->hasPort("\\B"))
- sig_b = assign_map(cell->getPort("\\B"));
- RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y"));
- if (cellport.second == "\\A" && !sig_b.is_fully_const())
+ if (cell->hasPort(ID::B))
+ sig_b = assign_map(cell->getPort(ID::B));
+ RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
+ if (cellport.second == ID::A && !sig_b.is_fully_const())
continue;
- if (cellport.second == "\\B" && !sig_a.is_fully_const())
+ if (cellport.second == ID::B && !sig_a.is_fully_const())
continue;
log(" found ctrl output: %s\n", log_signal(sig_y));
ctrl_out.append(sig_y);
@@ -368,21 +368,21 @@ static void extract_fsm(RTLIL::Wire *wire)
// create fsm cell
- RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm");
- fsm_cell->setPort("\\CLK", clk);
- fsm_cell->setPort("\\ARST", arst);
- fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? State::S1 : State::S0;
- fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? State::S1 : State::S0;
- fsm_cell->setPort("\\CTRL_IN", ctrl_in);
- fsm_cell->setPort("\\CTRL_OUT", ctrl_out);
- fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str());
+ RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), ID($fsm));
+ fsm_cell->setPort(ID::CLK, clk);
+ fsm_cell->setPort(ID::ARST, arst);
+ fsm_cell->parameters[ID::CLK_POLARITY] = clk_polarity ? State::S1 : State::S0;
+ fsm_cell->parameters[ID::ARST_POLARITY] = arst_polarity ? State::S1 : State::S0;
+ fsm_cell->setPort(ID::CTRL_IN, ctrl_in);
+ fsm_cell->setPort(ID::CTRL_OUT, ctrl_out);
+ fsm_cell->parameters[ID::NAME] = RTLIL::Const(wire->name.str());
fsm_cell->attributes = wire->attributes;
fsm_data.copy_to_cell(fsm_cell);
// rename original state wire
module->wires_.erase(wire->name);
- wire->attributes.erase("\\fsm_encoding");
+ wire->attributes.erase(ID::fsm_encoding);
wire->name = stringf("$fsm$oldstate%s", wire->name.c_str());
module->wires_[wire->name] = wire;
@@ -424,12 +424,9 @@ struct FsmExtractPass : public Pass {
CellTypes ct(design);
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->selected_modules())
{
- if (!design->selected(mod_it.second))
- continue;
-
- module = mod_it.second;
+ module = mod;
assign_map.set(module);
sig2driver.clear();
@@ -442,15 +439,15 @@ struct FsmExtractPass : public Pass {
assign_map.apply(sig);
sig2driver.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
}
- if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort("\\Y") &&
- cell->getPort("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) {
+ if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort(ID::Y) &&
+ cell->getPort(ID::Y).size() == 1 && (conn_it.first == ID::A || conn_it.first == ID::B)) {
RTLIL::SigSpec sig = conn_it.second;
assign_map.apply(sig);
sig2trigger.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
}
}
- if (cell->type == "$pmux") {
- RTLIL::SigSpec sel_sig = assign_map(cell->getPort("\\S"));
+ if (cell->type == ID($pmux)) {
+ RTLIL::SigSpec sel_sig = assign_map(cell->getPort(ID::S));
for (auto &bit1 : sel_sig)
for (auto &bit2 : sel_sig)
if (bit1 != bit2)
@@ -459,10 +456,9 @@ struct FsmExtractPass : public Pass {
}
std::vector<RTLIL::Wire*> wire_list;
- for (auto &wire_it : module->wires_)
- if (wire_it.second->attributes.count("\\fsm_encoding") > 0 && wire_it.second->attributes["\\fsm_encoding"].decode_string() != "none")
- if (design->selected(module, wire_it.second))
- wire_list.push_back(wire_it.second);
+ for (auto wire : module->selected_wires())
+ if (wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes[ID::fsm_encoding].decode_string() != "none")
+ wire_list.push_back(wire);
for (auto wire : wire_list)
extract_fsm(wire);
}
diff --git a/passes/fsm/fsm_info.cc b/passes/fsm/fsm_info.cc
index 0548259ee..90250f9b7 100644
--- a/passes/fsm/fsm_info.cc
+++ b/passes/fsm/fsm_info.cc
@@ -46,16 +46,15 @@ struct FsmInfoPass : public Pass {
log_header(design, "Executing FSM_INFO pass (dumping all available information on FSM cells).\n");
extra_args(args, 1, design);
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
- for (auto &cell_it : mod_it.second->cells_)
- if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) {
- log("\n");
- log("FSM `%s' from module `%s':\n", cell_it.second->name.c_str(), mod_it.first.c_str());
- FsmData fsm_data;
- fsm_data.copy_from_cell(cell_it.second);
- fsm_data.log_info(cell_it.second);
- }
+ for (auto mod : design->selected_modules())
+ for (auto cell : mod->selected_cells())
+ if (cell->type == ID($fsm)) {
+ log("\n");
+ log("FSM `%s' from module `%s':\n", log_id(cell), log_id(mod));
+ FsmData fsm_data;
+ fsm_data.copy_from_cell(cell);
+ fsm_data.log_info(cell);
+ }
}
} FsmInfoPass;
diff --git a/passes/fsm/fsm_map.cc b/passes/fsm/fsm_map.cc
index 80913fda8..1765df092 100644
--- a/passes/fsm/fsm_map.cc
+++ b/passes/fsm/fsm_map.cc
@@ -74,15 +74,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
RTLIL::Wire *eq_wire = module->addWire(NEW_ID);
and_sig.append(RTLIL::SigSpec(eq_wire));
- RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq");
- eq_cell->setPort("\\A", eq_sig_a);
- eq_cell->setPort("\\B", eq_sig_b);
- eq_cell->setPort("\\Y", RTLIL::SigSpec(eq_wire));
- eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
- eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
- eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size());
- eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.size());
- eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+ RTLIL::Cell *eq_cell = module->addCell(NEW_ID, ID($eq));
+ eq_cell->setPort(ID::A, eq_sig_a);
+ eq_cell->setPort(ID::B, eq_sig_b);
+ eq_cell->setPort(ID::Y, RTLIL::SigSpec(eq_wire));
+ eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
+ eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
+ eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(eq_sig_a.size());
+ eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(eq_sig_b.size());
+ eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
}
std::set<int> complete_in_state_cache = it.second;
@@ -102,12 +102,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
RTLIL::Wire *or_wire = module->addWire(NEW_ID);
and_sig.append(RTLIL::SigSpec(or_wire));
- RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or");
- or_cell->setPort("\\A", or_sig);
- or_cell->setPort("\\Y", RTLIL::SigSpec(or_wire));
- or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
- or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size());
- or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+ RTLIL::Cell *or_cell = module->addCell(NEW_ID, ID($reduce_or));
+ or_cell->setPort(ID::A, or_sig);
+ or_cell->setPort(ID::Y, RTLIL::SigSpec(or_wire));
+ or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
+ or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(or_sig.size());
+ or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
}
}
@@ -118,15 +118,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
RTLIL::Wire *and_wire = module->addWire(NEW_ID);
cases_vector.append(RTLIL::SigSpec(and_wire));
- RTLIL::Cell *and_cell = module->addCell(NEW_ID, "$and");
- and_cell->setPort("\\A", and_sig.extract(0, 1));
- and_cell->setPort("\\B", and_sig.extract(1, 1));
- and_cell->setPort("\\Y", RTLIL::SigSpec(and_wire));
- and_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
- and_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
- and_cell->parameters["\\A_WIDTH"] = RTLIL::Const(1);
- and_cell->parameters["\\B_WIDTH"] = RTLIL::Const(1);
- and_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+ RTLIL::Cell *and_cell = module->addCell(NEW_ID, ID($and));
+ and_cell->setPort(ID::A, and_sig.extract(0, 1));
+ and_cell->setPort(ID::B, and_sig.extract(1, 1));
+ and_cell->setPort(ID::Y, RTLIL::SigSpec(and_wire));
+ and_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
+ and_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
+ and_cell->parameters[ID::A_WIDTH] = RTLIL::Const(1);
+ and_cell->parameters[ID::B_WIDTH] = RTLIL::Const(1);
+ and_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
break;
}
case 1:
@@ -141,12 +141,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
}
if (cases_vector.size() > 1) {
- RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or");
- or_cell->setPort("\\A", cases_vector);
- or_cell->setPort("\\Y", output);
- or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
- or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size());
- or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+ RTLIL::Cell *or_cell = module->addCell(NEW_ID, ID($reduce_or));
+ or_cell->setPort(ID::A, cases_vector);
+ or_cell->setPort(ID::Y, output);
+ or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
+ or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(cases_vector.size());
+ or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
} else if (cases_vector.size() == 1) {
module->connect(RTLIL::SigSig(output, cases_vector));
} else {
@@ -161,31 +161,31 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
FsmData fsm_data;
fsm_data.copy_from_cell(fsm_cell);
- RTLIL::SigSpec ctrl_in = fsm_cell->getPort("\\CTRL_IN");
- RTLIL::SigSpec ctrl_out = fsm_cell->getPort("\\CTRL_OUT");
+ RTLIL::SigSpec ctrl_in = fsm_cell->getPort(ID::CTRL_IN);
+ RTLIL::SigSpec ctrl_out = fsm_cell->getPort(ID::CTRL_OUT);
// create state register
- RTLIL::Wire *state_wire = module->addWire(module->uniquify(fsm_cell->parameters["\\NAME"].decode_string()), fsm_data.state_bits);
+ RTLIL::Wire *state_wire = module->addWire(module->uniquify(fsm_cell->parameters[ID::NAME].decode_string()), fsm_data.state_bits);
RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits);
RTLIL::Cell *state_dff = module->addCell(NEW_ID, "");
- if (fsm_cell->getPort("\\ARST").is_fully_const()) {
- state_dff->type = "$dff";
+ if (fsm_cell->getPort(ID::ARST).is_fully_const()) {
+ state_dff->type = ID($dff);
} else {
- state_dff->type = "$adff";
- state_dff->parameters["\\ARST_POLARITY"] = fsm_cell->parameters["\\ARST_POLARITY"];
- state_dff->parameters["\\ARST_VALUE"] = fsm_data.state_table[fsm_data.reset_state];
- for (auto &bit : state_dff->parameters["\\ARST_VALUE"].bits)
+ state_dff->type = ID($adff);
+ state_dff->parameters[ID::ARST_POLARITY] = fsm_cell->parameters[ID::ARST_POLARITY];
+ state_dff->parameters[ID::ARST_VALUE] = fsm_data.state_table[fsm_data.reset_state];
+ for (auto &bit : state_dff->parameters[ID::ARST_VALUE].bits)
if (bit != RTLIL::State::S1)
bit = RTLIL::State::S0;
- state_dff->setPort("\\ARST", fsm_cell->getPort("\\ARST"));
+ state_dff->setPort(ID::ARST, fsm_cell->getPort(ID::ARST));
}
- state_dff->parameters["\\WIDTH"] = RTLIL::Const(fsm_data.state_bits);
- state_dff->parameters["\\CLK_POLARITY"] = fsm_cell->parameters["\\CLK_POLARITY"];
- state_dff->setPort("\\CLK", fsm_cell->getPort("\\CLK"));
- state_dff->setPort("\\D", RTLIL::SigSpec(next_state_wire));
- state_dff->setPort("\\Q", RTLIL::SigSpec(state_wire));
+ state_dff->parameters[ID::WIDTH] = RTLIL::Const(fsm_data.state_bits);
+ state_dff->parameters[ID::CLK_POLARITY] = fsm_cell->parameters[ID::CLK_POLARITY];
+ state_dff->setPort(ID::CLK, fsm_cell->getPort(ID::CLK));
+ state_dff->setPort(ID::D, RTLIL::SigSpec(next_state_wire));
+ state_dff->setPort(ID::Q, RTLIL::SigSpec(state_wire));
// decode state register
@@ -212,20 +212,20 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
{
encoding_is_onehot = false;
- RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq");
- eq_cell->setPort("\\A", sig_a);
- eq_cell->setPort("\\B", sig_b);
- eq_cell->setPort("\\Y", RTLIL::SigSpec(state_onehot, i));
- eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
- eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
- eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size());
- eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.size());
- eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+ RTLIL::Cell *eq_cell = module->addCell(NEW_ID, ID($eq));
+ eq_cell->setPort(ID::A, sig_a);
+ eq_cell->setPort(ID::B, sig_b);
+ eq_cell->setPort(ID::Y, RTLIL::SigSpec(state_onehot, i));
+ eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
+ eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
+ eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig_a.size());
+ eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(sig_b.size());
+ eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
}
}
if (encoding_is_onehot)
- state_wire->set_bool_attribute("\\onehot");
+ state_wire->set_bool_attribute(ID::onehot);
// generate next_state signal
@@ -285,13 +285,13 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
}
}
- RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$pmux");
- mux_cell->setPort("\\A", sig_a);
- mux_cell->setPort("\\B", sig_b);
- mux_cell->setPort("\\S", sig_s);
- mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire));
- mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size());
- mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size());
+ RTLIL::Cell *mux_cell = module->addCell(NEW_ID, ID($pmux));
+ mux_cell->setPort(ID::A, sig_a);
+ mux_cell->setPort(ID::B, sig_b);
+ mux_cell->setPort(ID::S, sig_s);
+ mux_cell->setPort(ID::Y, RTLIL::SigSpec(next_state_wire));
+ mux_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_a.size());
+ mux_cell->parameters[ID::S_WIDTH] = RTLIL::Const(sig_s.size());
}
}
@@ -336,15 +336,13 @@ struct FsmMapPass : public Pass {
log_header(design, "Executing FSM_MAP pass (mapping FSMs to basic logic).\n");
extra_args(args, 1, design);
- for (auto &mod_it : design->modules_) {
- if (!design->selected(mod_it.second))
- continue;
+ for (auto mod : design->selected_modules()) {
std::vector<RTLIL::Cell*> fsm_cells;
- for (auto &cell_it : mod_it.second->cells_)
- if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
- fsm_cells.push_back(cell_it.second);
+ for (auto cell : mod->selected_cells())
+ if (cell->type == ID($fsm))
+ fsm_cells.push_back(cell);
for (auto cell : fsm_cells)
- map_fsm(cell, mod_it.second);
+ map_fsm(cell, mod);
}
}
} FsmMapPass;
diff --git a/passes/fsm/fsm_opt.cc b/passes/fsm/fsm_opt.cc
index 048daee55..89e8132d4 100644
--- a/passes/fsm/fsm_opt.cc
+++ b/passes/fsm/fsm_opt.cc
@@ -81,10 +81,10 @@ struct FsmOpt
{
RTLIL::SigBit bit = sig.as_bit();
- if (bit.wire == NULL || bit.wire->attributes.count("\\unused_bits") == 0)
+ if (bit.wire == NULL || bit.wire->attributes.count(ID::unused_bits) == 0)
return false;
- char *str = strdup(bit.wire->attributes["\\unused_bits"].decode_string().c_str());
+ char *str = strdup(bit.wire->attributes[ID::unused_bits].decode_string().c_str());
for (char *tok = strtok(str, " "); tok != NULL; tok = strtok(NULL, " ")) {
if (tok[0] && bit.offset == atoi(tok)) {
free(str);
@@ -98,7 +98,7 @@ struct FsmOpt
void opt_const_and_unused_inputs()
{
- RTLIL::SigSpec ctrl_in = cell->getPort("\\CTRL_IN");
+ RTLIL::SigSpec ctrl_in = cell->getPort(ID::CTRL_IN);
std::vector<bool> ctrl_in_used(ctrl_in.size());
std::vector<FsmData::transition_t> new_transition_table;
@@ -119,15 +119,15 @@ struct FsmOpt
for (int i = int(ctrl_in_used.size())-1; i >= 0; i--) {
if (!ctrl_in_used[i]) {
- log(" Removing unused input signal %s.\n", log_signal(cell->getPort("\\CTRL_IN").extract(i, 1)));
+ log(" Removing unused input signal %s.\n", log_signal(cell->getPort(ID::CTRL_IN).extract(i, 1)));
for (auto &tr : new_transition_table) {
RTLIL::SigSpec tmp(tr.ctrl_in);
tmp.remove(i, 1);
tr.ctrl_in = tmp.as_const();
}
- RTLIL::SigSpec new_ctrl_in = cell->getPort("\\CTRL_IN");
+ RTLIL::SigSpec new_ctrl_in = cell->getPort(ID::CTRL_IN);
new_ctrl_in.remove(i, 1);
- cell->setPort("\\CTRL_IN", new_ctrl_in);
+ cell->setPort(ID::CTRL_IN, new_ctrl_in);
fsm_data.num_inputs--;
}
}
@@ -139,12 +139,12 @@ struct FsmOpt
void opt_unused_outputs()
{
for (int i = 0; i < fsm_data.num_outputs; i++) {
- RTLIL::SigSpec sig = cell->getPort("\\CTRL_OUT").extract(i, 1);
+ RTLIL::SigSpec sig = cell->getPort(ID::CTRL_OUT).extract(i, 1);
if (signal_is_unused(sig)) {
log(" Removing unused output signal %s.\n", log_signal(sig));
- RTLIL::SigSpec new_ctrl_out = cell->getPort("\\CTRL_OUT");
+ RTLIL::SigSpec new_ctrl_out = cell->getPort(ID::CTRL_OUT);
new_ctrl_out.remove(i, 1);
- cell->setPort("\\CTRL_OUT", new_ctrl_out);
+ cell->setPort(ID::CTRL_OUT, new_ctrl_out);
for (auto &tr : fsm_data.transition_table) {
RTLIL::SigSpec tmp(tr.ctrl_out);
tmp.remove(i, 1);
@@ -158,7 +158,7 @@ struct FsmOpt
void opt_alias_inputs()
{
- RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
+ RTLIL::SigSpec &ctrl_in = cell->connections_[ID::CTRL_IN];
for (int i = 0; i < ctrl_in.size(); i++)
for (int j = i+1; j < ctrl_in.size(); j++)
@@ -195,8 +195,8 @@ struct FsmOpt
void opt_feedback_inputs()
{
- RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
- RTLIL::SigSpec &ctrl_out = cell->connections_["\\CTRL_OUT"];
+ RTLIL::SigSpec &ctrl_in = cell->connections_[ID::CTRL_IN];
+ RTLIL::SigSpec &ctrl_out = cell->connections_[ID::CTRL_OUT];
for (int j = 0; j < ctrl_out.size(); j++)
for (int i = 0; i < ctrl_in.size(); i++)
@@ -340,12 +340,10 @@ struct FsmOptPass : public Pass {
log_header(design, "Executing FSM_OPT pass (simple optimizations of FSMs).\n");
extra_args(args, 1, design);
- for (auto &mod_it : design->modules_) {
- if (design->selected(mod_it.second))
- for (auto &cell_it : mod_it.second->cells_)
- if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
- FsmData::optimize_fsm(cell_it.second, mod_it.second);
- }
+ for (auto mod : design->selected_modules())
+ for (auto cell : mod->selected_cells())
+ if (cell->type == ID($fsm))
+ FsmData::optimize_fsm(cell, mod);
}
} FsmOptPass;
diff --git a/passes/fsm/fsm_recode.cc b/passes/fsm/fsm_recode.cc
index fa1ff48cc..7edb923b9 100644
--- a/passes/fsm/fsm_recode.cc
+++ b/passes/fsm/fsm_recode.cc
@@ -32,7 +32,7 @@ PRIVATE_NAMESPACE_BEGIN
static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &fsm_data, const char *prefix, FILE *f)
{
- std::string name = cell->parameters["\\NAME"].decode_string();
+ std::string name = cell->parameters[ID::NAME].decode_string();
fprintf(f, "set_fsm_state_vector {");
for (int i = fsm_data.state_bits-1; i >= 0; i--)
@@ -53,7 +53,7 @@ static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &
static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fsm_file, FILE *encfile, std::string default_encoding)
{
- std::string encoding = cell->attributes.count("\\fsm_encoding") ? cell->attributes.at("\\fsm_encoding").decode_string() : "auto";
+ std::string encoding = cell->attributes.count(ID::fsm_encoding) ? cell->attributes.at(ID::fsm_encoding).decode_string() : "auto";
log("Recoding FSM `%s' from module `%s' using `%s' encoding:\n", cell->name.c_str(), module->name.c_str(), encoding.c_str());
@@ -95,7 +95,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs
log_error("FSM encoding `%s' is not supported!\n", encoding.c_str());
if (encfile)
- fprintf(encfile, ".fsm %s %s\n", log_id(module), RTLIL::unescape_id(cell->parameters["\\NAME"].decode_string()).c_str());
+ fprintf(encfile, ".fsm %s %s\n", log_id(module), RTLIL::unescape_id(cell->parameters[ID::NAME].decode_string()).c_str());
int state_idx_counter = fsm_data.reset_state >= 0 ? 1 : 0;
for (int i = 0; i < int(fsm_data.state_table.size()); i++)
@@ -181,11 +181,10 @@ struct FsmRecodePass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
- for (auto &cell_it : mod_it.second->cells_)
- if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
- fsm_recode(cell_it.second, mod_it.second, fm_set_fsm_file, encfile, default_encoding);
+ for (auto mod : design->selected_modules())
+ for (auto cell : mod->selected_cells())
+ if (cell->type == ID($fsm))
+ fsm_recode(cell, mod, fm_set_fsm_file, encfile, default_encoding);
if (fm_set_fsm_file != NULL)
fclose(fm_set_fsm_file);
diff --git a/passes/fsm/fsmdata.h b/passes/fsm/fsmdata.h
index 68222769a..47398b558 100644
--- a/passes/fsm/fsmdata.h
+++ b/passes/fsm/fsmdata.h
@@ -33,31 +33,31 @@ struct FsmData
void copy_to_cell(RTLIL::Cell *cell)
{
- cell->parameters["\\CTRL_IN_WIDTH"] = RTLIL::Const(num_inputs);
- cell->parameters["\\CTRL_OUT_WIDTH"] = RTLIL::Const(num_outputs);
+ cell->parameters[ID::CTRL_IN_WIDTH] = RTLIL::Const(num_inputs);
+ cell->parameters[ID::CTRL_OUT_WIDTH] = RTLIL::Const(num_outputs);
int state_num_log2 = 0;
for (int i = state_table.size(); i > 0; i = i >> 1)
state_num_log2++;
state_num_log2 = max(state_num_log2, 1);
- cell->parameters["\\STATE_BITS"] = RTLIL::Const(state_bits);
- cell->parameters["\\STATE_NUM"] = RTLIL::Const(state_table.size());
- cell->parameters["\\STATE_NUM_LOG2"] = RTLIL::Const(state_num_log2);
- cell->parameters["\\STATE_RST"] = RTLIL::Const(reset_state);
- cell->parameters["\\STATE_TABLE"] = RTLIL::Const();
+ cell->parameters[ID::STATE_BITS] = RTLIL::Const(state_bits);
+ cell->parameters[ID::STATE_NUM] = RTLIL::Const(state_table.size());
+ cell->parameters[ID::STATE_NUM_LOG2] = RTLIL::Const(state_num_log2);
+ cell->parameters[ID::STATE_RST] = RTLIL::Const(reset_state);
+ cell->parameters[ID::STATE_TABLE] = RTLIL::Const();
for (int i = 0; i < int(state_table.size()); i++) {
- std::vector<RTLIL::State> &bits_table = cell->parameters["\\STATE_TABLE"].bits;
+ std::vector<RTLIL::State> &bits_table = cell->parameters[ID::STATE_TABLE].bits;
std::vector<RTLIL::State> &bits_state = state_table[i].bits;
bits_table.insert(bits_table.end(), bits_state.begin(), bits_state.end());
}
- cell->parameters["\\TRANS_NUM"] = RTLIL::Const(transition_table.size());
- cell->parameters["\\TRANS_TABLE"] = RTLIL::Const();
+ cell->parameters[ID::TRANS_NUM] = RTLIL::Const(transition_table.size());
+ cell->parameters[ID::TRANS_TABLE] = RTLIL::Const();
for (int i = 0; i < int(transition_table.size()); i++)
{
- std::vector<RTLIL::State> &bits_table = cell->parameters["\\TRANS_TABLE"].bits;
+ std::vector<RTLIL::State> &bits_table = cell->parameters[ID::TRANS_TABLE].bits;
transition_t &tr = transition_table[i];
RTLIL::Const const_state_in = RTLIL::Const(tr.state_in, state_num_log2);
@@ -78,21 +78,21 @@ struct FsmData
void copy_from_cell(RTLIL::Cell *cell)
{
- num_inputs = cell->parameters["\\CTRL_IN_WIDTH"].as_int();
- num_outputs = cell->parameters["\\CTRL_OUT_WIDTH"].as_int();
+ num_inputs = cell->parameters[ID::CTRL_IN_WIDTH].as_int();
+ num_outputs = cell->parameters[ID::CTRL_OUT_WIDTH].as_int();
- state_bits = cell->parameters["\\STATE_BITS"].as_int();
- reset_state = cell->parameters["\\STATE_RST"].as_int();
+ state_bits = cell->parameters[ID::STATE_BITS].as_int();
+ reset_state = cell->parameters[ID::STATE_RST].as_int();
- int state_num = cell->parameters["\\STATE_NUM"].as_int();
- int state_num_log2 = cell->parameters["\\STATE_NUM_LOG2"].as_int();
- int trans_num = cell->parameters["\\TRANS_NUM"].as_int();
+ int state_num = cell->parameters[ID::STATE_NUM].as_int();
+ int state_num_log2 = cell->parameters[ID::STATE_NUM_LOG2].as_int();
+ int trans_num = cell->parameters[ID::TRANS_NUM].as_int();
if (reset_state < 0 || reset_state >= state_num)
reset_state = -1;
- RTLIL::Const state_table = cell->parameters["\\STATE_TABLE"];
- RTLIL::Const trans_table = cell->parameters["\\TRANS_TABLE"];
+ RTLIL::Const state_table = cell->parameters[ID::STATE_TABLE];
+ RTLIL::Const trans_table = cell->parameters[ID::TRANS_TABLE];
for (int i = 0; i < state_num; i++) {
RTLIL::Const state_code;
@@ -134,7 +134,7 @@ struct FsmData
{
log("-------------------------------------\n");
log("\n");
- log(" Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters["\\NAME"].decode_string().c_str());
+ log(" Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters[ID::NAME].decode_string().c_str());
log("\n");
log(" Number of input signals: %3d\n", num_inputs);
log(" Number of output signals: %3d\n", num_outputs);
@@ -142,13 +142,13 @@ struct FsmData
log("\n");
log(" Input signals:\n");
- RTLIL::SigSpec sig_in = cell->getPort("\\CTRL_IN");
+ RTLIL::SigSpec sig_in = cell->getPort(ID::CTRL_IN);
for (int i = 0; i < GetSize(sig_in); i++)
log(" %3d: %s\n", i, log_signal(sig_in[i]));
log("\n");
log(" Output signals:\n");
- RTLIL::SigSpec sig_out = cell->getPort("\\CTRL_OUT");
+ RTLIL::SigSpec sig_out = cell->getPort(ID::CTRL_OUT);
for (int i = 0; i < GetSize(sig_out); i++)
log(" %3d: %s\n", i, log_signal(sig_out[i]));
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index 3f4fe502d..3880b19fe 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -120,7 +120,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
RTLIL::Module *mod = new RTLIL::Module;
mod->name = celltype;
- mod->attributes["\\blackbox"] = RTLIL::Const(1);
+ mod->attributes[ID::blackbox] = RTLIL::Const(1);
design->add(mod);
for (auto &decl : ports) {
@@ -166,9 +166,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// If any of the ports are actually interface ports, we will always need to
// reprocess the module:
- if(!module->get_bool_attribute("\\interfaces_replaced_in_module")) {
+ if(!module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
for (auto wire : module->wires()) {
- if ((wire->port_input || wire->port_output) && wire->get_bool_attribute("\\is_interface"))
+ if ((wire->port_input || wire->port_output) && wire->get_bool_attribute(ID::is_interface))
has_interface_ports = true;
}
}
@@ -177,7 +177,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module;
for (auto cell : module->cells())
{
- if(cell->get_bool_attribute("\\is_interface")) {
+ if(cell->get_bool_attribute(ID::is_interface)) {
RTLIL::Module *intf_module = design->module(cell->type);
interfaces_in_module[cell->name] = intf_module;
}
@@ -253,24 +253,24 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to
// some lists, so that the ports for sub-modules can be replaced further down:
for (auto &conn : cell->connections()) {
- if(mod->wire(conn.first) != nullptr && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list
- //const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type");
+ if(mod->wire(conn.first) != nullptr && mod->wire(conn.first)->get_bool_attribute(ID::is_interface)) { // Check if the connection is present as an interface in the sub-module's port list
+ //const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute(ID::interface_type);
//for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module (not crucially important, but good for robustness)
//}
// Find if the sub-module has set a modport for the current interface connection:
- const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport");
+ const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute(ID::interface_modport);
std::string interface_modport = "";
for (auto &d : interface_modport_pool) {
interface_modport = "\\" + d;
}
- if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { // Check if the connected wire is a potential interface in the parent module
+ if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute(ID::is_interface)) { // Check if the connected wire is a potential interface in the parent module
std::string interface_name_str = conn.second.bits()[0].wire->name.str();
interface_name_str.replace(0,23,""); // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name
interface_name_str = "\\" + interface_name_str;
RTLIL::IdString interface_name = interface_name_str;
bool not_found_interface = false;
- if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
+ if(module->get_bool_attribute(ID::interfaces_replaced_in_module)) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
// Check if the interface instance is present in module:
// Interface instances may either have the plain name or the name appended with '_inst_from_top_dummy'.
// Check for both of them here
@@ -309,7 +309,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// which will delay the expansion of this cell:
if (not_found_interface) {
// If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error:
- if(!(module->get_bool_attribute("\\cells_not_processed"))) {
+ if(!(module->get_bool_attribute(ID::cells_not_processed))) {
log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module));
}
else {
@@ -367,10 +367,10 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// If there are no overridden parameters AND not interfaces, then we can use the existing module instance as the type
// for the cell:
- if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute("\\module_not_derived")))) {
+ if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute(ID::module_not_derived)))) {
// If the cell being processed is an the interface instance itself, go down to "handle_interface_instance:",
// so that the signals of the interface are added to the parent module.
- if (mod->get_bool_attribute("\\is_interface")) {
+ if (mod->get_bool_attribute(ID::is_interface)) {
goto handle_interface_instance;
}
continue;
@@ -384,23 +384,23 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
// We add all the signals of the interface explicitly to the parent module. This is always needed when we encounter
// an interface instance:
- if (mod->get_bool_attribute("\\is_interface") && cell->get_bool_attribute("\\module_not_derived")) {
- cell->set_bool_attribute("\\is_interface");
+ if (mod->get_bool_attribute(ID::is_interface) && cell->get_bool_attribute(ID::module_not_derived)) {
+ cell->set_bool_attribute(ID::is_interface);
RTLIL::Module *derived_module = design->module(cell->type);
interfaces_in_module[cell->name] = derived_module;
did_something = true;
}
// We clear 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell)
- cell->attributes.erase("\\module_not_derived");
+ cell->attributes.erase(ID::module_not_derived);
}
// Clear the attribute 'cells_not_processed' such that it can be known that we
// have been through all cells at least once, and that we can know whether
// to flag an error because of interface instances not found:
- module->attributes.erase("\\cells_not_processed");
+ module->attributes.erase(ID::cells_not_processed);
// If any interface instances or interface ports were found in the module, we need to rederive it completely:
- if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute("\\interfaces_replaced_in_module")) {
+ if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
module->reprocess_module(design, interfaces_in_module);
return did_something;
}
@@ -475,7 +475,7 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
// safe to delete all of the remaining dummy interface ports:
pool<RTLIL::Wire*> del_wires;
for(auto wire : mod->wires()) {
- if ((wire->port_input || wire->port_output) && wire->get_bool_attribute("\\is_interface")) {
+ if ((wire->port_input || wire->port_output) && wire->get_bool_attribute(ID::is_interface)) {
del_wires.insert(wire);
}
}
@@ -502,7 +502,7 @@ bool set_keep_assert(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
if (cache.count(mod) == 0)
for (auto c : mod->cells()) {
RTLIL::Module *m = mod->design->module(c->type);
- if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in("$assert", "$assume", "$live", "$fair", "$cover"))
+ if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover)))
return cache[mod] = true;
}
return cache[mod];
@@ -532,11 +532,11 @@ int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db)
RTLIL::Module *check_if_top_has_changed(Design *design, Module *top_mod)
{
- if(top_mod != NULL && top_mod->get_bool_attribute("\\initial_top"))
+ if(top_mod != NULL && top_mod->get_bool_attribute(ID::initial_top))
return top_mod;
else {
for (auto mod : design->modules()) {
- if (mod->get_bool_attribute("\\top")) {
+ if (mod->get_bool_attribute(ID::top)) {
return mod;
}
}
@@ -814,7 +814,7 @@ struct HierarchyPass : public Pass {
if (top_mod == nullptr)
for (auto mod : design->modules())
- if (mod->get_bool_attribute("\\top"))
+ if (mod->get_bool_attribute(ID::top))
top_mod = mod;
if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) {
@@ -860,9 +860,9 @@ struct HierarchyPass : public Pass {
if (top_mod != NULL) {
for (auto mod : design->modules())
if (mod == top_mod)
- mod->attributes["\\initial_top"] = RTLIL::Const(1);
+ mod->attributes[ID::initial_top] = RTLIL::Const(1);
else
- mod->attributes.erase("\\initial_top");
+ mod->attributes.erase(ID::initial_top);
}
bool did_something = true;
@@ -897,7 +897,7 @@ struct HierarchyPass : public Pass {
// Delete modules marked as 'to_delete':
std::vector<RTLIL::Module *> modules_to_delete;
for(auto mod : design->modules()) {
- if (mod->get_bool_attribute("\\to_delete")) {
+ if (mod->get_bool_attribute(ID::to_delete)) {
modules_to_delete.push_back(mod);
}
}
@@ -915,10 +915,10 @@ struct HierarchyPass : public Pass {
if (top_mod != NULL) {
for (auto mod : design->modules()) {
if (mod == top_mod)
- mod->attributes["\\top"] = RTLIL::Const(1);
+ mod->attributes[ID::top] = RTLIL::Const(1);
else
- mod->attributes.erase("\\top");
- mod->attributes.erase("\\initial_top");
+ mod->attributes.erase(ID::top);
+ mod->attributes.erase(ID::initial_top);
}
}
@@ -927,7 +927,7 @@ struct HierarchyPass : public Pass {
for (auto mod : design->modules())
if (set_keep_assert(cache, mod)) {
log("Module %s directly or indirectly contains formal properties -> setting \"keep\" attribute.\n", log_id(mod));
- mod->set_bool_attribute("\\keep");
+ mod->set_bool_attribute(ID::keep);
}
}
@@ -983,8 +983,8 @@ struct HierarchyPass : public Pass {
{
for (auto module : design->modules())
for (auto wire : module->wires())
- if (wire->port_input && wire->attributes.count("\\defaultvalue"))
- defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");
+ if (wire->port_input && wire->attributes.count(ID::defaultvalue))
+ defaults_db[module->name][wire->name] = wire->attributes.at(ID::defaultvalue);
}
// Process SV implicit wildcard port connections
std::set<Module*> blackbox_derivatives;
@@ -994,7 +994,7 @@ struct HierarchyPass : public Pass {
{
for (auto cell : module->cells())
{
- if (!cell->get_bool_attribute(ID(wildcard_port_conns)))
+ if (!cell->get_bool_attribute(ID::wildcard_port_conns))
continue;
Module *m = design->module(cell->type);
@@ -1003,7 +1003,7 @@ struct HierarchyPass : public Pass {
RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
// Need accurate port widths for error checking; so must derive blackboxes with dynamic port widths
- if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
+ if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) {
IdString new_m_name = m->derive(design, cell->parameters, true);
if (new_m_name.empty())
continue;
@@ -1036,7 +1036,7 @@ struct HierarchyPass : public Pass {
RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
cell->setPort(wire->name, parent_wire);
}
- cell->attributes.erase(ID(wildcard_port_conns));
+ cell->attributes.erase(ID::wildcard_port_conns);
}
}
@@ -1071,11 +1071,11 @@ struct HierarchyPass : public Pass {
for (auto wire : module->wires())
{
- if (wire->get_bool_attribute("\\wand")) {
+ if (wire->get_bool_attribute(ID::wand)) {
wand_map[wire] = SigSpec();
wand_wor_index.insert(wire);
}
- if (wire->get_bool_attribute("\\wor")) {
+ if (wire->get_bool_attribute(ID::wor)) {
wor_map[wire] = SigSpec();
wand_wor_index.insert(wire);
}
@@ -1186,7 +1186,7 @@ struct HierarchyPass : public Pass {
if (m == nullptr)
continue;
- if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
+ if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) {
IdString new_m_name = m->derive(design, cell->parameters, true);
if (new_m_name.empty())
continue;
diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc
index 3b4f33a60..2db7cf26b 100644
--- a/passes/hierarchy/submod.cc
+++ b/passes/hierarchy/submod.cc
@@ -51,7 +51,7 @@ struct SubmodWorker
RTLIL::Wire *new_wire;
RTLIL::Const is_int_driven;
bool is_int_used, is_ext_driven, is_ext_used;
- wire_flags_t(RTLIL::Wire* wire) : new_wire(NULL), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { }
+ wire_flags_t(RTLIL::Wire* wire) : new_wire(nullptr), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { }
};
std::map<RTLIL::Wire*, wire_flags_t> wire_flags;
bool flag_found_something;
@@ -75,7 +75,7 @@ struct SubmodWorker
void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used)
{
for (auto &c : sig.chunks())
- if (c.wire != NULL) {
+ if (c.wire != nullptr) {
flag_wire(c.wire, create, set_int_used, set_ext_driven, set_ext_used);
if (set_int_driven)
for (int i = c.offset; i < c.offset+c.width; i++) {
@@ -100,8 +100,7 @@ struct SubmodWorker
flag_signal(conn.second, true, true, true, false, false);
}
}
- for (auto &it : module->cells_) {
- RTLIL::Cell *cell = it.second;
+ for (auto cell : module->cells()) {
if (submod.cells.count(cell) > 0)
continue;
if (ct.cell_known(cell->type)) {
@@ -176,16 +175,16 @@ struct SubmodWorker
new_wire->start_offset = wire->start_offset;
new_wire->attributes = wire->attributes;
if (!flags.is_int_driven.is_fully_zero()) {
- new_wire->attributes.erase(ID(init));
+ new_wire->attributes.erase(ID::init);
auto sig = sigmap(wire);
for (int i = 0; i < GetSize(sig); i++) {
if (flags.is_int_driven[i] == State::S0)
continue;
if (!sig[i].wire)
continue;
- auto it = sig[i].wire->attributes.find(ID(init));
+ auto it = sig[i].wire->attributes.find(ID::init);
if (it != sig[i].wire->attributes.end()) {
- auto jt = new_wire->attributes.insert(std::make_pair(ID(init), Const(State::Sx, GetSize(sig)))).first;
+ auto jt = new_wire->attributes.insert(std::make_pair(ID::init, Const(State::Sx, GetSize(sig)))).first;
jt->second[i] = it->second[sig[i].offset];
it->second[sig[i].offset] = State::Sx;
}
@@ -211,7 +210,7 @@ struct SubmodWorker
RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell);
for (auto &conn : new_cell->connections_)
for (auto &bit : conn.second)
- if (bit.wire != NULL) {
+ if (bit.wire != nullptr) {
log_assert(wire_flags.count(bit.wire) > 0);
bit.wire = wire_flags.at(bit.wire).new_wire;
}
@@ -274,24 +273,23 @@ struct SubmodWorker
if (opt_name.empty())
{
- for (auto &it : module->wires_)
- it.second->attributes.erase("\\submod");
+ for (auto wire : module->wires())
+ wire->attributes.erase(ID::submod);
- for (auto &it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = it.second;
- if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].bits.size() == 0) {
- cell->attributes.erase("\\submod");
+ if (cell->attributes.count(ID::submod) == 0 || cell->attributes[ID::submod].bits.size() == 0) {
+ cell->attributes.erase(ID::submod);
continue;
}
- std::string submod_str = cell->attributes["\\submod"].decode_string();
- cell->attributes.erase("\\submod");
+ std::string submod_str = cell->attributes[ID::submod].decode_string();
+ cell->attributes.erase(ID::submod);
if (submodules.count(submod_str) == 0) {
submodules[submod_str].name = submod_str;
submodules[submod_str].full_name = module->name.str() + "_" + submod_str;
- while (design->modules_.count(submodules[submod_str].full_name) != 0 ||
+ while (design->module(submodules[submod_str].full_name) != nullptr ||
module->count_id(submodules[submod_str].full_name) != 0)
submodules[submod_str].full_name += "_";
}
@@ -301,9 +299,8 @@ struct SubmodWorker
}
else
{
- for (auto &it : module->cells_)
+ for (auto cell : module->cells())
{
- RTLIL::Cell *cell = it.second;
if (!design->selected(module, cell))
continue;
submodules[opt_name].name = opt_name;
@@ -392,12 +389,12 @@ struct SubmodPass : public Pass {
while (did_something) {
did_something = false;
std::vector<RTLIL::IdString> queued_modules;
- for (auto &mod_it : design->modules_)
- if (handled_modules.count(mod_it.first) == 0 && design->selected_whole_module(mod_it.first))
- queued_modules.push_back(mod_it.first);
+ for (auto mod : design->modules())
+ if (handled_modules.count(mod->name) == 0 && design->selected_whole_module(mod->name))
+ queued_modules.push_back(mod->name);
for (auto &modname : queued_modules)
- if (design->modules_.count(modname) != 0) {
- SubmodWorker worker(design, design->modules_[modname], copy_mode, hidden_mode);
+ if (design->module(modname) != nullptr) {
+ SubmodWorker worker(design, design->module(modname), copy_mode, hidden_mode);
handled_modules.insert(modname);
did_something = true;
}
@@ -407,15 +404,13 @@ struct SubmodPass : public Pass {
}
else
{
- RTLIL::Module *module = NULL;
- for (auto &mod_it : design->modules_) {
- if (!design->selected_module(mod_it.first))
- continue;
- if (module != NULL)
- log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod_it.first.c_str());
- module = mod_it.second;
+ RTLIL::Module *module = nullptr;
+ for (auto mod : design->selected_modules()) {
+ if (module != nullptr)
+ log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod->name.c_str());
+ module = mod;
}
- if (module == NULL)
+ if (module == nullptr)
log("Nothing selected -> do nothing.\n");
else {
Pass::call_on_module(design, module, "opt_clean");
diff --git a/passes/hierarchy/uniquify.cc b/passes/hierarchy/uniquify.cc
index ad3220918..5dbd15a7e 100644
--- a/passes/hierarchy/uniquify.cc
+++ b/passes/hierarchy/uniquify.cc
@@ -64,7 +64,7 @@ struct UniquifyPass : public Pass {
for (auto module : design->selected_modules())
{
- if (!module->get_bool_attribute("\\unique") && !module->get_bool_attribute("\\top"))
+ if (!module->get_bool_attribute(ID::unique) && !module->get_bool_attribute(ID::top))
continue;
for (auto cell : module->selected_cells())
@@ -78,7 +78,7 @@ struct UniquifyPass : public Pass {
if (tmod->get_blackbox_attribute())
continue;
- if (tmod->get_bool_attribute("\\unique") && newname == tmod->name)
+ if (tmod->get_bool_attribute(ID::unique) && newname == tmod->name)
continue;
log("Creating module %s from %s.\n", log_id(newname), log_id(tmod));
@@ -86,9 +86,9 @@ struct UniquifyPass : public Pass {
auto smod = tmod->clone();
smod->name = newname;
cell->type = newname;
- smod->set_bool_attribute("\\unique");
- if (smod->attributes.count("\\hdlname") == 0)
- smod->attributes["\\hdlname"] = string(log_id(tmod->name));
+ smod->set_bool_attribute(ID::unique);
+ if (smod->attributes.count(ID::hdlname) == 0)
+ smod->attributes[ID::hdlname] = string(log_id(tmod->name));
design->add(smod);
did_something = true;
diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc
index 24478f2ee..0898ec288 100644
--- a/passes/memory/memory_bram.cc
+++ b/passes/memory/memory_bram.cc
@@ -105,11 +105,11 @@ struct rules_t
log_error("Bram %s variants %d and %d have different values for 'groups'.\n", log_id(name), variant, other.variant);
if (abits != other.abits)
- variant_params["\\CFG_ABITS"] = abits;
+ variant_params[ID::CFG_ABITS] = abits;
if (dbits != other.dbits)
- variant_params["\\CFG_DBITS"] = dbits;
+ variant_params[ID::CFG_DBITS] = dbits;
if (init != other.init)
- variant_params["\\CFG_INIT"] = init;
+ variant_params[ID::CFG_INIT] = init;
for (int i = 0; i < groups; i++)
{
@@ -137,9 +137,26 @@ struct rules_t
vector<vector<std::tuple<bool,IdString,Const>>> attributes;
};
+ bool attr_icase;
dict<IdString, vector<bram_t>> brams;
vector<match_t> matches;
+ std::string map_case(std::string value) const
+ {
+ if (attr_icase) {
+ for (char &c : value)
+ c = tolower(c);
+ }
+ return value;
+ }
+
+ RTLIL::Const map_case(RTLIL::Const value) const
+ {
+ if (value.flags & RTLIL::CONST_FLAG_STRING)
+ return map_case(value.decode_string());
+ return value;
+ }
+
std::ifstream infile;
vector<string> tokens;
vector<string> labels;
@@ -337,7 +354,7 @@ struct rules_t
IdString key = RTLIL::escape_id(tokens[idx].substr(c1, c2));
Const val = c2 != std::string::npos ? tokens[idx].substr(c2+1) : RTLIL::Const(1);
- data.attributes.back().emplace_back(exists, key, val);
+ data.attributes.back().emplace_back(exists, key, map_case(val));
}
continue;
}
@@ -351,6 +368,7 @@ struct rules_t
rewrite_filename(filename);
infile.open(filename);
linecount = 0;
+ attr_icase = false;
if (infile.fail())
log_error("Can't open rules file `%s'.\n", filename.c_str());
@@ -360,6 +378,11 @@ struct rules_t
if (!labels.empty())
syntax_error();
+ if (GetSize(tokens) == 2 && tokens[0] == "attr_icase") {
+ attr_icase = atoi(tokens[1].c_str());
+ continue;
+ }
+
if (tokens[0] == "bram") {
parse_bram();
continue;
@@ -414,44 +437,44 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
log(" Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant);
// bram.dump_config();
- int mem_size = cell->getParam("\\SIZE").as_int();
- int mem_abits = cell->getParam("\\ABITS").as_int();
- int mem_width = cell->getParam("\\WIDTH").as_int();
- // int mem_offset = cell->getParam("\\OFFSET").as_int();
+ int mem_size = cell->getParam(ID::SIZE).as_int();
+ int mem_abits = cell->getParam(ID::ABITS).as_int();
+ int mem_width = cell->getParam(ID::WIDTH).as_int();
+ // int mem_offset = cell->getParam(ID::OFFSET).as_int();
- bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
+ bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef();
vector<Const> initdata;
if (cell_init) {
- Const initparam = cell->getParam("\\INIT");
+ Const initparam = cell->getParam(ID::INIT);
initdata.reserve(mem_size);
for (int i=0; i < mem_size; i++)
initdata.push_back(initparam.extract(mem_width*i, mem_width, State::Sx));
}
- int wr_ports = cell->getParam("\\WR_PORTS").as_int();
- auto wr_clken = SigSpec(cell->getParam("\\WR_CLK_ENABLE"));
- auto wr_clkpol = SigSpec(cell->getParam("\\WR_CLK_POLARITY"));
+ int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
+ auto wr_clken = SigSpec(cell->getParam(ID::WR_CLK_ENABLE));
+ auto wr_clkpol = SigSpec(cell->getParam(ID::WR_CLK_POLARITY));
wr_clken.extend_u0(wr_ports);
wr_clkpol.extend_u0(wr_ports);
- SigSpec wr_en = cell->getPort("\\WR_EN");
- SigSpec wr_clk = cell->getPort("\\WR_CLK");
- SigSpec wr_data = cell->getPort("\\WR_DATA");
- SigSpec wr_addr = cell->getPort("\\WR_ADDR");
+ SigSpec wr_en = cell->getPort(ID::WR_EN);
+ SigSpec wr_clk = cell->getPort(ID::WR_CLK);
+ SigSpec wr_data = cell->getPort(ID::WR_DATA);
+ SigSpec wr_addr = cell->getPort(ID::WR_ADDR);
- int rd_ports = cell->getParam("\\RD_PORTS").as_int();
- auto rd_clken = SigSpec(cell->getParam("\\RD_CLK_ENABLE"));
- auto rd_clkpol = SigSpec(cell->getParam("\\RD_CLK_POLARITY"));
- auto rd_transp = SigSpec(cell->getParam("\\RD_TRANSPARENT"));
+ int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
+ auto rd_clken = SigSpec(cell->getParam(ID::RD_CLK_ENABLE));
+ auto rd_clkpol = SigSpec(cell->getParam(ID::RD_CLK_POLARITY));
+ auto rd_transp = SigSpec(cell->getParam(ID::RD_TRANSPARENT));
rd_clken.extend_u0(rd_ports);
rd_clkpol.extend_u0(rd_ports);
rd_transp.extend_u0(rd_ports);
- SigSpec rd_en = cell->getPort("\\RD_EN");
- SigSpec rd_clk = cell->getPort("\\RD_CLK");
- SigSpec rd_data = cell->getPort("\\RD_DATA");
- SigSpec rd_addr = cell->getPort("\\RD_ADDR");
+ SigSpec rd_en = cell->getPort(ID::RD_EN);
+ SigSpec rd_clk = cell->getPort(ID::RD_CLK);
+ SigSpec rd_data = cell->getPort(ID::RD_DATA);
+ SigSpec rd_addr = cell->getPort(ID::RD_ADDR);
if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && wr_ports > 0)
{
@@ -843,7 +866,7 @@ grow_read_ports:;
}
else if (!exists)
continue;
- if (it->second != value)
+ if (rules.map_case(it->second) != value)
continue;
found = true;
break;
@@ -855,7 +878,7 @@ grow_read_ports:;
ss << "!";
IdString key = std::get<1>(sums.front());
ss << log_id(key);
- const Const &value = std::get<2>(sums.front());
+ const Const &value = rules.map_case(std::get<2>(sums.front()));
if (exists && value != Const(1))
ss << "=\"" << value.decode_string() << "\"";
@@ -915,7 +938,7 @@ grow_read_ports:;
else
initparam[i*bram.dbits+j] = padding;
}
- c->setParam("\\INIT", initparam);
+ c->setParam(ID::INIT, initparam);
}
for (auto &pi : portinfos)
@@ -1048,14 +1071,14 @@ void handle_cell(Cell *cell, const rules_t &rules)
{
log("Processing %s.%s:\n", log_id(cell->module), log_id(cell));
- bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
+ bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef();
dict<string, int> match_properties;
- match_properties["words"] = cell->getParam("\\SIZE").as_int();
- match_properties["abits"] = cell->getParam("\\ABITS").as_int();
- match_properties["dbits"] = cell->getParam("\\WIDTH").as_int();
- match_properties["wports"] = cell->getParam("\\WR_PORTS").as_int();
- match_properties["rports"] = cell->getParam("\\RD_PORTS").as_int();
+ match_properties["words"] = cell->getParam(ID::SIZE).as_int();
+ match_properties["abits"] = cell->getParam(ID::ABITS).as_int();
+ match_properties["dbits"] = cell->getParam(ID::WIDTH).as_int();
+ match_properties["wports"] = cell->getParam(ID::WR_PORTS).as_int();
+ match_properties["rports"] = cell->getParam(ID::RD_PORTS).as_int();
match_properties["bits"] = match_properties["words"] * match_properties["dbits"];
match_properties["ports"] = match_properties["wports"] + match_properties["rports"];
@@ -1079,9 +1102,6 @@ void handle_cell(Cell *cell, const rules_t &rules)
auto &bram = rules.brams.at(match.name).at(vi);
bool or_next_if_better = match.or_next_if_better || vi+1 < GetSize(rules.brams.at(match.name));
- if (failed_brams.count(pair<IdString, int>(bram.name, bram.variant)))
- continue;
-
int avail_rd_ports = 0;
int avail_wr_ports = 0;
for (int j = 0; j < bram.groups; j++) {
@@ -1117,6 +1137,9 @@ void handle_cell(Cell *cell, const rules_t &rules)
int efficiency = (100 * match_properties["bits"]) / (dups * cells * bram.dbits * (1 << bram.abits));
match_properties["efficiency"] = efficiency;
+ if (failed_brams.count(pair<IdString, int>(bram.name, bram.variant)))
+ goto next_match_rule;
+
log(" Metrics for %s: awaste=%d dwaste=%d bwaste=%d waste=%d efficiency=%d\n",
log_id(match.name), awaste, dwaste, bwaste, waste, efficiency);
@@ -1167,7 +1190,7 @@ void handle_cell(Cell *cell, const rules_t &rules)
}
else if (!exists)
continue;
- if (it->second != value)
+ if (rules.map_case(it->second) != value)
continue;
found = true;
break;
@@ -1179,7 +1202,7 @@ void handle_cell(Cell *cell, const rules_t &rules)
ss << "!";
IdString key = std::get<1>(sums.front());
ss << log_id(key);
- const Const &value = std::get<2>(sums.front());
+ const Const &value = rules.map_case(std::get<2>(sums.front()));
if (exists && value != Const(1))
ss << "=\"" << value.decode_string() << "\"";
@@ -1252,8 +1275,13 @@ struct MemoryBramPass : public Pass {
log("The given rules file describes the available resources and how they should be\n");
log("used.\n");
log("\n");
- log("The rules file contains a set of block ram description and a sequence of match\n");
- log("rules. A block ram description looks like this:\n");
+ log("The rules file contains configuration options, a set of block ram description\n");
+ log("and a sequence of match rules.\n");
+ log("\n");
+ log("The option 'attr_icase' configures how attribute values are matched. The value 0\n");
+ log("means case-sensitive, 1 means case-insensitive.\n");
+ log("\n");
+ log("A block ram description looks like this:\n");
log("\n");
log(" bram RAMB1024X32 # name of BRAM cell\n");
log(" init 1 # set to '1' if BRAM can be initialized\n");
@@ -1357,7 +1385,7 @@ struct MemoryBramPass : public Pass {
for (auto mod : design->selected_modules())
for (auto cell : mod->selected_cells())
- if (cell->type == "$mem")
+ if (cell->type == ID($mem))
handle_cell(cell, rules);
}
} MemoryBramPass;
diff --git a/passes/memory/memory_collect.cc b/passes/memory/memory_collect.cc
index 9dcb3f024..ef8b07811 100644
--- a/passes/memory/memory_collect.cc
+++ b/passes/memory/memory_collect.cc
@@ -25,11 +25,11 @@ PRIVATE_NAMESPACE_BEGIN
bool memcells_cmp(Cell *a, Cell *b)
{
- if (a->type == "$memrd" && b->type == "$memrd")
+ if (a->type == ID($memrd) && b->type == ID($memrd))
return a->name < b->name;
- if (a->type == "$memrd" || b->type == "$memrd")
- return (a->type == "$memrd") < (b->type == "$memrd");
- return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int();
+ if (a->type == ID($memrd) || b->type == ID($memrd))
+ return (a->type == ID($memrd)) < (b->type == ID($memrd));
+ return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int();
}
Cell *handle_memory(Module *module, RTLIL::Memory *memory)
@@ -60,16 +60,14 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
int addr_bits = 0;
std::vector<Cell*> memcells;
- for (auto &cell_it : module->cells_) {
- Cell *cell = cell_it.second;
- if (cell->type.in("$memrd", "$memwr", "$meminit") && memory->name == cell->parameters["\\MEMID"].decode_string()) {
- SigSpec addr = sigmap(cell->getPort("\\ADDR"));
+ for (auto cell : module->cells())
+ if (cell->type.in(ID($memrd), ID($memwr), ID($meminit)) && memory->name == cell->parameters[ID::MEMID].decode_string()) {
+ SigSpec addr = sigmap(cell->getPort(ID::ADDR));
for (int i = 0; i < GetSize(addr); i++)
if (addr[i] != State::S0)
addr_bits = std::max(addr_bits, i+1);
memcells.push_back(cell);
}
- }
if (memory->start_offset == 0 && addr_bits < 30 && (1 << addr_bits) < memory->size)
memory->size = 1 << addr_bits;
@@ -90,10 +88,10 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
{
log(" %s (%s)\n", log_id(cell), log_id(cell->type));
- if (cell->type == "$meminit")
+ if (cell->type == ID($meminit))
{
- SigSpec addr = sigmap(cell->getPort("\\ADDR"));
- SigSpec data = sigmap(cell->getPort("\\DATA"));
+ SigSpec addr = sigmap(cell->getPort(ID::ADDR));
+ SigSpec data = sigmap(cell->getPort(ID::DATA));
if (!addr.is_fully_const())
log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), log_id(cell));
@@ -112,14 +110,14 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
continue;
}
- if (cell->type == "$memwr")
+ if (cell->type == ID($memwr))
{
- SigSpec clk = sigmap(cell->getPort("\\CLK"));
- SigSpec clk_enable = SigSpec(cell->parameters["\\CLK_ENABLE"]);
- SigSpec clk_polarity = SigSpec(cell->parameters["\\CLK_POLARITY"]);
- SigSpec addr = sigmap(cell->getPort("\\ADDR"));
- SigSpec data = sigmap(cell->getPort("\\DATA"));
- SigSpec en = sigmap(cell->getPort("\\EN"));
+ SigSpec clk = sigmap(cell->getPort(ID::CLK));
+ SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]);
+ SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]);
+ SigSpec addr = sigmap(cell->getPort(ID::ADDR));
+ SigSpec data = sigmap(cell->getPort(ID::DATA));
+ SigSpec en = sigmap(cell->getPort(ID::EN));
if (!en.is_fully_zero())
{
@@ -142,15 +140,15 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
continue;
}
- if (cell->type == "$memrd")
+ if (cell->type == ID($memrd))
{
- SigSpec clk = sigmap(cell->getPort("\\CLK"));
- SigSpec clk_enable = SigSpec(cell->parameters["\\CLK_ENABLE"]);
- SigSpec clk_polarity = SigSpec(cell->parameters["\\CLK_POLARITY"]);
- SigSpec transparent = SigSpec(cell->parameters["\\TRANSPARENT"]);
- SigSpec addr = sigmap(cell->getPort("\\ADDR"));
- SigSpec data = sigmap(cell->getPort("\\DATA"));
- SigSpec en = sigmap(cell->getPort("\\EN"));
+ SigSpec clk = sigmap(cell->getPort(ID::CLK));
+ SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]);
+ SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]);
+ SigSpec transparent = SigSpec(cell->parameters[ID::TRANSPARENT]);
+ SigSpec addr = sigmap(cell->getPort(ID::ADDR));
+ SigSpec data = sigmap(cell->getPort(ID::DATA));
+ SigSpec en = sigmap(cell->getPort(ID::EN));
if (!en.is_fully_zero())
{
@@ -178,13 +176,13 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
std::stringstream sstr;
sstr << "$mem$" << memory->name.str() << "$" << (autoidx++);
- Cell *mem = module->addCell(sstr.str(), "$mem");
- mem->parameters["\\MEMID"] = Const(memory->name.str());
- mem->parameters["\\WIDTH"] = Const(memory->width);
- mem->parameters["\\OFFSET"] = Const(memory->start_offset);
- mem->parameters["\\SIZE"] = Const(memory->size);
- mem->parameters["\\ABITS"] = Const(addr_bits);
- mem->parameters["\\INIT"] = init_data;
+ Cell *mem = module->addCell(sstr.str(), ID($mem));
+ mem->parameters[ID::MEMID] = Const(memory->name.str());
+ mem->parameters[ID::WIDTH] = Const(memory->width);
+ mem->parameters[ID::OFFSET] = Const(memory->start_offset);
+ mem->parameters[ID::SIZE] = Const(memory->size);
+ mem->parameters[ID::ABITS] = Const(addr_bits);
+ mem->parameters[ID::INIT] = init_data;
log_assert(sig_wr_clk.size() == wr_ports);
log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const());
@@ -193,14 +191,14 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
log_assert(sig_wr_data.size() == wr_ports * memory->width);
log_assert(sig_wr_en.size() == wr_ports * memory->width);
- mem->parameters["\\WR_PORTS"] = Const(wr_ports);
- mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0;
- mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0;
+ mem->parameters[ID::WR_PORTS] = Const(wr_ports);
+ mem->parameters[ID::WR_CLK_ENABLE] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0;
+ mem->parameters[ID::WR_CLK_POLARITY] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0;
- mem->setPort("\\WR_CLK", sig_wr_clk);
- mem->setPort("\\WR_ADDR", sig_wr_addr);
- mem->setPort("\\WR_DATA", sig_wr_data);
- mem->setPort("\\WR_EN", sig_wr_en);
+ mem->setPort(ID::WR_CLK, sig_wr_clk);
+ mem->setPort(ID::WR_ADDR, sig_wr_addr);
+ mem->setPort(ID::WR_DATA, sig_wr_data);
+ mem->setPort(ID::WR_EN, sig_wr_en);
log_assert(sig_rd_clk.size() == rd_ports);
log_assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const());
@@ -208,15 +206,15 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
log_assert(sig_rd_addr.size() == rd_ports * addr_bits);
log_assert(sig_rd_data.size() == rd_ports * memory->width);
- mem->parameters["\\RD_PORTS"] = Const(rd_ports);
- mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0;
- mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0;
- mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : State::S0;
+ mem->parameters[ID::RD_PORTS] = Const(rd_ports);
+ mem->parameters[ID::RD_CLK_ENABLE] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0;
+ mem->parameters[ID::RD_CLK_POLARITY] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0;
+ mem->parameters[ID::RD_TRANSPARENT] = rd_ports ? sig_rd_transparent.as_const() : State::S0;
- mem->setPort("\\RD_CLK", sig_rd_clk);
- mem->setPort("\\RD_ADDR", sig_rd_addr);
- mem->setPort("\\RD_DATA", sig_rd_data);
- mem->setPort("\\RD_EN", sig_rd_en);
+ mem->setPort(ID::RD_CLK, sig_rd_clk);
+ mem->setPort(ID::RD_ADDR, sig_rd_addr);
+ mem->setPort(ID::RD_DATA, sig_rd_data);
+ mem->setPort(ID::RD_EN, sig_rd_en);
// Copy attributes from RTLIL memory to $mem
for (auto attr : memory->attributes)
@@ -260,9 +258,8 @@ struct MemoryCollectPass : public Pass {
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
log_header(design, "Executing MEMORY_COLLECT pass (generating $mem cells).\n");
extra_args(args, 1, design);
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
- handle_module(design, mod_it.second);
+ for (auto module : design->selected_modules())
+ handle_module(design, module);
}
} MemoryCollectPass;
diff --git a/passes/memory/memory_dff.cc b/passes/memory/memory_dff.cc
index be4b3c100..726a5c1ff 100644
--- a/passes/memory/memory_dff.cc
+++ b/passes/memory/memory_dff.cc
@@ -39,10 +39,10 @@ struct MemoryDffWorker
MemoryDffWorker(Module *module) : module(module), sigmap(module)
{
for (auto wire : module->wires()) {
- if (wire->attributes.count("\\init") == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec sig = sigmap(wire);
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(sig) && i < GetSize(initval); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
init_bits.insert(sig[i]);
@@ -66,8 +66,8 @@ struct MemoryDffWorker
if (after && forward_merged_dffs.count(cell))
continue;
- SigSpec this_clk = cell->getPort("\\CLK");
- bool this_clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
+ SigSpec this_clk = cell->getPort(ID::CLK);
+ bool this_clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool();
if (invbits.count(this_clk)) {
this_clk = invbits.at(this_clk);
@@ -81,10 +81,10 @@ struct MemoryDffWorker
continue;
}
- RTLIL::SigSpec q_norm = cell->getPort(after ? "\\D" : "\\Q");
+ RTLIL::SigSpec q_norm = cell->getPort(after ? ID::D : ID::Q);
sigmap.apply(q_norm);
- RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? "\\Q" : "\\D"));
+ RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? ID::Q : ID::D));
if (d.size() != 1)
continue;
@@ -113,19 +113,19 @@ struct MemoryDffWorker
bool clk_polarity = 0;
candidate_dffs.clear();
- RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
+ RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR);
if (!find_sig_before_dff(sig_addr, clk, clk_polarity)) {
log("no (compatible) $dff for address input found.\n");
return;
}
- RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
+ RTLIL::SigSpec sig_data = cell->getPort(ID::DATA);
if (!find_sig_before_dff(sig_data, clk, clk_polarity)) {
log("no (compatible) $dff for data input found.\n");
return;
}
- RTLIL::SigSpec sig_en = cell->getPort("\\EN");
+ RTLIL::SigSpec sig_en = cell->getPort(ID::EN);
if (!find_sig_before_dff(sig_en, clk, clk_polarity)) {
log("no (compatible) $dff for enable input found.\n");
return;
@@ -136,12 +136,12 @@ struct MemoryDffWorker
for (auto cell : candidate_dffs)
forward_merged_dffs.insert(cell);
- cell->setPort("\\CLK", clk);
- cell->setPort("\\ADDR", sig_addr);
- cell->setPort("\\DATA", sig_data);
- cell->setPort("\\EN", sig_en);
- cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
+ cell->setPort(ID::CLK, clk);
+ cell->setPort(ID::ADDR, sig_addr);
+ cell->setPort(ID::DATA, sig_data);
+ cell->setPort(ID::EN, sig_en);
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
log("merged $dff to cell.\n");
return;
@@ -161,10 +161,10 @@ struct MemoryDffWorker
RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size());
for (auto cell : module->cells())
- if (cell->type == "$dff") {
- RTLIL::SigSpec new_q = cell->getPort("\\Q");
+ if (cell->type == ID($dff)) {
+ RTLIL::SigSpec new_q = cell->getPort(ID::Q);
new_q.replace(sig, new_sig);
- cell->setPort("\\Q", new_q);
+ cell->setPort(ID::Q, new_q);
}
}
@@ -175,7 +175,7 @@ struct MemoryDffWorker
bool clk_polarity = 0;
RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx);
- RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
+ RTLIL::SigSpec sig_data = cell->getPort(ID::DATA);
for (auto bit : sigmap(sig_data))
if (sigbit_users_count[bit] > 1)
@@ -189,9 +189,9 @@ struct MemoryDffWorker
do {
bool enable_invert = mux_cells_a.count(sig_data) != 0;
Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data);
- check_q.push_back(sigmap(mux->getPort(enable_invert ? "\\B" : "\\A")));
- sig_data = sigmap(mux->getPort("\\Y"));
- en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S"));
+ check_q.push_back(sigmap(mux->getPort(enable_invert ? ID::B : ID::A)));
+ sig_data = sigmap(mux->getPort(ID::Y));
+ en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort(ID::S)) : mux->getPort(ID::S));
} while (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data));
for (auto bit : sig_data)
@@ -202,12 +202,12 @@ struct MemoryDffWorker
std::all_of(check_q.begin(), check_q.end(), [&](const SigSpec &cq) {return cq == sig_data; }))
{
disconnect_dff(sig_data);
- cell->setPort("\\CLK", clk_data);
- cell->setPort("\\EN", en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en);
- cell->setPort("\\DATA", sig_data);
- cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
- cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
+ cell->setPort(ID::CLK, clk_data);
+ cell->setPort(ID::EN, en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en);
+ cell->setPort(ID::DATA, sig_data);
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
+ cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
log("merged data $dff with rd enable to cell.\n");
return;
}
@@ -217,12 +217,12 @@ struct MemoryDffWorker
if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx))
{
disconnect_dff(sig_data);
- cell->setPort("\\CLK", clk_data);
- cell->setPort("\\EN", State::S1);
- cell->setPort("\\DATA", sig_data);
- cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
- cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
+ cell->setPort(ID::CLK, clk_data);
+ cell->setPort(ID::EN, State::S1);
+ cell->setPort(ID::DATA, sig_data);
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
+ cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
log("merged data $dff to cell.\n");
return;
}
@@ -230,16 +230,16 @@ struct MemoryDffWorker
skip_ff_after_read_merging:;
RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx);
- RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
+ RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR);
if (find_sig_before_dff(sig_addr, clk_addr, clk_polarity) &&
clk_addr != RTLIL::SigSpec(RTLIL::State::Sx))
{
- cell->setPort("\\CLK", clk_addr);
- cell->setPort("\\EN", State::S1);
- cell->setPort("\\ADDR", sig_addr);
- cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
- cell->parameters["\\TRANSPARENT"] = RTLIL::Const(1);
+ cell->setPort(ID::CLK, clk_addr);
+ cell->setPort(ID::EN, State::S1);
+ cell->setPort(ID::ADDR, sig_addr);
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
+ cell->parameters[ID::TRANSPARENT] = RTLIL::Const(1);
log("merged address $dff to cell.\n");
return;
}
@@ -256,18 +256,18 @@ struct MemoryDffWorker
}
for (auto cell : module->cells()) {
- if (cell->type == "$dff")
+ if (cell->type == ID($dff))
dff_cells.push_back(cell);
- if (cell->type == "$mux") {
- mux_cells_a[sigmap(cell->getPort("\\A"))] = cell;
- mux_cells_b[sigmap(cell->getPort("\\B"))] = cell;
+ if (cell->type == ID($mux)) {
+ mux_cells_a[sigmap(cell->getPort(ID::A))] = cell;
+ mux_cells_b[sigmap(cell->getPort(ID::B))] = cell;
}
- if (cell->type.in("$not", "$_NOT_") || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) {
- SigSpec sig_a = cell->getPort("\\A");
- SigSpec sig_y = cell->getPort("\\Y");
- if (cell->type == "$not")
- sig_a.extend_u0(GetSize(sig_y), cell->getParam("\\A_SIGNED").as_bool());
- if (cell->type == "$logic_not")
+ if (cell->type.in(ID($not), ID($_NOT_)) || (cell->type == ID($logic_not) && GetSize(cell->getPort(ID::A)) == 1)) {
+ SigSpec sig_a = cell->getPort(ID::A);
+ SigSpec sig_y = cell->getPort(ID::Y);
+ if (cell->type == ID($not))
+ sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
+ if (cell->type == ID($logic_not))
sig_y.extend_u0(1);
for (int i = 0; i < GetSize(sig_y); i++)
invbits[sig_y[i]] = sig_a[i];
@@ -279,12 +279,12 @@ struct MemoryDffWorker
}
for (auto cell : module->selected_cells())
- if (cell->type == "$memwr" && !cell->parameters["\\CLK_ENABLE"].as_bool())
+ if (cell->type == ID($memwr) && !cell->parameters[ID::CLK_ENABLE].as_bool())
handle_wr_cell(cell);
if (!flag_wr_only)
for (auto cell : module->selected_cells())
- if (cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool())
+ if (cell->type == ID($memrd) && !cell->parameters[ID::CLK_ENABLE].as_bool())
handle_rd_cell(cell);
}
};
diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc
index 65bccb5ef..9d455f55b 100644
--- a/passes/memory/memory_map.cc
+++ b/passes/memory/memory_map.cc
@@ -28,11 +28,32 @@ PRIVATE_NAMESPACE_BEGIN
struct MemoryMapWorker
{
+ bool attr_icase = false;
+ dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
+
RTLIL::Design *design;
RTLIL::Module *module;
std::map<std::pair<RTLIL::SigSpec, RTLIL::SigSpec>, RTLIL::SigBit> decoder_cache;
+ MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module) {}
+
+ std::string map_case(std::string value) const
+ {
+ if (attr_icase) {
+ for (char &c : value)
+ c = tolower(c);
+ }
+ return value;
+ }
+
+ RTLIL::Const map_case(RTLIL::Const value) const
+ {
+ if (value.flags & RTLIL::CONST_FLAG_STRING)
+ return map_case(value.decode_string());
+ return value;
+ }
+
std::string genid(RTLIL::IdString name, std::string token1 = "", int i = -1, std::string token2 = "", int j = -1, std::string token3 = "", int k = -1, std::string token4 = "")
{
std::stringstream sstr;
@@ -81,15 +102,15 @@ struct MemoryMapWorker
std::set<int> static_ports;
std::map<int, RTLIL::SigSpec> static_cells_map;
- int wr_ports = cell->parameters["\\WR_PORTS"].as_int();
- int rd_ports = cell->parameters["\\RD_PORTS"].as_int();
+ int wr_ports = cell->parameters[ID::WR_PORTS].as_int();
+ int rd_ports = cell->parameters[ID::RD_PORTS].as_int();
- int mem_size = cell->parameters["\\SIZE"].as_int();
- int mem_width = cell->parameters["\\WIDTH"].as_int();
- int mem_offset = cell->parameters["\\OFFSET"].as_int();
- int mem_abits = cell->parameters["\\ABITS"].as_int();
+ int mem_size = cell->parameters[ID::SIZE].as_int();
+ int mem_width = cell->parameters[ID::WIDTH].as_int();
+ int mem_offset = cell->parameters[ID::OFFSET].as_int();
+ int mem_abits = cell->parameters[ID::ABITS].as_int();
- SigSpec init_data = cell->getParam("\\INIT");
+ SigSpec init_data = cell->getParam(ID::INIT);
init_data.extend_u0(mem_size*mem_width, true);
// delete unused memory cell
@@ -98,23 +119,53 @@ struct MemoryMapWorker
return;
}
+ // check if attributes allow us to infer FFRAM for this cell
+ for (const auto &attr : attributes) {
+ if (cell->attributes.count(attr.first)) {
+ const auto &cell_attr = cell->attributes[attr.first];
+ if (attr.second.empty()) {
+ log("Not mapping memory cell %s in module %s (attribute %s is set).\n",
+ cell->name.c_str(), module->name.c_str(), attr.first.c_str());
+ return;
+ }
+
+ bool found = false;
+ for (auto &value : attr.second) {
+ if (map_case(cell_attr) == map_case(value)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ if (cell_attr.flags & RTLIL::CONST_FLAG_STRING) {
+ log("Not mapping memory cell %s in module %s (attribute %s is set to \"%s\").\n",
+ cell->name.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.decode_string().c_str());
+ } else {
+ log("Not mapping memory cell %s in module %s (attribute %s is set to %d).\n",
+ cell->name.c_str(), module->name.c_str(), attr.first.c_str(), cell_attr.as_int());
+ }
+ return;
+ }
+ }
+ }
+
// all write ports must share the same clock
- RTLIL::SigSpec clocks = cell->getPort("\\WR_CLK");
- RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"];
- RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"];
+ RTLIL::SigSpec clocks = cell->getPort(ID::WR_CLK);
+ RTLIL::Const clocks_pol = cell->parameters[ID::WR_CLK_POLARITY];
+ RTLIL::Const clocks_en = cell->parameters[ID::WR_CLK_ENABLE];
clocks_pol.bits.resize(wr_ports);
clocks_en.bits.resize(wr_ports);
RTLIL::SigSpec refclock;
RTLIL::State refclock_pol = RTLIL::State::Sx;
for (int i = 0; i < clocks.size(); i++) {
- RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(i * mem_width, mem_width);
+ RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(i * mem_width, mem_width);
if (wr_en.is_fully_const() && !wr_en.as_bool()) {
static_ports.insert(i);
continue;
}
if (clocks_en.bits[i] != RTLIL::State::S1) {
- RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(i*mem_abits, mem_abits);
- RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(i*mem_width, mem_width);
+ RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(i*mem_abits, mem_abits);
+ RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(i*mem_width, mem_width);
if (wr_addr.is_fully_const()) {
// FIXME: Actually we should check for wr_en.is_fully_const() also and
// create a $adff cell with this ports wr_en input as reset pin when wr_en
@@ -155,21 +206,21 @@ struct MemoryMapWorker
}
else
{
- RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), "$dff");
- c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
+ RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), ID($dff));
+ c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
if (clocks_pol.bits.size() > 0) {
- c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]);
- c->setPort("\\CLK", clocks.extract(0, 1));
+ c->parameters[ID::CLK_POLARITY] = RTLIL::Const(clocks_pol.bits[0]);
+ c->setPort(ID::CLK, clocks.extract(0, 1));
} else {
- c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1);
- c->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::S0));
+ c->parameters[ID::CLK_POLARITY] = RTLIL::Const(RTLIL::State::S1);
+ c->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::S0));
}
RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width);
data_reg_in.push_back(RTLIL::SigSpec(w_in));
- c->setPort("\\D", data_reg_in.back());
+ c->setPort(ID::D, data_reg_in.back());
- std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i);
+ std::string w_out_name = stringf("%s[%d]", cell->parameters[ID::MEMID].decode_string().c_str(), i);
if (module->wires_.count(w_out_name) > 0)
w_out_name = genid(cell->name, "", i, "$q");
@@ -177,10 +228,10 @@ struct MemoryMapWorker
SigSpec w_init = init_data.extract(i*mem_width, mem_width);
if (!w_init.is_fully_undef())
- w_out->attributes["\\init"] = w_init.as_const();
+ w_out->attributes[ID::init] = w_init.as_const();
data_reg_out.push_back(RTLIL::SigSpec(w_out));
- c->setPort("\\Q", data_reg_out.back());
+ c->setPort(ID::Q, data_reg_out.back());
}
}
@@ -188,55 +239,55 @@ struct MemoryMapWorker
int count_dff = 0, count_mux = 0, count_wrmux = 0;
- for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++)
+ for (int i = 0; i < cell->parameters[ID::RD_PORTS].as_int(); i++)
{
- RTLIL::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits);
+ RTLIL::SigSpec rd_addr = cell->getPort(ID::RD_ADDR).extract(i*mem_abits, mem_abits);
if (mem_offset)
rd_addr = module->Sub(NEW_ID, rd_addr, SigSpec(mem_offset, GetSize(rd_addr)));
std::vector<RTLIL::SigSpec> rd_signals;
- rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width));
+ rd_signals.push_back(cell->getPort(ID::RD_DATA).extract(i*mem_width, mem_width));
- if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1)
+ if (cell->parameters[ID::RD_CLK_ENABLE].bits[i] == RTLIL::State::S1)
{
RTLIL::Cell *dff_cell = nullptr;
- if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1)
+ if (cell->parameters[ID::RD_TRANSPARENT].bits[i] == RTLIL::State::S1)
{
- dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
- dff_cell->parameters["\\WIDTH"] = RTLIL::Const(mem_abits);
- dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
- dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
- dff_cell->setPort("\\D", rd_addr);
+ dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff));
+ dff_cell->parameters[ID::WIDTH] = RTLIL::Const(mem_abits);
+ dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]);
+ dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1));
+ dff_cell->setPort(ID::D, rd_addr);
count_dff++;
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits);
- dff_cell->setPort("\\Q", RTLIL::SigSpec(w));
+ dff_cell->setPort(ID::Q, RTLIL::SigSpec(w));
rd_addr = RTLIL::SigSpec(w);
}
else
{
- dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
- dff_cell->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
- dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
- dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
- dff_cell->setPort("\\Q", rd_signals.back());
+ dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff));
+ dff_cell->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
+ dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]);
+ dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1));
+ dff_cell->setPort(ID::Q, rd_signals.back());
count_dff++;
RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width);
rd_signals.clear();
rd_signals.push_back(RTLIL::SigSpec(w));
- dff_cell->setPort("\\D", rd_signals.back());
+ dff_cell->setPort(ID::D, rd_signals.back());
}
- SigBit en_bit = cell->getPort("\\RD_EN").extract(i);
+ SigBit en_bit = cell->getPort(ID::RD_EN).extract(i);
if (en_bit != State::S1) {
SigSpec new_d = module->Mux(genid(cell->name, "$rdenmux", i),
- dff_cell->getPort("\\Q"), dff_cell->getPort("\\D"), en_bit);
- dff_cell->setPort("\\D", new_d);
+ dff_cell->getPort(ID::Q), dff_cell->getPort(ID::D), en_bit);
+ dff_cell->setPort(ID::D, new_d);
}
}
@@ -246,17 +297,17 @@ struct MemoryMapWorker
for (size_t k = 0; k < rd_signals.size(); k++)
{
- RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux");
- c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
- c->setPort("\\Y", rd_signals[k]);
- c->setPort("\\S", rd_addr.extract(mem_abits-j-1, 1));
+ RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), ID($mux));
+ c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
+ c->setPort(ID::Y, rd_signals[k]);
+ c->setPort(ID::S, rd_addr.extract(mem_abits-j-1, 1));
count_mux++;
- c->setPort("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width));
- c->setPort("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width));
+ c->setPort(ID::A, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width));
+ c->setPort(ID::B, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width));
- next_rd_signals.push_back(c->getPort("\\A"));
- next_rd_signals.push_back(c->getPort("\\B"));
+ next_rd_signals.push_back(c->getPort(ID::A));
+ next_rd_signals.push_back(c->getPort(ID::B));
}
next_rd_signals.swap(rd_signals);
@@ -275,11 +326,11 @@ struct MemoryMapWorker
RTLIL::SigSpec sig = data_reg_out[i];
- for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++)
+ for (int j = 0; j < cell->parameters[ID::WR_PORTS].as_int(); j++)
{
- RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits);
- RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width);
- RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width);
+ RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(j*mem_abits, mem_abits);
+ RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(j*mem_width, mem_width);
+ RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(j*mem_width, mem_width);
if (mem_offset)
wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem_offset, GetSize(wr_addr)));
@@ -303,27 +354,27 @@ struct MemoryMapWorker
if (wr_bit != State::S1)
{
- RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and");
- c->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- c->parameters["\\B_SIGNED"] = RTLIL::Const(0);
- c->parameters["\\A_WIDTH"] = RTLIL::Const(1);
- c->parameters["\\B_WIDTH"] = RTLIL::Const(1);
- c->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
- c->setPort("\\A", w);
- c->setPort("\\B", wr_bit);
+ RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), ID($and));
+ c->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ c->parameters[ID::B_SIGNED] = RTLIL::Const(0);
+ c->parameters[ID::A_WIDTH] = RTLIL::Const(1);
+ c->parameters[ID::B_WIDTH] = RTLIL::Const(1);
+ c->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
+ c->setPort(ID::A, w);
+ c->setPort(ID::B, wr_bit);
w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"));
- c->setPort("\\Y", RTLIL::SigSpec(w));
+ c->setPort(ID::Y, RTLIL::SigSpec(w));
}
- RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux");
- c->parameters["\\WIDTH"] = wr_width;
- c->setPort("\\A", sig.extract(wr_offset, wr_width));
- c->setPort("\\B", wr_data.extract(wr_offset, wr_width));
- c->setPort("\\S", RTLIL::SigSpec(w));
+ RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), ID($mux));
+ c->parameters[ID::WIDTH] = wr_width;
+ c->setPort(ID::A, sig.extract(wr_offset, wr_width));
+ c->setPort(ID::B, wr_data.extract(wr_offset, wr_width));
+ c->setPort(ID::S, RTLIL::SigSpec(w));
w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width);
- c->setPort("\\Y", w);
+ c->setPort(ID::Y, w);
sig.replace(wr_offset, w);
wr_offset += wr_width;
@@ -339,11 +390,11 @@ struct MemoryMapWorker
module->remove(cell);
}
- MemoryMapWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module)
+ void run()
{
std::vector<RTLIL::Cell*> cells;
for (auto cell : module->selected_cells())
- if (cell->type == "$mem" && design->selected(module, cell))
+ if (cell->type == ID($mem))
cells.push_back(cell);
for (auto cell : cells)
handle_cell(cell);
@@ -356,17 +407,73 @@ struct MemoryMapPass : public Pass {
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" memory_map [selection]\n");
+ log(" memory_map [options] [selection]\n");
log("\n");
log("This pass converts multiport memory cells as generated by the memory_collect\n");
log("pass to word-wide DFFs and address decoders.\n");
log("\n");
+ log(" -attr !<name>\n");
+ log(" do not map memories that have attribute <name> set.\n");
+ log("\n");
+ log(" -attr <name>[=<value>]\n");
+ log(" for memories that have attribute <name> set, only map them if its value\n");
+ log(" is a string <value> (if specified), or an integer 1 (otherwise). if this\n");
+ log(" option is specified multiple times, map the memory if the attribute is\n");
+ log(" to any of the values.\n");
+ log("\n");
+ log(" -iattr\n");
+ log(" for -attr, ignore case of <value>.\n");
+ log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ bool attr_icase = false;
+ dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes;
+
log_header(design, "Executing MEMORY_MAP pass (converting $mem cells to logic and flip-flops).\n");
- extra_args(args, 1, design);
- for (auto mod : design->selected_modules())
- MemoryMapWorker(design, mod);
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ if (args[argidx] == "-attr" && argidx + 1 < args.size())
+ {
+ std::string attr_arg = args[++argidx];
+ std::string name;
+ RTLIL::Const value;
+ size_t eq_at = attr_arg.find('=');
+ if (eq_at != std::string::npos) {
+ name = attr_arg.substr(0, eq_at);
+ value = attr_arg.substr(eq_at + 1);
+ } else {
+ name = attr_arg;
+ value = RTLIL::Const(1);
+ }
+ if (attr_arg.size() > 1 && attr_arg[0] == '!') {
+ if (value != RTLIL::Const(1)) {
+ --argidx;
+ break; // we don't support -attr !<name>=<value>
+ }
+ attributes[RTLIL::escape_id(name.substr(1))].clear();
+ } else {
+ attributes[RTLIL::escape_id(name)].push_back(value);
+ }
+ continue;
+ }
+ if (args[argidx] == "-iattr")
+ {
+ attr_icase = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ for (auto mod : design->selected_modules()) {
+ MemoryMapWorker worker(design, mod);
+ worker.attr_icase = attr_icase;
+ worker.attributes = attributes;
+ worker.run();
+ }
}
} MemoryMapPass;
diff --git a/passes/memory/memory_memx.cc b/passes/memory/memory_memx.cc
index 958370164..5d5f61c7d 100644
--- a/passes/memory/memory_memx.cc
+++ b/passes/memory/memory_memx.cc
@@ -47,18 +47,18 @@ struct MemoryMemxPass : public Pass {
vector<Cell*> mem_port_cells;
for (auto cell : module->selected_cells())
- if (cell->type.in("$memrd", "$memwr"))
+ if (cell->type.in(ID($memrd), ID($memwr)))
mem_port_cells.push_back(cell);
for (auto cell : mem_port_cells)
{
- IdString memid = cell->getParam("\\MEMID").decode_string();
+ IdString memid = cell->getParam(ID::MEMID).decode_string();
RTLIL::Memory *mem = module->memories.at(memid);
int lowest_addr = mem->start_offset;
int highest_addr = mem->start_offset + mem->size - 1;
- SigSpec addr = cell->getPort("\\ADDR");
+ SigSpec addr = cell->getPort(ID::ADDR);
addr.extend_u0(32);
SigSpec addr_ok = module->Nex(NEW_ID, module->ReduceXor(NEW_ID, addr), module->ReduceXor(NEW_ID, {addr, State::S1}));
@@ -66,23 +66,23 @@ struct MemoryMemxPass : public Pass {
addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Ge(NEW_ID, addr, lowest_addr));
addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Le(NEW_ID, addr, highest_addr));
- if (cell->type == "$memrd")
+ if (cell->type == ID($memrd))
{
- if (cell->getParam("\\CLK_ENABLE").as_bool())
+ if (cell->getParam(ID::CLK_ENABLE).as_bool())
log_error("Cell %s.%s (%s) has an enabled clock. Clocked $memrd cells are not supported by memory_memx!\n",
log_id(module), log_id(cell), log_id(cell->type));
- SigSpec rdata = cell->getPort("\\DATA");
+ SigSpec rdata = cell->getPort(ID::DATA);
Wire *raw_rdata = module->addWire(NEW_ID, GetSize(rdata));
module->addMux(NEW_ID, SigSpec(State::Sx, GetSize(rdata)), raw_rdata, addr_ok, rdata);
- cell->setPort("\\DATA", raw_rdata);
+ cell->setPort(ID::DATA, raw_rdata);
}
- if (cell->type == "$memwr")
+ if (cell->type == ID($memwr))
{
- SigSpec en = cell->getPort("\\EN");
+ SigSpec en = cell->getPort(ID::EN);
en = module->And(NEW_ID, en, addr_ok.repeat(GetSize(en)));
- cell->setPort("\\EN", en);
+ cell->setPort(ID::EN, en);
}
}
}
diff --git a/passes/memory/memory_nordff.cc b/passes/memory/memory_nordff.cc
index ba0361c0f..487785397 100644
--- a/passes/memory/memory_nordff.cc
+++ b/passes/memory/memory_nordff.cc
@@ -52,19 +52,19 @@ struct MemoryNordffPass : public Pass {
for (auto module : design->selected_modules())
for (auto cell : vector<Cell*>(module->selected_cells()))
{
- if (cell->type != "$mem")
+ if (cell->type != ID($mem))
continue;
- int rd_ports = cell->getParam("\\RD_PORTS").as_int();
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
+ int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
- SigSpec rd_addr = cell->getPort("\\RD_ADDR");
- SigSpec rd_data = cell->getPort("\\RD_DATA");
- SigSpec rd_clk = cell->getPort("\\RD_CLK");
- SigSpec rd_en = cell->getPort("\\RD_EN");
- Const rd_clk_enable = cell->getParam("\\RD_CLK_ENABLE");
- Const rd_clk_polarity = cell->getParam("\\RD_CLK_POLARITY");
+ SigSpec rd_addr = cell->getPort(ID::RD_ADDR);
+ SigSpec rd_data = cell->getPort(ID::RD_DATA);
+ SigSpec rd_clk = cell->getPort(ID::RD_CLK);
+ SigSpec rd_en = cell->getPort(ID::RD_EN);
+ Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE);
+ Const rd_clk_polarity = cell->getParam(ID::RD_CLK_POLARITY);
for (int i = 0; i < rd_ports; i++)
{
@@ -72,11 +72,11 @@ struct MemoryNordffPass : public Pass {
if (clk_enable)
{
- bool clk_polarity = cell->getParam("\\RD_CLK_POLARITY")[i] == State::S1;
- bool transparent = cell->getParam("\\RD_TRANSPARENT")[i] == State::S1;
+ bool clk_polarity = cell->getParam(ID::RD_CLK_POLARITY)[i] == State::S1;
+ bool transparent = cell->getParam(ID::RD_TRANSPARENT)[i] == State::S1;
- SigSpec clk = cell->getPort("\\RD_CLK")[i] ;
- SigSpec en = cell->getPort("\\RD_EN")[i];
+ SigSpec clk = cell->getPort(ID::RD_CLK)[i] ;
+ SigSpec en = cell->getPort(ID::RD_EN)[i];
Cell *c;
if (transparent)
@@ -108,12 +108,12 @@ struct MemoryNordffPass : public Pass {
rd_clk_polarity[i] = State::S1;
}
- cell->setPort("\\RD_ADDR", rd_addr);
- cell->setPort("\\RD_DATA", rd_data);
- cell->setPort("\\RD_CLK", rd_clk);
- cell->setPort("\\RD_EN", rd_en);
- cell->setParam("\\RD_CLK_ENABLE", rd_clk_enable);
- cell->setParam("\\RD_CLK_POLARITY", rd_clk_polarity);
+ cell->setPort(ID::RD_ADDR, rd_addr);
+ cell->setPort(ID::RD_DATA, rd_data);
+ cell->setPort(ID::RD_CLK, rd_clk);
+ cell->setPort(ID::RD_EN, rd_en);
+ cell->setParam(ID::RD_CLK_ENABLE, rd_clk_enable);
+ cell->setParam(ID::RD_CLK_POLARITY, rd_clk_polarity);
}
}
} MemoryNordffPass;
diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc
index eb912cfd4..477246687 100644
--- a/passes/memory/memory_share.cc
+++ b/passes/memory/memory_share.cc
@@ -27,11 +27,11 @@ PRIVATE_NAMESPACE_BEGIN
bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b)
{
- if (a->type == "$memrd" && b->type == "$memrd")
+ if (a->type == ID($memrd) && b->type == ID($memrd))
return a->name < b->name;
- if (a->type == "$memrd" || b->type == "$memrd")
- return (a->type == "$memrd") < (b->type == "$memrd");
- return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int();
+ if (a->type == ID($memrd) || b->type == ID($memrd))
+ return (a->type == ID($memrd)) < (b->type == ID($memrd));
+ return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int();
}
struct MemoryShareWorker
@@ -64,18 +64,18 @@ struct MemoryShareWorker
RTLIL::Cell *cell = sig_to_mux.at(sig).first;
int bit_idx = sig_to_mux.at(sig).second;
- std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A"));
- std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B"));
- std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort("\\S"));
- std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
+ std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort(ID::A));
+ std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort(ID::B));
+ std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort(ID::S));
+ std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
log_assert(sig_y.at(bit_idx) == sig);
for (int i = 0; i < int(sig_s.size()); i++)
if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) {
if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) {
- RTLIL::SigSpec new_b = cell->getPort("\\B");
+ RTLIL::SigSpec new_b = cell->getPort(ID::B);
new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx);
- cell->setPort("\\B", new_b);
+ cell->setPort(ID::B, new_b);
}
return false;
}
@@ -90,9 +90,9 @@ struct MemoryShareWorker
new_state[sig_s[i]] = true;
if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) {
- RTLIL::SigSpec new_b = cell->getPort("\\B");
+ RTLIL::SigSpec new_b = cell->getPort(ID::B);
new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx);
- cell->setPort("\\B", new_b);
+ cell->setPort(ID::B, new_b);
}
}
@@ -101,9 +101,9 @@ struct MemoryShareWorker
new_state[sig_s[i]] = false;
if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) {
- RTLIL::SigSpec new_a = cell->getPort("\\A");
+ RTLIL::SigSpec new_a = cell->getPort(ID::A);
new_a.replace(bit_idx, RTLIL::State::Sx);
- cell->setPort("\\A", new_a);
+ cell->setPort(ID::A, new_a);
}
return false;
@@ -120,8 +120,8 @@ struct MemoryShareWorker
for (auto &cond : conditions) {
RTLIL::SigSpec sig1, sig2;
for (auto &it : cond) {
- sig1.append_bit(it.first);
- sig2.append_bit(it.second ? RTLIL::State::S1 : RTLIL::State::S0);
+ sig1.append(it.first);
+ sig2.append(it.second ? RTLIL::State::S1 : RTLIL::State::S0);
}
terms.append(module->Ne(NEW_ID, sig1, sig2));
created_conditions++;
@@ -155,12 +155,12 @@ struct MemoryShareWorker
{
bool ignore_data_port = false;
- if (cell->type.in("$mux", "$pmux"))
+ if (cell->type.in(ID($mux), ID($pmux)))
{
- std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A"));
- std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B"));
- std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort("\\S"));
- std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
+ std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort(ID::A));
+ std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort(ID::B));
+ std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort(ID::S));
+ std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
non_feedback_nets.insert(sig_s.begin(), sig_s.end());
@@ -173,13 +173,13 @@ struct MemoryShareWorker
continue;
}
- if (cell->type.in("$memwr", "$memrd") &&
- cell->parameters.at("\\MEMID").decode_string() == memid)
+ if (cell->type.in(ID($memwr), ID($memrd)) &&
+ cell->parameters.at(ID::MEMID).decode_string() == memid)
ignore_data_port = true;
for (auto conn : cell->connections())
{
- if (ignore_data_port && conn.first == "\\DATA")
+ if (ignore_data_port && conn.first == ID::DATA)
continue;
std::vector<RTLIL::SigBit> bits = sigmap(conn.second);
non_feedback_nets.insert(bits.begin(), bits.end());
@@ -204,11 +204,11 @@ struct MemoryShareWorker
for (auto cell : rd_ports)
{
- if (cell->parameters.at("\\CLK_ENABLE").as_bool())
+ if (cell->parameters.at(ID::CLK_ENABLE).as_bool())
continue;
- RTLIL::SigSpec sig_addr = sigmap(cell->getPort("\\ADDR"));
- std::vector<RTLIL::SigBit> sig_data = sigmap(cell->getPort("\\DATA"));
+ RTLIL::SigSpec sig_addr = sigmap(cell->getPort(ID::ADDR));
+ std::vector<RTLIL::SigBit> sig_data = sigmap(cell->getPort(ID::DATA));
for (int i = 0; i < int(sig_data.size()); i++)
if (non_feedback_nets.count(sig_data[i]))
@@ -228,14 +228,14 @@ struct MemoryShareWorker
for (auto cell : wr_ports)
{
- RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort("\\ADDR"));
+ RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort(ID::ADDR));
if (!async_rd_bits.count(sig_addr))
continue;
log(" Analyzing write port %s.\n", log_id(cell));
- std::vector<RTLIL::SigBit> cell_data = cell->getPort("\\DATA");
- std::vector<RTLIL::SigBit> cell_en = cell->getPort("\\EN");
+ std::vector<RTLIL::SigBit> cell_data = cell->getPort(ID::DATA);
+ std::vector<RTLIL::SigBit> cell_en = cell->getPort(ID::EN);
int created_conditions = 0;
for (int i = 0; i < int(cell_data.size()); i++)
@@ -250,7 +250,7 @@ struct MemoryShareWorker
if (created_conditions) {
log(" Added enable logic for %d different cases.\n", created_conditions);
- cell->setPort("\\EN", cell_en);
+ cell->setPort(ID::EN, cell_en);
}
}
}
@@ -284,8 +284,8 @@ struct MemoryShareWorker
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_bits[i], v_mask_bits[i]);
if (groups.count(key) == 0) {
groups[key].first = grouped_bits.size();
- grouped_bits.append_bit(v_bits[i]);
- grouped_mask_bits.append_bit(v_mask_bits[i]);
+ grouped_bits.append(v_bits[i]);
+ grouped_mask_bits.append(v_mask_bits[i]);
}
groups[key].second.push_back(i);
}
@@ -295,7 +295,7 @@ struct MemoryShareWorker
for (int i = 0; i < bits.size(); i++) {
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_bits[i], v_mask_bits[i]);
- result.append_bit(grouped_result.at(groups.at(key).first));
+ result.append(grouped_result.at(groups.at(key).first));
}
return result;
@@ -326,7 +326,7 @@ struct MemoryShareWorker
for (int i = 0; i < int(v_old_en.size()); i++) {
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(v_old_en[i], v_next_en[i]);
- new_merged_en.append_bit(grouped_new_en.at(groups.at(key)));
+ new_merged_en.append(grouped_new_en.at(groups.at(key)));
}
// Create the new merged_data signal.
@@ -368,15 +368,15 @@ struct MemoryShareWorker
for (int i = 0; i < int(wr_ports.size()); i++)
{
RTLIL::Cell *cell = wr_ports.at(i);
- RTLIL::SigSpec addr = sigmap_xmux(cell->getPort("\\ADDR"));
+ RTLIL::SigSpec addr = sigmap_xmux(cell->getPort(ID::ADDR));
- if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable ||
- (cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk ||
- cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity)))
+ if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable ||
+ (cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk ||
+ cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity)))
{
- cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool();
- cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool();
- cache_clk = sigmap(cell->getPort("\\CLK"));
+ cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
+ cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool();
+ cache_clk = sigmap(cell->getPort(ID::CLK));
last_port_by_addr.clear();
if (cache_clk_enable)
@@ -388,7 +388,7 @@ struct MemoryShareWorker
log(" Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr));
log(" Active bits: ");
- std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort("\\EN"));
+ std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort(ID::EN));
active_bits_on_port.push_back(std::vector<bool>(en_bits.size()));
for (int k = int(en_bits.size())-1; k >= 0; k--) {
active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0;
@@ -410,13 +410,13 @@ struct MemoryShareWorker
// Force this ports addr input to addr directly (skip don't care muxes)
- cell->setPort("\\ADDR", addr);
+ cell->setPort(ID::ADDR, addr);
// If any of the ports between `last_i' and `i' write to the same address, this
// will have priority over whatever `last_i` wrote. So we need to revisit those
// ports and mask the EN bits accordingly.
- RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort("\\EN"));
+ RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort(ID::EN));
for (int j = last_i+1; j < i; j++)
{
@@ -431,20 +431,20 @@ struct MemoryShareWorker
found_overlapping_bits_i_j:
log(" Creating collosion-detect logic for port %d.\n", j);
RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID);
- module->addEq(NEW_ID, addr, wr_ports[j]->getPort("\\ADDR"), is_same_addr);
- merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort("\\EN")));
+ module->addEq(NEW_ID, addr, wr_ports[j]->getPort(ID::ADDR), is_same_addr);
+ merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort(ID::EN)));
}
}
// Then we need to merge the (masked) EN and the DATA signals.
- RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort("\\DATA");
+ RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort(ID::DATA);
if (found_overlapping_bits) {
log(" Creating logic for merging DATA and EN ports.\n");
- merge_en_data(merged_en, merged_data, sigmap(cell->getPort("\\EN")), sigmap(cell->getPort("\\DATA")));
+ merge_en_data(merged_en, merged_data, sigmap(cell->getPort(ID::EN)), sigmap(cell->getPort(ID::DATA)));
} else {
- RTLIL::SigSpec cell_en = sigmap(cell->getPort("\\EN"));
- RTLIL::SigSpec cell_data = sigmap(cell->getPort("\\DATA"));
+ RTLIL::SigSpec cell_en = sigmap(cell->getPort(ID::EN));
+ RTLIL::SigSpec cell_data = sigmap(cell->getPort(ID::DATA));
for (int k = 0; k < int(en_bits.size()); k++)
if (!active_bits_on_port[last_i][k]) {
merged_en.replace(k, cell_en.extract(k, 1));
@@ -454,14 +454,14 @@ struct MemoryShareWorker
// Connect the new EN and DATA signals and remove the old write port.
- cell->setPort("\\EN", merged_en);
- cell->setPort("\\DATA", merged_data);
+ cell->setPort(ID::EN, merged_en);
+ cell->setPort(ID::DATA, merged_data);
module->remove(wr_ports[last_i]);
wr_ports[last_i] = NULL;
log(" Active bits: ");
- std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort("\\EN"));
+ std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort(ID::EN));
active_bits_on_port.push_back(std::vector<bool>(en_bits.size()));
for (int k = int(en_bits.size())-1; k >= 0; k--)
log("%c", active_bits_on_port[i][k] ? '1' : '0');
@@ -500,7 +500,7 @@ struct MemoryShareWorker
std::set<int> considered_port_pairs;
for (int i = 0; i < int(wr_ports.size()); i++) {
- std::vector<RTLIL::SigBit> bits = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
+ std::vector<RTLIL::SigBit> bits = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
for (auto bit : bits)
if (bit == RTLIL::State::S1)
goto port_is_always_active;
@@ -519,13 +519,13 @@ struct MemoryShareWorker
{
RTLIL::Cell *cell = wr_ports.at(i);
- if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable ||
- (cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk ||
- cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity)))
+ if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable ||
+ (cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk ||
+ cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity)))
{
- cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool();
- cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool();
- cache_clk = sigmap(cell->getPort("\\CLK"));
+ cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
+ cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool();
+ cache_clk = sigmap(cell->getPort(ID::CLK));
}
else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i))
considered_port_pairs.insert(i);
@@ -554,7 +554,7 @@ struct MemoryShareWorker
for (int i = 0; i < int(wr_ports.size()); i++)
if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1))
{
- RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
+ RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
port_to_sat_variable[i] = ez->expression(ez->OpOr, satgen.importSigSpec(sig));
std::vector<RTLIL::SigBit> bits = sig;
@@ -564,7 +564,7 @@ struct MemoryShareWorker
while (!bits_queue.empty())
{
for (auto bit : bits_queue)
- if (bit.wire && bit.wire->get_bool_attribute("\\onehot"))
+ if (bit.wire && bit.wire->get_bool_attribute(ID::onehot))
one_hot_wires.insert(bit.wire);
pool<ModWalker::PortBit> portbits;
@@ -609,13 +609,13 @@ struct MemoryShareWorker
log(" Merging port %d into port %d.\n", i-1, i);
port_to_sat_variable.at(i) = ez->OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i));
- RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort("\\ADDR");
- RTLIL::SigSpec last_data = wr_ports[i-1]->getPort("\\DATA");
- std::vector<RTLIL::SigBit> last_en = modwalker.sigmap(wr_ports[i-1]->getPort("\\EN"));
+ RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort(ID::ADDR);
+ RTLIL::SigSpec last_data = wr_ports[i-1]->getPort(ID::DATA);
+ std::vector<RTLIL::SigBit> last_en = modwalker.sigmap(wr_ports[i-1]->getPort(ID::EN));
- RTLIL::SigSpec this_addr = wr_ports[i]->getPort("\\ADDR");
- RTLIL::SigSpec this_data = wr_ports[i]->getPort("\\DATA");
- std::vector<RTLIL::SigBit> this_en = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
+ RTLIL::SigSpec this_addr = wr_ports[i]->getPort(ID::ADDR);
+ RTLIL::SigSpec this_data = wr_ports[i]->getPort(ID::DATA);
+ std::vector<RTLIL::SigBit> this_en = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en);
@@ -624,9 +624,9 @@ struct MemoryShareWorker
else
this_addr.extend_u0(GetSize(last_addr));
- wr_ports[i]->setParam("\\ABITS", GetSize(this_addr));
- wr_ports[i]->setPort("\\ADDR", module->Mux(NEW_ID, last_addr, this_addr, this_en_active));
- wr_ports[i]->setPort("\\DATA", module->Mux(NEW_ID, last_data, this_data, this_en_active));
+ wr_ports[i]->setParam(ID::ABITS, GetSize(this_addr));
+ wr_ports[i]->setPort(ID::ADDR, module->Mux(NEW_ID, last_addr, this_addr, this_en_active));
+ wr_ports[i]->setPort(ID::DATA, module->Mux(NEW_ID, last_data, this_data, this_en_active));
std::map<std::pair<RTLIL::SigBit, RTLIL::SigBit>, int> groups_en;
RTLIL::SigSpec grouped_last_en, grouped_this_en, en;
@@ -635,8 +635,8 @@ struct MemoryShareWorker
for (int j = 0; j < int(this_en.size()); j++) {
std::pair<RTLIL::SigBit, RTLIL::SigBit> key(last_en[j], this_en[j]);
if (!groups_en.count(key)) {
- grouped_last_en.append_bit(last_en[j]);
- grouped_this_en.append_bit(this_en[j]);
+ grouped_last_en.append(last_en[j]);
+ grouped_this_en.append(this_en[j]);
groups_en[key] = grouped_en->width;
grouped_en->width++;
}
@@ -644,7 +644,7 @@ struct MemoryShareWorker
}
module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en);
- wr_ports[i]->setPort("\\EN", en);
+ wr_ports[i]->setPort(ID::EN, en);
module->remove(wr_ports[i-1]);
wr_ports[i-1] = NULL;
@@ -665,34 +665,40 @@ struct MemoryShareWorker
// Setup and run
// -------------
- MemoryShareWorker(RTLIL::Design *design, RTLIL::Module *module) :
- design(design), module(module), sigmap(module)
+ MemoryShareWorker(RTLIL::Design *design) : design(design), modwalker(design) {}
+
+ void operator()(RTLIL::Module* module)
{
std::map<std::string, std::pair<std::vector<RTLIL::Cell*>, std::vector<RTLIL::Cell*>>> memindex;
+ this->module = module;
+ sigmap.set(module);
+ sig_to_mux.clear();
+ conditions_logic_cache.clear();
+
sigmap_xmux = sigmap;
for (auto cell : module->cells())
{
- if (cell->type == "$memrd")
- memindex[cell->parameters.at("\\MEMID").decode_string()].first.push_back(cell);
+ if (cell->type == ID($memrd))
+ memindex[cell->parameters.at(ID::MEMID).decode_string()].first.push_back(cell);
- if (cell->type == "$memwr")
- memindex[cell->parameters.at("\\MEMID").decode_string()].second.push_back(cell);
+ if (cell->type == ID($memwr))
+ memindex[cell->parameters.at(ID::MEMID).decode_string()].second.push_back(cell);
- if (cell->type == "$mux")
+ if (cell->type == ID($mux))
{
- RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort("\\A"));
- RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort("\\B"));
+ RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort(ID::A));
+ RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort(ID::B));
if (sig_a.is_fully_undef())
- sigmap_xmux.add(cell->getPort("\\Y"), sig_b);
+ sigmap_xmux.add(cell->getPort(ID::Y), sig_b);
else if (sig_b.is_fully_undef())
- sigmap_xmux.add(cell->getPort("\\Y"), sig_a);
+ sigmap_xmux.add(cell->getPort(ID::Y), sig_a);
}
- if (cell->type.in("$mux", "$pmux"))
+ if (cell->type.in(ID($mux), ID($pmux)))
{
- std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
+ std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
for (int i = 0; i < int(sig_y.size()); i++)
sig_to_mux[sig_y[i]] = std::pair<RTLIL::Cell*, int>(cell, i);
}
@@ -706,18 +712,18 @@ struct MemoryShareWorker
}
cone_ct.setup_internals();
- cone_ct.cell_types.erase("$mul");
- cone_ct.cell_types.erase("$mod");
- cone_ct.cell_types.erase("$div");
- cone_ct.cell_types.erase("$pow");
- cone_ct.cell_types.erase("$shl");
- cone_ct.cell_types.erase("$shr");
- cone_ct.cell_types.erase("$sshl");
- cone_ct.cell_types.erase("$sshr");
- cone_ct.cell_types.erase("$shift");
- cone_ct.cell_types.erase("$shiftx");
-
- modwalker.setup(design, module, &cone_ct);
+ cone_ct.cell_types.erase(ID($mul));
+ cone_ct.cell_types.erase(ID($mod));
+ cone_ct.cell_types.erase(ID($div));
+ cone_ct.cell_types.erase(ID($pow));
+ cone_ct.cell_types.erase(ID($shl));
+ cone_ct.cell_types.erase(ID($shr));
+ cone_ct.cell_types.erase(ID($sshl));
+ cone_ct.cell_types.erase(ID($sshr));
+ cone_ct.cell_types.erase(ID($shift));
+ cone_ct.cell_types.erase(ID($shiftx));
+
+ modwalker.setup(module, &cone_ct);
for (auto &it : memindex)
consolidate_wr_using_sat(it.first, it.second.second);
@@ -755,8 +761,10 @@ struct MemorySharePass : public Pass {
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
log_header(design, "Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells).\n");
extra_args(args, 1, design);
+ MemoryShareWorker msw(design);
+
for (auto module : design->selected_modules())
- MemoryShareWorker(design, module);
+ msw(module);
}
} MemorySharePass;
diff --git a/passes/memory/memory_unpack.cc b/passes/memory/memory_unpack.cc
index 49ec66792..8d284edcd 100644
--- a/passes/memory/memory_unpack.cc
+++ b/passes/memory/memory_unpack.cc
@@ -31,53 +31,53 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
log("Creating $memrd and $memwr for memory `%s' in module `%s':\n",
memory->name.c_str(), module->name.c_str());
- RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at("\\MEMID").decode_string());
+ RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at(ID::MEMID).decode_string());
while (module->memories.count(mem_name) != 0)
mem_name = mem_name.str() + stringf("_%d", autoidx++);
RTLIL::Memory *mem = new RTLIL::Memory;
mem->name = mem_name;
- mem->width = memory->parameters.at("\\WIDTH").as_int();
- mem->start_offset = memory->parameters.at("\\OFFSET").as_int();
- mem->size = memory->parameters.at("\\SIZE").as_int();
+ mem->width = memory->parameters.at(ID::WIDTH).as_int();
+ mem->start_offset = memory->parameters.at(ID::OFFSET).as_int();
+ mem->size = memory->parameters.at(ID::SIZE).as_int();
module->memories[mem_name] = mem;
- int abits = memory->parameters.at("\\ABITS").as_int();
- int num_rd_ports = memory->parameters.at("\\RD_PORTS").as_int();
- int num_wr_ports = memory->parameters.at("\\WR_PORTS").as_int();
+ int abits = memory->parameters.at(ID::ABITS).as_int();
+ int num_rd_ports = memory->parameters.at(ID::RD_PORTS).as_int();
+ int num_wr_ports = memory->parameters.at(ID::WR_PORTS).as_int();
for (int i = 0; i < num_rd_ports; i++)
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$memrd");
- cell->parameters["\\MEMID"] = mem_name.str();
- cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
- cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
- cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_ENABLE")).extract(i, 1).as_const();
- cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const();
- cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const();
- cell->setPort("\\CLK", memory->getPort("\\RD_CLK").extract(i, 1));
- cell->setPort("\\EN", memory->getPort("\\RD_EN").extract(i, 1));
- cell->setPort("\\ADDR", memory->getPort("\\RD_ADDR").extract(i*abits, abits));
- cell->setPort("\\DATA", memory->getPort("\\RD_DATA").extract(i*mem->width, mem->width));
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($memrd));
+ cell->parameters[ID::MEMID] = mem_name.str();
+ cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS);
+ cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH);
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::SigSpec(memory->parameters.at(ID::RD_CLK_ENABLE)).extract(i, 1).as_const();
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::SigSpec(memory->parameters.at(ID::RD_CLK_POLARITY)).extract(i, 1).as_const();
+ cell->parameters[ID::TRANSPARENT] = RTLIL::SigSpec(memory->parameters.at(ID::RD_TRANSPARENT)).extract(i, 1).as_const();
+ cell->setPort(ID::CLK, memory->getPort(ID::RD_CLK).extract(i, 1));
+ cell->setPort(ID::EN, memory->getPort(ID::RD_EN).extract(i, 1));
+ cell->setPort(ID::ADDR, memory->getPort(ID::RD_ADDR).extract(i*abits, abits));
+ cell->setPort(ID::DATA, memory->getPort(ID::RD_DATA).extract(i*mem->width, mem->width));
}
for (int i = 0; i < num_wr_ports; i++)
{
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$memwr");
- cell->parameters["\\MEMID"] = mem_name.str();
- cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
- cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
- cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_ENABLE")).extract(i, 1).as_const();
- cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const();
- cell->parameters["\\PRIORITY"] = i;
- cell->setPort("\\CLK", memory->getPort("\\WR_CLK").extract(i, 1));
- cell->setPort("\\EN", memory->getPort("\\WR_EN").extract(i*mem->width, mem->width));
- cell->setPort("\\ADDR", memory->getPort("\\WR_ADDR").extract(i*abits, abits));
- cell->setPort("\\DATA", memory->getPort("\\WR_DATA").extract(i*mem->width, mem->width));
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($memwr));
+ cell->parameters[ID::MEMID] = mem_name.str();
+ cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS);
+ cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH);
+ cell->parameters[ID::CLK_ENABLE] = RTLIL::SigSpec(memory->parameters.at(ID::WR_CLK_ENABLE)).extract(i, 1).as_const();
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::SigSpec(memory->parameters.at(ID::WR_CLK_POLARITY)).extract(i, 1).as_const();
+ cell->parameters[ID::PRIORITY] = i;
+ cell->setPort(ID::CLK, memory->getPort(ID::WR_CLK).extract(i, 1));
+ cell->setPort(ID::EN, memory->getPort(ID::WR_EN).extract(i*mem->width, mem->width));
+ cell->setPort(ID::ADDR, memory->getPort(ID::WR_ADDR).extract(i*abits, abits));
+ cell->setPort(ID::DATA, memory->getPort(ID::WR_DATA).extract(i*mem->width, mem->width));
}
- Const initval = memory->parameters.at("\\INIT");
+ Const initval = memory->parameters.at(ID::INIT);
RTLIL::Cell *last_init_cell = nullptr;
SigSpec last_init_data;
int last_init_addr=0;
@@ -90,19 +90,19 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
continue;
found_non_undef_initval:
if (last_init_cell && last_init_addr+1 == i/mem->width) {
- last_init_cell->parameters["\\WORDS"] = last_init_cell->parameters["\\WORDS"].as_int() + 1;
+ last_init_cell->parameters[ID::WORDS] = last_init_cell->parameters[ID::WORDS].as_int() + 1;
last_init_data.append(val);
last_init_addr++;
} else {
if (last_init_cell)
- last_init_cell->setPort("\\DATA", last_init_data);
- RTLIL::Cell *cell = module->addCell(NEW_ID, "$meminit");
- cell->parameters["\\MEMID"] = mem_name.str();
- cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
- cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
- cell->parameters["\\WORDS"] = 1;
- cell->parameters["\\PRIORITY"] = i/mem->width;
- cell->setPort("\\ADDR", SigSpec(i/mem->width, abits));
+ last_init_cell->setPort(ID::DATA, last_init_data);
+ RTLIL::Cell *cell = module->addCell(NEW_ID, ID($meminit));
+ cell->parameters[ID::MEMID] = mem_name.str();
+ cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS);
+ cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH);
+ cell->parameters[ID::WORDS] = 1;
+ cell->parameters[ID::PRIORITY] = i/mem->width;
+ cell->setPort(ID::ADDR, SigSpec(i/mem->width, abits));
last_init_cell = cell;
last_init_addr = i/mem->width;
last_init_data = val;
@@ -110,7 +110,7 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
}
if (last_init_cell)
- last_init_cell->setPort("\\DATA", last_init_data);
+ last_init_cell->setPort(ID::DATA, last_init_data);
module->remove(memory);
}
@@ -118,11 +118,11 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
void handle_module(RTLIL::Design *design, RTLIL::Module *module)
{
std::vector<RTLIL::IdString> memcells;
- for (auto &cell_it : module->cells_)
- if (cell_it.second->type == "$mem" && design->selected(module, cell_it.second))
- memcells.push_back(cell_it.first);
+ for (auto cell : module->cells())
+ if (cell->type == ID($mem) && design->selected(module, cell))
+ memcells.push_back(cell->name);
for (auto &it : memcells)
- handle_memory(module, module->cells_.at(it));
+ handle_memory(module, module->cell(it));
}
struct MemoryUnpackPass : public Pass {
@@ -140,9 +140,8 @@ struct MemoryUnpackPass : public Pass {
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
log_header(design, "Executing MEMORY_UNPACK pass (generating $memrd/$memwr cells form $mem cells).\n");
extra_args(args, 1, design);
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
- handle_module(design, mod_it.second);
+ for (auto module : design->selected_modules())
+ handle_module(design, module);
}
} MemoryUnpackPass;
diff --git a/passes/opt/muxpack.cc b/passes/opt/muxpack.cc
index c40c02acd..9df49ab3c 100644
--- a/passes/opt/muxpack.cc
+++ b/passes/opt/muxpack.cc
@@ -208,8 +208,8 @@ struct MuxpackWorker
{
Cell *prev_cell = sig_chain_prev.at(a_sig);
log_assert(prev_cell);
- SigSpec s_sig = sigmap(cell->getPort(ID(S)));
- s_sig.append(sigmap(prev_cell->getPort(ID(S))));
+ SigSpec s_sig = sigmap(cell->getPort(ID::S));
+ s_sig.append(sigmap(prev_cell->getPort(ID::S)));
if (!excl_db.query(s_sig))
goto start_cell;
}
@@ -271,26 +271,26 @@ struct MuxpackWorker
first_cell->type = ID($pmux);
SigSpec b_sig = first_cell->getPort(ID::B);
- SigSpec s_sig = first_cell->getPort(ID(S));
+ SigSpec s_sig = first_cell->getPort(ID::S);
for (int i = 1; i < cases; i++) {
Cell* prev_cell = chain[cursor+i-1];
Cell* cursor_cell = chain[cursor+i];
if (sigmap(prev_cell->getPort(ID::Y)) == sigmap(cursor_cell->getPort(ID::A))) {
b_sig.append(cursor_cell->getPort(ID::B));
- s_sig.append(cursor_cell->getPort(ID(S)));
+ s_sig.append(cursor_cell->getPort(ID::S));
}
else {
log_assert(cursor_cell->type == ID($mux));
b_sig.append(cursor_cell->getPort(ID::A));
- s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S))));
+ s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID::S)));
}
remove_cells.insert(cursor_cell);
}
first_cell->setPort(ID::B, b_sig);
- first_cell->setPort(ID(S), s_sig);
- first_cell->setParam(ID(S_WIDTH), GetSize(s_sig));
+ first_cell->setPort(ID::S, s_sig);
+ first_cell->setParam(ID::S_WIDTH, GetSize(s_sig));
first_cell->setPort(ID::Y, last_cell->getPort(ID::Y));
cursor += cases;
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index cac265a52..6271376f1 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -183,8 +183,8 @@ void rmunused_module_cells(Module *module, bool verbose)
int count_nontrivial_wire_attrs(RTLIL::Wire *w)
{
int count = w->attributes.size();
- count -= w->attributes.count(ID(src));
- count -= w->attributes.count(ID(unused_bits));
+ count -= w->attributes.count(ID::src);
+ count -= w->attributes.count(ID::unused_bits);
return count;
}
@@ -203,8 +203,8 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool &regs, SigPoo
return !(w2->port_input && w2->port_output);
if (w1->name[0] == '\\' && w2->name[0] == '\\') {
- if (regs.check_any(s1) != regs.check_any(s2))
- return regs.check_any(s2);
+ if (regs.check(s1) != regs.check(s2))
+ return regs.check(s2);
if (direct_wires.count(w1) != direct_wires.count(w2))
return direct_wires.count(w2) != 0;
if (conns.check_any(s1) != conns.check_any(s2))
@@ -317,12 +317,12 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
log_assert(GetSize(s1) == GetSize(s2));
Const initval;
- if (wire->attributes.count(ID(init)))
- initval = wire->attributes.at(ID(init));
+ if (wire->attributes.count(ID::init))
+ initval = wire->attributes.at(ID::init);
if (GetSize(initval) != GetSize(wire))
initval.bits.resize(GetSize(wire), State::Sx);
if (initval.is_fully_undef())
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
if (GetSize(wire) == 0) {
// delete zero-width wires, unless they are module ports
@@ -358,14 +358,14 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
s2[i] = initval[i];
initval[i] = State::Sx;
}
- new_conn.first.append_bit(s1[i]);
- new_conn.second.append_bit(s2[i]);
+ new_conn.first.append(s1[i]);
+ new_conn.second.append(s2[i]);
}
if (new_conn.first.size() > 0) {
if (initval.is_fully_undef())
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
else
- wire->attributes.at(ID(init)) = initval;
+ wire->attributes.at(ID::init) = initval;
used_signals.add(new_conn.first);
used_signals.add(new_conn.second);
module->connect(new_conn);
@@ -383,11 +383,11 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
}
}
if (unused_bits.empty() || wire->port_id != 0)
- wire->attributes.erase(ID(unused_bits));
+ wire->attributes.erase(ID::unused_bits);
else
- wire->attributes[ID(unused_bits)] = RTLIL::Const(unused_bits);
+ wire->attributes[ID::unused_bits] = RTLIL::Const(unused_bits);
} else {
- wire->attributes.erase(ID(unused_bits));
+ wire->attributes.erase(ID::unused_bits);
}
}
}
@@ -406,6 +406,9 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
if (verbose && del_temp_wires_count)
log_debug(" removed %d unused temporary wires.\n", del_temp_wires_count);
+ if (!del_wires_queue.empty())
+ module->design->scratchpad_set_bool("opt.did_something", true);
+
return !del_wires_queue.empty();
}
@@ -419,18 +422,18 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
dict<SigBit, State> qbits;
for (auto cell : module->cells())
- if (fftypes.cell_known(cell->type) && cell->hasPort(ID(Q)))
+ if (fftypes.cell_known(cell->type) && cell->hasPort(ID::Q))
{
- SigSpec sig = cell->getPort(ID(Q));
+ SigSpec sig = cell->getPort(ID::Q);
for (int i = 0; i < GetSize(sig); i++)
{
SigBit bit = sig[i];
- if (bit.wire == nullptr || bit.wire->attributes.count(ID(init)) == 0)
+ if (bit.wire == nullptr || bit.wire->attributes.count(ID::init) == 0)
continue;
- Const init = bit.wire->attributes.at(ID(init));
+ Const init = bit.wire->attributes.at(ID::init);
if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz)
continue;
@@ -445,10 +448,10 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
if (!purge_mode && wire->name[0] == '\\')
continue;
- if (wire->attributes.count(ID(init)) == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
- Const init = wire->attributes.at(ID(init));
+ Const init = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++)
{
@@ -471,11 +474,14 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
if (verbose)
log_debug(" removing redundant init attribute on %s.\n", log_id(wire));
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
did_something = true;
next_wire:;
}
+ if (did_something)
+ module->design->scratchpad_set_bool("opt.did_something", true);
+
return did_something;
}
@@ -487,7 +493,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
std::vector<RTLIL::Cell*> delcells;
for (auto cell : module->cells())
if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) {
- bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->type == ID($pos) && cell->getParam(ID::A_SIGNED).as_bool();
RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec y = cell->getPort(ID::Y);
a.extend_u0(GetSize(y), is_signed);
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 4a2f170b8..3229dd1b2 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -31,9 +31,8 @@ PRIVATE_NAMESPACE_BEGIN
bool did_something;
-void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
+void replace_undriven(RTLIL::Module *module, const CellTypes &ct)
{
- CellTypes ct(design);
SigMap sigmap(module);
SigPool driven_signals;
SigPool used_signals;
@@ -51,9 +50,9 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
}
for (auto wire : module->wires()) {
- if (wire->attributes.count(ID(init))) {
+ if (wire->attributes.count(ID::init)) {
SigSpec sig = sigmap(wire);
- Const initval = wire->attributes.at(ID(init));
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) {
if (initval[i] == State::S0 || initval[i] == State::S1)
initbits[sig[i]] = make_pair(wire, initval[i]);
@@ -99,18 +98,18 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
for (auto wire : revisit_initwires) {
SigSpec sig = sm2(wire);
- Const initval = wire->attributes.at(ID(init));
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) {
if (SigBit(initval[i]) == sig[i])
initval[i] = State::Sx;
}
if (initval.is_fully_undef()) {
log_debug("Removing init attribute from %s/%s.\n", log_id(module), log_id(wire));
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
did_something = true;
- } else if (initval != wire->attributes.at(ID(init))) {
+ } else if (initval != wire->attributes.at(ID::init)) {
log_debug("Updating init attribute on %s/%s: %s\n", log_id(module), log_id(wire), log_signal(initval));
- wire->attributes[ID(init)] = initval;
+ wire->attributes[ID::init] = initval;
did_something = true;
}
}
@@ -137,7 +136,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ
{
IdString b_name = cell->hasPort(ID::B) ? ID::B : ID::A;
- bool a_signed = cell->parameters.at(ID(A_SIGNED)).as_bool();
+ bool a_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
bool b_signed = cell->parameters.at(b_name.str() + "_SIGNED").as_bool();
RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID::A));
@@ -193,11 +192,11 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ
for (auto &it : grouped_bits[i]) {
for (auto &bit : it.second) {
- new_conn.first.append_bit(bit);
- new_conn.second.append_bit(RTLIL::SigBit(new_y, new_a.size()));
+ new_conn.first.append(bit);
+ new_conn.second.append(RTLIL::SigBit(new_y, new_a.size()));
}
- new_a.append_bit(it.first.first);
- new_b.append_bit(it.first.second);
+ new_a.append(it.first.first);
+ new_b.append(it.first.second);
}
if (cell->type.in(ID($and), ID($or)) && i == GRP_CONST_A) {
@@ -210,17 +209,17 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ
RTLIL::Cell *c = module->addCell(NEW_ID, cell->type);
c->setPort(ID::A, new_a);
- c->parameters[ID(A_WIDTH)] = new_a.size();
- c->parameters[ID(A_SIGNED)] = false;
+ c->parameters[ID::A_WIDTH] = new_a.size();
+ c->parameters[ID::A_SIGNED] = false;
if (b_name == ID::B) {
c->setPort(ID::B, new_b);
- c->parameters[ID(B_WIDTH)] = new_b.size();
- c->parameters[ID(B_SIGNED)] = false;
+ c->parameters[ID::B_WIDTH] = new_b.size();
+ c->parameters[ID::B_SIGNED] = false;
}
c->setPort(ID::Y, new_y);
- c->parameters[ID(Y_WIDTH)] = new_y->width;
+ c->parameters[ID::Y_WIDTH] = new_y->width;
c->check();
module->connect(new_conn);
@@ -373,7 +372,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A));
if (cell->type.in(ID($mux), ID($_MUX_)) &&
cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0))
- invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID(S)));
+ invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::S));
if (ct_combinational.cell_known(cell->type))
for (auto &conn : cell->connections()) {
RTLIL::SigSpec sig = assign_map(conn.second);
@@ -402,36 +401,36 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (clkinv)
{
if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($adff), ID($fsm), ID($memrd), ID($memwr)))
- handle_polarity_inv(cell, ID(CLK), ID(CLK_POLARITY), assign_map, invert_map);
+ handle_polarity_inv(cell, ID::CLK, ID::CLK_POLARITY, assign_map, invert_map);
if (cell->type.in(ID($sr), ID($dffsr), ID($dlatchsr))) {
- handle_polarity_inv(cell, ID(SET), ID(SET_POLARITY), assign_map, invert_map);
- handle_polarity_inv(cell, ID(CLR), ID(CLR_POLARITY), assign_map, invert_map);
+ handle_polarity_inv(cell, ID::SET, ID::SET_POLARITY, assign_map, invert_map);
+ handle_polarity_inv(cell, ID::CLR, ID::CLR_POLARITY, assign_map, invert_map);
}
if (cell->type.in(ID($dffe), ID($dlatch), ID($dlatchsr)))
- handle_polarity_inv(cell, ID(EN), ID(EN_POLARITY), assign_map, invert_map);
+ handle_polarity_inv(cell, ID::EN, ID::EN_POLARITY, assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID(S), assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_SR_?N_", "$_SR_?P_", ID(R), assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID::S, assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_SR_?N_", "$_SR_?P_", ID::R, assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFF_N_", "$_DFF_P_", ID(C), assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFF_N_", "$_DFF_P_", ID::C, assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFFE_N?_", "$_DFFE_P?_", ID(C), assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFFE_?N_", "$_DFFE_?P_", ID(E), assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFFE_N?_", "$_DFFE_P?_", ID::C, assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFFE_?N_", "$_DFFE_?P_", ID::E, assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFF_N??_", "$_DFF_P??_", ID(C), assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFF_?N?_", "$_DFF_?P?_", ID(R), assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFF_N??_", "$_DFF_P??_", ID::C, assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFF_?N?_", "$_DFF_?P?_", ID::R, assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFFSR_N??_", "$_DFFSR_P??_", ID(C), assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFFSR_?N?_", "$_DFFSR_?P?_", ID(S), assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DFFSR_??N_", "$_DFFSR_??P_", ID(R), assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFFSR_N??_", "$_DFFSR_P??_", ID::C, assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFFSR_?N?_", "$_DFFSR_?P?_", ID::S, assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DFFSR_??N_", "$_DFFSR_??P_", ID::R, assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DLATCH_N_", "$_DLATCH_P_", ID(E), assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DLATCH_N_", "$_DLATCH_P_", ID::E, assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DLATCHSR_N??_", "$_DLATCHSR_P??_", ID(E), assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DLATCHSR_?N?_", "$_DLATCHSR_?P?_", ID(S), assign_map, invert_map);
- handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID(R), assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DLATCHSR_N??_", "$_DLATCHSR_P??_", ID::E, assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DLATCHSR_?N?_", "$_DLATCHSR_?P?_", ID::S, assign_map, invert_map);
+ handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID::R, assign_map, invert_map);
}
bool detect_const_and = false;
@@ -440,13 +439,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (cell->type.in(ID($reduce_and), ID($_AND_)))
detect_const_and = true;
- if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool())
+ if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID::A_SIGNED).as_bool())
detect_const_and = true;
if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($_OR_)))
detect_const_or = true;
- if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool())
+ if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID::A_SIGNED).as_bool())
detect_const_or = true;
if (detect_const_and || detect_const_or)
@@ -496,6 +495,42 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
}
+ if (cell->type.in(ID($_XOR_), ID($_XNOR_)) || (cell->type.in(ID($xor), ID($xnor)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID::A_SIGNED).as_bool()))
+ {
+ SigBit sig_a = assign_map(cell->getPort(ID::A));
+ SigBit sig_b = assign_map(cell->getPort(ID::B));
+ if (!sig_a.wire)
+ std::swap(sig_a, sig_b);
+ if (sig_b == State::S0 || sig_b == State::S1) {
+ if (cell->type.in(ID($xor), ID($_XOR_))) {
+ cover("opt.opt_expr.xor_buffer");
+ SigSpec sig_y;
+ if (cell->type == ID($xor))
+ sig_y = (sig_b == State::S1 ? module->Not(NEW_ID, sig_a).as_bit() : sig_a);
+ else if (cell->type == ID($_XOR_))
+ sig_y = (sig_b == State::S1 ? module->NotGate(NEW_ID, sig_a) : sig_a);
+ else log_abort();
+ replace_cell(assign_map, module, cell, "xor_buffer", ID::Y, sig_y);
+ goto next_cell;
+ }
+ if (cell->type.in(ID($xnor), ID($_XNOR_))) {
+ cover("opt.opt_expr.xnor_buffer");
+ SigSpec sig_y;
+ if (cell->type == ID($xnor)) {
+ sig_y = (sig_b == State::S1 ? sig_a : module->Not(NEW_ID, sig_a).as_bit());
+ int width = cell->getParam(ID::Y_WIDTH).as_int();
+ sig_y.append(RTLIL::Const(State::S1, width-1));
+ }
+ else if (cell->type == ID($_XNOR_))
+ sig_y = (sig_b == State::S1 ? sig_a : module->NotGate(NEW_ID, sig_a));
+ else log_abort();
+ replace_cell(assign_map, module, cell, "xnor_buffer", ID::Y, sig_y);
+ goto next_cell;
+ }
+ log_abort();
+ }
+ }
+
if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($reduce_xor), ID($reduce_xnor), ID($neg)) &&
GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1)
{
@@ -536,7 +571,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
log_debug("Replacing port A of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_sig_a));
cell->setPort(ID::A, new_sig_a);
- cell->parameters.at(ID(A_WIDTH)) = GetSize(new_sig_a);
+ cell->parameters.at(ID::A_WIDTH) = GetSize(new_sig_a);
did_something = true;
}
}
@@ -559,7 +594,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
log_debug("Replacing port B of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_sig_b));
cell->setPort(ID::B, new_sig_b);
- cell->parameters.at(ID(B_WIDTH)) = GetSize(new_sig_b);
+ cell->parameters.at(ID::B_WIDTH) = GetSize(new_sig_b);
did_something = true;
}
}
@@ -585,7 +620,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
cell->setPort(ID::A, sig_a = new_a);
- cell->parameters.at(ID(A_WIDTH)) = 1;
+ cell->parameters.at(ID::A_WIDTH) = 1;
did_something = true;
}
}
@@ -611,7 +646,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
cell->setPort(ID::A, sig_a = new_a);
- cell->parameters.at(ID(A_WIDTH)) = 1;
+ cell->parameters.at(ID::A_WIDTH) = 1;
did_something = true;
}
}
@@ -637,7 +672,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
log_debug("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b));
cell->setPort(ID::B, sig_b = new_b);
- cell->parameters.at(ID(B_WIDTH)) = 1;
+ cell->parameters.at(ID::B_WIDTH) = 1;
did_something = true;
}
}
@@ -651,10 +686,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
int i;
for (i = 0; i < GetSize(sig_y); i++) {
- if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx)
- module->connect(sig_y[i], sig_a[i]);
- else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx)
- module->connect(sig_y[i], sig_b[i]);
+ RTLIL::SigBit b = sig_b.at(i, State::Sx);
+ RTLIL::SigBit a = sig_a.at(i, State::Sx);
+ if (b == State::S0 && a != State::Sx)
+ module->connect(sig_y[i], a);
+ else if (sub && b == State::S1 && a == State::S1)
+ module->connect(sig_y[i], State::S0);
+ else if (!sub && a == State::S0 && b != State::Sx)
+ module->connect(sig_y[i], b);
else
break;
}
@@ -668,37 +707,37 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
}
- if (cell->type == "$alu")
+ if (cell->type == ID($alu))
{
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
- RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI)));
- RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI)));
- RTLIL::SigSpec sig_x = cell->getPort(ID(X));
+ RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID::CI));
+ RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID::BI));
+ RTLIL::SigSpec sig_x = cell->getPort(ID::X);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- RTLIL::SigSpec sig_co = cell->getPort(ID(CO));
+ RTLIL::SigSpec sig_co = cell->getPort(ID::CO);
- if (sig_ci.wire || sig_bi.wire)
- goto next_cell;
+ if (sig_bi != State::S0 && sig_bi != State::S1)
+ goto skip_fine_alu;
+ if (sig_ci != State::S0 && sig_ci != State::S1)
+ goto skip_fine_alu;
- bool sub = (sig_ci == State::S1 && sig_bi == State::S1);
-
- // If not a subtraction, yet there is a carry or B is inverted
- // then no optimisation is possible as carry will not be constant
- if (!sub && (sig_ci != State::S0 || sig_bi != State::S0))
- goto next_cell;
+ bool bi = sig_bi == State::S1;
+ bool ci = sig_ci == State::S1;
int i;
for (i = 0; i < GetSize(sig_y); i++) {
- if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) {
- module->connect(sig_x[i], sub ? module->Not(NEW_ID, sig_a[i]).as_bit() : sig_a[i]);
- module->connect(sig_y[i], sig_a[i]);
- module->connect(sig_co[i], sub ? State::S1 : State::S0);
+ RTLIL::SigBit b = sig_b.at(i, State::Sx);
+ RTLIL::SigBit a = sig_a.at(i, State::Sx);
+ if (b == ((bi ^ ci) ? State::S1 : State::S0) && a != State::Sx) {
+ module->connect(sig_y[i], a);
+ module->connect(sig_x[i], ci ? module->Not(NEW_ID, a).as_bit() : a);
+ module->connect(sig_co[i], ci ? State::S1 : State::S0);
}
- else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) {
- module->connect(sig_x[i], sig_b[i]);
- module->connect(sig_y[i], sig_b[i]);
- module->connect(sig_co[i], State::S0);
+ else if (a == (ci ? State::S1 : State::S0) && b != State::Sx) {
+ module->connect(sig_y[i], bi ? module->Not(NEW_ID, b).as_bit() : b);
+ module->connect(sig_x[i], (bi ^ ci) ? module->Not(NEW_ID, b).as_bit() : b);
+ module->connect(sig_co[i], ci ? State::S1 : State::S0);
}
else
break;
@@ -707,14 +746,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover("opt.opt_expr.fine.$alu");
cell->setPort(ID::A, sig_a.extract_end(i));
cell->setPort(ID::B, sig_b.extract_end(i));
- cell->setPort(ID(X), sig_x.extract_end(i));
+ cell->setPort(ID::X, sig_x.extract_end(i));
cell->setPort(ID::Y, sig_y.extract_end(i));
- cell->setPort(ID(CO), sig_co.extract_end(i));
+ cell->setPort(ID::CO, sig_co.extract_end(i));
cell->fixup_parameters();
did_something = true;
}
}
}
+skip_fine_alu:
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($shift), ID($shiftx), ID($shl), ID($shr), ID($sshl), ID($sshr),
ID($lt), ID($le), ID($ge), ID($gt), ID($neg), ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow)))
@@ -761,7 +801,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.trim", "$shiftx", "$shift", cell->type.str());
sig_a.remove(width, GetSize(sig_a)-width);
cell->setPort(ID::A, sig_a);
- cell->setParam(ID(A_WIDTH), width);
+ cell->setParam(ID::A_WIDTH, width);
did_something = true;
goto next_cell;
}
@@ -774,13 +814,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
goto next_cell;
}
- if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID(S)))) != 0) {
+ if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID::S))) != 0) {
cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str());
log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module));
RTLIL::SigSpec tmp = cell->getPort(ID::A);
cell->setPort(ID::A, cell->getPort(ID::B));
cell->setPort(ID::B, tmp);
- cell->setPort(ID(S), invert_map.at(assign_map(cell->getPort(ID(S)))));
+ cell->setPort(ID::S, invert_map.at(assign_map(cell->getPort(ID::S))));
did_something = true;
goto next_cell;
}
@@ -842,13 +882,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (input.match("11")) ACTION_DO_Y(0);
if (input.match(" *")) ACTION_DO_Y(x);
if (input.match("* ")) ACTION_DO_Y(x);
- if (input.match(" 0")) ACTION_DO(ID::Y, input.extract(1, 1));
- if (input.match("0 ")) ACTION_DO(ID::Y, input.extract(0, 1));
}
if (cell->type == ID($_MUX_)) {
RTLIL::SigSpec input;
- input.append(cell->getPort(ID(S)));
+ input.append(cell->getPort(ID::S));
input.append(cell->getPort(ID::B));
input.append(cell->getPort(ID::A));
assign_map.apply(input);
@@ -862,7 +900,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->type = ID($_NOT_);
cell->setPort(ID::A, input.extract(0, 1));
cell->unsetPort(ID::B);
- cell->unsetPort(ID(S));
+ cell->unsetPort(ID::S);
goto next_cell;
}
if (input.match("11 ")) ACTION_DO_Y(1);
@@ -878,7 +916,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
if (cell->type.in(ID($_TBUF_), ID($tribuf))) {
- RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID(E) : ID(EN));
+ RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID::E : ID::EN);
RTLIL::SigSpec a = cell->getPort(ID::A);
assign_map.apply(input);
assign_map.apply(a);
@@ -899,10 +937,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
RTLIL::SigSpec a = cell->getPort(ID::A);
RTLIL::SigSpec b = cell->getPort(ID::B);
- if (cell->parameters[ID(A_WIDTH)].as_int() != cell->parameters[ID(B_WIDTH)].as_int()) {
- int width = max(cell->parameters[ID(A_WIDTH)].as_int(), cell->parameters[ID(B_WIDTH)].as_int());
- a.extend_u0(width, cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool());
- b.extend_u0(width, cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool());
+ if (cell->parameters[ID::A_WIDTH].as_int() != cell->parameters[ID::B_WIDTH].as_int()) {
+ int width = max(cell->parameters[ID::A_WIDTH].as_int(), cell->parameters[ID::B_WIDTH].as_int());
+ a.extend_u0(width, cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool());
+ b.extend_u0(width, cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool());
}
RTLIL::SigSpec new_a, new_b;
@@ -912,7 +950,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) {
cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S0 : RTLIL::State::S1);
- new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false);
+ new_y.extend_u0(cell->parameters[ID::Y_WIDTH].as_int(), false);
replace_cell(assign_map, module, cell, "isneq", ID::Y, new_y);
goto next_cell;
}
@@ -925,7 +963,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (new_a.size() == 0) {
cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ? RTLIL::State::S1 : RTLIL::State::S0);
- new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false);
+ new_y.extend_u0(cell->parameters[ID::Y_WIDTH].as_int(), false);
replace_cell(assign_map, module, cell, "empty", ID::Y, new_y);
goto next_cell;
}
@@ -934,13 +972,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
cell->setPort(ID::A, new_a);
cell->setPort(ID::B, new_b);
- cell->parameters[ID(A_WIDTH)] = new_a.size();
- cell->parameters[ID(B_WIDTH)] = new_b.size();
+ cell->parameters[ID::A_WIDTH] = new_a.size();
+ cell->parameters[ID::B_WIDTH] = new_b.size();
}
}
- if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID(Y_WIDTH)].as_int() == 1 &&
- cell->parameters[ID(A_WIDTH)].as_int() == 1 && cell->parameters[ID(B_WIDTH)].as_int() == 1)
+ if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID::Y_WIDTH].as_int() == 1 &&
+ cell->parameters[ID::A_WIDTH].as_int() == 1 && cell->parameters[ID::B_WIDTH].as_int() == 1)
{
RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
@@ -964,8 +1002,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cover_list("opt.opt_expr.eqneq.isnot", "$eq", "$ne", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module));
cell->type = ID($not);
- cell->parameters.erase(ID(B_WIDTH));
- cell->parameters.erase(ID(B_SIGNED));
+ cell->parameters.erase(ID::B_WIDTH);
+ cell->parameters.erase(ID::B_SIGNED);
cell->unsetPort(ID::B);
did_something = true;
}
@@ -982,29 +1020,29 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool);
if (assign_map(cell->getPort(ID::A)).is_fully_zero()) {
cell->setPort(ID::A, cell->getPort(ID::B));
- cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED)));
- cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH)));
+ cell->setParam(ID::A_SIGNED, cell->getParam(ID::B_SIGNED));
+ cell->setParam(ID::A_WIDTH, cell->getParam(ID::B_WIDTH));
}
cell->unsetPort(ID::B);
- cell->unsetParam(ID(B_SIGNED));
- cell->unsetParam(ID(B_WIDTH));
+ cell->unsetParam(ID::B_SIGNED);
+ cell->unsetParam(ID::B_WIDTH);
did_something = true;
goto next_cell;
}
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && assign_map(cell->getPort(ID::B)).is_fully_const())
{
- bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID(A_SIGNED)).as_bool();
- int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID(B_SIGNED)).as_bool());
+ bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID::A_SIGNED).as_bool();
+ int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID::B_SIGNED).as_bool());
if (cell->type.in(ID($shl), ID($sshl)))
shift_bits *= -1;
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
- RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID(Y_WIDTH)).as_int());
+ RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID::Y_WIDTH).as_int());
if (GetSize(sig_a) < GetSize(sig_y))
- sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID(A_SIGNED)).as_bool());
+ sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
for (int i = 0; i < GetSize(sig_y); i++) {
int idx = i + shift_bits;
@@ -1032,12 +1070,26 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
bool identity_wrt_b = false;
bool arith_inverse = false;
- if (cell->type.in(ID($add), ID($sub), ID($or), ID($xor)))
+ if (cell->type.in(ID($add), ID($sub), ID($alu), ID($or), ID($xor)))
{
RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
- if (cell->type != ID($sub) && a.is_fully_const() && a.as_bool() == false)
+ bool sub = cell->type == ID($sub);
+
+ if (cell->type == ID($alu)) {
+ RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID::CI));
+ RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID::BI));
+
+ sub = (sig_ci == State::S1 && sig_bi == State::S1);
+
+ // If not a subtraction, yet there is a carry or B is inverted
+ // then no optimisation is possible as carry will not be constant
+ if (!sub && (sig_ci != State::S0 || sig_bi != State::S0))
+ goto skip_identity;
+ }
+
+ if (!sub && a.is_fully_const() && a.as_bool() == false)
identity_wrt_b = true;
if (b.is_fully_const() && b.as_bool() == false)
@@ -1057,10 +1109,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
- if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID(A_SIGNED)).as_bool(), arith_inverse))
+ if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID::A_SIGNED).as_bool(), arith_inverse))
identity_wrt_b = true;
else
- if (b.is_fully_const() && is_one_or_minus_one(b.as_const(), cell->getParam(ID(B_SIGNED)).as_bool(), arith_inverse))
+ if (b.is_fully_const() && is_one_or_minus_one(b.as_const(), cell->getParam(ID::B_SIGNED).as_bool(), arith_inverse))
identity_wrt_a = true;
}
@@ -1075,34 +1127,45 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (identity_wrt_a || identity_wrt_b)
{
if (identity_wrt_a)
- cover_list("opt.opt_expr.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str());
+ cover_list("opt.opt_expr.identwrt.a", "$add", "$sub", "$alu", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str());
if (identity_wrt_b)
- cover_list("opt.opt_expr.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str());
+ cover_list("opt.opt_expr.identwrt.b", "$add", "$sub", "$alu", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with identity for port %c.\n",
cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B');
+ if (cell->type == ID($alu)) {
+ int y_width = GetSize(cell->getPort(ID::Y));
+ module->connect(cell->getPort(ID::X), RTLIL::Const(State::S0, y_width));
+ module->connect(cell->getPort(ID::CO), RTLIL::Const(State::S0, y_width));
+ cell->unsetPort(ID::BI);
+ cell->unsetPort(ID::CI);
+ cell->unsetPort(ID::X);
+ cell->unsetPort(ID::CO);
+ }
+
if (!identity_wrt_a) {
cell->setPort(ID::A, cell->getPort(ID::B));
- cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH));
- cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED));
+ cell->setParam(ID::A_WIDTH, cell->getParam(ID::B_WIDTH));
+ cell->setParam(ID::A_SIGNED, cell->getParam(ID::B_SIGNED));
}
cell->type = arith_inverse ? ID($neg) : ID($pos);
cell->unsetPort(ID::B);
- cell->parameters.erase(ID(B_WIDTH));
- cell->parameters.erase(ID(B_SIGNED));
+ cell->parameters.erase(ID::B_WIDTH);
+ cell->parameters.erase(ID::B_SIGNED);
cell->check();
did_something = true;
goto next_cell;
}
}
+skip_identity:
if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) &&
cell->getPort(ID::A) == State::S0 && cell->getPort(ID::B) == State::S1) {
cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str());
- replace_cell(assign_map, module, cell, "mux_bool", ID::Y, cell->getPort(ID(S)));
+ replace_cell(assign_map, module, cell, "mux_bool", ID::Y, cell->getPort(ID::S));
goto next_cell;
}
@@ -1110,15 +1173,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->getPort(ID::A) == State::S1 && cell->getPort(ID::B) == State::S0) {
cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module));
- cell->setPort(ID::A, cell->getPort(ID(S)));
+ cell->setPort(ID::A, cell->getPort(ID::S));
cell->unsetPort(ID::B);
- cell->unsetPort(ID(S));
+ cell->unsetPort(ID::S);
if (cell->type == ID($mux)) {
- Const width = cell->parameters[ID(WIDTH)];
- cell->parameters[ID(A_WIDTH)] = width;
- cell->parameters[ID(Y_WIDTH)] = width;
- cell->parameters[ID(A_SIGNED)] = 0;
- cell->parameters.erase(ID(WIDTH));
+ Const width = cell->parameters[ID::WIDTH];
+ cell->parameters[ID::A_WIDTH] = width;
+ cell->parameters[ID::Y_WIDTH] = width;
+ cell->parameters[ID::A_SIGNED] = 0;
+ cell->parameters.erase(ID::WIDTH);
cell->type = ID($not);
} else
cell->type = ID($_NOT_);
@@ -1129,16 +1192,16 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S0) {
cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module));
- cell->setPort(ID::A, cell->getPort(ID(S)));
- cell->unsetPort(ID(S));
+ cell->setPort(ID::A, cell->getPort(ID::S));
+ cell->unsetPort(ID::S);
if (cell->type == ID($mux)) {
- Const width = cell->parameters[ID(WIDTH)];
- cell->parameters[ID(A_WIDTH)] = width;
- cell->parameters[ID(B_WIDTH)] = width;
- cell->parameters[ID(Y_WIDTH)] = width;
- cell->parameters[ID(A_SIGNED)] = 0;
- cell->parameters[ID(B_SIGNED)] = 0;
- cell->parameters.erase(ID(WIDTH));
+ Const width = cell->parameters[ID::WIDTH];
+ cell->parameters[ID::A_WIDTH] = width;
+ cell->parameters[ID::B_WIDTH] = width;
+ cell->parameters[ID::Y_WIDTH] = width;
+ cell->parameters[ID::A_SIGNED] = 0;
+ cell->parameters[ID::B_SIGNED] = 0;
+ cell->parameters.erase(ID::WIDTH);
cell->type = ID($and);
} else
cell->type = ID($_AND_);
@@ -1149,16 +1212,16 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::B) == State::S1) {
cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str());
log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module));
- cell->setPort(ID::B, cell->getPort(ID(S)));
- cell->unsetPort(ID(S));
+ cell->setPort(ID::B, cell->getPort(ID::S));
+ cell->unsetPort(ID::S);
if (cell->type == ID($mux)) {
- Const width = cell->parameters[ID(WIDTH)];
- cell->parameters[ID(A_WIDTH)] = width;
- cell->parameters[ID(B_WIDTH)] = width;
- cell->parameters[ID(Y_WIDTH)] = width;
- cell->parameters[ID(A_SIGNED)] = 0;
- cell->parameters[ID(B_SIGNED)] = 0;
- cell->parameters.erase(ID(WIDTH));
+ Const width = cell->parameters[ID::WIDTH];
+ cell->parameters[ID::A_WIDTH] = width;
+ cell->parameters[ID::B_WIDTH] = width;
+ cell->parameters[ID::Y_WIDTH] = width;
+ cell->parameters[ID::A_SIGNED] = 0;
+ cell->parameters[ID::B_SIGNED] = 0;
+ cell->parameters.erase(ID::WIDTH);
cell->type = ID($or);
} else
cell->type = ID($_OR_);
@@ -1170,14 +1233,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
RTLIL::SigSpec new_a, new_b, new_s;
int width = GetSize(cell->getPort(ID::A));
if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) ||
- cell->getPort(ID(S)).is_fully_undef()) {
+ cell->getPort(ID::S).is_fully_undef()) {
cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str());
replace_cell(assign_map, module, cell, "mux_undef", ID::Y, cell->getPort(ID::A));
goto next_cell;
}
- for (int i = 0; i < cell->getPort(ID(S)).size(); i++) {
+ for (int i = 0; i < cell->getPort(ID::S).size(); i++) {
RTLIL::SigSpec old_b = cell->getPort(ID::B).extract(i*width, width);
- RTLIL::SigSpec old_s = cell->getPort(ID(S)).extract(i, 1);
+ RTLIL::SigSpec old_s = cell->getPort(ID::S).extract(i, 1);
if (old_b.is_fully_undef() || old_s.is_fully_undef())
continue;
new_b.append(old_b);
@@ -1199,48 +1262,48 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
replace_cell(assign_map, module, cell, "mux_sel01", ID::Y, new_s);
goto next_cell;
}
- if (cell->getPort(ID(S)).size() != new_s.size()) {
+ if (cell->getPort(ID::S).size() != new_s.size()) {
cover_list("opt.opt_expr.mux_reduce", "$mux", "$pmux", cell->type.str());
log_debug("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n",
- GetSize(cell->getPort(ID(S))) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module));
+ GetSize(cell->getPort(ID::S)) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module));
cell->setPort(ID::A, new_a);
cell->setPort(ID::B, new_b);
- cell->setPort(ID(S), new_s);
+ cell->setPort(ID::S, new_s);
if (new_s.size() > 1) {
cell->type = ID($pmux);
- cell->parameters[ID(S_WIDTH)] = new_s.size();
+ cell->parameters[ID::S_WIDTH] = new_s.size();
} else {
cell->type = ID($mux);
- cell->parameters.erase(ID(S_WIDTH));
+ cell->parameters.erase(ID::S_WIDTH);
}
did_something = true;
}
}
#define FOLD_1ARG_CELL(_t) \
- if (cell->type == "$" #_t) { \
+ if (cell->type == ID($##_t)) { \
RTLIL::SigSpec a = cell->getPort(ID::A); \
assign_map.apply(a); \
if (a.is_fully_const()) { \
RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \
RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), dummy_arg, \
- cell->parameters[ID(A_SIGNED)].as_bool(), false, \
- cell->parameters[ID(Y_WIDTH)].as_int())); \
+ cell->parameters[ID::A_SIGNED].as_bool(), false, \
+ cell->parameters[ID::Y_WIDTH].as_int())); \
cover("opt.opt_expr.const.$" #_t); \
replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), ID::Y, y); \
goto next_cell; \
} \
}
#define FOLD_2ARG_CELL(_t) \
- if (cell->type == "$" #_t) { \
+ if (cell->type == ID($##_t)) { \
RTLIL::SigSpec a = cell->getPort(ID::A); \
RTLIL::SigSpec b = cell->getPort(ID::B); \
assign_map.apply(a), assign_map.apply(b); \
if (a.is_fully_const() && b.is_fully_const()) { \
RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \
- cell->parameters[ID(A_SIGNED)].as_bool(), \
- cell->parameters[ID(B_SIGNED)].as_bool(), \
- cell->parameters[ID(Y_WIDTH)].as_int())); \
+ cell->parameters[ID::A_SIGNED].as_bool(), \
+ cell->parameters[ID::B_SIGNED].as_bool(), \
+ cell->parameters[ID::Y_WIDTH].as_int())); \
cover("opt.opt_expr.const.$" #_t); \
replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), ID::Y, y); \
goto next_cell; \
@@ -1289,7 +1352,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
// be very conservative with optimizing $mux cells as we do not want to break mux trees
if (cell->type == ID($mux)) {
- RTLIL::SigSpec input = assign_map(cell->getPort(ID(S)));
+ RTLIL::SigSpec input = assign_map(cell->getPort(ID::S));
RTLIL::SigSpec inA = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec inB = assign_map(cell->getPort(ID::B));
if (input.is_fully_const())
@@ -1300,8 +1363,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (!keepdc && cell->type == ID($mul))
{
- bool a_signed = cell->parameters[ID(A_SIGNED)].as_bool();
- bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool();
+ bool a_signed = cell->parameters[ID::A_SIGNED].as_bool();
+ bool b_signed = cell->parameters[ID::B_SIGNED].as_bool();
bool swapped_ab = false;
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
@@ -1342,8 +1405,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
if (!swapped_ab) {
cell->setPort(ID::A, cell->getPort(ID::B));
- cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH));
- cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED));
+ cell->parameters.at(ID::A_WIDTH) = cell->parameters.at(ID::B_WIDTH);
+ cell->parameters.at(ID::A_SIGNED) = cell->parameters.at(ID::B_SIGNED);
}
std::vector<RTLIL::SigBit> new_b = RTLIL::SigSpec(i, 6);
@@ -1352,8 +1415,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
new_b.pop_back();
cell->type = ID($shl);
- cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
- cell->parameters[ID(B_SIGNED)] = false;
+ cell->parameters[ID::B_WIDTH] = GetSize(new_b);
+ cell->parameters[ID::B_SIGNED] = false;
cell->setPort(ID::B, new_b);
cell->check();
@@ -1361,11 +1424,44 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
goto next_cell;
}
}
+
+ sig_a = assign_map(cell->getPort(ID::A));
+ sig_b = assign_map(cell->getPort(ID::B));
+ int a_zeros, b_zeros;
+ for (a_zeros = 0; a_zeros < GetSize(sig_a); a_zeros++)
+ if (sig_a[a_zeros] != RTLIL::State::S0)
+ break;
+ for (b_zeros = 0; b_zeros < GetSize(sig_b); b_zeros++)
+ if (sig_b[b_zeros] != RTLIL::State::S0)
+ break;
+ if (a_zeros || b_zeros) {
+ int y_zeros = a_zeros + b_zeros;
+ cover("opt.opt_expr.mul_low_zeros");
+
+ log_debug("Removing low %d A and %d B bits from cell `%s' in module `%s'.\n",
+ a_zeros, b_zeros, cell->name.c_str(), module->name.c_str());
+
+ if (a_zeros) {
+ cell->setPort(ID::A, sig_a.extract_end(a_zeros));
+ cell->parameters[ID::A_WIDTH] = GetSize(sig_a) - a_zeros;
+ }
+ if (b_zeros) {
+ cell->setPort(ID::B, sig_b.extract_end(b_zeros));
+ cell->parameters[ID::B_WIDTH] = GetSize(sig_b) - b_zeros;
+ }
+ cell->setPort(ID::Y, sig_y.extract_end(y_zeros));
+ cell->parameters[ID::Y_WIDTH] = GetSize(sig_y) - y_zeros;
+ module->connect(RTLIL::SigSig(sig_y.extract(0, y_zeros), RTLIL::SigSpec(0, y_zeros)));
+ cell->check();
+
+ did_something = true;
+ goto next_cell;
+ }
}
if (!keepdc && cell->type.in(ID($div), ID($mod)))
{
- bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool();
+ bool b_signed = cell->parameters[ID::B_SIGNED].as_bool();
SigSpec sig_b = assign_map(cell->getPort(ID::B));
SigSpec sig_y = assign_map(cell->getPort(ID::Y));
@@ -1403,8 +1499,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
new_b.pop_back();
cell->type = ID($shr);
- cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
- cell->parameters[ID(B_SIGNED)] = false;
+ cell->parameters[ID::B_WIDTH] = GetSize(new_b);
+ cell->parameters[ID::B_SIGNED] = false;
cell->setPort(ID::B, new_b);
cell->check();
}
@@ -1421,7 +1517,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
new_b.push_back(State::S0);
cell->type = ID($and);
- cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
+ cell->parameters[ID::B_WIDTH] = GetSize(new_b);
cell->setPort(ID::B, new_b);
cell->check();
}
@@ -1432,6 +1528,99 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
}
+ // Find places in $alu cell where the carry is constant, and split it at these points.
+ if (do_fine && !keepdc && cell->type == ID($alu))
+ {
+ bool a_signed = cell->parameters[ID::A_SIGNED].as_bool();
+ bool b_signed = cell->parameters[ID::B_SIGNED].as_bool();
+ bool is_signed = a_signed && b_signed;
+
+ RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
+ RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
+ RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
+ RTLIL::SigSpec sig_bi = assign_map(cell->getPort(ID::BI));
+ if (GetSize(sig_a) == 0)
+ sig_a = State::S0;
+ if (GetSize(sig_b) == 0)
+ sig_b = State::S0;
+ sig_a.extend_u0(GetSize(sig_y), is_signed);
+ sig_b.extend_u0(GetSize(sig_y), is_signed);
+
+ if (sig_bi != State::S0 && sig_bi != State::S1)
+ goto skip_alu_split;
+
+ std::vector<std::pair<int, State>> split_points;
+
+ for (int i = 0; i < GetSize(sig_y); i++) {
+ SigBit bit_a = sig_a[i];
+ SigBit bit_b = sig_b[i];
+ if (bit_a != State::S0 && bit_a != State::S1)
+ continue;
+ if (bit_b != State::S0 && bit_b != State::S1)
+ continue;
+ if (sig_bi == State::S1) {
+ if (bit_b == State::S0)
+ bit_b = State::S1;
+ else
+ bit_b = State::S0;
+ }
+ if (bit_a != bit_b)
+ continue;
+ split_points.push_back(std::make_pair(i + 1, bit_a.data));
+ }
+
+ if (split_points.empty() || split_points[0].first == GetSize(sig_y))
+ goto skip_alu_split;
+
+ for (auto &p : split_points)
+ log_debug("Splitting $alu cell `%s' in module `%s' at const-carry point %d.\n",
+ cell->name.c_str(), module->name.c_str(), p.first);
+
+ if (split_points.back().first != GetSize(sig_y))
+ split_points.push_back(std::make_pair(GetSize(sig_y), State::Sx));
+
+ RTLIL::SigSpec sig_ci = assign_map(cell->getPort(ID::CI));
+ int prev = 0;
+ RTLIL::SigSpec sig_x = assign_map(cell->getPort(ID::X));
+ RTLIL::SigSpec sig_co = assign_map(cell->getPort(ID::CO));
+
+ for (auto &p : split_points) {
+ int cur = p.first;
+ int sz = cur - prev;
+ bool last = cur == GetSize(sig_y);
+
+ RTLIL::Cell *c = module->addCell(NEW_ID, cell->type);
+ c->setPort(ID::A, sig_a.extract(prev, sz));
+ c->setPort(ID::B, sig_b.extract(prev, sz));
+ c->setPort(ID::BI, sig_bi);
+ c->setPort(ID::CI, sig_ci);
+ c->setPort(ID::Y, sig_y.extract(prev, sz));
+ c->setPort(ID::X, sig_x.extract(prev, sz));
+ RTLIL::SigSpec new_co = sig_co.extract(prev, sz);
+ if (p.second != State::Sx) {
+ module->connect(new_co[sz-1], p.second);
+ RTLIL::Wire *dummy = module->addWire(NEW_ID);
+ new_co[sz-1] = dummy;
+ }
+ c->setPort(ID::CO, new_co);
+ c->parameters[ID::A_WIDTH] = sz;
+ c->parameters[ID::B_WIDTH] = sz;
+ c->parameters[ID::Y_WIDTH] = sz;
+ c->parameters[ID::A_SIGNED] = last ? a_signed : false;
+ c->parameters[ID::B_SIGNED] = last ? b_signed : false;
+
+ prev = p.first;
+ sig_ci = p.second;
+ }
+
+ cover("opt.opt_expr.alu_split");
+ module->remove(cell);
+
+ did_something = true;
+ goto next_cell;
+ }
+skip_alu_split:
+
// remove redundant pairs of bits in ==, ===, !=, and !==
// replace cell with const driver if inputs can't be equal
if (do_fine && cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex)))
@@ -1442,10 +1631,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
contradiction_cache.promote(State::S0);
contradiction_cache.promote(State::S1);
- int a_width = cell->getParam(ID(A_WIDTH)).as_int();
- int b_width = cell->getParam(ID(B_WIDTH)).as_int();
+ int a_width = cell->getParam(ID::A_WIDTH).as_int();
+ int b_width = cell->getParam(ID::B_WIDTH).as_int();
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
int width = is_signed ? std::min(a_width, b_width) : std::max(a_width, b_width);
SigSpec sig_a = cell->getPort(ID::A);
@@ -1499,8 +1688,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
cell->setPort(ID::A, sig_a);
cell->setPort(ID::B, sig_b);
- cell->setParam(ID(A_WIDTH), GetSize(sig_a));
- cell->setParam(ID(B_WIDTH), GetSize(sig_b));
+ cell->setParam(ID::A_WIDTH, GetSize(sig_a));
+ cell->setParam(ID::B_WIDTH, GetSize(sig_b));
did_something = true;
goto next_cell;
@@ -1513,9 +1702,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
IdString cmp_type = cell->type;
SigSpec var_sig = cell->getPort(ID::A);
SigSpec const_sig = cell->getPort(ID::B);
- int var_width = cell->parameters[ID(A_WIDTH)].as_int();
- int const_width = cell->parameters[ID(B_WIDTH)].as_int();
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ int var_width = cell->parameters[ID::A_WIDTH].as_int();
+ int const_width = cell->parameters[ID::B_WIDTH].as_int();
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
if (!const_sig.is_fully_const())
{
@@ -1590,7 +1779,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
int const_bit_set = get_highest_hot_index(const_sig);
- if(const_bit_set >= var_width)
+ if (const_bit_set >= var_width)
{
string cmp_name;
if (cmp_type == ID($lt) || cmp_type == ID($le))
@@ -1737,13 +1926,14 @@ struct OptExprPass : public Pass {
}
extra_args(args, argidx, design);
+ CellTypes ct(design);
for (auto module : design->selected_modules())
{
log("Optimizing module %s.\n", log_id(module));
if (undriven) {
did_something = false;
- replace_undriven(design, module);
+ replace_undriven(module, ct);
if (did_something)
design->scratchpad_set_bool("opt.did_something", true);
}
diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc
index c4f278706..12927d052 100644
--- a/passes/opt/opt_lut.cc
+++ b/passes/opt/opt_lut.cc
@@ -41,8 +41,8 @@ struct OptLutWorker
bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs)
{
SigSpec lut_input = sigmap(lut->getPort(ID::A));
- int lut_width = lut->getParam(ID(WIDTH)).as_int();
- Const lut_table = lut->getParam(ID(LUT));
+ int lut_width = lut->getParam(ID::WIDTH).as_int();
+ Const lut_table = lut->getParam(ID::LUT);
int lut_index = 0;
for (int i = 0; i < lut_width; i++)
@@ -107,7 +107,7 @@ struct OptLutWorker
if (lut_output.wire->get_bool_attribute(ID::keep))
continue;
- int lut_width = cell->getParam(ID(WIDTH)).as_int();
+ int lut_width = cell->getParam(ID::WIDTH).as_int();
SigSpec lut_input = cell->getPort(ID::A);
int lut_arity = 0;
@@ -305,7 +305,7 @@ struct OptLutWorker
auto lutA = worklist.pop();
SigSpec lutA_input = sigmap(lutA->getPort(ID::A));
SigSpec lutA_output = sigmap(lutA->getPort(ID::Y)[0]);
- int lutA_width = lutA->getParam(ID(WIDTH)).as_int();
+ int lutA_width = lutA->getParam(ID::WIDTH).as_int();
int lutA_arity = luts_arity[lutA];
pool<int> &lutA_dlogic_inputs = luts_dlogic_inputs[lutA];
@@ -323,7 +323,7 @@ struct OptLutWorker
auto lutB = port.cell;
SigSpec lutB_input = sigmap(lutB->getPort(ID::A));
SigSpec lutB_output = sigmap(lutB->getPort(ID::Y)[0]);
- int lutB_width = lutB->getParam(ID(WIDTH)).as_int();
+ int lutB_width = lutB->getParam(ID::WIDTH).as_int();
int lutB_arity = luts_arity[lutB];
pool<int> &lutB_dlogic_inputs = luts_dlogic_inputs[lutB];
@@ -372,7 +372,7 @@ struct OptLutWorker
log_debug(" Not combining LUTs into cell A (combined LUT wider than cell A).\n");
else if (lutB_dlogic_inputs.size() > 0)
log_debug(" Not combining LUTs into cell A (cell B is connected to dedicated logic).\n");
- else if (lutB->get_bool_attribute(ID(lut_keep)))
+ else if (lutB->get_bool_attribute(ID::lut_keep))
log_debug(" Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n");
else
combine_mask |= COMBINE_A;
@@ -380,7 +380,7 @@ struct OptLutWorker
log_debug(" Not combining LUTs into cell B (combined LUT wider than cell B).\n");
else if (lutA_dlogic_inputs.size() > 0)
log_debug(" Not combining LUTs into cell B (cell A is connected to dedicated logic).\n");
- else if (lutA->get_bool_attribute(ID(lut_keep)))
+ else if (lutA->get_bool_attribute(ID::lut_keep))
log_debug(" Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n");
else
combine_mask |= COMBINE_B;
@@ -440,7 +440,7 @@ struct OptLutWorker
lutR_unique.insert(bit);
}
- int lutM_width = lutM->getParam(ID(WIDTH)).as_int();
+ int lutM_width = lutM->getParam(ID::WIDTH).as_int();
SigSpec lutM_input = sigmap(lutM->getPort(ID::A));
std::vector<SigBit> lutM_new_inputs;
for (int i = 0; i < lutM_width; i++)
@@ -482,11 +482,11 @@ struct OptLutWorker
lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs);
}
- log_debug(" Cell A truth table: %s.\n", lutA->getParam(ID(LUT)).as_string().c_str());
- log_debug(" Cell B truth table: %s.\n", lutB->getParam(ID(LUT)).as_string().c_str());
+ log_debug(" Cell A truth table: %s.\n", lutA->getParam(ID::LUT).as_string().c_str());
+ log_debug(" Cell B truth table: %s.\n", lutB->getParam(ID::LUT).as_string().c_str());
log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str());
- lutM->setParam(ID(LUT), lutM_new_table);
+ lutM->setParam(ID::LUT, lutM_new_table);
lutM->setPort(ID::A, lutM_new_inputs);
lutM->setPort(ID::Y, lutB_output);
diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc
index cf5248ced..1d32e84bb 100644
--- a/passes/opt/opt_lut_ins.cc
+++ b/passes/opt/opt_lut_ins.cc
@@ -80,7 +80,7 @@ struct OptLutInsPass : public Pass {
continue;
inputs = cell->getPort(ID::A).bits();
output = cell->getPort(ID::Y);
- lut = cell->getParam(ID(LUT));
+ lut = cell->getParam(ID::LUT);
} else if (techname == "xilinx" || techname == "gowin") {
if (cell->type == ID(LUT1)) {
inputs = {
@@ -125,20 +125,20 @@ struct OptLutInsPass : public Pass {
// Not a LUT.
continue;
}
- lut = cell->getParam(ID(INIT));
+ lut = cell->getParam(ID::INIT);
if (techname == "xilinx")
- output = cell->getPort(ID(O));
+ output = cell->getPort(ID::O);
else
- output = cell->getPort(ID(F));
+ output = cell->getPort(ID::F);
} else if (techname == "ecp5") {
if (cell->type == ID(LUT4)) {
inputs = {
cell->getPort(ID::A),
cell->getPort(ID::B),
- cell->getPort(ID(C)),
- cell->getPort(ID(D)),
+ cell->getPort(ID::C),
+ cell->getPort(ID::D),
};
- lut = cell->getParam(ID(INIT));
+ lut = cell->getParam(ID::INIT);
output = cell->getPort(ID(Z));
ignore_const = true;
} else {
@@ -217,19 +217,19 @@ struct OptLutInsPass : public Pass {
module->connect(output, new_lut[0]);
} else {
if (techname == "") {
- cell->setParam(ID(LUT), new_lut);
- cell->setParam(ID(WIDTH), GetSize(new_inputs));
+ cell->setParam(ID::LUT, new_lut);
+ cell->setParam(ID::WIDTH, GetSize(new_inputs));
cell->setPort(ID::A, new_inputs);
} else if (techname == "ecp5") {
log_assert(GetSize(new_inputs) == 4);
- cell->setParam(ID(INIT), new_lut);
+ cell->setParam(ID::INIT, new_lut);
cell->setPort(ID::A, new_inputs[0]);
cell->setPort(ID::B, new_inputs[1]);
- cell->setPort(ID(C), new_inputs[2]);
- cell->setPort(ID(D), new_inputs[3]);
+ cell->setPort(ID::C, new_inputs[2]);
+ cell->setPort(ID::D, new_inputs[3]);
} else {
// xilinx, gowin
- cell->setParam(ID(INIT), new_lut);
+ cell->setParam(ID::INIT, new_lut);
if (techname == "xilinx")
log_assert(GetSize(new_inputs) <= 6);
else
diff --git a/passes/opt/opt_mem.cc b/passes/opt/opt_mem.cc
index 98d3551eb..ff9c06453 100644
--- a/passes/opt/opt_mem.cc
+++ b/passes/opt/opt_mem.cc
@@ -45,17 +45,17 @@ struct OptMemWorker
for (auto cell : module->cells())
{
if (cell->type == ID($memrd)) {
- IdString id = cell->getParam(ID(MEMID)).decode_string();
+ IdString id = cell->getParam(ID::MEMID).decode_string();
memrd.at(id).push_back(cell->name);
}
if (cell->type == ID($memwr)) {
- IdString id = cell->getParam(ID(MEMID)).decode_string();
+ IdString id = cell->getParam(ID::MEMID).decode_string();
memwr.at(id).push_back(cell->name);
}
if (cell->type == ID($meminit)) {
- IdString id = cell->getParam(ID(MEMID)).decode_string();
+ IdString id = cell->getParam(ID::MEMID).decode_string();
meminit.at(id).push_back(cell->name);
}
}
diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc
index 8823a9061..d845926fc 100644
--- a/passes/opt/opt_merge.cc
+++ b/passes/opt/opt_merge.cc
@@ -26,7 +26,6 @@
#include <stdio.h>
#include <set>
-#define USE_CELL_HASH_CACHE
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
@@ -41,13 +40,11 @@ struct OptMergeWorker
CellTypes ct;
int total_count;
-#ifdef USE_CELL_HASH_CACHE
- dict<const RTLIL::Cell*, std::string> cell_hash_cache;
-#endif
+ SHA1 checksum;
static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn)
{
- SigSpec sig_s = conn.at(ID(S));
+ SigSpec sig_s = conn.at(ID::S);
SigSpec sig_b = conn.at(ID::B);
int s_width = GetSize(sig_s);
@@ -59,16 +56,15 @@ struct OptMergeWorker
std::sort(sb_pairs.begin(), sb_pairs.end());
- conn[ID(S)] = SigSpec();
+ conn[ID::S] = SigSpec();
conn[ID::B] = SigSpec();
for (auto &it : sb_pairs) {
- conn[ID(S)].append(it.first);
+ conn[ID::S].append(it.first);
conn[ID::B].append(it.second);
}
}
-#ifdef USE_CELL_HASH_CACHE
std::string int_to_hash_string(unsigned int v)
{
if (v == 0)
@@ -83,14 +79,9 @@ struct OptMergeWorker
std::string hash_cell_parameters_and_connections(const RTLIL::Cell *cell)
{
- if (cell_hash_cache.count(cell) > 0)
- return cell_hash_cache[cell];
-
+ vector<string> hash_conn_strings;
std::string hash_string = cell->type.str() + "\n";
- for (auto &it : cell->parameters)
- hash_string += "P " + it.first.str() + "=" + it.second.as_string() + "\n";
-
const dict<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections();
dict<RTLIL::IdString, RTLIL::SigSpec> alt_conn;
@@ -119,18 +110,25 @@ struct OptMergeWorker
alt_conn = *conn;
assign_map.apply(alt_conn.at(ID::A));
assign_map.apply(alt_conn.at(ID::B));
- assign_map.apply(alt_conn.at(ID(S)));
+ assign_map.apply(alt_conn.at(ID::S));
sort_pmux_conn(alt_conn);
conn = &alt_conn;
}
- vector<string> hash_conn_strings;
-
for (auto &it : *conn) {
- if (cell->output(it.first))
- continue;
- RTLIL::SigSpec sig = it.second;
- assign_map.apply(sig);
+ RTLIL::SigSpec sig;
+ if (cell->output(it.first)) {
+ if (it.first == ID::Q && RTLIL::builtin_ff_cell_types().count(cell->type)) {
+ // For the 'Q' output of state elements,
+ // use its (* init *) attribute value
+ for (const auto &b : dff_init_map(it.second))
+ sig.append(b.wire ? State::Sx : b);
+ }
+ else
+ continue;
+ }
+ else
+ sig = assign_map(it.second);
string s = "C " + it.first.str() + "=";
for (auto &chunk : sig.chunks()) {
if (chunk.wire)
@@ -143,50 +141,59 @@ struct OptMergeWorker
hash_conn_strings.push_back(s + "\n");
}
+ for (auto &it : cell->parameters)
+ hash_conn_strings.push_back("P " + it.first.str() + "=" + it.second.as_string() + "\n");
+
std::sort(hash_conn_strings.begin(), hash_conn_strings.end());
for (auto it : hash_conn_strings)
hash_string += it;
- cell_hash_cache[cell] = sha1(hash_string);
- return cell_hash_cache[cell];
+ checksum.update(hash_string);
+ return checksum.final();
}
-#endif
- bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2, bool &lt)
+ bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2)
{
-#ifdef USE_CELL_HASH_CACHE
- std::string hash1 = hash_cell_parameters_and_connections(cell1);
- std::string hash2 = hash_cell_parameters_and_connections(cell2);
-
- if (hash1 != hash2) {
- lt = hash1 < hash2;
- return true;
- }
-#endif
-
- if (cell1->parameters != cell2->parameters) {
- std::map<RTLIL::IdString, RTLIL::Const> p1(cell1->parameters.begin(), cell1->parameters.end());
- std::map<RTLIL::IdString, RTLIL::Const> p2(cell2->parameters.begin(), cell2->parameters.end());
- lt = p1 < p2;
- return true;
- }
-
- dict<RTLIL::IdString, RTLIL::SigSpec> conn1 = cell1->connections();
- dict<RTLIL::IdString, RTLIL::SigSpec> conn2 = cell2->connections();
-
- for (auto &it : conn1) {
- if (cell1->output(it.first))
- it.second = RTLIL::SigSpec();
- else
- assign_map.apply(it.second);
- }
-
- for (auto &it : conn2) {
- if (cell2->output(it.first))
- it.second = RTLIL::SigSpec();
- else
- assign_map.apply(it.second);
+ log_assert(cell1 != cell2);
+ if (cell1->type != cell2->type) return false;
+
+ if (cell1->parameters != cell2->parameters)
+ return false;
+
+ if (cell1->connections_.size() != cell2->connections_.size())
+ return false;
+ for (const auto &it : cell1->connections_)
+ if (!cell2->connections_.count(it.first))
+ return false;
+
+ decltype(Cell::connections_) conn1, conn2;
+ conn1.reserve(cell1->connections_.size());
+ conn2.reserve(cell1->connections_.size());
+
+ for (const auto &it : cell1->connections_) {
+ if (cell1->output(it.first)) {
+ if (it.first == ID::Q && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") ||
+ cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") ||
+ cell1->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) {
+ // For the 'Q' output of state elements,
+ // use the (* init *) attribute value
+ auto &sig1 = conn1[it.first];
+ for (const auto &b : dff_init_map(it.second))
+ sig1.append(b.wire ? State::Sx : b);
+ auto &sig2 = conn2[it.first];
+ for (const auto &b : dff_init_map(cell2->getPort(it.first)))
+ sig2.append(b.wire ? State::Sx : b);
+ }
+ else {
+ conn1[it.first] = RTLIL::SigSpec();
+ conn2[it.first] = RTLIL::SigSpec();
+ }
+ }
+ else {
+ conn1[it.first] = assign_map(it.second);
+ conn2[it.first] = assign_map(cell2->getPort(it.first));
+ }
}
if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) ||
@@ -215,54 +222,9 @@ struct OptMergeWorker
sort_pmux_conn(conn2);
}
- if (conn1 != conn2) {
- std::map<RTLIL::IdString, RTLIL::SigSpec> c1(conn1.begin(), conn1.end());
- std::map<RTLIL::IdString, RTLIL::SigSpec> c2(conn2.begin(), conn2.end());
- lt = c1 < c2;
- return true;
- }
-
- if (conn1.count(ID(Q)) != 0 && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") ||
- cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") ||
- cell1->type.in("$adff", "$sr", "$ff", "$_FF_"))) {
- std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort(ID(Q))).to_sigbit_vector();
- std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort(ID(Q))).to_sigbit_vector();
- for (size_t i = 0; i < q1.size(); i++)
- if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) {
- lt = q1.at(i) < q2.at(i);
- return true;
- }
- }
-
- return false;
+ return conn1 == conn2;
}
- bool compare_cells(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2)
- {
- if (cell1->type != cell2->type)
- return cell1->type < cell2->type;
-
- if ((!mode_share_all && !ct.cell_known(cell1->type)) || !cell1->known())
- return cell1 < cell2;
-
- if (cell1->has_keep_attr() || cell2->has_keep_attr())
- return cell1 < cell2;
-
- bool lt;
- if (compare_cell_parameters_and_connections(cell1, cell2, lt))
- return lt;
-
- return false;
- }
-
- struct CompareCells {
- OptMergeWorker *that;
- CompareCells(OptMergeWorker *that) : that(that) {}
- bool operator()(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) const {
- return that->compare_cells(cell1, cell2);
- }
- };
-
OptMergeWorker(RTLIL::Design *design, RTLIL::Module *module, bool mode_nomux, bool mode_share_all) :
design(design), module(module), assign_map(module), mode_share_all(mode_share_all)
{
@@ -289,8 +251,8 @@ struct OptMergeWorker
dff_init_map.set(module);
for (auto &it : module->wires_)
- if (it.second->attributes.count(ID(init)) != 0) {
- Const initval = it.second->attributes.at(ID(init));
+ if (it.second->attributes.count(ID::init) != 0) {
+ Const initval = it.second->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
dff_init_map.add(SigBit(it.second, i), initval[i]);
@@ -299,9 +261,6 @@ struct OptMergeWorker
bool did_something = true;
while (did_something)
{
-#ifdef USE_CELL_HASH_CACHE
- cell_hash_cache.clear();
-#endif
std::vector<RTLIL::Cell*> cells;
cells.reserve(module->cells_.size());
for (auto &it : module->cells_) {
@@ -312,42 +271,51 @@ struct OptMergeWorker
}
did_something = false;
- std::map<RTLIL::Cell*, RTLIL::Cell*, CompareCells> sharemap(CompareCells(this));
+ dict<std::string, RTLIL::Cell*> sharemap;
for (auto cell : cells)
{
- if (sharemap.count(cell) > 0) {
- did_something = true;
- log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str());
- for (auto &it : cell->connections()) {
- if (cell->output(it.first)) {
- RTLIL::SigSpec other_sig = sharemap[cell]->getPort(it.first);
- log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(),
- log_signal(it.second), log_signal(other_sig));
- module->connect(RTLIL::SigSig(it.second, other_sig));
- assign_map.add(it.second, other_sig);
-
- if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") ||
- cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") ||
- cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) {
- for (auto c : it.second.chunks()) {
- auto jt = c.wire->attributes.find(ID(init));
- if (jt == c.wire->attributes.end())
- continue;
- for (int i = c.offset; i < c.offset + c.width; i++)
- jt->second[i] = State::Sx;
+ if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known())
+ continue;
+
+ auto hash = hash_cell_parameters_and_connections(cell);
+ auto r = sharemap.insert(std::make_pair(hash, cell));
+ if (!r.second) {
+ if (compare_cell_parameters_and_connections(cell, r.first->second)) {
+ if (cell->has_keep_attr()) {
+ if (r.first->second->has_keep_attr())
+ continue;
+ std::swap(r.first->second, cell);
+ }
+
+
+ did_something = true;
+ log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), r.first->second->name.c_str());
+ for (auto &it : cell->connections()) {
+ if (cell->output(it.first)) {
+ RTLIL::SigSpec other_sig = r.first->second->getPort(it.first);
+ log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(),
+ log_signal(it.second), log_signal(other_sig));
+ module->connect(RTLIL::SigSig(it.second, other_sig));
+ assign_map.add(it.second, other_sig);
+
+ if (it.first == ID::Q && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") ||
+ cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") ||
+ cell->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) {
+ for (auto c : it.second.chunks()) {
+ auto jt = c.wire->attributes.find(ID::init);
+ if (jt == c.wire->attributes.end())
+ continue;
+ for (int i = c.offset; i < c.offset + c.width; i++)
+ jt->second[i] = State::Sx;
+ }
+ dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second)));
}
- dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second)));
}
}
+ log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str());
+ module->remove(cell);
+ total_count++;
}
- log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str());
-#ifdef USE_CELL_HASH_CACHE
- cell_hash_cache.erase(cell);
-#endif
- module->remove(cell);
- total_count++;
- } else {
- sharemap[cell] = cell;
}
}
}
diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc
index 3c486bbcc..d076addae 100644
--- a/passes/opt/opt_muxtree.cc
+++ b/passes/opt/opt_muxtree.cc
@@ -88,7 +88,7 @@ struct OptMuxtreeWorker
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
- RTLIL::SigSpec sig_s = cell->getPort(ID(S));
+ RTLIL::SigSpec sig_s = cell->getPort(ID::S);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
muxinfo_t muxinfo;
@@ -229,7 +229,7 @@ struct OptMuxtreeWorker
RTLIL::SigSpec sig_a = mi.cell->getPort(ID::A);
RTLIL::SigSpec sig_b = mi.cell->getPort(ID::B);
- RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S));
+ RTLIL::SigSpec sig_s = mi.cell->getPort(ID::S);
RTLIL::SigSpec sig_y = mi.cell->getPort(ID::Y);
RTLIL::SigSpec sig_ports = sig_b;
@@ -257,12 +257,12 @@ struct OptMuxtreeWorker
mi.cell->setPort(ID::A, new_sig_a);
mi.cell->setPort(ID::B, new_sig_b);
- mi.cell->setPort(ID(S), new_sig_s);
+ mi.cell->setPort(ID::S, new_sig_s);
if (GetSize(new_sig_s) == 1) {
mi.cell->type = ID($mux);
- mi.cell->parameters.erase(ID(S_WIDTH));
+ mi.cell->parameters.erase(ID::S_WIDTH);
} else {
- mi.cell->parameters[ID(S_WIDTH)] = RTLIL::Const(GetSize(new_sig_s));
+ mi.cell->parameters[ID::S_WIDTH] = RTLIL::Const(GetSize(new_sig_s));
}
}
}
@@ -366,7 +366,7 @@ struct OptMuxtreeWorker
idict<int> ctrl_bits;
if (portname == ID::B)
width = GetSize(muxinfo.cell->getPort(ID::A));
- for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false))
+ for (int bit : sig2bits(muxinfo.cell->getPort(ID::S), false))
ctrl_bits(bit);
int port_idx = 0, port_off = 0;
diff --git a/passes/opt/opt_reduce.cc b/passes/opt/opt_reduce.cc
index f74655d1c..f640f50a0 100644
--- a/passes/opt/opt_reduce.cc
+++ b/passes/opt/opt_reduce.cc
@@ -96,7 +96,7 @@ struct OptReduceWorker
}
cell->setPort(ID::A, new_sig_a);
- cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size());
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(new_sig_a.size());
return;
}
@@ -104,7 +104,7 @@ struct OptReduceWorker
{
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
- RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S)));
+ RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID::S));
RTLIL::SigSpec new_sig_b, new_sig_s;
pool<RTLIL::SigSpec> handled_sig;
@@ -127,9 +127,9 @@ struct OptReduceWorker
{
RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or));
reduce_or_cell->setPort(ID::A, this_s);
- reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0);
- reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size());
- reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1);
+ reduce_or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ reduce_or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(this_s.size());
+ reduce_or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID);
this_s = RTLIL::SigSpec(reduce_or_wire);
@@ -156,12 +156,12 @@ struct OptReduceWorker
else
{
cell->setPort(ID::B, new_sig_b);
- cell->setPort(ID(S), new_sig_s);
+ cell->setPort(ID::S, new_sig_s);
if (new_sig_s.size() > 1) {
- cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size());
+ cell->parameters[ID::S_WIDTH] = RTLIL::Const(new_sig_s.size());
} else {
cell->type = ID($mux);
- cell->parameters.erase(ID(S_WIDTH));
+ cell->parameters.erase(ID::S_WIDTH);
}
}
}
@@ -192,13 +192,13 @@ struct OptReduceWorker
if (all_tuple_bits_same)
{
- old_sig_conn.first.append_bit(sig_y.at(i));
- old_sig_conn.second.append_bit(sig_a.at(i));
+ old_sig_conn.first.append(sig_y.at(i));
+ old_sig_conn.second.append(sig_a.at(i));
}
else if (consolidated_in_tuples_map.count(in_tuple))
{
- old_sig_conn.first.append_bit(sig_y.at(i));
- old_sig_conn.second.append_bit(consolidated_in_tuples_map.at(in_tuple));
+ old_sig_conn.first.append(sig_y.at(i));
+ old_sig_conn.second.append(consolidated_in_tuples_map.at(in_tuple));
}
else
{
@@ -222,14 +222,14 @@ struct OptReduceWorker
}
cell->setPort(ID::B, RTLIL::SigSpec());
- for (int i = 1; i <= cell->getPort(ID(S)).size(); i++)
+ for (int i = 1; i <= cell->getPort(ID::S).size(); i++)
for (auto &in_tuple : consolidated_in_tuples) {
RTLIL::SigSpec new_b = cell->getPort(ID::B);
new_b.append(in_tuple.at(i));
cell->setPort(ID::B, new_b);
}
- cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size());
+ cell->parameters[ID::WIDTH] = RTLIL::Const(new_sig_y.size());
cell->setPort(ID::Y, new_sig_y);
log(" New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)),
@@ -255,14 +255,14 @@ struct OptReduceWorker
for (auto &cell_it : module->cells_) {
RTLIL::Cell *cell = cell_it.second;
if (cell->type == ID($mem))
- mem_wren_sigs.add(assign_map(cell->getPort(ID(WR_EN))));
+ mem_wren_sigs.add(assign_map(cell->getPort(ID::WR_EN)));
if (cell->type == ID($memwr))
- mem_wren_sigs.add(assign_map(cell->getPort(ID(EN))));
+ mem_wren_sigs.add(assign_map(cell->getPort(ID::EN)));
}
for (auto &cell_it : module->cells_) {
RTLIL::Cell *cell = cell_it.second;
- if (cell->type == ID($dff) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Q)))))
- mem_wren_sigs.add(assign_map(cell->getPort(ID(D))));
+ if (cell->type == ID($dff) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Q))))
+ mem_wren_sigs.add(assign_map(cell->getPort(ID::D)));
}
bool keep_expanding_mem_wren_sigs = true;
diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc
index 0bf74098a..81326a417 100644
--- a/passes/opt/opt_rmdff.cc
+++ b/passes/opt/opt_rmdff.cc
@@ -41,7 +41,7 @@ void remove_init_attr(SigSpec sig)
for (auto bit : assign_map(sig))
if (init_attributes.count(bit))
for (auto wbit : init_attributes.at(bit))
- wbit.wire->attributes.at(ID(init))[wbit.offset] = State::Sx;
+ wbit.wire->attributes.at(ID::init)[wbit.offset] = State::Sx;
}
bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
@@ -49,17 +49,17 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
SigSpec sig_set, sig_clr;
State pol_set, pol_clr;
- if (cell->hasPort(ID(S)))
- sig_set = cell->getPort(ID(S));
+ if (cell->hasPort(ID::S))
+ sig_set = cell->getPort(ID::S);
- if (cell->hasPort(ID(R)))
- sig_clr = cell->getPort(ID(R));
+ if (cell->hasPort(ID::R))
+ sig_clr = cell->getPort(ID::R);
- if (cell->hasPort(ID(SET)))
- sig_set = cell->getPort(ID(SET));
+ if (cell->hasPort(ID::SET))
+ sig_set = cell->getPort(ID::SET);
- if (cell->hasPort(ID(CLR)))
- sig_clr = cell->getPort(ID(CLR));
+ if (cell->hasPort(ID::CLR))
+ sig_clr = cell->getPort(ID::CLR);
log_assert(GetSize(sig_set) == GetSize(sig_clr));
@@ -72,16 +72,16 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
pol_clr = cell->type[13] == 'P' ? State::S1 : State::S0;
} else
if (cell->type.in(ID($dffsr), ID($dlatchsr))) {
- pol_set = cell->parameters[ID(SET_POLARITY)].as_bool() ? State::S1 : State::S0;
- pol_clr = cell->parameters[ID(CLR_POLARITY)].as_bool() ? State::S1 : State::S0;
+ pol_set = cell->parameters[ID::SET_POLARITY].as_bool() ? State::S1 : State::S0;
+ pol_clr = cell->parameters[ID::CLR_POLARITY].as_bool() ? State::S1 : State::S0;
} else
log_abort();
State npol_set = pol_set == State::S0 ? State::S1 : State::S0;
State npol_clr = pol_clr == State::S0 ? State::S1 : State::S0;
- SigSpec sig_d = cell->getPort(ID(D));
- SigSpec sig_q = cell->getPort(ID(Q));
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
bool did_something = false;
bool proper_sr = false;
@@ -139,18 +139,18 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
if (cell->type.in(ID($dffsr), ID($dlatchsr)))
{
- cell->setParam(ID(WIDTH), GetSize(sig_d));
- cell->setPort(ID(SET), sig_set);
- cell->setPort(ID(CLR), sig_clr);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setParam(ID::WIDTH, GetSize(sig_d));
+ cell->setPort(ID::SET, sig_set);
+ cell->setPort(ID::CLR, sig_clr);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
}
else
{
- cell->setPort(ID(S), sig_set);
- cell->setPort(ID(R), sig_clr);
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::S, sig_set);
+ cell->setPort(ID::R, sig_clr);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
}
if (proper_sr)
@@ -171,24 +171,24 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$adff", log_id(mod));
cell->type = ID($adff);
- cell->setParam(ID(ARST_POLARITY), unified_pol);
- cell->setParam(ID(ARST_VALUE), reset_val);
- cell->setPort(ID(ARST), sig_reset);
-
- cell->unsetParam(ID(SET_POLARITY));
- cell->unsetParam(ID(CLR_POLARITY));
- cell->unsetPort(ID(SET));
- cell->unsetPort(ID(CLR));
+ cell->setParam(ID::ARST_POLARITY, unified_pol);
+ cell->setParam(ID::ARST_VALUE, reset_val);
+ cell->setPort(ID::ARST, sig_reset);
+
+ cell->unsetParam(ID::SET_POLARITY);
+ cell->unsetParam(ID::CLR_POLARITY);
+ cell->unsetPort(ID::SET);
+ cell->unsetPort(ID::CLR);
}
else
{
log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$dff", log_id(mod));
cell->type = ID($dff);
- cell->unsetParam(ID(SET_POLARITY));
- cell->unsetParam(ID(CLR_POLARITY));
- cell->unsetPort(ID(SET));
- cell->unsetPort(ID(CLR));
+ cell->unsetParam(ID::SET_POLARITY);
+ cell->unsetParam(ID::CLR_POLARITY);
+ cell->unsetPort(ID::SET);
+ cell->unsetPort(ID::CLR);
}
return true;
@@ -208,8 +208,8 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), log_id(new_type), log_id(mod));
cell->type = new_type;
- cell->unsetPort(ID(S));
- cell->unsetPort(ID(R));
+ cell->unsetPort(ID::S);
+ cell->unsetPort(ID::R);
return true;
}
@@ -223,17 +223,17 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
State on_state, off_state;
if (dlatch->type == ID($dlatch)) {
- sig_e = assign_map(dlatch->getPort(ID(EN)));
- on_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S1 : State::S0;
- off_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S0 : State::S1;
+ sig_e = assign_map(dlatch->getPort(ID::EN));
+ on_state = dlatch->getParam(ID::EN_POLARITY).as_bool() ? State::S1 : State::S0;
+ off_state = dlatch->getParam(ID::EN_POLARITY).as_bool() ? State::S0 : State::S1;
} else
if (dlatch->type == ID($_DLATCH_P_)) {
- sig_e = assign_map(dlatch->getPort(ID(E)));
+ sig_e = assign_map(dlatch->getPort(ID::E));
on_state = State::S1;
off_state = State::S0;
} else
if (dlatch->type == ID($_DLATCH_N_)) {
- sig_e = assign_map(dlatch->getPort(ID(E)));
+ sig_e = assign_map(dlatch->getPort(ID::E));
on_state = State::S0;
off_state = State::S1;
} else
@@ -242,15 +242,15 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
if (sig_e == off_state)
{
RTLIL::Const val_init;
- for (auto bit : dff_init_map(dlatch->getPort(ID(Q))))
+ for (auto bit : dff_init_map(dlatch->getPort(ID::Q)))
val_init.bits.push_back(bit.wire == NULL ? bit.data : State::Sx);
- mod->connect(dlatch->getPort(ID(Q)), val_init);
+ mod->connect(dlatch->getPort(ID::Q), val_init);
goto delete_dlatch;
}
if (sig_e == on_state)
{
- mod->connect(dlatch->getPort(ID(Q)), dlatch->getPort(ID(D)));
+ mod->connect(dlatch->getPort(ID::Q), dlatch->getPort(ID::D));
goto delete_dlatch;
}
@@ -258,7 +258,7 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
delete_dlatch:
log("Removing %s (%s) from module %s.\n", log_id(dlatch), log_id(dlatch->type), log_id(mod));
- remove_init_attr(dlatch->getPort(ID(Q)));
+ remove_init_attr(dlatch->getPort(ID::Q));
mod->remove(dlatch);
return true;
}
@@ -269,23 +269,23 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
RTLIL::Const val_cp, val_rp, val_rv, val_ep;
if (dff->type == ID($_FF_)) {
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
}
else if (dff->type == ID($_DFF_N_) || dff->type == ID($_DFF_P_)) {
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
- sig_c = dff->getPort(ID(C));
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
+ sig_c = dff->getPort(ID::C);
val_cp = RTLIL::Const(dff->type == ID($_DFF_P_), 1);
}
else if (dff->type.begins_with("$_DFF_") && dff->type.compare(9, 1, "_") == 0 &&
(dff->type[6] == 'N' || dff->type[6] == 'P') &&
(dff->type[7] == 'N' || dff->type[7] == 'P') &&
(dff->type[8] == '0' || dff->type[8] == '1')) {
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
- sig_c = dff->getPort(ID(C));
- sig_r = dff->getPort(ID(R));
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
+ sig_c = dff->getPort(ID::C);
+ sig_r = dff->getPort(ID::R);
val_cp = RTLIL::Const(dff->type[6] == 'P', 1);
val_rp = RTLIL::Const(dff->type[7] == 'P', 1);
val_rv = RTLIL::Const(dff->type[8] == '1', 1);
@@ -293,39 +293,39 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
else if (dff->type.begins_with("$_DFFE_") && dff->type.compare(9, 1, "_") == 0 &&
(dff->type[7] == 'N' || dff->type[7] == 'P') &&
(dff->type[8] == 'N' || dff->type[8] == 'P')) {
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
- sig_c = dff->getPort(ID(C));
- sig_e = dff->getPort(ID(E));
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
+ sig_c = dff->getPort(ID::C);
+ sig_e = dff->getPort(ID::E);
val_cp = RTLIL::Const(dff->type[7] == 'P', 1);
val_ep = RTLIL::Const(dff->type[8] == 'P', 1);
}
else if (dff->type == ID($ff)) {
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
}
else if (dff->type == ID($dff)) {
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
- sig_c = dff->getPort(ID(CLK));
- val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
+ sig_c = dff->getPort(ID::CLK);
+ val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1);
}
else if (dff->type == ID($dffe)) {
- sig_e = dff->getPort(ID(EN));
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
- sig_c = dff->getPort(ID(CLK));
- val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
- val_ep = RTLIL::Const(dff->parameters[ID(EN_POLARITY)].as_bool(), 1);
+ sig_e = dff->getPort(ID::EN);
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
+ sig_c = dff->getPort(ID::CLK);
+ val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1);
+ val_ep = RTLIL::Const(dff->parameters[ID::EN_POLARITY].as_bool(), 1);
}
else if (dff->type == ID($adff)) {
- sig_d = dff->getPort(ID(D));
- sig_q = dff->getPort(ID(Q));
- sig_c = dff->getPort(ID(CLK));
- sig_r = dff->getPort(ID(ARST));
- val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
- val_rp = RTLIL::Const(dff->parameters[ID(ARST_POLARITY)].as_bool(), 1);
- val_rv = dff->parameters[ID(ARST_VALUE)];
+ sig_d = dff->getPort(ID::D);
+ sig_q = dff->getPort(ID::Q);
+ sig_c = dff->getPort(ID::CLK);
+ sig_r = dff->getPort(ID::ARST);
+ val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1);
+ val_rp = RTLIL::Const(dff->parameters[ID::ARST_POLARITY].as_bool(), 1);
+ val_rv = dff->parameters[ID::ARST_VALUE];
}
else
log_abort();
@@ -422,15 +422,15 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
if (dff->type == ID($adff)) {
dff->type = ID($dff);
- dff->unsetPort(ID(ARST));
- dff->unsetParam(ID(ARST_POLARITY));
- dff->unsetParam(ID(ARST_VALUE));
+ dff->unsetPort(ID::ARST);
+ dff->unsetParam(ID::ARST_POLARITY);
+ dff->unsetParam(ID::ARST_VALUE);
return true;
}
log_assert(dff->type.begins_with("$_DFF_"));
dff->type = stringf("$_DFF_%c_", + dff->type[6]);
- dff->unsetPort(ID(R));
+ dff->unsetPort(ID::R);
}
// If enable signal is present, and is fully constant
@@ -447,14 +447,14 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
if (dff->type == ID($dffe)) {
dff->type = ID($dff);
- dff->unsetPort(ID(EN));
- dff->unsetParam(ID(EN_POLARITY));
+ dff->unsetPort(ID::EN);
+ dff->unsetParam(ID::EN_POLARITY);
return true;
}
log_assert(dff->type.begins_with("$_DFFE_"));
dff->type = stringf("$_DFF_%c_", + dff->type[7]);
- dff->unsetPort(ID(E));
+ dff->unsetPort(ID::E);
}
if (sat && has_init && (!sig_r.size() || val_init == val_rv))
@@ -509,9 +509,9 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", sigbit_init_val ? 1 : 0,
position, log_id(dff), log_id(dff->type), log_id(mod));
- SigSpec tmp = dff->getPort(ID(D));
+ SigSpec tmp = dff->getPort(ID::D);
tmp[position] = sigbit_init_val;
- dff->setPort(ID(D), tmp);
+ dff->setPort(ID::D, tmp);
removed_sigbits = true;
}
@@ -528,7 +528,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
delete_dff:
log("Removing %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod));
- remove_init_attr(dff->getPort(ID(Q)));
+ remove_init_attr(dff->getPort(ID::Q));
mod->remove(dff);
for (auto &entry : bit2driver)
@@ -588,8 +588,8 @@ struct OptRmdffPass : public Pass {
for (auto wire : module->wires())
{
- if (wire->attributes.count(ID(init)) != 0) {
- Const initval = wire->attributes.at(ID(init));
+ if (wire->attributes.count(ID::init) != 0) {
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++)
if (initval[i] == State::S0 || initval[i] == State::S1)
dff_init_map.add(SigBit(wire, i), initval[i]);
diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc
index f59f978a6..1f69c98f4 100644
--- a/passes/opt/opt_share.cc
+++ b/passes/opt/opt_share.cc
@@ -98,8 +98,8 @@ struct ExtSigSpec {
bool cell_supported(RTLIL::Cell *cell)
{
if (cell->type.in(ID($alu))) {
- RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
- RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
+ RTLIL::SigSpec sig_bi = cell->getPort(ID::BI);
+ RTLIL::SigSpec sig_ci = cell->getPort(ID::CI);
if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci)
return true;
@@ -139,7 +139,7 @@ RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_na
RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) {
if (cell->type == ID($alu) && port_name == ID::B)
- return cell->getPort(ID(BI));
+ return cell->getPort(ID::BI);
else if (cell->type == ID($sub) && port_name == ID::B)
return RTLIL::Const(1, 1);
@@ -190,7 +190,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
auto shared_op = ports[0].op;
if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; }))
- max_width = std::max(max_width, shared_op->getParam(ID(Y_WIDTH)).as_int());
+ max_width = std::max(max_width, shared_op->getParam(ID::Y_WIDTH).as_int());
for (auto &operand : muxed_operands)
@@ -210,7 +210,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
RTLIL::SigSpec mux_y = mux->getPort(ID::Y);
RTLIL::SigSpec mux_a = mux->getPort(ID::A);
RTLIL::SigSpec mux_b = mux->getPort(ID::B);
- RTLIL::SigSpec mux_s = mux->getPort(ID(S));
+ RTLIL::SigSpec mux_s = mux->getPort(ID::S);
RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width);
RTLIL::SigSpec shared_pmux_b;
@@ -237,7 +237,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
mux->setPort(ID::A, mux_a);
mux->setPort(ID::B, mux_b);
mux->setPort(ID::Y, mux_y);
- mux->setPort(ID(S), mux_s);
+ mux->setPort(ID::S, mux_s);
for (const auto &op : muxed_operands)
shared_pmux_b.append(op.sig);
@@ -245,26 +245,26 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s);
if (shared_op->type.in(ID($alu))) {
- RTLIL::SigSpec alu_x = shared_op->getPort(ID(X));
- RTLIL::SigSpec alu_co = shared_op->getPort(ID(CO));
+ RTLIL::SigSpec alu_x = shared_op->getPort(ID::X);
+ RTLIL::SigSpec alu_co = shared_op->getPort(ID::CO);
- shared_op->setPort(ID(X), alu_x.extract(0, conn_width));
- shared_op->setPort(ID(CO), alu_co.extract(0, conn_width));
+ shared_op->setPort(ID::X, alu_x.extract(0, conn_width));
+ shared_op->setPort(ID::CO, alu_co.extract(0, conn_width));
}
bool is_fine = shared_op->type.in(FINE_BITWISE_OPS);
if (!is_fine)
- shared_op->setParam(ID(Y_WIDTH), conn_width);
+ shared_op->setParam(ID::Y_WIDTH, conn_width);
if (decode_port(shared_op, ID::A, &assign_map) == operand) {
shared_op->setPort(ID::B, mux_to_oper);
if (!is_fine)
- shared_op->setParam(ID(B_WIDTH), max_width);
+ shared_op->setParam(ID::B_WIDTH, max_width);
} else {
shared_op->setPort(ID::A, mux_to_oper);
if (!is_fine)
- shared_op->setParam(ID(A_WIDTH), max_width);
+ shared_op->setParam(ID::A_WIDTH, max_width);
}
}
@@ -452,7 +452,7 @@ dict<RTLIL::SigSpec, OpMuxConn> find_valid_op_mux_conns(RTLIL::Module *module, d
for (auto cell : module->cells()) {
if (cell->type.in(ID($mux), ID($_MUX_), ID($pmux))) {
- remove_connected_ops(cell->getPort(ID(S)));
+ remove_connected_ops(cell->getPort(ID::S));
find_op_mux_conns(cell);
} else {
for (auto &conn : cell->connections())
@@ -510,7 +510,7 @@ struct OptSharePass : public Pass {
continue;
if (cell->type == ID($alu)) {
- for (RTLIL::IdString port_name : {ID(X), ID(CO)}) {
+ for (RTLIL::IdString port_name : {ID::X, ID::CO}) {
auto mux_insig = assign_map(cell->getPort(port_name));
outsig_to_operator[mux_insig] = cell;
for (auto outbit : mux_insig)
@@ -552,7 +552,7 @@ struct OptSharePass : public Pass {
if (p.mux->type.in(ID($mux), ID($_MUX_)))
mux_port_num = 2;
else
- mux_port_num = p.mux->getPort(ID(S)).size();
+ mux_port_num = p.mux->getPort(ID::S).size();
mux_port_conns.resize(mux_port_num);
}
diff --git a/passes/opt/pmux2shiftx.cc b/passes/opt/pmux2shiftx.cc
index 92b5794ac..11b80b6b3 100644
--- a/passes/opt/pmux2shiftx.cc
+++ b/passes/opt/pmux2shiftx.cc
@@ -46,7 +46,7 @@ struct OnehotDatabase
for (auto wire : module->wires())
{
- auto it = wire->attributes.find(ID(init));
+ auto it = wire->attributes.find(ID::init);
if (it == wire->attributes.end())
continue;
@@ -65,10 +65,10 @@ struct OnehotDatabase
if (cell->type.in(ID($adff), ID($dff), ID($dffe), ID($dlatch), ID($ff)))
{
- output = cell->getPort(ID(Q));
+ output = cell->getPort(ID::Q);
if (cell->type == ID($adff))
- inputs.push_back(cell->getParam(ID(ARST_VALUE)));
- inputs.push_back(cell->getPort(ID(D)));
+ inputs.push_back(cell->getParam(ID::ARST_VALUE));
+ inputs.push_back(cell->getPort(ID::D));
}
if (cell->type.in(ID($mux), ID($pmux)))
@@ -299,16 +299,16 @@ struct Pmux2ShiftxPass : public Pass {
SigSpec A = sigmap(cell->getPort(ID::A));
SigSpec B = sigmap(cell->getPort(ID::B));
- int a_width = cell->getParam(ID(A_WIDTH)).as_int();
- int b_width = cell->getParam(ID(B_WIDTH)).as_int();
+ int a_width = cell->getParam(ID::A_WIDTH).as_int();
+ int b_width = cell->getParam(ID::B_WIDTH).as_int();
if (a_width < b_width) {
- bool a_signed = cell->getParam(ID(A_SIGNED)).as_int();
+ bool a_signed = cell->getParam(ID::A_SIGNED).as_int();
A.extend_u0(b_width, a_signed);
}
if (b_width < a_width) {
- bool b_signed = cell->getParam(ID(B_SIGNED)).as_int();
+ bool b_signed = cell->getParam(ID::B_SIGNED).as_int();
B.extend_u0(a_width, b_signed);
}
@@ -331,7 +331,7 @@ struct Pmux2ShiftxPass : public Pass {
pair<SigSpec, Const> entry;
for (auto it : bits) {
- entry.first.append_bit(it.first);
+ entry.first.append(it.first);
entry.second.bits.push_back(it.second);
}
@@ -352,7 +352,7 @@ struct Pmux2ShiftxPass : public Pass {
pair<SigSpec, Const> entry;
for (auto it : bits) {
- entry.first.append_bit(it.first);
+ entry.first.append(it.first);
entry.second.bits.push_back(it.second);
}
@@ -368,7 +368,7 @@ struct Pmux2ShiftxPass : public Pass {
continue;
string src = cell->get_src_attribute();
- int width = cell->getParam(ID(WIDTH)).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
int width_bits = ceil_log2(width);
int extwidth = width;
@@ -379,7 +379,7 @@ struct Pmux2ShiftxPass : public Pass {
SigSpec A = cell->getPort(ID::A);
SigSpec B = cell->getPort(ID::B);
- SigSpec S = sigmap(cell->getPort(ID(S)));
+ SigSpec S = sigmap(cell->getPort(ID::S));
for (int i = 0; i < GetSize(S); i++)
{
if (!eqdb.count(S[i]))
@@ -400,7 +400,7 @@ struct Pmux2ShiftxPass : public Pass {
log(" data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits);
}
- SigSpec updated_S = cell->getPort(ID(S));
+ SigSpec updated_S = cell->getPort(ID::S);
SigSpec updated_B = cell->getPort(ID::B);
while (!seldb.empty())
@@ -727,9 +727,9 @@ struct Pmux2ShiftxPass : public Pass {
}
// update $pmux cell
- cell->setPort(ID(S), updated_S);
+ cell->setPort(ID::S, updated_S);
cell->setPort(ID::B, updated_B);
- cell->setParam(ID(S_WIDTH), GetSize(updated_S));
+ cell->setParam(ID::S_WIDTH, GetSize(updated_S));
}
}
}
@@ -785,16 +785,16 @@ struct OnehotPass : public Pass {
SigSpec A = sigmap(cell->getPort(ID::A));
SigSpec B = sigmap(cell->getPort(ID::B));
- int a_width = cell->getParam(ID(A_WIDTH)).as_int();
- int b_width = cell->getParam(ID(B_WIDTH)).as_int();
+ int a_width = cell->getParam(ID::A_WIDTH).as_int();
+ int b_width = cell->getParam(ID::B_WIDTH).as_int();
if (a_width < b_width) {
- bool a_signed = cell->getParam(ID(A_SIGNED)).as_int();
+ bool a_signed = cell->getParam(ID::A_SIGNED).as_int();
A.extend_u0(b_width, a_signed);
}
if (b_width < a_width) {
- bool b_signed = cell->getParam(ID(B_SIGNED)).as_int();
+ bool b_signed = cell->getParam(ID::B_SIGNED).as_int();
B.extend_u0(a_width, b_signed);
}
diff --git a/passes/opt/share.cc b/passes/opt/share.cc
index 92ce3fd11..2839507b0 100644
--- a/passes/opt/share.cc
+++ b/passes/opt/share.cc
@@ -41,7 +41,8 @@ struct ShareWorkerConfig
struct ShareWorker
{
- ShareWorkerConfig config;
+ const ShareWorkerConfig config;
+ int limit;
pool<RTLIL::IdString> generic_ops;
RTLIL::Design *design;
@@ -49,7 +50,6 @@ struct ShareWorker
CellTypes fwd_ct, cone_ct;
ModWalker modwalker;
- ModIndex mi;
pool<RTLIL::Cell*> cells_to_remove;
pool<RTLIL::Cell*> recursion_state;
@@ -90,7 +90,7 @@ struct ShareWorker
for (auto &pbit : portbits) {
if (pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) {
- pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(ID(S))).to_sigbit_pool();
+ pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(ID::S)).to_sigbit_pool();
terminal_bits.insert(bits.begin(), bits.end());
queue_bits.insert(bits.begin(), bits.end());
visited_cells.insert(pbit.cell);
@@ -331,7 +331,7 @@ struct ShareWorker
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID::Y)));
supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID::Y)));
- supercell->setParam(ID(Y_WIDTH), width);
+ supercell->setParam(ID::Y_WIDTH, width);
supercell->setPort(ID::Y, sig_y);
supermacc.optimize(width);
@@ -369,21 +369,21 @@ struct ShareWorker
}
if (cell->type == ID($memrd)) {
- if (cell->parameters.at(ID(CLK_ENABLE)).as_bool())
+ if (cell->parameters.at(ID::CLK_ENABLE).as_bool())
continue;
- if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID(ADDR))).is_fully_const())
+ if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID::ADDR)).is_fully_const())
shareable_cells.insert(cell);
continue;
}
if (cell->type.in(ID($mul), ID($div), ID($mod))) {
- if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 4)
+ if (config.opt_aggressive || cell->parameters.at(ID::Y_WIDTH).as_int() >= 4)
shareable_cells.insert(cell);
continue;
}
if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
- if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 8)
+ if (config.opt_aggressive || cell->parameters.at(ID::Y_WIDTH).as_int() >= 8)
shareable_cells.insert(cell);
continue;
}
@@ -403,7 +403,7 @@ struct ShareWorker
if (c1->type == ID($memrd))
{
- if (c1->parameters.at(ID(MEMID)).decode_string() != c2->parameters.at(ID(MEMID)).decode_string())
+ if (c1->parameters.at(ID::MEMID).decode_string() != c2->parameters.at(ID::MEMID).decode_string())
return false;
return true;
@@ -413,11 +413,11 @@ struct ShareWorker
{
if (!config.opt_aggressive)
{
- int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
- int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
+ int a1_width = c1->parameters.at(ID::A_WIDTH).as_int();
+ int y1_width = c1->parameters.at(ID::Y_WIDTH).as_int();
- int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
- int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
+ int a2_width = c2->parameters.at(ID::A_WIDTH).as_int();
+ int y2_width = c2->parameters.at(ID::Y_WIDTH).as_int();
if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false;
@@ -430,13 +430,13 @@ struct ShareWorker
{
if (!config.opt_aggressive)
{
- int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
- int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
- int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
+ int a1_width = c1->parameters.at(ID::A_WIDTH).as_int();
+ int b1_width = c1->parameters.at(ID::B_WIDTH).as_int();
+ int y1_width = c1->parameters.at(ID::Y_WIDTH).as_int();
- int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
- int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
- int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
+ int a2_width = c2->parameters.at(ID::A_WIDTH).as_int();
+ int b2_width = c2->parameters.at(ID::B_WIDTH).as_int();
+ int y2_width = c2->parameters.at(ID::Y_WIDTH).as_int();
if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
if (max(b1_width, b2_width) > 2 * min(b1_width, b2_width)) return false;
@@ -450,13 +450,13 @@ struct ShareWorker
{
if (!config.opt_aggressive)
{
- int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
- int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
- int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
+ int a1_width = c1->parameters.at(ID::A_WIDTH).as_int();
+ int b1_width = c1->parameters.at(ID::B_WIDTH).as_int();
+ int y1_width = c1->parameters.at(ID::Y_WIDTH).as_int();
- int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
- int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
- int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
+ int a2_width = c2->parameters.at(ID::A_WIDTH).as_int();
+ int b2_width = c2->parameters.at(ID::B_WIDTH).as_int();
+ int y2_width = c2->parameters.at(ID::Y_WIDTH).as_int();
int min1_width = min(a1_width, b1_width);
int max1_width = max(a1_width, b1_width);
@@ -510,21 +510,21 @@ struct ShareWorker
if (config.generic_uni_ops.count(c1->type))
{
- if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
+ if (c1->parameters.at(ID::A_SIGNED).as_bool() != c2->parameters.at(ID::A_SIGNED).as_bool())
{
- RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
+ RTLIL::Cell *unsigned_cell = c1->parameters.at(ID::A_SIGNED).as_bool() ? c2 : c1;
if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
- unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
+ unsigned_cell->parameters.at(ID::A_WIDTH) = unsigned_cell->parameters.at(ID::A_WIDTH).as_int() + 1;
RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
- new_a.append_bit(RTLIL::State::S0);
+ new_a.append(RTLIL::State::S0);
unsigned_cell->setPort(ID::A, new_a);
}
- unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
+ unsigned_cell->parameters.at(ID::A_SIGNED) = true;
unsigned_cell->check();
}
- bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
- log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
+ bool a_signed = c1->parameters.at(ID::A_SIGNED).as_bool();
+ log_assert(a_signed == c2->parameters.at(ID::A_SIGNED).as_bool());
RTLIL::SigSpec a1 = c1->getPort(ID::A);
RTLIL::SigSpec y1 = c1->getPort(ID::Y);
@@ -544,9 +544,9 @@ struct ShareWorker
RTLIL::Wire *y = module->addWire(NEW_ID, y_width);
RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
- supercell->parameters[ID(A_SIGNED)] = a_signed;
- supercell->parameters[ID(A_WIDTH)] = a_width;
- supercell->parameters[ID(Y_WIDTH)] = y_width;
+ supercell->parameters[ID::A_SIGNED] = a_signed;
+ supercell->parameters[ID::A_WIDTH] = a_width;
+ supercell->parameters[ID::Y_WIDTH] = y_width;
supercell->setPort(ID::A, a);
supercell->setPort(ID::Y, y);
@@ -563,11 +563,11 @@ struct ShareWorker
if (config.generic_cbin_ops.count(c1->type))
{
- int score_unflipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()) +
- max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int());
+ int score_unflipped = max(c1->parameters.at(ID::A_WIDTH).as_int(), c2->parameters.at(ID::A_WIDTH).as_int()) +
+ max(c1->parameters.at(ID::B_WIDTH).as_int(), c2->parameters.at(ID::B_WIDTH).as_int());
- int score_flipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()) +
- max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int());
+ int score_flipped = max(c1->parameters.at(ID::A_WIDTH).as_int(), c2->parameters.at(ID::B_WIDTH).as_int()) +
+ max(c1->parameters.at(ID::B_WIDTH).as_int(), c2->parameters.at(ID::A_WIDTH).as_int());
if (score_flipped < score_unflipped)
{
@@ -575,36 +575,36 @@ struct ShareWorker
c2->setPort(ID::A, c2->getPort(ID::B));
c2->setPort(ID::B, tmp);
- std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH)));
- std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED)));
+ std::swap(c2->parameters.at(ID::A_WIDTH), c2->parameters.at(ID::B_WIDTH));
+ std::swap(c2->parameters.at(ID::A_SIGNED), c2->parameters.at(ID::B_SIGNED));
modified_src_cells = true;
}
}
- if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
+ if (c1->parameters.at(ID::A_SIGNED).as_bool() != c2->parameters.at(ID::A_SIGNED).as_bool())
{
- RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
+ RTLIL::Cell *unsigned_cell = c1->parameters.at(ID::A_SIGNED).as_bool() ? c2 : c1;
if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
- unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
+ unsigned_cell->parameters.at(ID::A_WIDTH) = unsigned_cell->parameters.at(ID::A_WIDTH).as_int() + 1;
RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
- new_a.append_bit(RTLIL::State::S0);
+ new_a.append(RTLIL::State::S0);
unsigned_cell->setPort(ID::A, new_a);
}
- unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
+ unsigned_cell->parameters.at(ID::A_SIGNED) = true;
modified_src_cells = true;
}
- if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool())
+ if (c1->parameters.at(ID::B_SIGNED).as_bool() != c2->parameters.at(ID::B_SIGNED).as_bool())
{
- RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1;
+ RTLIL::Cell *unsigned_cell = c1->parameters.at(ID::B_SIGNED).as_bool() ? c2 : c1;
if (unsigned_cell->getPort(ID::B).to_sigbit_vector().back() != RTLIL::State::S0) {
- unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1;
+ unsigned_cell->parameters.at(ID::B_WIDTH) = unsigned_cell->parameters.at(ID::B_WIDTH).as_int() + 1;
RTLIL::SigSpec new_b = unsigned_cell->getPort(ID::B);
- new_b.append_bit(RTLIL::State::S0);
+ new_b.append(RTLIL::State::S0);
unsigned_cell->setPort(ID::B, new_b);
}
- unsigned_cell->parameters.at(ID(B_SIGNED)) = true;
+ unsigned_cell->parameters.at(ID::B_SIGNED) = true;
modified_src_cells = true;
}
@@ -613,11 +613,11 @@ struct ShareWorker
c2->check();
}
- bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
- bool b_signed = c1->parameters.at(ID(B_SIGNED)).as_bool();
+ bool a_signed = c1->parameters.at(ID::A_SIGNED).as_bool();
+ bool b_signed = c1->parameters.at(ID::B_SIGNED).as_bool();
- log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
- log_assert(b_signed == c2->parameters.at(ID(B_SIGNED)).as_bool());
+ log_assert(a_signed == c2->parameters.at(ID::A_SIGNED).as_bool());
+ log_assert(b_signed == c2->parameters.at(ID::B_SIGNED).as_bool());
if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr))
b_signed = false;
@@ -664,32 +664,32 @@ struct ShareWorker
RTLIL::Wire *co = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr;
RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
- supercell->parameters[ID(A_SIGNED)] = a_signed;
- supercell->parameters[ID(B_SIGNED)] = b_signed;
- supercell->parameters[ID(A_WIDTH)] = a_width;
- supercell->parameters[ID(B_WIDTH)] = b_width;
- supercell->parameters[ID(Y_WIDTH)] = y_width;
+ supercell->parameters[ID::A_SIGNED] = a_signed;
+ supercell->parameters[ID::B_SIGNED] = b_signed;
+ supercell->parameters[ID::A_WIDTH] = a_width;
+ supercell->parameters[ID::B_WIDTH] = b_width;
+ supercell->parameters[ID::Y_WIDTH] = y_width;
supercell->setPort(ID::A, a);
supercell->setPort(ID::B, b);
supercell->setPort(ID::Y, y);
if (c1->type == ID($alu)) {
RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID);
- supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci));
- supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(BI)), c1->getPort(ID(BI)), act, bi));
- supercell->setPort(ID(CI), ci);
- supercell->setPort(ID(BI), bi);
- supercell->setPort(ID(CO), co);
- supercell->setPort(ID(X), x);
+ supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID::CI), c1->getPort(ID::CI), act, ci));
+ supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID::BI), c1->getPort(ID::BI), act, bi));
+ supercell->setPort(ID::CI, ci);
+ supercell->setPort(ID::BI, bi);
+ supercell->setPort(ID::CO, co);
+ supercell->setPort(ID::X, x);
}
supercell->check();
supercell_aux.insert(module->addPos(NEW_ID, y, y1));
supercell_aux.insert(module->addPos(NEW_ID, y, y2));
if (c1->type == ID($alu)) {
- supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID(CO))));
- supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID(CO))));
- supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID(X))));
- supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID(X))));
+ supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID::CO)));
+ supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID::CO)));
+ supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID::X)));
+ supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID::X)));
}
supercell_aux.insert(supercell);
@@ -708,15 +708,15 @@ struct ShareWorker
if (c1->type == ID($memrd))
{
RTLIL::Cell *supercell = module->addCell(NEW_ID, c1);
- RTLIL::SigSpec addr1 = c1->getPort(ID(ADDR));
- RTLIL::SigSpec addr2 = c2->getPort(ID(ADDR));
+ RTLIL::SigSpec addr1 = c1->getPort(ID::ADDR);
+ RTLIL::SigSpec addr2 = c2->getPort(ID::ADDR);
if (GetSize(addr1) < GetSize(addr2))
addr1.extend_u0(GetSize(addr2));
else
addr2.extend_u0(GetSize(addr1));
- supercell->setPort(ID(ADDR), addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1);
- supercell->parameters[ID(ABITS)] = RTLIL::Const(GetSize(addr1));
- supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID(DATA)), c2->getPort(ID(DATA))));
+ supercell->setPort(ID::ADDR, addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1);
+ supercell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr1));
+ supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID::DATA), c2->getPort(ID::DATA)));
supercell_aux.insert(supercell);
return supercell;
}
@@ -747,8 +747,8 @@ struct ShareWorker
modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]);
for (auto &bit : pbits) {
- if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID(S))
- forbidden_controls_cache[cell].insert(bit.cell->getPort(ID(S)).extract(bit.offset, 1));
+ if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID::S)
+ forbidden_controls_cache[cell].insert(bit.cell->getPort(ID::S).extract(bit.offset, 1));
consumer_cells.insert(bit.cell);
}
@@ -790,7 +790,7 @@ struct ShareWorker
p.second.bits.clear();
for (auto &it : p_bits) {
- p.first.append_bit(it.first);
+ p.first.append(it.first);
p.second.bits.push_back(it.second);
}
@@ -890,10 +890,10 @@ struct ShareWorker
bool used_in_a = false;
std::set<int> used_in_b_parts;
- int width = c->parameters.at(ID(WIDTH)).as_int();
+ int width = c->parameters.at(ID::WIDTH).as_int();
std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort(ID::A));
std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort(ID::B));
- std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID(S)));
+ std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID::S));
for (auto &bit : sig_a)
if (cell_out_bits.count(bit))
@@ -906,14 +906,14 @@ struct ShareWorker
if (used_in_a)
for (auto p : c_patterns) {
for (int i = 0; i < GetSize(sig_s); i++)
- p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0);
+ p.first.append(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0);
if (sort_check_activation_pattern(p))
activation_patterns_cache[cell].insert(p);
}
for (int idx : used_in_b_parts)
for (auto p : c_patterns) {
- p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1);
+ p.first.append(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1);
if (sort_check_activation_pattern(p))
activation_patterns_cache[cell].insert(p);
}
@@ -948,7 +948,7 @@ struct ShareWorker
RTLIL::SigSpec signal;
for (auto &bit : all_bits)
- signal.append_bit(bit);
+ signal.append(bit);
return signal;
}
@@ -963,7 +963,7 @@ struct ShareWorker
for (int i = 0; i < GetSize(p_first); i++)
if (filter_bits.count(p_first[i]) == 0) {
- new_p.first.append_bit(p_first[i]);
+ new_p.first.append(p_first[i]);
new_p.second.bits.push_back(p.second.bits.at(i));
}
@@ -1071,6 +1071,8 @@ struct ShareWorker
ct.setup_internals();
ct.setup_stdcells();
+ ModIndex mi(module);
+
pool<RTLIL::Cell*> queue, covered;
queue.insert(cell);
@@ -1117,13 +1119,9 @@ struct ShareWorker
module->remove(cell);
}
- ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) :
- config(config), design(design), module(module), mi(module)
+ ShareWorker(ShareWorkerConfig config, RTLIL::Design* design) :
+ config(config), design(design), modwalker(design)
{
- #ifndef NDEBUG
- bool before_scc = module_has_scc();
- #endif
-
generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end());
generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end());
generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end());
@@ -1140,8 +1138,27 @@ struct ShareWorker
cone_ct.cell_types.erase(ID($shr));
cone_ct.cell_types.erase(ID($sshl));
cone_ct.cell_types.erase(ID($sshr));
+ }
- modwalker.setup(design, module);
+ void operator()(RTLIL::Module *module) {
+ this->module = module;
+
+ #ifndef NDEBUG
+ bool before_scc = module_has_scc();
+ #endif
+
+ limit = config.limit;
+ modwalker.setup(module);
+
+ cells_to_remove.clear();
+ recursion_state.clear();
+ topo_cell_drivers.clear();
+ topo_bit_drivers.clear();
+ exclusive_ctrls.clear();
+ terminal_bits.clear();
+ shareable_cells.clear();
+ forbidden_controls_cache.clear();
+ activation_patterns_cache.clear();
find_terminal_bits();
find_shareable_cells();
@@ -1154,8 +1171,8 @@ struct ShareWorker
for (auto cell : module->cells())
if (cell->type == ID($pmux))
- for (auto bit : cell->getPort(ID(S)))
- for (auto other_bit : cell->getPort(ID(S)))
+ for (auto bit : cell->getPort(ID::S))
+ for (auto other_bit : cell->getPort(ID::S))
if (bit < other_bit)
exclusive_ctrls.push_back(std::pair<RTLIL::SigBit, RTLIL::SigBit>(bit, other_bit));
@@ -1399,8 +1416,8 @@ struct ShareWorker
topo_cell_drivers[cell] = { supercell };
topo_cell_drivers[other_cell] = { supercell };
- if (config.limit > 0)
- config.limit--;
+ if (limit > 0)
+ limit--;
break;
}
@@ -1528,9 +1545,10 @@ struct SharePass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &mod_it : design->modules_)
- if (design->selected(mod_it.second))
- ShareWorker(config, design, mod_it.second);
+ ShareWorker sw(config, design);
+
+ for (auto module : design->selected_modules())
+ sw(module);
}
} SharePass;
diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc
index 04b882db9..195400bf0 100644
--- a/passes/opt/wreduce.cc
+++ b/passes/opt/wreduce.cc
@@ -65,7 +65,7 @@ struct WreduceWorker
SigSpec sig_a = mi.sigmap(cell->getPort(ID::A));
SigSpec sig_b = mi.sigmap(cell->getPort(ID::B));
- SigSpec sig_s = mi.sigmap(cell->getPort(ID(S)));
+ SigSpec sig_s = mi.sigmap(cell->getPort(ID::S));
SigSpec sig_y = mi.sigmap(cell->getPort(ID::Y));
std::vector<SigBit> bits_removed;
@@ -98,7 +98,7 @@ struct WreduceWorker
SigSpec sig_removed;
for (int i = GetSize(bits_removed)-1; i >= 0; i--)
- sig_removed.append_bit(bits_removed[i]);
+ sig_removed.append(bits_removed[i]);
if (GetSize(bits_removed) == GetSize(sig_y)) {
log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type));
@@ -141,8 +141,8 @@ struct WreduceWorker
{
// Reduce size of FF if inputs are just sign/zero extended or output bit is not used
- SigSpec sig_d = mi.sigmap(cell->getPort(ID(D)));
- SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q)));
+ SigSpec sig_d = mi.sigmap(cell->getPort(ID::D));
+ SigSpec sig_q = mi.sigmap(cell->getPort(ID::Q));
bool is_adff = (cell->type == ID($adff));
Const initval, arst_value;
@@ -151,8 +151,8 @@ struct WreduceWorker
if (width_before == 0)
return;
- if (cell->parameters.count(ID(ARST_VALUE))) {
- arst_value = cell->parameters[ID(ARST_VALUE)];
+ if (cell->parameters.count(ID::ARST_VALUE)) {
+ arst_value = cell->parameters[ID::ARST_VALUE];
}
bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0;
@@ -220,13 +220,13 @@ struct WreduceWorker
work_queue_bits.insert(bit);
// Narrow ARST_VALUE parameter to new size.
- if (cell->parameters.count(ID(ARST_VALUE))) {
+ if (cell->parameters.count(ID::ARST_VALUE)) {
arst_value.bits.resize(GetSize(sig_q));
- cell->setParam(ID(ARST_VALUE), arst_value);
+ cell->setParam(ID::ARST_VALUE, arst_value);
}
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), sig_q);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
cell->fixup_parameters();
}
@@ -306,8 +306,8 @@ struct WreduceWorker
GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) {
log("Converting cell %s.%s (%s) from signed to unsigned.\n",
log_id(module), log_id(cell), log_id(cell->type));
- cell->setParam(ID(A_SIGNED), 0);
- cell->setParam(ID(B_SIGNED), 0);
+ cell->setParam(ID::A_SIGNED, 0);
+ cell->setParam(ID::B_SIGNED, 0);
port_a_signed = false;
port_b_signed = false;
did_something = true;
@@ -319,7 +319,7 @@ struct WreduceWorker
if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) {
log("Converting cell %s.%s (%s) from signed to unsigned.\n",
log_id(module), log_id(cell), log_id(cell->type));
- cell->setParam(ID(A_SIGNED), 0);
+ cell->setParam(ID::A_SIGNED, 0);
port_a_signed = false;
did_something = true;
}
@@ -349,7 +349,7 @@ struct WreduceWorker
if (cell->type.in(ID($pos), ID($add), ID($mul), ID($and), ID($or), ID($xor), ID($sub)))
{
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub);
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool() || cell->type == ID($sub);
int a_size = 0, b_size = 0;
if (cell->hasPort(ID::A)) a_size = GetSize(cell->getPort(ID::A));
@@ -392,8 +392,8 @@ struct WreduceWorker
static int count_nontrivial_wire_attrs(RTLIL::Wire *w)
{
int count = w->attributes.size();
- count -= w->attributes.count(ID(src));
- count -= w->attributes.count(ID(unused_bits));
+ count -= w->attributes.count(ID::src);
+ count -= w->attributes.count(ID::unused_bits);
return count;
}
@@ -406,8 +406,8 @@ struct WreduceWorker
if (w->get_bool_attribute(ID::keep))
for (auto bit : mi.sigmap(w))
keep_bits.insert(bit);
- if (w->attributes.count(ID(init))) {
- Const initval = w->attributes.at(ID(init));
+ if (w->attributes.count(ID::init)) {
+ Const initval = w->attributes.at(ID::init);
SigSpec initsig = init_attr_sigmap(w);
int width = std::min(GetSize(initval), GetSize(initsig));
for (int i = 0; i < width; i++)
@@ -464,8 +464,8 @@ struct WreduceWorker
if (!remove_init_bits.empty()) {
for (auto w : module->wires()) {
- if (w->attributes.count(ID(init))) {
- Const initval = w->attributes.at(ID(init));
+ if (w->attributes.count(ID::init)) {
+ Const initval = w->attributes.at(ID::init);
Const new_initval(State::Sx, GetSize(w));
SigSpec initsig = init_attr_sigmap(w);
int width = std::min(GetSize(initval), GetSize(initsig));
@@ -473,7 +473,7 @@ struct WreduceWorker
if (!remove_init_bits.count(initsig[i]))
new_initval[i] = initval[i];
}
- w->attributes.at(ID(init)) = new_initval;
+ w->attributes.at(ID::init) = new_initval;
}
}
}
@@ -539,7 +539,7 @@ struct WreducePass : public Pass {
SigSpec sig = c->getPort(ID::Y);
if (!sig.has_const()) {
c->setPort(ID::Y, sig[0]);
- c->setParam(ID(Y_WIDTH), 1);
+ c->setParam(ID::Y_WIDTH, 1);
sig.remove(0);
module->connect(sig, Const(0, GetSize(sig)));
}
@@ -549,7 +549,7 @@ struct WreducePass : public Pass {
{
SigSpec A = c->getPort(ID::A);
int original_a_width = GetSize(A);
- if (c->getParam(ID(A_SIGNED)).as_bool()) {
+ if (c->getParam(ID::A_SIGNED).as_bool()) {
while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0)
A.remove(GetSize(A)-1, 1);
} else {
@@ -560,12 +560,12 @@ struct WreducePass : public Pass {
log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n",
original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type));
c->setPort(ID::A, A);
- c->setParam(ID(A_WIDTH), GetSize(A));
+ c->setParam(ID::A_WIDTH, GetSize(A));
}
SigSpec B = c->getPort(ID::B);
int original_b_width = GetSize(B);
- if (c->getParam(ID(B_SIGNED)).as_bool()) {
+ if (c->getParam(ID::B_SIGNED).as_bool()) {
while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0)
B.remove(GetSize(B)-1, 1);
} else {
@@ -576,23 +576,23 @@ struct WreducePass : public Pass {
log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n",
original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type));
c->setPort(ID::B, B);
- c->setParam(ID(B_WIDTH), GetSize(B));
+ c->setParam(ID::B_WIDTH, GetSize(B));
}
}
if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
- IdString memid = c->getParam(ID(MEMID)).decode_string();
+ IdString memid = c->getParam(ID::MEMID).decode_string();
RTLIL::Memory *mem = module->memories.at(memid);
if (mem->start_offset >= 0) {
- int cur_addrbits = c->getParam(ID(ABITS)).as_int();
+ int cur_addrbits = c->getParam(ID::ABITS).as_int();
int max_addrbits = ceil_log2(mem->start_offset + mem->size);
if (cur_addrbits > max_addrbits) {
log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n",
cur_addrbits-max_addrbits, cur_addrbits,
c->type == ID($memrd) ? "read" : c->type == ID($memwr) ? "write" : "init",
log_id(module), log_id(c), log_id(memid));
- c->setParam(ID(ABITS), max_addrbits);
- c->setPort(ID(ADDR), c->getPort(ID(ADDR)).extract(0, max_addrbits));
+ c->setParam(ID::ABITS, max_addrbits);
+ c->setPort(ID::ADDR, c->getPort(ID::ADDR).extract(0, max_addrbits));
}
}
}
diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc
index c364cd91a..bfddfd0eb 100644
--- a/passes/pmgen/ice40_dsp.cc
+++ b/passes/pmgen/ice40_dsp.cc
@@ -73,11 +73,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
// SB_MAC16 Input Interface
SigSpec A = st.sigA;
- A.extend_u0(16, st.mul->parameters.at(ID(A_SIGNED), State::S0).as_bool());
+ A.extend_u0(16, st.mul->parameters.at(ID::A_SIGNED, State::S0).as_bool());
log_assert(GetSize(A) == 16);
SigSpec B = st.sigB;
- B.extend_u0(16, st.mul->parameters.at(ID(B_SIGNED), State::S0).as_bool());
+ B.extend_u0(16, st.mul->parameters.at(ID::B_SIGNED, State::S0).as_bool());
log_assert(GetSize(B) == 16);
SigSpec CD = st.sigCD;
@@ -88,8 +88,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setPort(ID::A, A);
cell->setPort(ID::B, B);
- cell->setPort(ID(C), CD.extract(16, 16));
- cell->setPort(ID(D), CD.extract(0, 16));
+ cell->setPort(ID::C, CD.extract(16, 16));
+ cell->setPort(ID::D, CD.extract(0, 16));
cell->setParam(ID(A_REG), st.ffA ? State::S1 : State::S0);
cell->setParam(ID(B_REG), st.ffB ? State::S1 : State::S0);
@@ -98,15 +98,15 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
SigSpec AHOLD, BHOLD, CDHOLD;
if (st.ffAholdmux)
- AHOLD = st.ffAholdpol ? st.ffAholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffAholdmux->getPort(ID(S)));
+ AHOLD = st.ffAholdpol ? st.ffAholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffAholdmux->getPort(ID::S));
else
AHOLD = State::S0;
if (st.ffBholdmux)
- BHOLD = st.ffBholdpol ? st.ffBholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffBholdmux->getPort(ID(S)));
+ BHOLD = st.ffBholdpol ? st.ffBholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffBholdmux->getPort(ID::S));
else
BHOLD = State::S0;
if (st.ffCDholdmux)
- CDHOLD = st.ffCDholdpol ? st.ffCDholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffCDholdmux->getPort(ID(S)));
+ CDHOLD = st.ffCDholdpol ? st.ffCDholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffCDholdmux->getPort(ID::S));
else
CDHOLD = State::S0;
cell->setPort(ID(AHOLD), AHOLD);
@@ -116,11 +116,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
SigSpec IRSTTOP, IRSTBOT;
if (st.ffArstmux)
- IRSTTOP = st.ffArstpol ? st.ffArstmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffArstmux->getPort(ID(S)));
+ IRSTTOP = st.ffArstpol ? st.ffArstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffArstmux->getPort(ID::S));
else
IRSTTOP = State::S0;
if (st.ffBrstmux)
- IRSTBOT = st.ffBrstpol ? st.ffBrstmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffBrstmux->getPort(ID(S)));
+ IRSTBOT = st.ffBrstpol ? st.ffBrstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffBrstmux->getPort(ID::S));
else
IRSTBOT = State::S0;
cell->setPort(ID(IRSTTOP), IRSTTOP);
@@ -128,7 +128,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
if (st.clock != SigBit())
{
- cell->setPort(ID(CLK), st.clock);
+ cell->setPort(ID::CLK, st.clock);
cell->setPort(ID(CE), State::S1);
cell->setParam(ID(NEG_TRIGGER), st.clock_pol ? State::S0 : State::S1);
@@ -156,7 +156,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
}
else
{
- cell->setPort(ID(CLK), State::S0);
+ cell->setPort(ID::CLK, State::S0);
cell->setPort(ID(CE), State::S0);
cell->setParam(ID(NEG_TRIGGER), State::S0);
}
@@ -166,7 +166,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setPort(ID(SIGNEXTIN), State::Sx);
cell->setPort(ID(SIGNEXTOUT), pm.module->addWire(NEW_ID));
- cell->setPort(ID(CI), State::Sx);
+ cell->setPort(ID::CI, State::Sx);
cell->setPort(ID(ACCUMCI), State::Sx);
cell->setPort(ID(ACCUMCO), pm.module->addWire(NEW_ID));
@@ -178,19 +178,19 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
if (O_width == 33) {
log_assert(st.add);
// If we have a signed multiply-add, then perform sign extension
- if (st.add->getParam(ID(A_SIGNED)).as_bool() && st.add->getParam(ID(B_SIGNED)).as_bool())
+ if (st.add->getParam(ID::A_SIGNED).as_bool() && st.add->getParam(ID::B_SIGNED).as_bool())
pm.module->connect(O[32], O[31]);
else
- cell->setPort(ID(CO), O[32]);
+ cell->setPort(ID::CO, O[32]);
O.remove(O_width-1);
}
else
- cell->setPort(ID(CO), pm.module->addWire(NEW_ID));
+ cell->setPort(ID::CO, pm.module->addWire(NEW_ID));
log_assert(GetSize(O) <= 32);
if (GetSize(O) < 32)
O.append(pm.module->addWire(NEW_ID, 32-GetSize(O)));
- cell->setPort(ID(O), O);
+ cell->setPort(ID::O, O);
bool accum = false;
if (st.add) {
@@ -208,7 +208,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
SigSpec OHOLD;
if (st.ffOholdmux)
- OHOLD = st.ffOholdpol ? st.ffOholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffOholdmux->getPort(ID(S)));
+ OHOLD = st.ffOholdpol ? st.ffOholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffOholdmux->getPort(ID::S));
else
OHOLD = State::S0;
cell->setPort(ID(OHOLDTOP), OHOLD);
@@ -216,7 +216,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
SigSpec ORST;
if (st.ffOrstmux)
- ORST = st.ffOrstpol ? st.ffOrstmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffOrstmux->getPort(ID(S)));
+ ORST = st.ffOrstpol ? st.ffOrstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffOrstmux->getPort(ID::S));
else
ORST = State::S0;
cell->setPort(ID(ORSTTOP), ORST);
@@ -225,9 +225,9 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
SigSpec acc_reset = State::S0;
if (st.mux) {
if (st.muxAB == ID::A)
- acc_reset = st.mux->getPort(ID(S));
+ acc_reset = st.mux->getPort(ID::S);
else
- acc_reset = pm.module->Not(NEW_ID, st.mux->getPort(ID(S)));
+ acc_reset = pm.module->Not(NEW_ID, st.mux->getPort(ID::S));
}
cell->setPort(ID(OLOADTOP), acc_reset);
cell->setPort(ID(OLOADBOT), acc_reset);
@@ -248,8 +248,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
cell->setParam(ID(BOTADDSUB_CARRYSELECT), Const(0, 2));
cell->setParam(ID(MODE_8x8), State::S0);
- cell->setParam(ID(A_SIGNED), st.mul->parameters.at(ID(A_SIGNED), State::S0).as_bool());
- cell->setParam(ID(B_SIGNED), st.mul->parameters.at(ID(B_SIGNED), State::S0).as_bool());
+ cell->setParam(ID::A_SIGNED, st.mul->parameters.at(ID::A_SIGNED, State::S0).as_bool());
+ cell->setParam(ID::B_SIGNED, st.mul->parameters.at(ID::B_SIGNED, State::S0).as_bool());
if (st.ffO) {
if (st.o_lo)
@@ -257,7 +257,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
else
cell->setParam(ID(TOPOUTPUT_SELECT), Const(1, 2));
- st.ffO->connections_.at(ID(Q)).replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
+ st.ffO->connections_.at(ID::Q).replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
cell->setParam(ID(BOTOUTPUT_SELECT), Const(1, 2));
}
else {
diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc
index 0053c8872..97d2008c2 100644
--- a/passes/pmgen/ice40_wrapcarry.cc
+++ b/passes/pmgen/ice40_wrapcarry.cc
@@ -37,26 +37,26 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
log(" replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n");
- Cell *cell = pm.module->addCell(NEW_ID, "$__ICE40_CARRY_WRAPPER");
+ Cell *cell = pm.module->addCell(NEW_ID, ID($__ICE40_CARRY_WRAPPER));
pm.module->swap_names(cell, st.carry);
- cell->setPort("\\A", st.carry->getPort("\\I0"));
- cell->setPort("\\B", st.carry->getPort("\\I1"));
- auto CI = st.carry->getPort("\\CI");
- cell->setPort("\\CI", CI);
- cell->setPort("\\CO", st.carry->getPort("\\CO"));
+ cell->setPort(ID::A, st.carry->getPort(ID(I0)));
+ cell->setPort(ID::B, st.carry->getPort(ID(I1)));
+ auto CI = st.carry->getPort(ID::CI);
+ cell->setPort(ID::CI, CI);
+ cell->setPort(ID::CO, st.carry->getPort(ID::CO));
- cell->setPort("\\I0", st.lut->getPort("\\I0"));
- auto I3 = st.lut->getPort("\\I3");
+ cell->setPort(ID(I0), st.lut->getPort(ID(I0)));
+ auto I3 = st.lut->getPort(ID(I3));
if (pm.sigmap(CI) == pm.sigmap(I3)) {
- cell->setParam("\\I3_IS_CI", State::S1);
+ cell->setParam(ID(I3_IS_CI), State::S1);
I3 = State::Sx;
}
else
- cell->setParam("\\I3_IS_CI", State::S0);
- cell->setPort("\\I3", I3);
- cell->setPort("\\O", st.lut->getPort("\\O"));
- cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT"));
+ cell->setParam(ID(I3_IS_CI), State::S0);
+ cell->setPort(ID(I3), I3);
+ cell->setPort(ID::O, st.lut->getPort(ID::O));
+ cell->setParam(ID::LUT, st.lut->getParam(ID(LUT_INIT)));
for (const auto &a : st.carry->attributes)
cell->attributes[stringf("\\SB_CARRY.%s", a.first.c_str())] = a.second;
@@ -117,18 +117,18 @@ struct Ice40WrapCarryPass : public Pass {
continue;
auto carry = module->addCell(NEW_ID, ID(SB_CARRY));
- carry->setPort(ID(I0), cell->getPort(ID(A)));
- carry->setPort(ID(I1), cell->getPort(ID(B)));
- carry->setPort(ID(CI), cell->getPort(ID(CI)));
- carry->setPort(ID(CO), cell->getPort(ID(CO)));
+ carry->setPort(ID(I0), cell->getPort(ID::A));
+ carry->setPort(ID(I1), cell->getPort(ID::B));
+ carry->setPort(ID::CI, cell->getPort(ID::CI));
+ carry->setPort(ID::CO, cell->getPort(ID::CO));
module->swap_names(carry, cell);
auto lut_name = cell->attributes.at(ID(SB_LUT4.name), Const(NEW_ID.str())).decode_string();
auto lut = module->addCell(lut_name, ID($lut));
- lut->setParam(ID(WIDTH), 4);
- lut->setParam(ID(LUT), cell->getParam(ID(LUT)));
- auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3));
- lut->setPort(ID(A), { I3, cell->getPort(ID(B)), cell->getPort(ID(A)), cell->getPort(ID(I0)) });
- lut->setPort(ID(Y), cell->getPort(ID(O)));
+ lut->setParam(ID::WIDTH, 4);
+ lut->setParam(ID::LUT, cell->getParam(ID::LUT));
+ auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3));
+ lut->setPort(ID::A, { I3, cell->getPort(ID::B), cell->getPort(ID::A), cell->getPort(ID(I0)) });
+ lut->setPort(ID::Y, cell->getPort(ID::O));
Const src;
for (const auto &a : cell->attributes)
@@ -136,16 +136,16 @@ struct Ice40WrapCarryPass : public Pass {
carry->attributes[a.first.c_str() + strlen("\\SB_CARRY.")] = a.second;
else if (a.first.begins_with("\\SB_LUT4.\\"))
lut->attributes[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second;
- else if (a.first == ID(src))
+ else if (a.first == ID::src)
src = a.second;
- else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived)))
+ else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID::module_not_derived))
continue;
else
log_abort();
if (!src.empty()) {
- carry->attributes.insert(std::make_pair(ID(src), src));
- lut->attributes.insert(std::make_pair(ID(src), src));
+ carry->attributes.insert(std::make_pair(ID::src, src));
+ lut->attributes.insert(std::make_pair(ID::src, src));
}
module->remove(cell);
diff --git a/passes/pmgen/peepopt.cc b/passes/pmgen/peepopt.cc
index 2230145df..4379ce1e6 100644
--- a/passes/pmgen/peepopt.cc
+++ b/passes/pmgen/peepopt.cc
@@ -87,7 +87,7 @@ struct PeepoptPass : public Pass {
peepopt_pm pm(module);
for (auto w : module->wires()) {
- auto it = w->attributes.find(ID(init));
+ auto it = w->attributes.find(ID::init);
if (it != w->attributes.end()) {
SigSpec sig = pm.sigmap(w);
Const val = it->second;
@@ -109,7 +109,7 @@ struct PeepoptPass : public Pass {
pm.run_dffmux();
for (auto w : module->wires()) {
- auto it = w->attributes.find(ID(init));
+ auto it = w->attributes.find(ID::init);
if (it != w->attributes.end()) {
SigSpec sig = pm.sigmap(w);
Const &val = it->second;
diff --git a/passes/pmgen/test_pmgen.cc b/passes/pmgen/test_pmgen.cc
index 72dc18dcc..9cfad03ef 100644
--- a/passes/pmgen/test_pmgen.cc
+++ b/passes/pmgen/test_pmgen.cc
@@ -40,16 +40,16 @@ void reduce_chain(test_pmgen_pm &pm)
log("Found chain of length %d (%s):\n", GetSize(ud.longest_chain), log_id(st.first->type));
SigSpec A;
- SigSpec Y = ud.longest_chain.front().first->getPort(ID(Y));
+ SigSpec Y = ud.longest_chain.front().first->getPort(ID::Y);
auto last_cell = ud.longest_chain.back().first;
for (auto it : ud.longest_chain) {
auto cell = it.first;
if (cell == last_cell) {
- A.append(cell->getPort(ID(A)));
- A.append(cell->getPort(ID(B)));
+ A.append(cell->getPort(ID::A));
+ A.append(cell->getPort(ID::B));
} else {
- A.append(cell->getPort(it.second == ID(A) ? ID(B) : ID(A)));
+ A.append(cell->getPort(it.second == ID::A ? ID::B : ID::A));
}
log(" %s\n", log_id(cell));
pm.autoremove(cell);
@@ -78,7 +78,7 @@ void reduce_tree(test_pmgen_pm &pm)
return;
SigSpec A = ud.leaves;
- SigSpec Y = st.first->getPort(ID(Y));
+ SigSpec Y = st.first->getPort(ID::Y);
pm.autoremove(st.first);
log("Found %s tree with %d leaves for %s (%s).\n", log_id(st.first->type),
diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc
index ae7967d7c..f1f4b4206 100644
--- a/passes/pmgen/xilinx_dsp.cc
+++ b/passes/pmgen/xilinx_dsp.cc
@@ -52,7 +52,7 @@ static Cell* addDsp(Module *module) {
cell->setParam(ID(USE_SIMD), Const("ONE48"));
cell->setParam(ID(USE_DPORT), Const("FALSE"));
- cell->setPort(ID(D), Const(0, 25));
+ cell->setPort(ID::D, Const(0, 25));
cell->setPort(ID(INMODE), Const(0, 5));
cell->setPort(ID(ALUMODE), Const(0, 4));
cell->setPort(ID(OPMODE), Const(0, 7));
@@ -72,15 +72,15 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
for (auto cell : selected_cells) {
if (!cell->type.in(ID($add), ID($sub)))
continue;
- SigSpec Y = cell->getPort(ID(Y));
+ SigSpec Y = cell->getPort(ID::Y);
if (!Y.is_chunk())
continue;
if (!Y.as_chunk().wire->get_strpool_attribute(ID(use_dsp)).count("simd"))
continue;
if (GetSize(Y) > 25)
continue;
- SigSpec A = cell->getPort(ID(A));
- SigSpec B = cell->getPort(ID(B));
+ SigSpec A = cell->getPort(ID::A);
+ SigSpec B = cell->getPort(ID::B);
if (GetSize(Y) <= 13) {
if (GetSize(A) > 12)
continue;
@@ -106,11 +106,11 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
}
auto f12 = [module](SigSpec &AB, SigSpec &C, SigSpec &P, SigSpec &CARRYOUT, Cell *lane) {
- SigSpec A = lane->getPort(ID(A));
- SigSpec B = lane->getPort(ID(B));
- SigSpec Y = lane->getPort(ID(Y));
- A.extend_u0(12, lane->getParam(ID(A_SIGNED)).as_bool());
- B.extend_u0(12, lane->getParam(ID(B_SIGNED)).as_bool());
+ SigSpec A = lane->getPort(ID::A);
+ SigSpec B = lane->getPort(ID::B);
+ SigSpec Y = lane->getPort(ID::Y);
+ A.extend_u0(12, lane->getParam(ID::A_SIGNED).as_bool());
+ B.extend_u0(12, lane->getParam(ID::B_SIGNED).as_bool());
AB.append(A);
C.append(B);
if (GetSize(Y) < 13)
@@ -174,10 +174,10 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
log_assert(GetSize(C) == 48);
log_assert(GetSize(P) == 48);
log_assert(GetSize(CARRYOUT) == 4);
- cell->setPort(ID(A), AB.extract(18, 30));
- cell->setPort(ID(B), AB.extract(0, 18));
- cell->setPort(ID(C), C);
- cell->setPort(ID(P), P);
+ cell->setPort(ID::A, AB.extract(18, 30));
+ cell->setPort(ID::B, AB.extract(0, 18));
+ cell->setPort(ID::C, C);
+ cell->setPort(ID::P, P);
cell->setPort(ID(CARRYOUT), CARRYOUT);
if (lane1->type == ID($sub))
cell->setPort(ID(ALUMODE), Const::from_string("0011"));
@@ -194,11 +194,11 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
g12(simd12_sub);
auto f24 = [module](SigSpec &AB, SigSpec &C, SigSpec &P, SigSpec &CARRYOUT, Cell *lane) {
- SigSpec A = lane->getPort(ID(A));
- SigSpec B = lane->getPort(ID(B));
- SigSpec Y = lane->getPort(ID(Y));
- A.extend_u0(24, lane->getParam(ID(A_SIGNED)).as_bool());
- B.extend_u0(24, lane->getParam(ID(B_SIGNED)).as_bool());
+ SigSpec A = lane->getPort(ID::A);
+ SigSpec B = lane->getPort(ID::B);
+ SigSpec Y = lane->getPort(ID::Y);
+ A.extend_u0(24, lane->getParam(ID::A_SIGNED).as_bool());
+ B.extend_u0(24, lane->getParam(ID::B_SIGNED).as_bool());
C.append(A);
AB.append(B);
if (GetSize(Y) < 25)
@@ -238,10 +238,10 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
log_assert(GetSize(C) == 48);
log_assert(GetSize(P) == 48);
log_assert(GetSize(CARRYOUT) == 4);
- cell->setPort(ID(A), AB.extract(18, 30));
- cell->setPort(ID(B), AB.extract(0, 18));
- cell->setPort(ID(C), C);
- cell->setPort(ID(P), P);
+ cell->setPort(ID::A, AB.extract(18, 30));
+ cell->setPort(ID::B, AB.extract(0, 18));
+ cell->setPort(ID::C, C);
+ cell->setPort(ID::P, P);
cell->setPort(ID(CARRYOUT), CARRYOUT);
if (lane1->type == ID($sub))
cell->setPort(ID(ALUMODE), Const::from_string("0011"));
@@ -280,19 +280,19 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
if (st.preAdd) {
log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type));
- bool A_SIGNED = st.preAdd->getParam(ID(A_SIGNED)).as_bool();
- bool D_SIGNED = st.preAdd->getParam(ID(B_SIGNED)).as_bool();
- if (st.sigA == st.preAdd->getPort(ID(B)))
+ bool A_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool();
+ bool D_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool();
+ if (st.sigA == st.preAdd->getPort(ID::B))
std::swap(A_SIGNED, D_SIGNED);
st.sigA.extend_u0(30, A_SIGNED);
st.sigD.extend_u0(25, D_SIGNED);
- cell->setPort(ID(A), st.sigA);
- cell->setPort(ID(D), st.sigD);
+ cell->setPort(ID::A, st.sigA);
+ cell->setPort(ID::D, st.sigD);
cell->setPort(ID(INMODE), Const::from_string("00100"));
if (st.ffAD) {
if (st.ffADcemux) {
- SigSpec S = st.ffADcemux->getPort(ID(S));
+ SigSpec S = st.ffADcemux->getPort(ID::S);
cell->setPort(ID(CEAD), st.ffADcepol ? S : pm.module->Not(NEW_ID, S));
}
else
@@ -310,7 +310,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
SigSpec &opmode = cell->connections_.at(ID(OPMODE));
if (st.postAddMux) {
log_assert(st.ffP);
- opmode[4] = st.postAddMux->getPort(ID(S));
+ opmode[4] = st.postAddMux->getPort(ID::S);
pm.autoremove(st.postAddMux);
}
else if (st.ffP && st.sigC == st.sigP)
@@ -321,11 +321,11 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
opmode[5] = State::S1;
if (opmode[4] != State::S0) {
- if (st.postAddMuxAB == ID(A))
- st.sigC.extend_u0(48, st.postAdd->getParam(ID(B_SIGNED)).as_bool());
+ if (st.postAddMuxAB == ID::A)
+ st.sigC.extend_u0(48, st.postAdd->getParam(ID::B_SIGNED).as_bool());
else
- st.sigC.extend_u0(48, st.postAdd->getParam(ID(A_SIGNED)).as_bool());
- cell->setPort(ID(C), st.sigC);
+ st.sigC.extend_u0(48, st.postAdd->getParam(ID::A_SIGNED).as_bool());
+ cell->setPort(ID::C, st.sigC);
}
pm.autoremove(st.postAdd);
@@ -337,7 +337,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
cell->setParam(ID(SEL_MASK), Const("MASK"));
if (st.overflow->type == ID($ge)) {
- Const B = st.overflow->getPort(ID(B)).as_const();
+ Const B = st.overflow->getPort(ID::B).as_const();
log_assert(std::count(B.bits.begin(), B.bits.end(), State::S1) == 1);
// Since B is an exact power of 2, subtract 1
// by inverting all bits up until hitting
@@ -352,7 +352,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
cell->setParam(ID(MASK), B);
cell->setParam(ID(PATTERN), Const(0, 48));
- cell->setPort(ID(OVERFLOW), st.overflow->getPort(ID(Y)));
+ cell->setPort(ID(OVERFLOW), st.overflow->getPort(ID::Y));
}
else log_abort();
@@ -361,29 +361,29 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
if (st.clock != SigBit())
{
- cell->setPort(ID(CLK), st.clock);
+ cell->setPort(ID::CLK, st.clock);
auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) {
- SigSpec D = ff->getPort(ID(D));
- SigSpec Q = pm.sigmap(ff->getPort(ID(Q)));
+ SigSpec D = ff->getPort(ID::D);
+ SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
if (!A.empty())
A.replace(Q, D);
if (rstmux) {
- SigSpec Y = rstmux->getPort(ID(Y));
- SigSpec AB = rstmux->getPort(rstpol ? ID(A) : ID(B));
+ SigSpec Y = rstmux->getPort(ID::Y);
+ SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B);
if (!A.empty())
A.replace(Y, AB);
if (rstport != IdString()) {
- SigSpec S = rstmux->getPort(ID(S));
+ SigSpec S = rstmux->getPort(ID::S);
cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
}
}
else if (rstport != IdString())
cell->setPort(rstport, State::S0);
if (cemux) {
- SigSpec Y = cemux->getPort(ID(Y));
- SigSpec BA = cemux->getPort(cepol ? ID(B) : ID(A));
- SigSpec S = cemux->getPort(ID(S));
+ SigSpec Y = cemux->getPort(ID::Y);
+ SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A);
+ SigSpec S = cemux->getPort(ID::S);
if (!A.empty())
A.replace(Y, BA);
cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S));
@@ -392,7 +392,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
cell->setPort(ceport, State::S1);
for (auto c : Q.chunks()) {
- auto it = c.wire->attributes.find(ID(init));
+ auto it = c.wire->attributes.find(ID::init);
if (it == c.wire->attributes.end())
continue;
for (int i = c.offset; i < c.offset+c.width; i++) {
@@ -403,7 +403,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
};
if (st.ffA2) {
- SigSpec A = cell->getPort(ID(A));
+ SigSpec A = cell->getPort(ID::A);
f(A, st.ffA2, st.ffA2cemux, st.ffA2cepol, ID(CEA2), st.ffA2rstmux, st.ffArstpol, ID(RSTA));
if (st.ffA1) {
f(A, st.ffA1, st.ffA1cemux, st.ffA1cepol, ID(CEA1), st.ffA1rstmux, st.ffArstpol, IdString());
@@ -415,10 +415,10 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
cell->setParam(ID(ACASCREG), 1);
}
pm.add_siguser(A, cell);
- cell->setPort(ID(A), A);
+ cell->setPort(ID::A, A);
}
if (st.ffB2) {
- SigSpec B = cell->getPort(ID(B));
+ SigSpec B = cell->getPort(ID::B);
f(B, st.ffB2, st.ffB2cemux, st.ffB2cepol, ID(CEB2), st.ffB2rstmux, st.ffBrstpol, ID(RSTB));
if (st.ffB1) {
f(B, st.ffB1, st.ffB1cemux, st.ffB1cepol, ID(CEB1), st.ffB1rstmux, st.ffBrstpol, IdString());
@@ -430,25 +430,25 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
cell->setParam(ID(BCASCREG), 1);
}
pm.add_siguser(B, cell);
- cell->setPort(ID(B), B);
+ cell->setPort(ID::B, B);
}
if (st.ffD) {
- SigSpec D = cell->getPort(ID(D));
+ SigSpec D = cell->getPort(ID::D);
f(D, st.ffD, st.ffDcemux, st.ffDcepol, ID(CED), st.ffDrstmux, st.ffDrstpol, ID(RSTD));
pm.add_siguser(D, cell);
- cell->setPort(ID(D), D);
+ cell->setPort(ID::D, D);
cell->setParam(ID(DREG), 1);
}
if (st.ffM) {
SigSpec M; // unused
f(M, st.ffM, st.ffMcemux, st.ffMcepol, ID(CEM), st.ffMrstmux, st.ffMrstpol, ID(RSTM));
- st.ffM->connections_.at(ID(Q)).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
+ st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
cell->setParam(ID(MREG), State::S1);
}
if (st.ffP) {
SigSpec P; // unused
f(P, st.ffP, st.ffPcemux, st.ffPcepol, ID(CEP), st.ffPrstmux, st.ffPrstpol, ID(RSTP));
- st.ffP->connections_.at(ID(Q)).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
+ st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
cell->setParam(ID(PREG), State::S1);
}
@@ -483,7 +483,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
SigSpec P = st.sigP;
if (GetSize(P) < 48)
P.append(pm.module->addWire(NEW_ID, 48-GetSize(P)));
- cell->setPort(ID(P), P);
+ cell->setPort(ID::P, P);
pm.blacklist(cell);
}
@@ -511,12 +511,12 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
if (st.preAdd) {
log(" preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type));
- bool D_SIGNED = st.preAdd->getParam(ID(A_SIGNED)).as_bool();
- bool B_SIGNED = st.preAdd->getParam(ID(B_SIGNED)).as_bool();
+ bool D_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool();
+ bool B_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool();
st.sigB.extend_u0(18, B_SIGNED);
st.sigD.extend_u0(18, D_SIGNED);
- cell->setPort(ID(B), st.sigB);
- cell->setPort(ID(D), st.sigD);
+ cell->setPort(ID::B, st.sigB);
+ cell->setPort(ID::D, st.sigD);
opmode[4] = State::S1;
if (st.preAdd->type == ID($add))
opmode[6] = State::S0;
@@ -532,7 +532,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
if (st.postAddMux) {
log_assert(st.ffP);
- opmode[2] = st.postAddMux->getPort(ID(S));
+ opmode[2] = st.postAddMux->getPort(ID::S);
pm.autoremove(st.postAddMux);
}
else if (st.ffP && st.sigC == st.sigP)
@@ -542,11 +542,11 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
opmode[3] = State::S1;
if (opmode[2] != State::S0) {
- if (st.postAddMuxAB == ID(A))
- st.sigC.extend_u0(48, st.postAdd->getParam(ID(B_SIGNED)).as_bool());
+ if (st.postAddMuxAB == ID::A)
+ st.sigC.extend_u0(48, st.postAdd->getParam(ID::B_SIGNED).as_bool());
else
- st.sigC.extend_u0(48, st.postAdd->getParam(ID(A_SIGNED)).as_bool());
- cell->setPort(ID(C), st.sigC);
+ st.sigC.extend_u0(48, st.postAdd->getParam(ID::A_SIGNED).as_bool());
+ cell->setPort(ID::C, st.sigC);
}
pm.autoremove(st.postAdd);
@@ -554,29 +554,29 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
if (st.clock != SigBit())
{
- cell->setPort(ID(CLK), st.clock);
+ cell->setPort(ID::CLK, st.clock);
auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) {
- SigSpec D = ff->getPort(ID(D));
- SigSpec Q = pm.sigmap(ff->getPort(ID(Q)));
+ SigSpec D = ff->getPort(ID::D);
+ SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
if (!A.empty())
A.replace(Q, D);
if (rstmux) {
- SigSpec Y = rstmux->getPort(ID(Y));
- SigSpec AB = rstmux->getPort(rstpol ? ID(A) : ID(B));
+ SigSpec Y = rstmux->getPort(ID::Y);
+ SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B);
if (!A.empty())
A.replace(Y, AB);
if (rstport != IdString()) {
- SigSpec S = rstmux->getPort(ID(S));
+ SigSpec S = rstmux->getPort(ID::S);
cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
}
}
else if (rstport != IdString())
cell->setPort(rstport, State::S0);
if (cemux) {
- SigSpec Y = cemux->getPort(ID(Y));
- SigSpec BA = cemux->getPort(cepol ? ID(B) : ID(A));
- SigSpec S = cemux->getPort(ID(S));
+ SigSpec Y = cemux->getPort(ID::Y);
+ SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A);
+ SigSpec S = cemux->getPort(ID::S);
if (!A.empty())
A.replace(Y, BA);
cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S));
@@ -585,7 +585,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
cell->setPort(ceport, State::S1);
for (auto c : Q.chunks()) {
- auto it = c.wire->attributes.find(ID(init));
+ auto it = c.wire->attributes.find(ID::init);
if (it == c.wire->attributes.end())
continue;
for (int i = c.offset; i < c.offset+c.width; i++) {
@@ -596,7 +596,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
};
if (st.ffA0 || st.ffA1) {
- SigSpec A = cell->getPort(ID(A));
+ SigSpec A = cell->getPort(ID::A);
if (st.ffA1) {
f(A, st.ffA1, st.ffA1cemux, st.ffAcepol, ID(CEA), st.ffA1rstmux, st.ffArstpol, ID(RSTA));
cell->setParam(ID(A1REG), 1);
@@ -606,10 +606,10 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
cell->setParam(ID(A0REG), 1);
}
pm.add_siguser(A, cell);
- cell->setPort(ID(A), A);
+ cell->setPort(ID::A, A);
}
if (st.ffB0 || st.ffB1) {
- SigSpec B = cell->getPort(ID(B));
+ SigSpec B = cell->getPort(ID::B);
if (st.ffB1) {
f(B, st.ffB1, st.ffB1cemux, st.ffBcepol, ID(CEB), st.ffB1rstmux, st.ffBrstpol, ID(RSTB));
cell->setParam(ID(B1REG), 1);
@@ -619,25 +619,25 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
cell->setParam(ID(B0REG), 1);
}
pm.add_siguser(B, cell);
- cell->setPort(ID(B), B);
+ cell->setPort(ID::B, B);
}
if (st.ffD) {
- SigSpec D = cell->getPort(ID(D));
+ SigSpec D = cell->getPort(ID::D);
f(D, st.ffD, st.ffDcemux, st.ffDcepol, ID(CED), st.ffDrstmux, st.ffDrstpol, ID(RSTD));
pm.add_siguser(D, cell);
- cell->setPort(ID(D), D);
+ cell->setPort(ID::D, D);
cell->setParam(ID(DREG), 1);
}
if (st.ffM) {
SigSpec M; // unused
f(M, st.ffM, st.ffMcemux, st.ffMcepol, ID(CEM), st.ffMrstmux, st.ffMrstpol, ID(RSTM));
- st.ffM->connections_.at(ID(Q)).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
+ st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
cell->setParam(ID(MREG), State::S1);
}
if (st.ffP) {
SigSpec P; // unused
f(P, st.ffP, st.ffPcemux, st.ffPcepol, ID(CEP), st.ffPrstmux, st.ffPrstpol, ID(RSTP));
- st.ffP->connections_.at(ID(Q)).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
+ st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
cell->setParam(ID(PREG), State::S1);
}
@@ -667,7 +667,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
SigSpec P = st.sigP;
if (GetSize(P) < 48)
P.append(pm.module->addWire(NEW_ID, 48-GetSize(P)));
- cell->setPort(ID(P), P);
+ cell->setPort(ID::P, P);
pm.blacklist(cell);
}
@@ -683,29 +683,29 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
if (st.clock != SigBit())
{
- cell->setPort(ID(CLK), st.clock);
+ cell->setPort(ID::CLK, st.clock);
auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) {
- SigSpec D = ff->getPort(ID(D));
- SigSpec Q = pm.sigmap(ff->getPort(ID(Q)));
+ SigSpec D = ff->getPort(ID::D);
+ SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
if (!A.empty())
A.replace(Q, D);
if (rstmux) {
- SigSpec Y = rstmux->getPort(ID(Y));
- SigSpec AB = rstmux->getPort(rstpol ? ID(A) : ID(B));
+ SigSpec Y = rstmux->getPort(ID::Y);
+ SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B);
if (!A.empty())
A.replace(Y, AB);
if (rstport != IdString()) {
- SigSpec S = rstmux->getPort(ID(S));
+ SigSpec S = rstmux->getPort(ID::S);
cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
}
}
else if (rstport != IdString())
cell->setPort(rstport, State::S0);
if (cemux) {
- SigSpec Y = cemux->getPort(ID(Y));
- SigSpec BA = cemux->getPort(cepol ? ID(B) : ID(A));
- SigSpec S = cemux->getPort(ID(S));
+ SigSpec Y = cemux->getPort(ID::Y);
+ SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A);
+ SigSpec S = cemux->getPort(ID::S);
if (!A.empty())
A.replace(Y, BA);
cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S));
@@ -714,7 +714,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
cell->setPort(ceport, State::S1);
for (auto c : Q.chunks()) {
- auto it = c.wire->attributes.find(ID(init));
+ auto it = c.wire->attributes.find(ID::init);
if (it == c.wire->attributes.end())
continue;
for (int i = c.offset; i < c.offset+c.width; i++) {
@@ -725,10 +725,10 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
};
if (st.ffC) {
- SigSpec C = cell->getPort(ID(C));
+ SigSpec C = cell->getPort(ID::C);
f(C, st.ffC, st.ffCcemux, st.ffCcepol, ID(CEC), st.ffCrstmux, st.ffCrstpol, ID(RSTC));
pm.add_siguser(C, cell);
- cell->setPort(ID(C), C);
+ cell->setPort(ID::C, C);
cell->setParam(ID(CREG), 1);
}
diff --git a/passes/pmgen/xilinx_srl.cc b/passes/pmgen/xilinx_srl.cc
index 3d264e8d4..24b525b93 100644
--- a/passes/pmgen/xilinx_srl.cc
+++ b/passes/pmgen/xilinx_srl.cc
@@ -36,9 +36,9 @@ void run_fixed(xilinx_srl_pm &pm)
for (auto cell : ud.longest_chain) {
log_debug(" %s\n", log_id(cell));
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) {
- SigBit Q = cell->getPort(ID(Q));
+ SigBit Q = cell->getPort(ID::Q);
log_assert(Q.wire);
- auto it = Q.wire->attributes.find(ID(init));
+ auto it = Q.wire->attributes.find(ID::init);
if (it != Q.wire->attributes.end()) {
auto &i = it->second[Q.offset];
initval.append(i);
@@ -48,7 +48,7 @@ void run_fixed(xilinx_srl_pm &pm)
initval.append(State::Sx);
}
else if (cell->type.in(ID(FDRE), ID(FDRE_1))) {
- if (cell->parameters.at(ID(INIT), State::S0).as_bool())
+ if (cell->parameters.at(ID::INIT, State::S0).as_bool())
initval.append(State::S1);
else
initval.append(State::S0);
@@ -64,11 +64,11 @@ void run_fixed(xilinx_srl_pm &pm)
pm.module->swap_names(c, first_cell);
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID(FDRE), ID(FDRE_1))) {
- c->setParam(ID(DEPTH), GetSize(ud.longest_chain));
- c->setParam(ID(INIT), initval.as_const());
+ c->setParam(ID::DEPTH, GetSize(ud.longest_chain));
+ c->setParam(ID::INIT, initval.as_const());
if (first_cell->type.in(ID($_DFF_P_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
c->setParam(ID(CLKPOL), 1);
- else if (first_cell->type.in(ID($_DFF_N_), ID($DFFE_NN_), ID($_DFFE_NP_), ID(FDRE_1)))
+ else if (first_cell->type.in(ID($_DFF_N_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID(FDRE_1)))
c->setParam(ID(CLKPOL), 0);
else if (first_cell->type.in(ID(FDRE))) {
if (!first_cell->parameters.at(ID(IS_C_INVERTED), State::S0).as_bool())
@@ -85,16 +85,16 @@ void run_fixed(xilinx_srl_pm &pm)
else
c->setParam(ID(ENPOL), 2);
- c->setPort(ID(C), first_cell->getPort(ID(C)));
- c->setPort(ID(D), first_cell->getPort(ID(D)));
- c->setPort(ID(Q), last_cell->getPort(ID(Q)));
- c->setPort(ID(L), GetSize(ud.longest_chain)-1);
+ c->setPort(ID::C, first_cell->getPort(ID::C));
+ c->setPort(ID::D, first_cell->getPort(ID::D));
+ c->setPort(ID::Q, last_cell->getPort(ID::Q));
+ c->setPort(ID::L, GetSize(ud.longest_chain)-1);
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
- c->setPort(ID(E), State::S1);
+ c->setPort(ID::E, State::S1);
else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
- c->setPort(ID(E), first_cell->getPort(ID(E)));
+ c->setPort(ID::E, first_cell->getPort(ID::E));
else if (first_cell->type.in(ID(FDRE), ID(FDRE_1)))
- c->setPort(ID(E), first_cell->getPort(ID(CE)));
+ c->setPort(ID::E, first_cell->getPort(ID(CE)));
else
log_abort();
}
@@ -117,9 +117,9 @@ void run_variable(xilinx_srl_pm &pm)
auto slice = i.second;
log_debug(" %s\n", log_id(cell));
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID($dff), ID($dffe))) {
- SigBit Q = cell->getPort(ID(Q))[slice];
+ SigBit Q = cell->getPort(ID::Q)[slice];
log_assert(Q.wire);
- auto it = Q.wire->attributes.find(ID(init));
+ auto it = Q.wire->attributes.find(ID::init);
if (it != Q.wire->attributes.end()) {
auto &i = it->second[Q.offset];
initval.append(i);
@@ -140,15 +140,15 @@ void run_variable(xilinx_srl_pm &pm)
pm.module->swap_names(c, first_cell);
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID($dff), ID($dffe))) {
- c->setParam(ID(DEPTH), GetSize(ud.chain));
- c->setParam(ID(INIT), initval.as_const());
+ c->setParam(ID::DEPTH, GetSize(ud.chain));
+ c->setParam(ID::INIT, initval.as_const());
Const clkpol, enpol;
if (first_cell->type.in(ID($_DFF_P_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
clkpol = 1;
- else if (first_cell->type.in(ID($_DFF_N_), ID($DFFE_NN_), ID($_DFFE_NP_)))
+ else if (first_cell->type.in(ID($_DFF_N_), ID($_DFFE_NN_), ID($_DFFE_NP_)))
clkpol = 0;
else if (first_cell->type.in(ID($dff), ID($dffe)))
- clkpol = first_cell->getParam(ID(CLK_POLARITY));
+ clkpol = first_cell->getParam(ID::CLK_POLARITY);
else
log_abort();
if (first_cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
@@ -156,27 +156,27 @@ void run_variable(xilinx_srl_pm &pm)
else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_PN_)))
enpol = 0;
else if (first_cell->type.in(ID($dffe)))
- enpol = first_cell->getParam(ID(EN_POLARITY));
+ enpol = first_cell->getParam(ID::EN_POLARITY);
else
enpol = 2;
c->setParam(ID(CLKPOL), clkpol);
c->setParam(ID(ENPOL), enpol);
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
- c->setPort(ID(C), first_cell->getPort(ID(C)));
+ c->setPort(ID::C, first_cell->getPort(ID::C));
else if (first_cell->type.in(ID($dff), ID($dffe)))
- c->setPort(ID(C), first_cell->getPort(ID(CLK)));
+ c->setPort(ID::C, first_cell->getPort(ID::CLK));
else
log_abort();
- c->setPort(ID(D), first_cell->getPort(ID(D))[first_slice]);
- c->setPort(ID(Q), st.shiftx->getPort(ID(Y)));
- c->setPort(ID(L), st.shiftx->getPort(ID(B)));
+ c->setPort(ID::D, first_cell->getPort(ID::D)[first_slice]);
+ c->setPort(ID::Q, st.shiftx->getPort(ID::Y));
+ c->setPort(ID::L, st.shiftx->getPort(ID::B));
if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($dff)))
- c->setPort(ID(E), State::S1);
+ c->setPort(ID::E, State::S1);
else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
- c->setPort(ID(E), first_cell->getPort(ID(E)));
+ c->setPort(ID::E, first_cell->getPort(ID::E));
else if (first_cell->type.in(ID($dffe)))
- c->setPort(ID(E), first_cell->getPort(ID(EN)));
+ c->setPort(ID::E, first_cell->getPort(ID::EN));
else
log_abort();
}
diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc
index c606deb88..e400fcb72 100644
--- a/passes/proc/proc_arst.cc
+++ b/passes/proc/proc_arst.cc
@@ -39,45 +39,45 @@ bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref,
for (auto cell : mod->cells())
{
- if (cell->type == "$reduce_or" && cell->getPort("\\Y") == signal)
- return check_signal(mod, cell->getPort("\\A"), ref, polarity);
+ if (cell->type == ID($reduce_or) && cell->getPort(ID::Y) == signal)
+ return check_signal(mod, cell->getPort(ID::A), ref, polarity);
- if (cell->type == "$reduce_bool" && cell->getPort("\\Y") == signal)
- return check_signal(mod, cell->getPort("\\A"), ref, polarity);
+ if (cell->type == ID($reduce_bool) && cell->getPort(ID::Y) == signal)
+ return check_signal(mod, cell->getPort(ID::A), ref, polarity);
- if (cell->type == "$logic_not" && cell->getPort("\\Y") == signal) {
+ if (cell->type == ID($logic_not) && cell->getPort(ID::Y) == signal) {
polarity = !polarity;
- return check_signal(mod, cell->getPort("\\A"), ref, polarity);
+ return check_signal(mod, cell->getPort(ID::A), ref, polarity);
}
- if (cell->type == "$not" && cell->getPort("\\Y") == signal) {
+ if (cell->type == ID($not) && cell->getPort(ID::Y) == signal) {
polarity = !polarity;
- return check_signal(mod, cell->getPort("\\A"), ref, polarity);
+ return check_signal(mod, cell->getPort(ID::A), ref, polarity);
}
- if (cell->type.in("$eq", "$eqx") && cell->getPort("\\Y") == signal) {
- if (cell->getPort("\\A").is_fully_const()) {
- if (!cell->getPort("\\A").as_bool())
+ if (cell->type.in(ID($eq), ID($eqx)) && cell->getPort(ID::Y) == signal) {
+ if (cell->getPort(ID::A).is_fully_const()) {
+ if (!cell->getPort(ID::A).as_bool())
polarity = !polarity;
- return check_signal(mod, cell->getPort("\\B"), ref, polarity);
+ return check_signal(mod, cell->getPort(ID::B), ref, polarity);
}
- if (cell->getPort("\\B").is_fully_const()) {
- if (!cell->getPort("\\B").as_bool())
+ if (cell->getPort(ID::B).is_fully_const()) {
+ if (!cell->getPort(ID::B).as_bool())
polarity = !polarity;
- return check_signal(mod, cell->getPort("\\A"), ref, polarity);
+ return check_signal(mod, cell->getPort(ID::A), ref, polarity);
}
}
- if (cell->type.in("$ne", "$nex") && cell->getPort("\\Y") == signal) {
- if (cell->getPort("\\A").is_fully_const()) {
- if (cell->getPort("\\A").as_bool())
+ if (cell->type.in(ID($ne), ID($nex)) && cell->getPort(ID::Y) == signal) {
+ if (cell->getPort(ID::A).is_fully_const()) {
+ if (cell->getPort(ID::A).as_bool())
polarity = !polarity;
- return check_signal(mod, cell->getPort("\\B"), ref, polarity);
+ return check_signal(mod, cell->getPort(ID::B), ref, polarity);
}
- if (cell->getPort("\\B").is_fully_const()) {
- if (cell->getPort("\\B").as_bool())
+ if (cell->getPort(ID::B).is_fully_const()) {
+ if (cell->getPort(ID::B).as_bool())
polarity = !polarity;
- return check_signal(mod, cell->getPort("\\A"), ref, polarity);
+ return check_signal(mod, cell->getPort(ID::A), ref, polarity);
}
}
}
@@ -261,8 +261,8 @@ struct ProcArstPass : public Pass {
for (auto &act : sync->actions) {
RTLIL::SigSpec arst_sig, arst_val;
for (auto &chunk : act.first.chunks())
- if (chunk.wire && chunk.wire->attributes.count("\\init")) {
- RTLIL::SigSpec value = chunk.wire->attributes.at("\\init");
+ if (chunk.wire && chunk.wire->attributes.count(ID::init)) {
+ RTLIL::SigSpec value = chunk.wire->attributes.at(ID::init);
value.extend_u0(chunk.wire->width, false);
arst_sig.append(chunk);
arst_val.append(value.extract(chunk.offset, chunk.width));
@@ -285,7 +285,7 @@ struct ProcArstPass : public Pass {
}
for (auto wire : delete_initattr_wires)
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
} ProcArstPass;
diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc
index 519d35cd6..59cc5bd65 100644
--- a/passes/proc/proc_dff.cc
+++ b/passes/proc/proc_dff.cc
@@ -75,69 +75,69 @@ void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec
log_abort();
if (sync_low_signals.size() > 1) {
- RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or");
- cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size());
- cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
- cell->setPort("\\A", sync_low_signals);
- cell->setPort("\\Y", sync_low_signals = mod->addWire(NEW_ID));
+ RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($reduce_or));
+ cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_low_signals.size());
+ cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
+ cell->setPort(ID::A, sync_low_signals);
+ cell->setPort(ID::Y, sync_low_signals = mod->addWire(NEW_ID));
}
if (sync_low_signals.size() > 0) {
- RTLIL::Cell *cell = mod->addCell(NEW_ID, "$not");
- cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size());
- cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
- cell->setPort("\\A", sync_low_signals);
- cell->setPort("\\Y", mod->addWire(NEW_ID));
- sync_high_signals.append(cell->getPort("\\Y"));
+ RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($not));
+ cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_low_signals.size());
+ cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
+ cell->setPort(ID::A, sync_low_signals);
+ cell->setPort(ID::Y, mod->addWire(NEW_ID));
+ sync_high_signals.append(cell->getPort(ID::Y));
}
if (sync_high_signals.size() > 1) {
- RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or");
- cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size());
- cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
- cell->setPort("\\A", sync_high_signals);
- cell->setPort("\\Y", sync_high_signals = mod->addWire(NEW_ID));
+ RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($reduce_or));
+ cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_high_signals.size());
+ cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
+ cell->setPort(ID::A, sync_high_signals);
+ cell->setPort(ID::Y, sync_high_signals = mod->addWire(NEW_ID));
}
- RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, "$not");
- inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size());
- inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size());
- inv_cell->setPort("\\A", sync_value);
- inv_cell->setPort("\\Y", sync_value_inv = mod->addWire(NEW_ID, sig_d.size()));
-
- RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, "$mux");
- mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
- mux_set_cell->setPort("\\A", sig_sr_set);
- mux_set_cell->setPort("\\B", sync_value);
- mux_set_cell->setPort("\\S", sync_high_signals);
- mux_set_cell->setPort("\\Y", sig_sr_set = mod->addWire(NEW_ID, sig_d.size()));
-
- RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, "$mux");
- mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
- mux_clr_cell->setPort("\\A", sig_sr_clr);
- mux_clr_cell->setPort("\\B", sync_value_inv);
- mux_clr_cell->setPort("\\S", sync_high_signals);
- mux_clr_cell->setPort("\\Y", sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()));
+ RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, ID($not));
+ inv_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ inv_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig_d.size());
+ inv_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(sig_d.size());
+ inv_cell->setPort(ID::A, sync_value);
+ inv_cell->setPort(ID::Y, sync_value_inv = mod->addWire(NEW_ID, sig_d.size()));
+
+ RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, ID($mux));
+ mux_set_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
+ mux_set_cell->setPort(ID::A, sig_sr_set);
+ mux_set_cell->setPort(ID::B, sync_value);
+ mux_set_cell->setPort(ID::S, sync_high_signals);
+ mux_set_cell->setPort(ID::Y, sig_sr_set = mod->addWire(NEW_ID, sig_d.size()));
+
+ RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, ID($mux));
+ mux_clr_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
+ mux_clr_cell->setPort(ID::A, sig_sr_clr);
+ mux_clr_cell->setPort(ID::B, sync_value_inv);
+ mux_clr_cell->setPort(ID::S, sync_high_signals);
+ mux_clr_cell->setPort(ID::Y, sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()));
}
std::stringstream sstr;
sstr << "$procdff$" << (autoidx++);
- RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr");
+ RTLIL::Cell *cell = mod->addCell(sstr.str(), ID($dffsr));
cell->attributes = proc->attributes;
- cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
- cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1);
- cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
- cell->setPort("\\CLK", clk);
- cell->setPort("\\SET", sig_sr_set);
- cell->setPort("\\CLR", sig_sr_clr);
+ cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1);
+ cell->parameters[ID::SET_POLARITY] = RTLIL::Const(true, 1);
+ cell->parameters[ID::CLR_POLARITY] = RTLIL::Const(true, 1);
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, sig_q);
+ cell->setPort(ID::CLK, clk);
+ cell->setPort(ID::SET, sig_sr_set);
+ cell->setPort(ID::CLR, sig_sr_clr);
log(" created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n",
cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative");
@@ -153,38 +153,38 @@ void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec sig_set
RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size());
RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.size());
- RTLIL::Cell *inv_set = mod->addCell(NEW_ID, "$not");
- inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size());
- inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size());
- inv_set->setPort("\\A", sig_set);
- inv_set->setPort("\\Y", sig_set_inv);
-
- RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux");
- mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
- mux_sr_set->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size()));
- mux_sr_set->setPort(set_polarity ? "\\B" : "\\A", sig_set);
- mux_sr_set->setPort("\\Y", sig_sr_set);
- mux_sr_set->setPort("\\S", set);
-
- RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux");
- mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
- mux_sr_clr->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size()));
- mux_sr_clr->setPort(set_polarity ? "\\B" : "\\A", sig_set_inv);
- mux_sr_clr->setPort("\\Y", sig_sr_clr);
- mux_sr_clr->setPort("\\S", set);
-
- RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr");
+ RTLIL::Cell *inv_set = mod->addCell(NEW_ID, ID($not));
+ inv_set->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ inv_set->parameters[ID::A_WIDTH] = RTLIL::Const(sig_in.size());
+ inv_set->parameters[ID::Y_WIDTH] = RTLIL::Const(sig_in.size());
+ inv_set->setPort(ID::A, sig_set);
+ inv_set->setPort(ID::Y, sig_set_inv);
+
+ RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, ID($mux));
+ mux_sr_set->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
+ mux_sr_set->setPort(set_polarity ? ID::A : ID::B, RTLIL::Const(0, sig_in.size()));
+ mux_sr_set->setPort(set_polarity ? ID::B : ID::A, sig_set);
+ mux_sr_set->setPort(ID::Y, sig_sr_set);
+ mux_sr_set->setPort(ID::S, set);
+
+ RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, ID($mux));
+ mux_sr_clr->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
+ mux_sr_clr->setPort(set_polarity ? ID::A : ID::B, RTLIL::Const(0, sig_in.size()));
+ mux_sr_clr->setPort(set_polarity ? ID::B : ID::A, sig_set_inv);
+ mux_sr_clr->setPort(ID::Y, sig_sr_clr);
+ mux_sr_clr->setPort(ID::S, set);
+
+ RTLIL::Cell *cell = mod->addCell(sstr.str(), ID($dffsr));
cell->attributes = proc->attributes;
- cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
- cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1);
- cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1);
- cell->setPort("\\D", sig_in);
- cell->setPort("\\Q", sig_out);
- cell->setPort("\\CLK", clk);
- cell->setPort("\\SET", sig_sr_set);
- cell->setPort("\\CLR", sig_sr_clr);
+ cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1);
+ cell->parameters[ID::SET_POLARITY] = RTLIL::Const(true, 1);
+ cell->parameters[ID::CLR_POLARITY] = RTLIL::Const(true, 1);
+ cell->setPort(ID::D, sig_in);
+ cell->setPort(ID::Q, sig_out);
+ cell->setPort(ID::CLK, clk);
+ cell->setPort(ID::SET, sig_sr_set);
+ cell->setPort(ID::CLR, sig_sr_clr);
log(" created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->type.c_str(), cell->name.c_str(),
clk_polarity ? "positive" : "negative", set_polarity ? "positive" : "negative");
@@ -196,24 +196,24 @@ void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_rst, RT
std::stringstream sstr;
sstr << "$procdff$" << (autoidx++);
- RTLIL::Cell *cell = mod->addCell(sstr.str(), clk.empty() ? "$ff" : arst ? "$adff" : "$dff");
+ RTLIL::Cell *cell = mod->addCell(sstr.str(), clk.empty() ? ID($ff) : arst ? ID($adff) : ID($dff));
cell->attributes = proc->attributes;
- cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
+ cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
if (arst) {
- cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity, 1);
- cell->parameters["\\ARST_VALUE"] = val_rst;
+ cell->parameters[ID::ARST_POLARITY] = RTLIL::Const(arst_polarity, 1);
+ cell->parameters[ID::ARST_VALUE] = val_rst;
}
if (!clk.empty()) {
- cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
+ cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1);
}
- cell->setPort("\\D", sig_in);
- cell->setPort("\\Q", sig_out);
+ cell->setPort(ID::D, sig_in);
+ cell->setPort(ID::Q, sig_out);
if (arst)
- cell->setPort("\\ARST", *arst);
+ cell->setPort(ID::ARST, *arst);
if (!clk.empty())
- cell->setPort("\\CLK", clk);
+ cell->setPort(ID::CLK, clk);
if (!clk.empty())
log(" created %s cell `%s' with %s edge clock", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative");
@@ -303,15 +303,15 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
}
log_assert(inputs.size() == compare.size());
- RTLIL::Cell *cell = mod->addCell(NEW_ID, "$ne");
- cell->parameters["\\A_SIGNED"] = RTLIL::Const(false, 1);
- cell->parameters["\\B_SIGNED"] = RTLIL::Const(false, 1);
- cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size());
- cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.size());
- cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
- cell->setPort("\\A", inputs);
- cell->setPort("\\B", compare);
- cell->setPort("\\Y", sync_level->signal);
+ RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($ne));
+ cell->parameters[ID::A_SIGNED] = RTLIL::Const(false, 1);
+ cell->parameters[ID::B_SIGNED] = RTLIL::Const(false, 1);
+ cell->parameters[ID::A_WIDTH] = RTLIL::Const(inputs.size());
+ cell->parameters[ID::B_WIDTH] = RTLIL::Const(inputs.size());
+ cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
+ cell->setPort(ID::A, inputs);
+ cell->setPort(ID::B, compare);
+ cell->setPort(ID::Y, sync_level->signal);
many_async_rules.clear();
}
diff --git a/passes/proc/proc_dlatch.cc b/passes/proc/proc_dlatch.cc
index a0c8351b6..c9da1d1e3 100644
--- a/passes/proc/proc_dlatch.cc
+++ b/passes/proc/proc_dlatch.cc
@@ -42,16 +42,16 @@ struct proc_dlatch_db_t
{
for (auto cell : module->cells())
{
- if (cell->type.in("$mux", "$pmux"))
+ if (cell->type.in(ID($mux), ID($pmux)))
{
- auto sig_y = sigmap(cell->getPort("\\Y"));
+ auto sig_y = sigmap(cell->getPort(ID::Y));
for (int i = 0; i < GetSize(sig_y); i++)
mux_drivers[sig_y[i]] = pair<Cell*, int>(cell, i);
pool<SigBit> mux_srcbits_pool;
- for (auto bit : sigmap(cell->getPort("\\A")))
+ for (auto bit : sigmap(cell->getPort(ID::A)))
mux_srcbits_pool.insert(bit);
- for (auto bit : sigmap(cell->getPort("\\B")))
+ for (auto bit : sigmap(cell->getPort(ID::B)))
mux_srcbits_pool.insert(bit);
vector<SigBit> mux_srcbits_vec;
@@ -180,9 +180,9 @@ struct proc_dlatch_db_t
Cell *cell = it->second.first;
int index = it->second.second;
- SigSpec sig_a = sigmap(cell->getPort("\\A"));
- SigSpec sig_b = sigmap(cell->getPort("\\B"));
- SigSpec sig_s = sigmap(cell->getPort("\\S"));
+ SigSpec sig_a = sigmap(cell->getPort(ID::A));
+ SigSpec sig_b = sigmap(cell->getPort(ID::B));
+ SigSpec sig_s = sigmap(cell->getPort(ID::S));
int width = GetSize(sig_a);
pool<int> children;
@@ -190,9 +190,9 @@ struct proc_dlatch_db_t
int n = find_mux_feedback(sig_a[index], needle, set_undef);
if (n != false_node) {
if (set_undef && sig_a[index] == needle) {
- SigSpec sig = cell->getPort("\\A");
+ SigSpec sig = cell->getPort(ID::A);
sig[index] = State::Sx;
- cell->setPort("\\A", sig);
+ cell->setPort(ID::A, sig);
}
for (int i = 0; i < GetSize(sig_s); i++)
n = make_inner(sig_s[i], State::S0, n);
@@ -203,9 +203,9 @@ struct proc_dlatch_db_t
n = find_mux_feedback(sig_b[i*width + index], needle, set_undef);
if (n != false_node) {
if (set_undef && sig_b[i*width + index] == needle) {
- SigSpec sig = cell->getPort("\\B");
+ SigSpec sig = cell->getPort(ID::B);
sig[i*width + index] = State::Sx;
- cell->setPort("\\B", sig);
+ cell->setPort(ID::B, sig);
}
children.insert(make_inner(sig_s[i], State::S1, n));
}
@@ -257,9 +257,9 @@ struct proc_dlatch_db_t
void fixup_mux(Cell *cell)
{
- SigSpec sig_a = cell->getPort("\\A");
- SigSpec sig_b = cell->getPort("\\B");
- SigSpec sig_s = cell->getPort("\\S");
+ SigSpec sig_a = cell->getPort(ID::A);
+ SigSpec sig_b = cell->getPort(ID::B);
+ SigSpec sig_s = cell->getPort(ID::S);
SigSpec sig_any_valid_b;
SigSpec sig_new_b, sig_new_s;
@@ -278,18 +278,18 @@ struct proc_dlatch_db_t
}
if (sig_a.is_fully_undef() && !sig_any_valid_b.empty())
- cell->setPort("\\A", sig_any_valid_b);
+ cell->setPort(ID::A, sig_any_valid_b);
if (GetSize(sig_new_s) == 1) {
- cell->type = "$mux";
- cell->unsetParam("\\S_WIDTH");
+ cell->type = ID($mux);
+ cell->unsetParam(ID::S_WIDTH);
} else {
- cell->type = "$pmux";
- cell->setParam("\\S_WIDTH", GetSize(sig_new_s));
+ cell->type = ID($pmux);
+ cell->setParam(ID::S_WIDTH, GetSize(sig_new_s));
}
- cell->setPort("\\B", sig_new_b);
- cell->setPort("\\S", sig_new_s);
+ cell->setPort(ID::B, sig_new_b);
+ cell->setPort(ID::S, sig_new_s);
}
void fixup_muxes()
@@ -317,7 +317,7 @@ struct proc_dlatch_db_t
pool<Cell*> next_queue;
for (auto cell : queue) {
- if (cell->type.in("$mux", "$pmux"))
+ if (cell->type.in(ID($mux), ID($pmux)))
fixup_mux(cell);
for (auto bit : upstream_cell2net[cell])
for (auto cell : upstream_net2cell[bit])
@@ -349,7 +349,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
continue;
}
- if (proc->get_bool_attribute(ID(always_ff)))
+ if (proc->get_bool_attribute(ID::always_ff))
log_error("Found non edge/level sensitive event in always_ff process `%s.%s'.\n",
db.module->name.c_str(), proc->name.c_str());
@@ -387,7 +387,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
int offset = 0;
for (auto chunk : nolatches_bits.first.chunks()) {
SigSpec lhs = chunk, rhs = nolatches_bits.second.extract(offset, chunk.width);
- if (proc->get_bool_attribute(ID(always_latch)))
+ if (proc->get_bool_attribute(ID::always_latch))
log_error("No latch inferred for signal `%s.%s' from always_latch process `%s.%s'.\n",
db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str());
else
@@ -418,7 +418,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
cell->set_src_attribute(src);
db.generated_dlatches.insert(cell);
- if (proc->get_bool_attribute(ID(always_comb)))
+ if (proc->get_bool_attribute(ID::always_comb))
log_error("Latch inferred for signal `%s.%s' from always_comb process `%s.%s'.\n",
db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str());
else
diff --git a/passes/proc/proc_init.cc b/passes/proc/proc_init.cc
index 462a384b7..dc00019aa 100644
--- a/passes/proc/proc_init.cc
+++ b/passes/proc/proc_init.cc
@@ -54,7 +54,7 @@ void proc_init(RTLIL::Module *mod, SigMap &sigmap, RTLIL::Process *proc)
log_cmd_error("Non-const initialization value: %s = %s\n", log_signal(lhs_c), log_signal(valuesig));
Const value = valuesig.as_const();
- Const &wireinit = lhs_c.wire->attributes["\\init"];
+ Const &wireinit = lhs_c.wire->attributes[ID::init];
while (GetSize(wireinit.bits) < lhs_c.wire->width)
wireinit.bits.push_back(State::Sx);
diff --git a/passes/proc/proc_mux.cc b/passes/proc/proc_mux.cc
index d029282fd..867ba1698 100644
--- a/passes/proc/proc_mux.cc
+++ b/passes/proc/proc_mux.cc
@@ -147,7 +147,7 @@ struct SnippetSwCache
void apply_attrs(RTLIL::Cell *cell, const RTLIL::SwitchRule *sw, const RTLIL::CaseRule *cs)
{
cell->attributes = sw->attributes;
- cell->add_strpool_attribute("\\src", cs->get_strpool_attribute("\\src"));
+ cell->add_strpool_attribute(ID::src, cs->get_strpool_attribute(ID::src));
}
RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
@@ -178,19 +178,19 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
else
{
// create compare cell
- RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), ifxmode ? "$eqx" : "$eq");
+ RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), ifxmode ? ID($eqx) : ID($eq));
apply_attrs(eq_cell, sw, cs);
- eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0);
+ eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(0);
- eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size());
- eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.size());
- eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+ eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig.size());
+ eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(comp.size());
+ eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
- eq_cell->setPort("\\A", sig);
- eq_cell->setPort("\\B", comp);
- eq_cell->setPort("\\Y", RTLIL::SigSpec(cmp_wire, cmp_wire->width++));
+ eq_cell->setPort(ID::A, sig);
+ eq_cell->setPort(ID::B, comp);
+ eq_cell->setPort(ID::Y, RTLIL::SigSpec(cmp_wire, cmp_wire->width++));
}
}
@@ -204,15 +204,15 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
ctrl_wire = mod->addWire(sstr.str() + "_CTRL");
// reduce cmp vector to one logic signal
- RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", "$reduce_or");
+ RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", ID($reduce_or));
apply_attrs(any_cell, sw, cs);
- any_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
- any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width);
- any_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
+ any_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
+ any_cell->parameters[ID::A_WIDTH] = RTLIL::Const(cmp_wire->width);
+ any_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
- any_cell->setPort("\\A", cmp_wire);
- any_cell->setPort("\\Y", RTLIL::SigSpec(ctrl_wire));
+ any_cell->setPort(ID::A, cmp_wire);
+ any_cell->setPort(ID::Y, RTLIL::SigSpec(ctrl_wire));
}
return RTLIL::SigSpec(ctrl_wire);
@@ -239,14 +239,14 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
RTLIL::Wire *result_wire = mod->addWire(sstr.str() + "_Y", when_signal.size());
// create the multiplexer itself
- RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), "$mux");
+ RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), ID($mux));
apply_attrs(mux_cell, sw, cs);
- mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size());
- mux_cell->setPort("\\A", else_signal);
- mux_cell->setPort("\\B", when_signal);
- mux_cell->setPort("\\S", ctrl_sig);
- mux_cell->setPort("\\Y", RTLIL::SigSpec(result_wire));
+ mux_cell->parameters[ID::WIDTH] = RTLIL::Const(when_signal.size());
+ mux_cell->setPort(ID::A, else_signal);
+ mux_cell->setPort(ID::B, when_signal);
+ mux_cell->setPort(ID::S, ctrl_sig);
+ mux_cell->setPort(ID::Y, RTLIL::SigSpec(result_wire));
last_mux_cell = mux_cell;
return RTLIL::SigSpec(result_wire);
@@ -255,24 +255,24 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
{
log_assert(last_mux_cell != NULL);
- log_assert(when_signal.size() == last_mux_cell->getPort("\\A").size());
+ log_assert(when_signal.size() == last_mux_cell->getPort(ID::A).size());
- if (when_signal == last_mux_cell->getPort("\\A"))
+ if (when_signal == last_mux_cell->getPort(ID::A))
return;
RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
log_assert(ctrl_sig.size() == 1);
- last_mux_cell->type = "$pmux";
+ last_mux_cell->type = ID($pmux);
- RTLIL::SigSpec new_s = last_mux_cell->getPort("\\S");
+ RTLIL::SigSpec new_s = last_mux_cell->getPort(ID::S);
new_s.append(ctrl_sig);
- last_mux_cell->setPort("\\S", new_s);
+ last_mux_cell->setPort(ID::S, new_s);
- RTLIL::SigSpec new_b = last_mux_cell->getPort("\\B");
+ RTLIL::SigSpec new_b = last_mux_cell->getPort(ID::B);
new_b.append(when_signal);
- last_mux_cell->setPort("\\B", new_b);
+ last_mux_cell->setPort(ID::B, new_b);
- last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->getPort("\\S").size();
+ last_mux_cell->parameters[ID::S_WIDTH] = last_mux_cell->getPort(ID::S).size();
}
const pool<SigBit> &get_full_case_bits(SnippetSwCache &swcache, RTLIL::SwitchRule *sw)
@@ -281,7 +281,7 @@ const pool<SigBit> &get_full_case_bits(SnippetSwCache &swcache, RTLIL::SwitchRul
{
pool<SigBit> bits;
- if (sw->get_bool_attribute("\\full_case"))
+ if (sw->get_bool_attribute(ID::full_case))
{
bool first_case = true;
@@ -337,7 +337,7 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
std::vector<int> pgroups(sw->cases.size());
bool is_simple_parallel_case = true;
- if (!sw->get_bool_attribute("\\parallel_case")) {
+ if (!sw->get_bool_attribute(ID::parallel_case)) {
if (!swpara.count(sw)) {
pool<Const> case_values;
for (size_t i = 0; i < sw->cases.size(); i++) {
diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc
index d4aee9df0..8d11447f6 100644
--- a/passes/proc/proc_prune.cc
+++ b/passes/proc/proc_prune.cc
@@ -38,7 +38,7 @@ struct PruneWorker
pool<RTLIL::SigBit> do_switch(RTLIL::SwitchRule *sw, pool<RTLIL::SigBit> assigned, pool<RTLIL::SigBit> &affected)
{
pool<RTLIL::SigBit> all_assigned;
- bool full_case = sw->get_bool_attribute("\\full_case");
+ bool full_case = sw->get_bool_attribute(ID::full_case);
bool first = true;
for (auto it : sw->cases) {
if (it->compare.empty())
@@ -93,7 +93,7 @@ struct PruneWorker
for (int i = 0; i < GetSize(lhs); i++) {
RTLIL::SigBit lhs_bit = lhs[i];
if (lhs_bit.wire && !assigned[lhs_bit]) {
- conn.first.append_bit(lhs_bit);
+ conn.first.append(lhs_bit);
conn.second.append(rhs.extract(i));
}
}
diff --git a/passes/proc/proc_rmdead.cc b/passes/proc/proc_rmdead.cc
index 4f40be446..6afaf25d1 100644
--- a/passes/proc/proc_rmdead.cc
+++ b/passes/proc/proc_rmdead.cc
@@ -62,8 +62,8 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter)
pool.take_all();
}
- if (pool.empty() && !sw->get_bool_attribute("\\full_case")) {
- sw->set_bool_attribute("\\full_case");
+ if (pool.empty() && !sw->get_bool_attribute(ID::full_case)) {
+ sw->set_bool_attribute(ID::full_case);
full_case_counter++;
}
}
diff --git a/passes/sat/assertpmux.cc b/passes/sat/assertpmux.cc
index 3b432c461..5bf2296ab 100644
--- a/passes/sat/assertpmux.cc
+++ b/passes/sat/assertpmux.cc
@@ -52,14 +52,14 @@ struct AssertpmuxWorker
for (auto cell : module->cells())
{
- if (cell->type.in("$mux", "$pmux"))
+ if (cell->type.in(ID($mux), ID($pmux)))
{
- int width = cell->getParam("\\WIDTH").as_int();
- int numports = cell->type == "$mux" ? 2 : cell->getParam("\\S_WIDTH").as_int() + 1;
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int numports = cell->type == ID($mux) ? 2 : cell->getParam(ID::S_WIDTH).as_int() + 1;
- SigSpec sig_a = sigmap(cell->getPort("\\A"));
- SigSpec sig_b = sigmap(cell->getPort("\\B"));
- SigSpec sig_s = sigmap(cell->getPort("\\S"));
+ SigSpec sig_a = sigmap(cell->getPort(ID::A));
+ SigSpec sig_b = sigmap(cell->getPort(ID::B));
+ SigSpec sig_s = sigmap(cell->getPort(ID::S));
for (int i = 0; i < numports; i++) {
SigSpec bits = i == 0 ? sig_a : sig_b.extract(width*(i-1), width);
@@ -98,12 +98,12 @@ struct AssertpmuxWorker
if (muxport_actsignal.count(muxport) == 0) {
if (portidx == 0)
- muxport_actsignal[muxport] = module->LogicNot(NEW_ID, cell->getPort("\\S"));
+ muxport_actsignal[muxport] = module->LogicNot(NEW_ID, cell->getPort(ID::S));
else
- muxport_actsignal[muxport] = cell->getPort("\\S")[portidx-1];
+ muxport_actsignal[muxport] = cell->getPort(ID::S)[portidx-1];
}
- output.append(module->LogicAnd(NEW_ID, muxport_actsignal.at(muxport), get_bit_activation(cell->getPort("\\Y")[bitidx])));
+ output.append(module->LogicAnd(NEW_ID, muxport_actsignal.at(muxport), get_bit_activation(cell->getPort(ID::Y)[bitidx])));
}
output.sort_and_unify();
@@ -148,10 +148,10 @@ struct AssertpmuxWorker
{
log("Adding assert for $pmux cell %s.%s.\n", log_id(module), log_id(pmux));
- int swidth = pmux->getParam("\\S_WIDTH").as_int();
+ int swidth = pmux->getParam(ID::S_WIDTH).as_int();
int cntbits = ceil_log2(swidth+1);
- SigSpec sel = pmux->getPort("\\S");
+ SigSpec sel = pmux->getPort(ID::S);
SigSpec cnt(State::S0, cntbits);
for (int i = 0; i < swidth; i++)
@@ -164,7 +164,7 @@ struct AssertpmuxWorker
assert_en.append(module->LogicNot(NEW_ID, module->Initstate(NEW_ID)));
if (!flag_always)
- assert_en.append(get_activation(pmux->getPort("\\Y")));
+ assert_en.append(get_activation(pmux->getPort(ID::Y)));
if (GetSize(assert_en) == 0)
assert_en = State::S1;
@@ -174,8 +174,8 @@ struct AssertpmuxWorker
Cell *assert_cell = module->addAssert(NEW_ID, assert_a, assert_en);
- if (pmux->attributes.count("\\src") != 0)
- assert_cell->attributes["\\src"] = pmux->attributes.at("\\src");
+ if (pmux->attributes.count(ID::src) != 0)
+ assert_cell->attributes[ID::src] = pmux->attributes.at(ID::src);
}
};
@@ -227,7 +227,7 @@ struct AssertpmuxPass : public Pass {
vector<Cell*> pmux_cells;
for (auto cell : module->selected_cells())
- if (cell->type == "$pmux")
+ if (cell->type == ID($pmux))
pmux_cells.push_back(cell);
for (auto cell : pmux_cells)
diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc
index 740248545..e344e2b5b 100644
--- a/passes/sat/async2sync.cc
+++ b/passes/sat/async2sync.cc
@@ -66,9 +66,9 @@ struct Async2syncPass : public Pass {
pool<SigBit> del_initbits;
for (auto wire : module->wires())
- if (wire->attributes.count("\\init") > 0)
+ if (wire->attributes.count(ID::init) > 0)
{
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
SigSpec initsig = sigmap(wire);
for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
@@ -78,16 +78,16 @@ struct Async2syncPass : public Pass {
for (auto cell : vector<Cell*>(module->selected_cells()))
{
- if (cell->type.in("$adff"))
+ if (cell->type.in(ID($adff)))
{
- // bool clk_pol = cell->parameters["\\CLK_POLARITY"].as_bool();
- bool arst_pol = cell->parameters["\\ARST_POLARITY"].as_bool();
- Const arst_val = cell->parameters["\\ARST_VALUE"];
+ // bool clk_pol = cell->parameters[ID::CLK_POLARITY].as_bool();
+ bool arst_pol = cell->parameters[ID::ARST_POLARITY].as_bool();
+ Const arst_val = cell->parameters[ID::ARST_VALUE];
- // SigSpec sig_clk = cell->getPort("\\CLK");
- SigSpec sig_arst = cell->getPort("\\ARST");
- SigSpec sig_d = cell->getPort("\\D");
- SigSpec sig_q = cell->getPort("\\Q");
+ // SigSpec sig_clk = cell->getPort(ID::CLK);
+ SigSpec sig_arst = cell->getPort(ID::ARST);
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n",
log_id(module), log_id(cell), log_id(cell->type),
@@ -102,7 +102,7 @@ struct Async2syncPass : public Pass {
Wire *new_d = module->addWire(NEW_ID, GetSize(sig_d));
Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q));
- new_q->attributes["\\init"] = init_val;
+ new_q->attributes[ID::init] = init_val;
if (arst_pol) {
module->addMux(NEW_ID, sig_d, arst_val, sig_arst, new_d);
@@ -112,26 +112,26 @@ struct Async2syncPass : public Pass {
module->addMux(NEW_ID, arst_val, new_q, sig_arst, sig_q);
}
- cell->setPort("\\D", new_d);
- cell->setPort("\\Q", new_q);
- cell->unsetPort("\\ARST");
- cell->unsetParam("\\ARST_POLARITY");
- cell->unsetParam("\\ARST_VALUE");
- cell->type = "$dff";
+ cell->setPort(ID::D, new_d);
+ cell->setPort(ID::Q, new_q);
+ cell->unsetPort(ID::ARST);
+ cell->unsetParam(ID::ARST_POLARITY);
+ cell->unsetParam(ID::ARST_VALUE);
+ cell->type = ID($dff);
continue;
}
- if (cell->type.in("$dffsr"))
+ if (cell->type.in(ID($dffsr)))
{
- // bool clk_pol = cell->parameters["\\CLK_POLARITY"].as_bool();
- bool set_pol = cell->parameters["\\SET_POLARITY"].as_bool();
- bool clr_pol = cell->parameters["\\CLR_POLARITY"].as_bool();
+ // bool clk_pol = cell->parameters[ID::CLK_POLARITY].as_bool();
+ bool set_pol = cell->parameters[ID::SET_POLARITY].as_bool();
+ bool clr_pol = cell->parameters[ID::CLR_POLARITY].as_bool();
- // SigSpec sig_clk = cell->getPort("\\CLK");
- SigSpec sig_set = cell->getPort("\\SET");
- SigSpec sig_clr = cell->getPort("\\CLR");
- SigSpec sig_d = cell->getPort("\\D");
- SigSpec sig_q = cell->getPort("\\Q");
+ // SigSpec sig_clk = cell->getPort(ID::CLK);
+ SigSpec sig_set = cell->getPort(ID::SET);
+ SigSpec sig_clr = cell->getPort(ID::CLR);
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n",
log_id(module), log_id(cell), log_id(cell->type),
@@ -146,7 +146,7 @@ struct Async2syncPass : public Pass {
Wire *new_d = module->addWire(NEW_ID, GetSize(sig_d));
Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q));
- new_q->attributes["\\init"] = init_val;
+ new_q->attributes[ID::init] = init_val;
if (!set_pol)
sig_set = module->Not(NEW_ID, sig_set);
@@ -160,23 +160,23 @@ struct Async2syncPass : public Pass {
tmp = module->Or(NEW_ID, new_q, sig_set);
module->addAnd(NEW_ID, tmp, sig_clr, sig_q);
- cell->setPort("\\D", new_d);
- cell->setPort("\\Q", new_q);
- cell->unsetPort("\\SET");
- cell->unsetPort("\\CLR");
- cell->unsetParam("\\SET_POLARITY");
- cell->unsetParam("\\CLR_POLARITY");
- cell->type = "$dff";
+ cell->setPort(ID::D, new_d);
+ cell->setPort(ID::Q, new_q);
+ cell->unsetPort(ID::SET);
+ cell->unsetPort(ID::CLR);
+ cell->unsetParam(ID::SET_POLARITY);
+ cell->unsetParam(ID::CLR_POLARITY);
+ cell->type = ID($dff);
continue;
}
- if (cell->type.in("$dlatch"))
+ if (cell->type.in(ID($dlatch)))
{
- bool en_pol = cell->parameters["\\EN_POLARITY"].as_bool();
+ bool en_pol = cell->parameters[ID::EN_POLARITY].as_bool();
- SigSpec sig_en = cell->getPort("\\EN");
- SigSpec sig_d = cell->getPort("\\D");
- SigSpec sig_q = cell->getPort("\\Q");
+ SigSpec sig_en = cell->getPort(ID::EN);
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n",
log_id(module), log_id(cell), log_id(cell->type),
@@ -190,7 +190,7 @@ struct Async2syncPass : public Pass {
}
Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q));
- new_q->attributes["\\init"] = init_val;
+ new_q->attributes[ID::init] = init_val;
if (en_pol) {
module->addMux(NEW_ID, new_q, sig_d, sig_en, sig_q);
@@ -198,20 +198,20 @@ struct Async2syncPass : public Pass {
module->addMux(NEW_ID, sig_d, new_q, sig_en, sig_q);
}
- cell->setPort("\\D", sig_q);
- cell->setPort("\\Q", new_q);
- cell->unsetPort("\\EN");
- cell->unsetParam("\\EN_POLARITY");
- cell->type = "$ff";
+ cell->setPort(ID::D, sig_q);
+ cell->setPort(ID::Q, new_q);
+ cell->unsetPort(ID::EN);
+ cell->unsetParam(ID::EN_POLARITY);
+ cell->type = ID($ff);
continue;
}
}
for (auto wire : module->wires())
- if (wire->attributes.count("\\init") > 0)
+ if (wire->attributes.count(ID::init) > 0)
{
bool delete_initattr = true;
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
SigSpec initsig = sigmap(wire);
for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
@@ -221,9 +221,9 @@ struct Async2syncPass : public Pass {
delete_initattr = false;
if (delete_initattr)
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
else
- wire->attributes.at("\\init") = initval;
+ wire->attributes.at(ID::init) = initval;
}
}
}
diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc
index f9e7783a9..1e155e52c 100644
--- a/passes/sat/clk2fflogic.cc
+++ b/passes/sat/clk2fflogic.cc
@@ -60,9 +60,9 @@ struct Clk2fflogicPass : public Pass {
pool<SigBit> del_initbits;
for (auto wire : module->wires())
- if (wire->attributes.count("\\init") > 0)
+ if (wire->attributes.count(ID::init) > 0)
{
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
SigSpec initsig = sigmap(wire);
for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
@@ -72,26 +72,26 @@ struct Clk2fflogicPass : public Pass {
for (auto cell : vector<Cell*>(module->selected_cells()))
{
- if (cell->type.in("$mem"))
+ if (cell->type.in(ID($mem)))
{
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
- int rd_ports = cell->getParam("\\RD_PORTS").as_int();
- int wr_ports = cell->getParam("\\WR_PORTS").as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
+ int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
for (int i = 0; i < rd_ports; i++) {
- if (cell->getParam("\\RD_CLK_ENABLE").extract(i).as_bool())
+ if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool())
log_error("Read port %d of memory %s.%s is clocked. This is not supported by \"clk2fflogic\"! "
"Call \"memory\" with -nordff to avoid this error.\n", i, log_id(cell), log_id(module));
}
- Const wr_clk_en_param = cell->getParam("\\WR_CLK_ENABLE");
- Const wr_clk_pol_param = cell->getParam("\\WR_CLK_POLARITY");
+ Const wr_clk_en_param = cell->getParam(ID::WR_CLK_ENABLE);
+ Const wr_clk_pol_param = cell->getParam(ID::WR_CLK_POLARITY);
- SigSpec wr_clk_port = cell->getPort("\\WR_CLK");
- SigSpec wr_en_port = cell->getPort("\\WR_EN");
- SigSpec wr_addr_port = cell->getPort("\\WR_ADDR");
- SigSpec wr_data_port = cell->getPort("\\WR_DATA");
+ SigSpec wr_clk_port = cell->getPort(ID::WR_CLK);
+ SigSpec wr_en_port = cell->getPort(ID::WR_EN);
+ SigSpec wr_addr_port = cell->getPort(ID::WR_ADDR);
+ SigSpec wr_data_port = cell->getPort(ID::WR_DATA);
for (int wport = 0; wport < wr_ports; wport++)
{
@@ -111,17 +111,17 @@ struct Clk2fflogicPass : public Pass {
log_signal(addr), log_signal(data));
Wire *past_clk = module->addWire(NEW_ID);
- past_clk->attributes["\\init"] = clkpol ? State::S1 : State::S0;
+ past_clk->attributes[ID::init] = clkpol ? State::S1 : State::S0;
module->addFf(NEW_ID, clk, past_clk);
SigSpec clock_edge_pattern;
if (clkpol) {
- clock_edge_pattern.append_bit(State::S0);
- clock_edge_pattern.append_bit(State::S1);
+ clock_edge_pattern.append(State::S0);
+ clock_edge_pattern.append(State::S1);
} else {
- clock_edge_pattern.append_bit(State::S1);
- clock_edge_pattern.append_bit(State::S0);
+ clock_edge_pattern.append(State::S1);
+ clock_edge_pattern.append(State::S0);
}
SigSpec clock_edge = module->Eqx(NEW_ID, {clk, SigSpec(past_clk)}, clock_edge_pattern);
@@ -144,22 +144,22 @@ struct Clk2fflogicPass : public Pass {
wr_clk_pol_param[wport] = State::S0;
}
- cell->setParam("\\WR_CLK_ENABLE", wr_clk_en_param);
- cell->setParam("\\WR_CLK_POLARITY", wr_clk_pol_param);
+ cell->setParam(ID::WR_CLK_ENABLE, wr_clk_en_param);
+ cell->setParam(ID::WR_CLK_POLARITY, wr_clk_pol_param);
- cell->setPort("\\WR_CLK", wr_clk_port);
- cell->setPort("\\WR_EN", wr_en_port);
- cell->setPort("\\WR_ADDR", wr_addr_port);
- cell->setPort("\\WR_DATA", wr_data_port);
+ cell->setPort(ID::WR_CLK, wr_clk_port);
+ cell->setPort(ID::WR_EN, wr_en_port);
+ cell->setPort(ID::WR_ADDR, wr_addr_port);
+ cell->setPort(ID::WR_DATA, wr_data_port);
}
- if (cell->type.in("$dlatch", "$dlatchsr"))
+ if (cell->type.in(ID($dlatch), ID($dlatchsr)))
{
- bool enpol = cell->parameters["\\EN_POLARITY"].as_bool();
+ bool enpol = cell->parameters[ID::EN_POLARITY].as_bool();
- SigSpec sig_en = cell->getPort("\\EN");
- SigSpec sig_d = cell->getPort("\\D");
- SigSpec sig_q = cell->getPort("\\Q");
+ SigSpec sig_en = cell->getPort(ID::EN);
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n",
log_id(module), log_id(cell), log_id(cell->type),
@@ -168,7 +168,7 @@ struct Clk2fflogicPass : public Pass {
Wire *past_q = module->addWire(NEW_ID, GetSize(sig_q));
module->addFf(NEW_ID, sig_q, past_q);
- if (cell->type == "$dlatch")
+ if (cell->type == ID($dlatch))
{
if (enpol)
module->addMux(NEW_ID, past_q, sig_d, sig_en, sig_q);
@@ -183,13 +183,13 @@ struct Clk2fflogicPass : public Pass {
else
t = module->Mux(NEW_ID, sig_d, past_q, sig_en);
- SigSpec s = cell->getPort("\\SET");
- if (!cell->parameters["\\SET_POLARITY"].as_bool())
+ SigSpec s = cell->getPort(ID::SET);
+ if (!cell->parameters[ID::SET_POLARITY].as_bool())
s = module->Not(NEW_ID, s);
t = module->Or(NEW_ID, t, s);
- SigSpec c = cell->getPort("\\CLR");
- if (cell->parameters["\\CLR_POLARITY"].as_bool())
+ SigSpec c = cell->getPort(ID::CLR);
+ if (cell->parameters[ID::CLR_POLARITY].as_bool())
c = module->Not(NEW_ID, c);
module->addAnd(NEW_ID, t, c, sig_q);
}
@@ -208,13 +208,13 @@ struct Clk2fflogicPass : public Pass {
}
if (assign_initval)
- past_q->attributes["\\init"] = initval;
+ past_q->attributes[ID::init] = initval;
module->remove(cell);
continue;
}
- bool word_dff = cell->type.in("$dff", "$adff", "$dffsr");
+ bool word_dff = cell->type.in(ID($dff), ID($adff), ID($dffsr));
if (word_dff || cell->type.in(ID($_DFF_N_), ID($_DFF_P_),
ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_),
@@ -224,8 +224,8 @@ struct Clk2fflogicPass : public Pass {
bool clkpol;
SigSpec clk;
if (word_dff) {
- clkpol = cell->parameters["\\CLK_POLARITY"].as_bool();
- clk = cell->getPort("\\CLK");
+ clkpol = cell->parameters[ID::CLK_POLARITY].as_bool();
+ clk = cell->getPort(ID::CLK);
}
else {
if (cell->type.in(ID($_DFF_P_), ID($_DFF_N_),
@@ -236,19 +236,19 @@ struct Clk2fflogicPass : public Pass {
ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
clkpol = cell->type[8] == 'P';
else log_abort();
- clk = cell->getPort("\\C");
+ clk = cell->getPort(ID::C);
}
Wire *past_clk = module->addWire(NEW_ID);
- past_clk->attributes["\\init"] = clkpol ? State::S1 : State::S0;
+ past_clk->attributes[ID::init] = clkpol ? State::S1 : State::S0;
if (word_dff)
module->addFf(NEW_ID, clk, past_clk);
else
module->addFfGate(NEW_ID, clk, past_clk);
- SigSpec sig_d = cell->getPort("\\D");
- SigSpec sig_q = cell->getPort("\\Q");
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n",
log_id(module), log_id(cell), log_id(cell->type),
@@ -257,11 +257,11 @@ struct Clk2fflogicPass : public Pass {
SigSpec clock_edge_pattern;
if (clkpol) {
- clock_edge_pattern.append_bit(State::S0);
- clock_edge_pattern.append_bit(State::S1);
+ clock_edge_pattern.append(State::S0);
+ clock_edge_pattern.append(State::S1);
} else {
- clock_edge_pattern.append_bit(State::S1);
- clock_edge_pattern.append_bit(State::S0);
+ clock_edge_pattern.append(State::S1);
+ clock_edge_pattern.append(State::S0);
}
SigSpec clock_edge = module->Eqx(NEW_ID, {clk, SigSpec(past_clk)}, clock_edge_pattern);
@@ -277,20 +277,20 @@ struct Clk2fflogicPass : public Pass {
module->addFfGate(NEW_ID, sig_q, past_q);
}
- if (cell->type == "$adff")
+ if (cell->type == ID($adff))
{
- SigSpec arst = cell->getPort("\\ARST");
+ SigSpec arst = cell->getPort(ID::ARST);
SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
- Const rstval = cell->parameters["\\ARST_VALUE"];
+ Const rstval = cell->parameters[ID::ARST_VALUE];
Wire *past_arst = module->addWire(NEW_ID);
module->addFf(NEW_ID, arst, past_arst);
- if (cell->parameters["\\ARST_POLARITY"].as_bool())
+ if (cell->parameters[ID::ARST_POLARITY].as_bool())
arst = module->LogicOr(NEW_ID, arst, past_arst);
else
arst = module->LogicAnd(NEW_ID, arst, past_arst);
- if (cell->parameters["\\ARST_POLARITY"].as_bool())
+ if (cell->parameters[ID::ARST_POLARITY].as_bool())
module->addMux(NEW_ID, qval, rstval, arst, sig_q);
else
module->addMux(NEW_ID, rstval, qval, arst, sig_q);
@@ -299,7 +299,7 @@ struct Clk2fflogicPass : public Pass {
if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_)))
{
- SigSpec arst = cell->getPort("\\R");
+ SigSpec arst = cell->getPort(ID::R);
SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge);
SigBit rstval = (cell->type[8] == '1');
@@ -316,16 +316,16 @@ struct Clk2fflogicPass : public Pass {
module->addMuxGate(NEW_ID, rstval, qval, arst, sig_q);
}
else
- if (cell->type == "$dffsr")
+ if (cell->type == ID($dffsr))
{
SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
- SigSpec setval = cell->getPort("\\SET");
- SigSpec clrval = cell->getPort("\\CLR");
+ SigSpec setval = cell->getPort(ID::SET);
+ SigSpec clrval = cell->getPort(ID::CLR);
- if (!cell->parameters["\\SET_POLARITY"].as_bool())
+ if (!cell->parameters[ID::SET_POLARITY].as_bool())
setval = module->Not(NEW_ID, setval);
- if (cell->parameters["\\CLR_POLARITY"].as_bool())
+ if (cell->parameters[ID::CLR_POLARITY].as_bool())
clrval = module->Not(NEW_ID, clrval);
qval = module->Or(NEW_ID, qval, setval);
@@ -336,8 +336,8 @@ struct Clk2fflogicPass : public Pass {
ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
{
SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge);
- SigSpec setval = cell->getPort("\\S");
- SigSpec clrval = cell->getPort("\\R");
+ SigSpec setval = cell->getPort(ID::S);
+ SigSpec clrval = cell->getPort(ID::R);
if (cell->type[9] != 'P')
setval = module->Not(NEW_ID, setval);
@@ -348,7 +348,7 @@ struct Clk2fflogicPass : public Pass {
qval = module->OrGate(NEW_ID, qval, setval);
module->addAndGate(NEW_ID, qval, clrval, sig_q);
}
- else if (cell->type == "$dff")
+ else if (cell->type == ID($dff))
{
module->addMux(NEW_ID, past_q, past_d, clock_edge, sig_q);
}
@@ -371,8 +371,8 @@ struct Clk2fflogicPass : public Pass {
}
if (assign_initval) {
- past_d->attributes["\\init"] = initval;
- past_q->attributes["\\init"] = initval;
+ past_d->attributes[ID::init] = initval;
+ past_q->attributes[ID::init] = initval;
}
module->remove(cell);
@@ -381,10 +381,10 @@ struct Clk2fflogicPass : public Pass {
}
for (auto wire : module->wires())
- if (wire->attributes.count("\\init") > 0)
+ if (wire->attributes.count(ID::init) > 0)
{
bool delete_initattr = true;
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
SigSpec initsig = sigmap(wire);
for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
@@ -394,9 +394,9 @@ struct Clk2fflogicPass : public Pass {
delete_initattr = false;
if (delete_initattr)
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
else
- wire->attributes.at("\\init") = initval;
+ wire->attributes.at(ID::init) = initval;
}
}
diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc
index b4549bc39..26cc69211 100644
--- a/passes/sat/cutpoint.cc
+++ b/passes/sat/cutpoint.cc
@@ -75,7 +75,7 @@ struct CutpointPass : public Pass {
pool<SigBit> cutpoint_bits;
for (auto cell : module->selected_cells()) {
- if (cell->type == "$anyseq")
+ if (cell->type == ID($anyseq))
continue;
log("Removing cell %s.%s, making all cell outputs cutpoints.\n", log_id(module), log_id(cell));
for (auto &conn : cell->connections()) {
diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc
index 148480d55..f910ea80d 100644
--- a/passes/sat/eval.cc
+++ b/passes/sat/eval.cc
@@ -153,11 +153,11 @@ struct VlogHammerReporter
ez->assume(satgen.signals_eq(recorded_set_vars, recorded_set_vals));
- std::vector<int> y_vec = satgen.importDefSigSpec(module->wire("\\y"));
+ std::vector<int> y_vec = satgen.importDefSigSpec(module->wire(ID(y)));
std::vector<bool> y_values;
if (model_undef) {
- std::vector<int> y_undef_vec = satgen.importUndefSigSpec(module->wire("\\y"));
+ std::vector<int> y_undef_vec = satgen.importUndefSigSpec(module->wire(ID(y)));
y_vec.insert(y_vec.end(), y_undef_vec.begin(), y_undef_vec.end());
}
@@ -268,10 +268,10 @@ struct VlogHammerReporter
}
}
- if (module->wire("\\y") == nullptr)
+ if (module->wire(ID(y)) == nullptr)
log_error("No output wire (y) found in module %s!\n", log_id(module->name));
- RTLIL::SigSpec sig(module->wire("\\y"));
+ RTLIL::SigSpec sig(module->wire(ID(y)));
RTLIL::SigSpec undef;
while (!ce.eval(sig, undef)) {
diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc
index 8fb47f357..80ab82cd5 100644
--- a/passes/sat/expose.cc
+++ b/passes/sat/expose.cc
@@ -86,8 +86,8 @@ void find_dff_wires(std::set<RTLIL::IdString> &dff_wires, RTLIL::Module *module)
SigPool dffsignals;
for (auto cell : module->cells()) {
- if (ct.cell_known(cell->type) && cell->hasPort("\\Q"))
- dffsignals.add(sigmap(cell->getPort("\\Q")));
+ if (ct.cell_known(cell->type) && cell->hasPort(ID::Q))
+ dffsignals.add(sigmap(cell->getPort(ID::Q)));
}
for (auto w : module->wires()) {
@@ -112,11 +112,11 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Mo
info.arst_value = RTLIL::State::Sm;
info.cell = cell;
- if (info.cell->type == "$dff") {
- info.bit_clk = sigmap(info.cell->getPort("\\CLK")).as_bit();
- info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool();
- std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort("\\D")).to_sigbit_vector();
- std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort("\\Q")).to_sigbit_vector();
+ if (info.cell->type == ID($dff)) {
+ info.bit_clk = sigmap(info.cell->getPort(ID::CLK)).as_bit();
+ info.clk_polarity = info.cell->parameters.at(ID::CLK_POLARITY).as_bool();
+ std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort(ID::D)).to_sigbit_vector();
+ std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort(ID::Q)).to_sigbit_vector();
for (size_t i = 0; i < sig_d.size(); i++) {
info.bit_d = sig_d.at(i);
bit_info[sig_q.at(i)] = info;
@@ -124,14 +124,14 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Mo
continue;
}
- if (info.cell->type == "$adff") {
- info.bit_clk = sigmap(info.cell->getPort("\\CLK")).as_bit();
- info.bit_arst = sigmap(info.cell->getPort("\\ARST")).as_bit();
- info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool();
- info.arst_polarity = info.cell->parameters.at("\\ARST_POLARITY").as_bool();
- std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort("\\D")).to_sigbit_vector();
- std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort("\\Q")).to_sigbit_vector();
- std::vector<RTLIL::State> arst_value = info.cell->parameters.at("\\ARST_VALUE").bits;
+ if (info.cell->type == ID($adff)) {
+ info.bit_clk = sigmap(info.cell->getPort(ID::CLK)).as_bit();
+ info.bit_arst = sigmap(info.cell->getPort(ID::ARST)).as_bit();
+ info.clk_polarity = info.cell->parameters.at(ID::CLK_POLARITY).as_bool();
+ info.arst_polarity = info.cell->parameters.at(ID::ARST_POLARITY).as_bool();
+ std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort(ID::D)).to_sigbit_vector();
+ std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort(ID::Q)).to_sigbit_vector();
+ std::vector<RTLIL::State> arst_value = info.cell->parameters.at(ID::ARST_VALUE).bits;
for (size_t i = 0; i < sig_d.size(); i++) {
info.bit_d = sig_d.at(i);
info.arst_value = arst_value.at(i);
@@ -140,22 +140,22 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Mo
continue;
}
- if (info.cell->type.in("$_DFF_N_", "$_DFF_P_")) {
- info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit();
- info.clk_polarity = info.cell->type == "$_DFF_P_";
- info.bit_d = sigmap(info.cell->getPort("\\D")).as_bit();
- bit_info[sigmap(info.cell->getPort("\\Q")).as_bit()] = info;
+ if (info.cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) {
+ info.bit_clk = sigmap(info.cell->getPort(ID::C)).as_bit();
+ info.clk_polarity = info.cell->type == ID($_DFF_P_);
+ info.bit_d = sigmap(info.cell->getPort(ID::D)).as_bit();
+ bit_info[sigmap(info.cell->getPort(ID::Q)).as_bit()] = info;
continue;
}
if (info.cell->type.size() == 10 && info.cell->type.begins_with("$_DFF_")) {
- info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit();
- info.bit_arst = sigmap(info.cell->getPort("\\R")).as_bit();
+ info.bit_clk = sigmap(info.cell->getPort(ID::C)).as_bit();
+ info.bit_arst = sigmap(info.cell->getPort(ID::R)).as_bit();
info.clk_polarity = info.cell->type[6] == 'P';
info.arst_polarity = info.cell->type[7] == 'P';
info.arst_value = info.cell->type[0] == '1' ? RTLIL::State::S1 : RTLIL::State::S0;
- info.bit_d = sigmap(info.cell->getPort("\\D")).as_bit();
- bit_info[sigmap(info.cell->getPort("\\Q")).as_bit()] = info;
+ info.bit_d = sigmap(info.cell->getPort(ID::D)).as_bit();
+ bit_info[sigmap(info.cell->getPort(ID::Q)).as_bit()] = info;
continue;
}
}
@@ -526,11 +526,11 @@ struct ExposePass : public Pass {
for (auto &cell_name : info.cells) {
RTLIL::Cell *cell = module->cell(cell_name);
- std::vector<RTLIL::SigBit> cell_q_bits = sigmap(cell->getPort("\\Q")).to_sigbit_vector();
+ std::vector<RTLIL::SigBit> cell_q_bits = sigmap(cell->getPort(ID::Q)).to_sigbit_vector();
for (auto &bit : cell_q_bits)
if (wire_bits_set.count(bit))
bit = RTLIL::SigBit(wire_dummy_q, wire_dummy_q->width++);
- cell->setPort("\\Q", cell_q_bits);
+ cell->setPort(ID::Q, cell_q_bits);
}
RTLIL::Wire *wire_q = add_new_wire(module, wire->name.str() + sep + "q", wire->width);
@@ -558,12 +558,12 @@ struct ExposePass : public Pass {
if (info.clk_polarity) {
module->connect(RTLIL::SigSig(wire_c, info.sig_clk));
} else {
- RTLIL::Cell *c = module->addCell(NEW_ID, "$not");
- c->parameters["\\A_SIGNED"] = 0;
- c->parameters["\\A_WIDTH"] = 1;
- c->parameters["\\Y_WIDTH"] = 1;
- c->setPort("\\A", info.sig_clk);
- c->setPort("\\Y", wire_c);
+ RTLIL::Cell *c = module->addCell(NEW_ID, ID($not));
+ c->parameters[ID::A_SIGNED] = 0;
+ c->parameters[ID::A_WIDTH] = 1;
+ c->parameters[ID::Y_WIDTH] = 1;
+ c->setPort(ID::A, info.sig_clk);
+ c->setPort(ID::Y, wire_c);
}
if (info.sig_arst != RTLIL::State::Sm)
@@ -574,12 +574,12 @@ struct ExposePass : public Pass {
if (info.arst_polarity) {
module->connect(RTLIL::SigSig(wire_r, info.sig_arst));
} else {
- RTLIL::Cell *c = module->addCell(NEW_ID, "$not");
- c->parameters["\\A_SIGNED"] = 0;
- c->parameters["\\A_WIDTH"] = 1;
- c->parameters["\\Y_WIDTH"] = 1;
- c->setPort("\\A", info.sig_arst);
- c->setPort("\\Y", wire_r);
+ RTLIL::Cell *c = module->addCell(NEW_ID, ID($not));
+ c->parameters[ID::A_SIGNED] = 0;
+ c->parameters[ID::A_WIDTH] = 1;
+ c->parameters[ID::Y_WIDTH] = 1;
+ c->setPort(ID::A, info.sig_arst);
+ c->setPort(ID::Y, wire_r);
}
RTLIL::Wire *wire_v = add_new_wire(module, wire->name.str() + sep + "v", wire->width);
diff --git a/passes/sat/fmcombine.cc b/passes/sat/fmcombine.cc
index 00c098542..5066485aa 100644
--- a/passes/sat/fmcombine.cc
+++ b/passes/sat/fmcombine.cc
@@ -43,7 +43,7 @@ struct FmcombineWorker
FmcombineWorker(Design *design, IdString orig_type, const opts_t &opts) :
opts(opts), design(design), original(design->module(orig_type)),
- orig_type(orig_type), combined_type("$fmcombine" + orig_type.str())
+ orig_type(orig_type), combined_type(stringf("$fmcombine%s", orig_type.c_str()))
{
}
@@ -106,7 +106,7 @@ struct FmcombineWorker
for (auto cell : original->cells()) {
if (design->module(cell->type) == nullptr) {
- if (opts.anyeq && cell->type.in("$anyseq", "$anyconst")) {
+ if (opts.anyeq && cell->type.in(ID($anyseq), ID($anyconst))) {
Cell *gold = import_prim_cell(cell, "_gold");
for (auto &conn : cell->connections())
module->connect(import_sig(conn.second, "_gate"), gold->getPort(conn.first));
@@ -114,10 +114,10 @@ struct FmcombineWorker
Cell *gold = import_prim_cell(cell, "_gold");
Cell *gate = import_prim_cell(cell, "_gate");
if (opts.initeq) {
- if (cell->type.in("$ff", "$dff", "$dffe",
- "$dffsr", "$adff", "$dlatch", "$dlatchsr")) {
- SigSpec gold_q = gold->getPort("\\Q");
- SigSpec gate_q = gate->getPort("\\Q");
+ if (cell->type.in(ID($ff), ID($dff), ID($dffe),
+ ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr))) {
+ SigSpec gold_q = gold->getPort(ID::Q);
+ SigSpec gate_q = gate->getPort(ID::Q);
SigSpec en = module->Initstate(NEW_ID);
SigSpec eq = module->Eq(NEW_ID, gold_q, gate_q);
module->addAssume(NEW_ID, eq, en);
@@ -359,7 +359,7 @@ struct FmcombinePass : public Pass {
Cell *cell = module->addCell(combined_cell_name, worker.combined_type);
cell->attributes = gold_cell->attributes;
- cell->add_strpool_attribute("\\src", gate_cell->get_strpool_attribute("\\src"));
+ cell->add_strpool_attribute(ID::src, gate_cell->get_strpool_attribute(ID::src));
log("Combining cells %s and %s in module %s into new cell %s.\n", log_id(gold_cell), log_id(gate_cell), log_id(module), log_id(cell));
diff --git a/passes/sat/fminit.cc b/passes/sat/fminit.cc
index f3f00b382..555a28dc6 100644
--- a/passes/sat/fminit.cc
+++ b/passes/sat/fminit.cc
@@ -147,7 +147,7 @@ struct FminitPass : public Pass {
SigSpec insig = i > 0 ? ctrlsig.at(i-1) : State::S0;
Wire *outwire = module->addWire(NEW_ID);
- outwire->attributes[ID(init)] = i > 0 ? State::S0 : State::S1;
+ outwire->attributes[ID::init] = i > 0 ? State::S0 : State::S1;
if (clksig.empty())
module->addFf(NEW_ID, insig, outwire);
@@ -161,7 +161,7 @@ struct FminitPass : public Pass {
if (i+1 == GetSize(it.second) && ctrlsig_latched[i].empty())
{
Wire *ffwire = module->addWire(NEW_ID);
- ffwire->attributes[ID(init)] = State::S0;
+ ffwire->attributes[ID::init] = State::S0;
SigSpec outsig = module->Or(NEW_ID, ffwire, ctrlsig[i]);
if (clksig.empty())
diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc
index 54016e528..5dfd7bd3f 100644
--- a/passes/sat/freduce.cc
+++ b/passes/sat/freduce.cc
@@ -635,8 +635,8 @@ struct FreduceWorker
batches.push_back(outputs);
bits_full_total += outputs.size();
}
- if (inv_mode && cell->type == "$_NOT_")
- inv_pairs.insert(std::pair<RTLIL::SigBit, RTLIL::SigBit>(sigmap(cell->getPort("\\A")), sigmap(cell->getPort("\\Y"))));
+ if (inv_mode && cell->type == ID($_NOT_))
+ inv_pairs.insert(std::pair<RTLIL::SigBit, RTLIL::SigBit>(sigmap(cell->getPort(ID::A)), sigmap(cell->getPort(ID::Y))));
}
int bits_count = 0;
@@ -731,9 +731,9 @@ struct FreduceWorker
{
inv_sig = module->addWire(NEW_ID);
- RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_NOT_");
- inv_cell->setPort("\\A", grp[0].bit);
- inv_cell->setPort("\\Y", inv_sig);
+ RTLIL::Cell *inv_cell = module->addCell(NEW_ID, ID($_NOT_));
+ inv_cell->setPort(ID::A, grp[0].bit);
+ inv_cell->setPort(ID::Y, inv_sig);
}
module->connect(RTLIL::SigSig(grp[i].bit, inv_sig));
diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc
index 742433935..aeece9b94 100644
--- a/passes/sat/miter.cc
+++ b/passes/sat/miter.cc
@@ -116,8 +116,8 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
miter_module->name = miter_name;
design->add(miter_module);
- RTLIL::Cell *gold_cell = miter_module->addCell("\\gold", gold_name);
- RTLIL::Cell *gate_cell = miter_module->addCell("\\gate", gate_name);
+ RTLIL::Cell *gold_cell = miter_module->addCell(ID(gold), gold_name);
+ RTLIL::Cell *gate_cell = miter_module->addCell(ID(gate), gate_name);
RTLIL::SigSpec all_conditions;
@@ -149,63 +149,63 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
{
RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w_gold->width);
for (int i = 0; i < w_gold->width; i++) {
- RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx");
- eqx_cell->parameters["\\A_WIDTH"] = 1;
- eqx_cell->parameters["\\B_WIDTH"] = 1;
- eqx_cell->parameters["\\Y_WIDTH"] = 1;
- eqx_cell->parameters["\\A_SIGNED"] = 0;
- eqx_cell->parameters["\\B_SIGNED"] = 0;
- eqx_cell->setPort("\\A", RTLIL::SigSpec(w_gold, i));
- eqx_cell->setPort("\\B", RTLIL::State::Sx);
- eqx_cell->setPort("\\Y", gold_x.extract(i, 1));
+ RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, ID($eqx));
+ eqx_cell->parameters[ID::A_WIDTH] = 1;
+ eqx_cell->parameters[ID::B_WIDTH] = 1;
+ eqx_cell->parameters[ID::Y_WIDTH] = 1;
+ eqx_cell->parameters[ID::A_SIGNED] = 0;
+ eqx_cell->parameters[ID::B_SIGNED] = 0;
+ eqx_cell->setPort(ID::A, RTLIL::SigSpec(w_gold, i));
+ eqx_cell->setPort(ID::B, RTLIL::State::Sx);
+ eqx_cell->setPort(ID::Y, gold_x.extract(i, 1));
}
RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w_gold->width);
RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w_gate->width);
- RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or");
- or_gold_cell->parameters["\\A_WIDTH"] = w_gold->width;
- or_gold_cell->parameters["\\B_WIDTH"] = w_gold->width;
- or_gold_cell->parameters["\\Y_WIDTH"] = w_gold->width;
- or_gold_cell->parameters["\\A_SIGNED"] = 0;
- or_gold_cell->parameters["\\B_SIGNED"] = 0;
- or_gold_cell->setPort("\\A", w_gold);
- or_gold_cell->setPort("\\B", gold_x);
- or_gold_cell->setPort("\\Y", gold_masked);
-
- RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or");
- or_gate_cell->parameters["\\A_WIDTH"] = w_gate->width;
- or_gate_cell->parameters["\\B_WIDTH"] = w_gate->width;
- or_gate_cell->parameters["\\Y_WIDTH"] = w_gate->width;
- or_gate_cell->parameters["\\A_SIGNED"] = 0;
- or_gate_cell->parameters["\\B_SIGNED"] = 0;
- or_gate_cell->setPort("\\A", w_gate);
- or_gate_cell->setPort("\\B", gold_x);
- or_gate_cell->setPort("\\Y", gate_masked);
-
- RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
- eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
- eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
- eq_cell->parameters["\\Y_WIDTH"] = 1;
- eq_cell->parameters["\\A_SIGNED"] = 0;
- eq_cell->parameters["\\B_SIGNED"] = 0;
- eq_cell->setPort("\\A", gold_masked);
- eq_cell->setPort("\\B", gate_masked);
- eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
- this_condition = eq_cell->getPort("\\Y");
+ RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, ID($or));
+ or_gold_cell->parameters[ID::A_WIDTH] = w_gold->width;
+ or_gold_cell->parameters[ID::B_WIDTH] = w_gold->width;
+ or_gold_cell->parameters[ID::Y_WIDTH] = w_gold->width;
+ or_gold_cell->parameters[ID::A_SIGNED] = 0;
+ or_gold_cell->parameters[ID::B_SIGNED] = 0;
+ or_gold_cell->setPort(ID::A, w_gold);
+ or_gold_cell->setPort(ID::B, gold_x);
+ or_gold_cell->setPort(ID::Y, gold_masked);
+
+ RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, ID($or));
+ or_gate_cell->parameters[ID::A_WIDTH] = w_gate->width;
+ or_gate_cell->parameters[ID::B_WIDTH] = w_gate->width;
+ or_gate_cell->parameters[ID::Y_WIDTH] = w_gate->width;
+ or_gate_cell->parameters[ID::A_SIGNED] = 0;
+ or_gate_cell->parameters[ID::B_SIGNED] = 0;
+ or_gate_cell->setPort(ID::A, w_gate);
+ or_gate_cell->setPort(ID::B, gold_x);
+ or_gate_cell->setPort(ID::Y, gate_masked);
+
+ RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, ID($eqx));
+ eq_cell->parameters[ID::A_WIDTH] = w_gold->width;
+ eq_cell->parameters[ID::B_WIDTH] = w_gate->width;
+ eq_cell->parameters[ID::Y_WIDTH] = 1;
+ eq_cell->parameters[ID::A_SIGNED] = 0;
+ eq_cell->parameters[ID::B_SIGNED] = 0;
+ eq_cell->setPort(ID::A, gold_masked);
+ eq_cell->setPort(ID::B, gate_masked);
+ eq_cell->setPort(ID::Y, miter_module->addWire(NEW_ID));
+ this_condition = eq_cell->getPort(ID::Y);
}
else
{
- RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
- eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
- eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
- eq_cell->parameters["\\Y_WIDTH"] = 1;
- eq_cell->parameters["\\A_SIGNED"] = 0;
- eq_cell->parameters["\\B_SIGNED"] = 0;
- eq_cell->setPort("\\A", w_gold);
- eq_cell->setPort("\\B", w_gate);
- eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
- this_condition = eq_cell->getPort("\\Y");
+ RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, ID($eqx));
+ eq_cell->parameters[ID::A_WIDTH] = w_gold->width;
+ eq_cell->parameters[ID::B_WIDTH] = w_gate->width;
+ eq_cell->parameters[ID::Y_WIDTH] = 1;
+ eq_cell->parameters[ID::A_SIGNED] = 0;
+ eq_cell->parameters[ID::B_SIGNED] = 0;
+ eq_cell->setPort(ID::A, w_gold);
+ eq_cell->setPort(ID::B, w_gate);
+ eq_cell->setPort(ID::Y, miter_module->addWire(NEW_ID));
+ this_condition = eq_cell->getPort(ID::Y);
}
if (flag_make_outcmp)
@@ -220,31 +220,31 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
}
if (all_conditions.size() != 1) {
- RTLIL::Cell *reduce_cell = miter_module->addCell(NEW_ID, "$reduce_and");
- reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size();
- reduce_cell->parameters["\\Y_WIDTH"] = 1;
- reduce_cell->parameters["\\A_SIGNED"] = 0;
- reduce_cell->setPort("\\A", all_conditions);
- reduce_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
- all_conditions = reduce_cell->getPort("\\Y");
+ RTLIL::Cell *reduce_cell = miter_module->addCell(NEW_ID, ID($reduce_and));
+ reduce_cell->parameters[ID::A_WIDTH] = all_conditions.size();
+ reduce_cell->parameters[ID::Y_WIDTH] = 1;
+ reduce_cell->parameters[ID::A_SIGNED] = 0;
+ reduce_cell->setPort(ID::A, all_conditions);
+ reduce_cell->setPort(ID::Y, miter_module->addWire(NEW_ID));
+ all_conditions = reduce_cell->getPort(ID::Y);
}
if (flag_make_assert) {
- RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert");
- assert_cell->setPort("\\A", all_conditions);
- assert_cell->setPort("\\EN", State::S1);
+ RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, ID($assert));
+ assert_cell->setPort(ID::A, all_conditions);
+ assert_cell->setPort(ID::EN, State::S1);
}
- RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger");
+ RTLIL::Wire *w_trigger = miter_module->addWire(ID(trigger));
w_trigger->port_output = true;
- RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, "$not");
- not_cell->parameters["\\A_WIDTH"] = all_conditions.size();
- not_cell->parameters["\\A_WIDTH"] = all_conditions.size();
- not_cell->parameters["\\Y_WIDTH"] = w_trigger->width;
- not_cell->parameters["\\A_SIGNED"] = 0;
- not_cell->setPort("\\A", all_conditions);
- not_cell->setPort("\\Y", w_trigger);
+ RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, ID($not));
+ not_cell->parameters[ID::A_WIDTH] = all_conditions.size();
+ not_cell->parameters[ID::A_WIDTH] = all_conditions.size();
+ not_cell->parameters[ID::Y_WIDTH] = w_trigger->width;
+ not_cell->parameters[ID::A_SIGNED] = 0;
+ not_cell->setPort(ID::A, all_conditions);
+ not_cell->setPort(ID::Y, w_trigger);
miter_module->fixup_ports();
@@ -298,7 +298,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
for (auto wire : module->wires())
wire->port_output = false;
- Wire *trigger = module->addWire("\\trigger");
+ Wire *trigger = module->addWire(ID(trigger));
trigger->port_output = true;
module->fixup_ports();
@@ -312,13 +312,13 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
vector<Cell*> cell_list = module->cells();
for (auto cell : cell_list)
{
- if (!cell->type.in("$assert", "$assume"))
+ if (!cell->type.in(ID($assert), ID($assume)))
continue;
- SigBit is_active = module->Nex(NEW_ID, cell->getPort("\\A"), State::S1);
- SigBit is_enabled = module->Eqx(NEW_ID, cell->getPort("\\EN"), State::S1);
+ SigBit is_active = module->Nex(NEW_ID, cell->getPort(ID::A), State::S1);
+ SigBit is_enabled = module->Eqx(NEW_ID, cell->getPort(ID::EN), State::S1);
- if (cell->type == "$assert") {
+ if (cell->type == ID($assert)) {
assert_signals.append(module->And(NEW_ID, is_active, is_enabled));
} else {
assume_signals.append(module->And(NEW_ID, is_active, is_enabled));
@@ -334,7 +334,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
else
{
Wire *assume_q = module->addWire(NEW_ID);
- assume_q->attributes["\\init"] = State::S0;
+ assume_q->attributes[ID::init] = State::S0;
assume_signals.append(assume_q);
SigSpec assume_nok = module->ReduceOr(NEW_ID, assume_signals);
diff --git a/passes/sat/mutate.cc b/passes/sat/mutate.cc
index b53bbfeb2..af8ffca9e 100644
--- a/passes/sat/mutate.cc
+++ b/passes/sat/mutate.cc
@@ -439,7 +439,7 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena
dict<SigBit, int> bit_user_cnt;
for (auto wire : module->wires()) {
- if (wire->name[0] == '\\' && wire->attributes.count("\\src"))
+ if (wire->name[0] == '\\' && wire->attributes.count(ID::src))
sigmap.add(wire);
}
@@ -489,12 +489,12 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena
entry.port = conn.first;
entry.portbit = i;
- for (auto &s : cell->get_strpool_attribute("\\src"))
+ for (auto &s : cell->get_strpool_attribute(ID::src))
entry.src.insert(s);
SigBit bit = sigmap(conn.second[i]);
if (bit.wire && bit.wire->name[0] == '\\' && (cell->output(conn.first) || bit_user_cnt[bit] == 1)) {
- for (auto &s : bit.wire->get_strpool_attribute("\\src"))
+ for (auto &s : bit.wire->get_strpool_attribute(ID::src))
entry.src.insert(s);
entry.wire = bit.wire->name;
entry.wirebit = bit.offset;
diff --git a/passes/sat/sat.cc b/passes/sat/sat.cc
index 436ac1b01..6acdbc800 100644
--- a/passes/sat/sat.cc
+++ b/passes/sat/sat.cc
@@ -258,11 +258,11 @@ struct SatHelper
for (auto &it : module->wires_)
{
- if (it.second->attributes.count("\\init") == 0)
+ if (it.second->attributes.count(ID::init) == 0)
continue;
RTLIL::SigSpec lhs = sigmap(it.second);
- RTLIL::SigSpec rhs = it.second->attributes.at("\\init");
+ RTLIL::SigSpec rhs = it.second->attributes.at(ID::init);
log_assert(lhs.size() == rhs.size());
RTLIL::SigSpec removed_bits;
@@ -518,9 +518,9 @@ struct SatHelper
} else {
for (auto &d : drivers)
for (auto &p : d->connections()) {
- if (d->type == "$dff" && p.first == "\\CLK")
+ if (d->type == ID($dff) && p.first == ID::CLK)
continue;
- if (d->type.begins_with("$_DFF_") && p.first == "\\C")
+ if (d->type.begins_with("$_DFF_") && p.first == ID::C)
continue;
queued_signals.add(handled_signals.remove(sigmap(p.second)));
}
@@ -675,9 +675,9 @@ struct SatHelper
strftime(stime, sizeof(stime), "%c", now);
std::string module_fname = "unknown";
- auto apos = module->attributes.find("\\src");
+ auto apos = module->attributes.find(ID::src);
if(apos != module->attributes.end())
- module_fname = module->attributes["\\src"].decode_string();
+ module_fname = module->attributes[ID::src].decode_string();
fprintf(f, "$date\n");
fprintf(f, " %s\n", stime);
@@ -1354,8 +1354,8 @@ struct SatPass : public Pass {
if (show_regs) {
pool<Wire*> reg_wires;
for (auto cell : module->cells()) {
- if (cell->type == "$dff" || cell->type.begins_with("$_DFF_"))
- for (auto bit : cell->getPort("\\Q"))
+ if (cell->type == ID($dff) || cell->type.begins_with("$_DFF_"))
+ for (auto bit : cell->getPort(ID::Q))
if (bit.wire)
reg_wires.insert(bit.wire);
}
diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc
index d5634b26d..59bf5a712 100644
--- a/passes/sat/sim.cc
+++ b/passes/sat/sim.cc
@@ -108,8 +108,8 @@ struct SimInstance
}
}
- if (wire->attributes.count("\\init")) {
- Const initval = wire->attributes.at("\\init");
+ if (wire->attributes.count(ID::init)) {
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(sig) && i < GetSize(initval); i++)
if (initval[i] == State::S0 || initval[i] == State::S1) {
state_nets[sig[i]] = initval[i];
@@ -132,24 +132,24 @@ struct SimInstance
upd_cells[bit].insert(cell);
}
- if (cell->type.in("$dff")) {
+ if (cell->type.in(ID($dff))) {
ff_state_t ff;
ff.past_clock = State::Sx;
- ff.past_d = Const(State::Sx, cell->getParam("\\WIDTH").as_int());
+ ff.past_d = Const(State::Sx, cell->getParam(ID::WIDTH).as_int());
ff_database[cell] = ff;
}
- if (cell->type == "$mem")
+ if (cell->type == ID($mem))
{
mem_state_t mem;
- mem.past_wr_clk = Const(State::Sx, GetSize(cell->getPort("\\WR_CLK")));
- mem.past_wr_en = Const(State::Sx, GetSize(cell->getPort("\\WR_EN")));
- mem.past_wr_addr = Const(State::Sx, GetSize(cell->getPort("\\WR_ADDR")));
- mem.past_wr_data = Const(State::Sx, GetSize(cell->getPort("\\WR_DATA")));
+ mem.past_wr_clk = Const(State::Sx, GetSize(cell->getPort(ID::WR_CLK)));
+ mem.past_wr_en = Const(State::Sx, GetSize(cell->getPort(ID::WR_EN)));
+ mem.past_wr_addr = Const(State::Sx, GetSize(cell->getPort(ID::WR_ADDR)));
+ mem.past_wr_data = Const(State::Sx, GetSize(cell->getPort(ID::WR_DATA)));
- mem.data = cell->getParam("\\INIT");
- int sz = cell->getParam("\\SIZE").as_int() * cell->getParam("\\WIDTH").as_int();
+ mem.data = cell->getParam(ID::INIT);
+ int sz = cell->getParam(ID::SIZE).as_int() * cell->getParam(ID::WIDTH).as_int();
if (GetSize(mem.data) > sz)
mem.data.bits.resize(sz);
@@ -160,7 +160,7 @@ struct SimInstance
mem_database[cell] = mem;
}
- if (cell->type.in("$assert", "$cover", "$assume")) {
+ if (cell->type.in(ID($assert), ID($cover), ID($assume))) {
formal_database.insert(cell);
}
}
@@ -173,7 +173,7 @@ struct SimInstance
ff_state_t &ff = it.second;
zinit(ff.past_d);
- SigSpec qsig = cell->getPort("\\Q");
+ SigSpec qsig = cell->getPort(ID::Q);
Const qdata = get_state(qsig);
zinit(qdata);
set_state(qsig, qdata);
@@ -256,18 +256,18 @@ struct SimInstance
{
mem_state_t &mem = mem_database.at(cell);
- int num_rd_ports = cell->getParam("\\RD_PORTS").as_int();
+ int num_rd_ports = cell->getParam(ID::RD_PORTS).as_int();
- int size = cell->getParam("\\SIZE").as_int();
- int offset = cell->getParam("\\OFFSET").as_int();
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
+ int size = cell->getParam(ID::SIZE).as_int();
+ int offset = cell->getParam(ID::OFFSET).as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
- if (cell->getParam("\\RD_CLK_ENABLE").as_bool())
+ if (cell->getParam(ID::RD_CLK_ENABLE).as_bool())
log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(cell));
- SigSpec rd_addr_sig = cell->getPort("\\RD_ADDR");
- SigSpec rd_data_sig = cell->getPort("\\RD_DATA");
+ SigSpec rd_addr_sig = cell->getPort(ID::RD_ADDR);
+ SigSpec rd_data_sig = cell->getPort(ID::RD_DATA);
for (int port_idx = 0; port_idx < num_rd_ports; port_idx++)
{
@@ -303,19 +303,19 @@ struct SimInstance
RTLIL::SigSpec sig_a, sig_b, sig_c, sig_d, sig_s, sig_y;
bool has_a, has_b, has_c, has_d, has_s, has_y;
- has_a = cell->hasPort("\\A");
- has_b = cell->hasPort("\\B");
- has_c = cell->hasPort("\\C");
- has_d = cell->hasPort("\\D");
- has_s = cell->hasPort("\\S");
- has_y = cell->hasPort("\\Y");
+ has_a = cell->hasPort(ID::A);
+ has_b = cell->hasPort(ID::B);
+ has_c = cell->hasPort(ID::C);
+ has_d = cell->hasPort(ID::D);
+ has_s = cell->hasPort(ID::S);
+ has_y = cell->hasPort(ID::Y);
- if (has_a) sig_a = cell->getPort("\\A");
- if (has_b) sig_b = cell->getPort("\\B");
- if (has_c) sig_c = cell->getPort("\\C");
- if (has_d) sig_d = cell->getPort("\\D");
- if (has_s) sig_s = cell->getPort("\\S");
- if (has_y) sig_y = cell->getPort("\\Y");
+ if (has_a) sig_a = cell->getPort(ID::A);
+ if (has_b) sig_b = cell->getPort(ID::B);
+ if (has_c) sig_c = cell->getPort(ID::C);
+ if (has_d) sig_d = cell->getPort(ID::D);
+ if (has_s) sig_s = cell->getPort(ID::S);
+ if (has_y) sig_y = cell->getPort(ID::Y);
if (shared->debug)
log("[%s] eval %s (%s)\n", hiername().c_str(), log_id(cell), log_id(cell->type));
@@ -403,16 +403,16 @@ struct SimInstance
Cell *cell = it.first;
ff_state_t &ff = it.second;
- if (cell->type.in("$dff"))
+ if (cell->type.in(ID($dff)))
{
- bool clkpol = cell->getParam("\\CLK_POLARITY").as_bool();
- State current_clock = get_state(cell->getPort("\\CLK"))[0];
+ bool clkpol = cell->getParam(ID::CLK_POLARITY).as_bool();
+ State current_clock = get_state(cell->getPort(ID::CLK))[0];
if (clkpol ? (ff.past_clock == State::S1 || current_clock != State::S1) :
(ff.past_clock == State::S0 || current_clock != State::S0))
continue;
- if (set_state(cell->getPort("\\Q"), ff.past_d))
+ if (set_state(cell->getPort(ID::Q), ff.past_d))
did_something = true;
}
}
@@ -422,16 +422,16 @@ struct SimInstance
Cell *cell = it.first;
mem_state_t &mem = it.second;
- int num_wr_ports = cell->getParam("\\WR_PORTS").as_int();
+ int num_wr_ports = cell->getParam(ID::WR_PORTS).as_int();
- int size = cell->getParam("\\SIZE").as_int();
- int offset = cell->getParam("\\OFFSET").as_int();
- int abits = cell->getParam("\\ABITS").as_int();
- int width = cell->getParam("\\WIDTH").as_int();
+ int size = cell->getParam(ID::SIZE).as_int();
+ int offset = cell->getParam(ID::OFFSET).as_int();
+ int abits = cell->getParam(ID::ABITS).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
- Const wr_clk_enable = cell->getParam("\\WR_CLK_ENABLE");
- Const wr_clk_polarity = cell->getParam("\\WR_CLK_POLARITY");
- Const current_wr_clk = get_state(cell->getPort("\\WR_CLK"));
+ Const wr_clk_enable = cell->getParam(ID::WR_CLK_ENABLE);
+ Const wr_clk_polarity = cell->getParam(ID::WR_CLK_POLARITY);
+ Const current_wr_clk = get_state(cell->getPort(ID::WR_CLK));
for (int port_idx = 0; port_idx < num_wr_ports; port_idx++)
{
@@ -439,9 +439,9 @@ struct SimInstance
if (wr_clk_enable[port_idx] == State::S0)
{
- addr = get_state(cell->getPort("\\WR_ADDR").extract(port_idx*abits, abits));
- data = get_state(cell->getPort("\\WR_DATA").extract(port_idx*width, width));
- enable = get_state(cell->getPort("\\WR_EN").extract(port_idx*width, width));
+ addr = get_state(cell->getPort(ID::WR_ADDR).extract(port_idx*abits, abits));
+ data = get_state(cell->getPort(ID::WR_DATA).extract(port_idx*width, width));
+ enable = get_state(cell->getPort(ID::WR_EN).extract(port_idx*width, width));
}
else
{
@@ -485,9 +485,9 @@ struct SimInstance
Cell *cell = it.first;
ff_state_t &ff = it.second;
- if (cell->type.in("$dff")) {
- ff.past_clock = get_state(cell->getPort("\\CLK"))[0];
- ff.past_d = get_state(cell->getPort("\\D"));
+ if (cell->type.in(ID($dff))) {
+ ff.past_clock = get_state(cell->getPort(ID::CLK))[0];
+ ff.past_d = get_state(cell->getPort(ID::D));
}
}
@@ -496,28 +496,28 @@ struct SimInstance
Cell *cell = it.first;
mem_state_t &mem = it.second;
- mem.past_wr_clk = get_state(cell->getPort("\\WR_CLK"));
- mem.past_wr_en = get_state(cell->getPort("\\WR_EN"));
- mem.past_wr_addr = get_state(cell->getPort("\\WR_ADDR"));
- mem.past_wr_data = get_state(cell->getPort("\\WR_DATA"));
+ mem.past_wr_clk = get_state(cell->getPort(ID::WR_CLK));
+ mem.past_wr_en = get_state(cell->getPort(ID::WR_EN));
+ mem.past_wr_addr = get_state(cell->getPort(ID::WR_ADDR));
+ mem.past_wr_data = get_state(cell->getPort(ID::WR_DATA));
}
for (auto cell : formal_database)
{
string label = log_id(cell);
- if (cell->attributes.count("\\src"))
- label = cell->attributes.at("\\src").decode_string();
+ if (cell->attributes.count(ID::src))
+ label = cell->attributes.at(ID::src).decode_string();
- State a = get_state(cell->getPort("\\A"))[0];
- State en = get_state(cell->getPort("\\EN"))[0];
+ State a = get_state(cell->getPort(ID::A))[0];
+ State en = get_state(cell->getPort(ID::EN))[0];
- if (cell->type == "$cover" && en == State::S1 && a != State::S1)
+ if (cell->type == ID($cover) && en == State::S1 && a != State::S1)
log("Cover %s.%s (%s) reached.\n", hiername().c_str(), log_id(cell), label.c_str());
- if (cell->type == "$assume" && en == State::S1 && a != State::S1)
+ if (cell->type == ID($assume) && en == State::S1 && a != State::S1)
log("Assumption %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str());
- if (cell->type == "$assert" && en == State::S1 && a != State::S1)
+ if (cell->type == ID($assert) && en == State::S1 && a != State::S1)
log_warning("Assert %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str());
}
@@ -533,22 +533,22 @@ struct SimInstance
wbmods.insert(module);
for (auto wire : module->wires())
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
for (auto &it : ff_database)
{
Cell *cell = it.first;
- SigSpec sig_q = cell->getPort("\\Q");
+ SigSpec sig_q = cell->getPort(ID::Q);
Const initval = get_state(sig_q);
for (int i = 0; i < GetSize(sig_q); i++)
{
Wire *w = sig_q[i].wire;
- if (w->attributes.count("\\init") == 0)
- w->attributes["\\init"] = Const(State::Sx, GetSize(w));
+ if (w->attributes.count(ID::init) == 0)
+ w->attributes[ID::init] = Const(State::Sx, GetSize(w));
- w->attributes["\\init"][sig_q[i].offset] = initval[i];
+ w->attributes[ID::init][sig_q[i].offset] = initval[i];
}
}
@@ -564,7 +564,7 @@ struct SimInstance
initval.bits.pop_back();
}
- cell->setParam("\\INIT", initval);
+ cell->setParam(ID::INIT, initval);
}
for (auto it : children)
diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc
index c16db0d57..766b954df 100644
--- a/passes/techmap/Makefile.inc
+++ b/passes/techmap/Makefile.inc
@@ -34,7 +34,6 @@ OBJS += passes/techmap/aigmap.o
OBJS += passes/techmap/tribuf.o
OBJS += passes/techmap/lut2mux.o
OBJS += passes/techmap/nlutmap.o
-OBJS += passes/techmap/dffsr2dff.o
OBJS += passes/techmap/shregmap.o
OBJS += passes/techmap/deminout.o
OBJS += passes/techmap/insbuf.o
@@ -59,10 +58,10 @@ passes/techmap/techmap.inc: techlibs/common/techmap.v
passes/techmap/techmap.o: passes/techmap/techmap.inc
ifneq ($(CONFIG),emcc)
-TARGETS += yosys-filterlib$(EXE)
+TARGETS += $(PROGRAM_PREFIX)yosys-filterlib$(EXE)
EXTRA_OBJS += passes/techmap/filterlib.o
-yosys-filterlib$(EXE): passes/techmap/filterlib.o
+$(PROGRAM_PREFIX)yosys-filterlib$(EXE): passes/techmap/filterlib.o
$(Q) mkdir -p $(dir $@)
- $(P) $(LD) -o yosys-filterlib$(EXE) $(LDFLAGS) $^ $(LDLIBS)
+ $(P) $(LD) -o $(PROGRAM_PREFIX)yosys-filterlib$(EXE) $(LDFLAGS) $^ $(LDLIBS)
endif
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index e6c189c3e..0ee495abd 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -170,7 +170,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
if (clk_polarity != (cell->type == ID($_DFF_P_)))
return;
- if (clk_sig != assign_map(cell->getPort(ID(C))))
+ if (clk_sig != assign_map(cell->getPort(ID::C)))
return;
if (GetSize(en_sig) != 0)
return;
@@ -183,17 +183,17 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
return;
if (en_polarity != cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
return;
- if (clk_sig != assign_map(cell->getPort(ID(C))))
+ if (clk_sig != assign_map(cell->getPort(ID::C)))
return;
- if (en_sig != assign_map(cell->getPort(ID(E))))
+ if (en_sig != assign_map(cell->getPort(ID::E)))
return;
goto matching_dff;
}
if (0) {
matching_dff:
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
if (keepff)
for (auto &c : sig_q.chunks())
@@ -263,7 +263,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
- RTLIL::SigSpec sig_s = cell->getPort(ID(S));
+ RTLIL::SigSpec sig_s = cell->getPort(ID::S);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
assign_map.apply(sig_a);
@@ -285,7 +285,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
- RTLIL::SigSpec sig_c = cell->getPort(ID(C));
+ RTLIL::SigSpec sig_c = cell->getPort(ID::C);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
assign_map.apply(sig_a);
@@ -307,8 +307,8 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
- RTLIL::SigSpec sig_c = cell->getPort(ID(C));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
+ RTLIL::SigSpec sig_c = cell->getPort(ID::C);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
assign_map.apply(sig_a);
@@ -702,7 +702,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
if (dff_mode && clk_sig.empty())
log_cmd_error("Clock domain %s not found.\n", clk_str.c_str());
- std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
+ std::string tempdir_name = "/tmp/" + proc_program_prefix()+ "yosys-abc-XXXXXX";
if (!cleanup)
tempdir_name[0] = tempdir_name[4] = '_';
tempdir_name = make_temp_dir(tempdir_name);
@@ -1032,9 +1032,9 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
RTLIL::Wire *w = it.second;
RTLIL::Wire *orig_wire = nullptr;
RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire));
- if (orig_wire != nullptr && orig_wire->attributes.count(ID(src)))
- wire->attributes[ID(src)] = orig_wire->attributes[ID(src)];
- if (markgroups) wire->attributes[ID(abcgroup)] = map_autoidx;
+ if (orig_wire != nullptr && orig_wire->attributes.count(ID::src))
+ wire->attributes[ID::src] = orig_wire->attributes[ID::src];
+ if (markgroups) wire->attributes[ID::abcgroup] = map_autoidx;
design->select(module, wire);
}
@@ -1060,7 +1060,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
if (c->type == ID(NOT)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
@@ -1068,7 +1068,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
@@ -1077,89 +1077,89 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
if (c->type.in(ID(MUX), ID(NMUX))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type == ID(MUX4)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
- cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
+ cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type == ID(MUX8)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
- cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
- cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
- cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
- cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
- cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::E, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::E).as_wire()->name)]));
+ cell->setPort(ID::F, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::F).as_wire()->name)]));
+ cell->setPort(ID::G, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::G).as_wire()->name)]));
+ cell->setPort(ID::H, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::H).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
+ cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
+ cell->setPort(ID::U, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::U).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type == ID(MUX16)) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
- cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
- cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
- cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
- cell->setPort(ID(I), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(I)).as_wire()->name)]));
- cell->setPort(ID(J), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(J)).as_wire()->name)]));
- cell->setPort(ID(K), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(K)).as_wire()->name)]));
- cell->setPort(ID(L), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(L)).as_wire()->name)]));
- cell->setPort(ID(M), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(M)).as_wire()->name)]));
- cell->setPort(ID(N), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(N)).as_wire()->name)]));
- cell->setPort(ID(O), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(O)).as_wire()->name)]));
- cell->setPort(ID(P), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(P)).as_wire()->name)]));
- cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
- cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
- cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
- cell->setPort(ID(V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(V)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::E, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::E).as_wire()->name)]));
+ cell->setPort(ID::F, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::F).as_wire()->name)]));
+ cell->setPort(ID::G, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::G).as_wire()->name)]));
+ cell->setPort(ID::H, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::H).as_wire()->name)]));
+ cell->setPort(ID::I, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::I).as_wire()->name)]));
+ cell->setPort(ID::J, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::J).as_wire()->name)]));
+ cell->setPort(ID::K, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::K).as_wire()->name)]));
+ cell->setPort(ID::L, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::L).as_wire()->name)]));
+ cell->setPort(ID::M, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::M).as_wire()->name)]));
+ cell->setPort(ID::N, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::N).as_wire()->name)]));
+ cell->setPort(ID::O, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::O).as_wire()->name)]));
+ cell->setPort(ID::P, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::P).as_wire()->name)]));
+ cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
+ cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
+ cell->setPort(ID::U, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::U).as_wire()->name)]));
+ cell->setPort(ID::V, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::V).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type.in(ID(AOI3), ID(OAI3))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
}
if (c->type.in(ID(AOI4), ID(OAI4))) {
RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
- cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
+ cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
design->select(module, cell);
continue;
@@ -1172,12 +1172,12 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
} else {
log_assert(en_sig.size() == 1);
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
- cell->setPort(ID(E), en_sig);
+ cell->setPort(ID::E, en_sig);
}
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
- cell->setPort(ID(C), clk_sig);
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::Q, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Q).as_wire()->name)]));
+ cell->setPort(ID::C, clk_sig);
design->select(module, cell);
continue;
}
@@ -1201,17 +1201,17 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
} else {
log_assert(en_sig.size() == 1);
cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
- cell->setPort(ID(E), en_sig);
+ cell->setPort(ID::E, en_sig);
}
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
- cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
- cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
- cell->setPort(ID(C), clk_sig);
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
+ cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
+ cell->setPort(ID::Q, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Q).as_wire()->name)]));
+ cell->setPort(ID::C, clk_sig);
design->select(module, cell);
continue;
}
- if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)).as_int() == 2) {
+ if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
SigSpec my_a = module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)];
SigSpec my_y = module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)];
module->connect(my_y, my_a);
@@ -1219,7 +1219,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
}
RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
- if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
+ if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
cell->parameters = c->parameters;
for (auto &conn : c->connections()) {
RTLIL::SigSpec newsig;
@@ -1244,10 +1244,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
if (recover_init)
for (auto wire : mapped_mod->wires()) {
- if (wire->attributes.count(ID(init))) {
+ if (wire->attributes.count(ID::init)) {
Wire *w = module->wires_[remap_name(wire->name)];
- log_assert(w->attributes.count(ID(init)) == 0);
- w->attributes[ID(init)] = wire->attributes.at(ID(init));
+ log_assert(w->attributes.count(ID::init) == 0);
+ w->attributes[ID::init] = wire->attributes.at(ID::init);
}
}
@@ -1305,7 +1305,7 @@ struct AbcPass : public Pass {
#ifdef ABCEXTERNAL
log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
#else
- log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
+ log(" use the specified command instead of \"<yosys-bindir>/%syosys-abc\" to execute ABC.\n", proc_program_prefix().c_str());
#endif
log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
log("\n");
@@ -1491,7 +1491,7 @@ struct AbcPass : public Pass {
#ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL;
#else
- std::string exe_file = proc_self_dirname() + "yosys-abc";
+ std::string exe_file = proc_self_dirname() + proc_program_prefix() + "yosys-abc";
#endif
std::string script_file, liberty_file, constr_file, clk_str;
std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1";
@@ -1509,8 +1509,8 @@ struct AbcPass : public Pass {
#ifdef _WIN32
#ifndef ABCEXTERNAL
- if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe"))
- exe_file = proc_self_dirname() + "..\\yosys-abc";
+ if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix()+ "yosys-abc.exe"))
+ exe_file = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc";
#endif
#endif
@@ -1869,9 +1869,9 @@ struct AbcPass : public Pass {
signal_init.clear();
for (Wire *wire : mod->wires())
- if (wire->attributes.count(ID(init))) {
+ if (wire->attributes.count(ID::init)) {
SigSpec initsig = assign_map(wire);
- Const initval = wire->attributes.at(ID(init));
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
switch (initval[i]) {
case State::S0:
@@ -1930,14 +1930,14 @@ struct AbcPass : public Pass {
if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
{
- key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec());
+ key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID::C)), true, RTLIL::SigSpec());
}
else
if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
{
bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
- key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E))));
+ key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID::C)), this_en_pol, assign_map(cell->getPort(ID::E)));
}
else
continue;
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 212e0692d..1b3d5ff06 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -100,7 +100,7 @@ struct Abc9Pass : public ScriptPass
#ifdef ABCEXTERNAL
log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
#else
- log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
+ log(" use the specified command instead of \"<yosys-bindir>/%syosys-abc\" to execute ABC.\n", proc_program_prefix().c_str());
#endif
log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
log("\n");
@@ -318,7 +318,7 @@ struct Abc9Pass : public ScriptPass
log("Skipping module %s as it contains processes.\n", log_id(mod));
continue;
}
- log_assert(!mod->attributes.count(ID(abc9_box_id)));
+ log_assert(!mod->attributes.count(ID::abc9_box_id));
log_push();
active_design->selection().select(mod);
@@ -326,7 +326,7 @@ struct Abc9Pass : public ScriptPass
if (!active_design->selected_whole_module(mod))
log_error("Can't handle partially selected module %s!\n", log_id(mod));
- std::string tempdir_name = "/tmp/yosys-abc-XXXXXX";
+ std::string tempdir_name = "/tmp/" + proc_program_prefix() + "yosys-abc-XXXXXX";
if (!cleanup)
tempdir_name[0] = tempdir_name[4] = '_';
tempdir_name = make_temp_dir(tempdir_name);
diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc
index 898285c69..18618ff91 100644
--- a/passes/techmap/abc9_exe.cc
+++ b/passes/techmap/abc9_exe.cc
@@ -222,9 +222,9 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe
abc9_script += stringf("; &ps -l; &write -n %s/output.aig", tempdir_name.c_str());
if (design->scratchpad_get_bool("abc9.verify")) {
if (dff_mode)
- abc9_script += "; verify -s";
+ abc9_script += "; &verify -s";
else
- abc9_script += "; verify";
+ abc9_script += "; &verify";
}
abc9_script += "; time";
abc9_script = add_echos_to_abc9_cmd(abc9_script);
@@ -293,7 +293,7 @@ struct Abc9ExePass : public Pass {
#ifdef ABCEXTERNAL
log(" use the specified command instead of \"" ABCEXTERNAL "\" to execute ABC.\n");
#else
- log(" use the specified command instead of \"<yosys-bindir>/yosys-abc\" to execute ABC.\n");
+ log(" use the specified command instead of \"<yosys-bindir>/%syosys-abc\" to execute ABC.\n", proc_program_prefix().c_str());
#endif
log(" This can e.g. be used to call a specific version of ABC or a wrapper.\n");
log("\n");
@@ -367,7 +367,7 @@ struct Abc9ExePass : public Pass {
#ifdef ABCEXTERNAL
std::string exe_file = ABCEXTERNAL;
#else
- std::string exe_file = proc_self_dirname() + "yosys-abc";
+ std::string exe_file = proc_self_dirname() + proc_program_prefix()+ "yosys-abc";
#endif
std::string script_file, clk_str, box_file, lut_file;
std::string delay_target, lutin_shared = "-S 1", wire_delay;
@@ -383,8 +383,8 @@ struct Abc9ExePass : public Pass {
#ifdef _WIN32
#ifndef ABCEXTERNAL
- if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe"))
- exe_file = proc_self_dirname() + "..\\yosys-abc";
+ if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc.exe"))
+ exe_file = proc_self_dirname() + "..\\" + proc_program_prefix() + "yosys-abc";
#endif
#endif
diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc
index e1baf4e3d..8ae1b51ff 100644
--- a/passes/techmap/abc9_ops.cc
+++ b/passes/techmap/abc9_ops.cc
@@ -41,8 +41,8 @@ void check(RTLIL::Design *design)
if (m->name.begins_with("$paramod"))
continue;
- auto flop = m->get_bool_attribute(ID(abc9_flop));
- auto it = m->attributes.find(ID(abc9_box_id));
+ auto flop = m->get_bool_attribute(ID::abc9_flop);
+ auto it = m->attributes.find(ID::abc9_box_id);
if (!flop) {
if (it == m->attributes.end())
continue;
@@ -59,7 +59,7 @@ void check(RTLIL::Design *design)
for (const auto &port_name : m->ports) {
auto w = m->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
if (w->port_input) {
if (carry_in != IdString())
log_error("Module '%s' contains more than one (* abc9_carry *) input port.\n", log_id(m));
@@ -99,7 +99,7 @@ void mark_scc(RTLIL::Module *module)
// write_xaiger to break this wire into PI and POs)
pool<RTLIL::Const> ids_seen;
for (auto cell : module->cells()) {
- auto it = cell->attributes.find(ID(abc9_scc_id));
+ auto it = cell->attributes.find(ID::abc9_scc_id);
if (it == cell->attributes.end())
continue;
auto id = it->second;
@@ -111,7 +111,7 @@ void mark_scc(RTLIL::Module *module)
if (c.second.is_fully_const()) continue;
if (cell->output(c.first)) {
Wire *w = module->addWire(NEW_ID, GetSize(c.second));
- w->set_bool_attribute(ID(abc9_scc));
+ w->set_bool_attribute(ID::abc9_scc);
module->connect(w, c.second);
c.second = w;
}
@@ -130,7 +130,7 @@ void prep_dff(RTLIL::Module *module)
dict<clkdomain_t, int> clk_to_mergeability;
for (auto cell : module->cells()) {
- if (cell->type != "$__ABC9_FF_")
+ if (cell->type != ID($__ABC9_FF_))
continue;
Wire *abc9_clock_wire = module->wire(stringf("%s.clock", cell->name.c_str()));
@@ -141,7 +141,7 @@ void prep_dff(RTLIL::Module *module)
clkdomain_t key(abc9_clock);
auto r = clk_to_mergeability.insert(std::make_pair(abc9_clock, clk_to_mergeability.size() + 1));
- auto r2 = cell->attributes.insert(ID(abc9_mergeability));;
+ auto r2 = cell->attributes.insert(ID::abc9_mergeability);
log_assert(r2.second);
r2.first->second = r.first->second;
}
@@ -152,20 +152,20 @@ void prep_dff(RTLIL::Module *module)
dict<SigSpec, SigSpec> replace;
for (auto cell : holes_module->cells().to_vector()) {
- if (!cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
- "$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_"))
+ if (!cell->type.in(ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
+ ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1), ID($_DFF_PP0_), ID($_DFF_PP1_)))
continue;
- SigBit D = cell->getPort("\\D");
- SigBit Q = cell->getPort("\\Q");
+ SigBit D = cell->getPort(ID::D);
+ SigBit Q = cell->getPort(ID::Q);
// Emulate async control embedded inside $_DFF_* cell with mux in front of D
- if (cell->type.in("$_DFF_NN0_", "$_DFF_PN0_"))
- D = holes_module->MuxGate(NEW_ID, State::S0, D, cell->getPort("\\R"));
- else if (cell->type.in("$_DFF_NN1_", "$_DFF_PN1_"))
- D = holes_module->MuxGate(NEW_ID, State::S1, D, cell->getPort("\\R"));
- else if (cell->type.in("$_DFF_NP0_", "$_DFF_PP0_"))
- D = holes_module->MuxGate(NEW_ID, D, State::S0, cell->getPort("\\R"));
- else if (cell->type.in("$_DFF_NP1_", "$_DFF_PP1_"))
- D = holes_module->MuxGate(NEW_ID, D, State::S1, cell->getPort("\\R"));
+ if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_PN0_)))
+ D = holes_module->MuxGate(NEW_ID, State::S0, D, cell->getPort(ID::R));
+ else if (cell->type.in(ID($_DFF_NN1_), ID($_DFF_PN1_)))
+ D = holes_module->MuxGate(NEW_ID, State::S1, D, cell->getPort(ID::R));
+ else if (cell->type.in(ID($_DFF_NP0_), ID($_DFF_PP0_)))
+ D = holes_module->MuxGate(NEW_ID, D, State::S0, cell->getPort(ID::R));
+ else if (cell->type.in(ID($_DFF_NP1_), ID($_DFF_PP1_)))
+ D = holes_module->MuxGate(NEW_ID, D, State::S1, cell->getPort(ID::R));
// Remove the $_DFF_* cell from what needs to be a combinatorial box
holes_module->remove(cell);
Wire *port;
@@ -208,17 +208,17 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
dict<IdString, std::vector<IdString>> box_ports;
for (auto cell : module->cells()) {
- if (cell->type == "$__ABC9_FF_")
+ if (cell->type == ID($__ABC9_FF_))
continue;
if (cell->has_keep_attr())
continue;
auto inst_module = module->design->module(cell->type);
- bool abc9_flop = inst_module && inst_module->get_bool_attribute("\\abc9_flop");
+ bool abc9_flop = inst_module && inst_module->get_bool_attribute(ID::abc9_flop);
if (abc9_flop && !dff)
continue;
- if ((inst_module && inst_module->get_bool_attribute("\\abc9_box")) || abc9_flop) {
+ if ((inst_module && inst_module->get_bool_attribute(ID::abc9_box)) || abc9_flop) {
auto r = box_ports.insert(cell->type);
if (r.second) {
// Make carry in the last PI, and carry out the last PO
@@ -227,7 +227,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
for (const auto &port_name : inst_module->ports) {
auto w = inst_module->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
log_assert(w->port_input != w->port_output);
if (w->port_input)
carry_in = port_name;
@@ -289,7 +289,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
RTLIL::Module *holes_module = design->addModule(stringf("%s$holes", module->name.c_str()));
log_assert(holes_module);
- holes_module->set_bool_attribute("\\abc9_holes");
+ holes_module->set_bool_attribute(ID::abc9_holes);
dict<IdString, Cell*> cell_cache;
TimingInfo timing;
@@ -300,10 +300,10 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
log_assert(cell);
RTLIL::Module* box_module = design->module(cell->type);
- if (!box_module || (!box_module->get_bool_attribute("\\abc9_box") && !box_module->get_bool_attribute("\\abc9_flop")))
+ if (!box_module || (!box_module->get_bool_attribute(ID::abc9_box) && !box_module->get_bool_attribute(ID::abc9_flop)))
continue;
- cell->attributes["\\abc9_box_seq"] = box_count++;
+ cell->attributes[ID::abc9_box_seq] = box_count++;
IdString derived_type = box_module->derive(design, cell->parameters);
box_module = design->module(derived_type);
@@ -314,7 +314,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
if (box_module->has_processes())
Pass::call_on_module(design, box_module, "proc");
- if (box_module->get_bool_attribute("\\whitebox")) {
+ if (box_module->get_bool_attribute(ID::whitebox)) {
holes_cell = holes_module->addCell(cell->name, derived_type);
if (box_module->has_processes())
@@ -345,7 +345,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
// For flops only, create an extra 1-bit input that drives a new wire
// called "<cell>.abc9_ff.Q" that is used below
- if (box_module->get_bool_attribute("\\abc9_flop")) {
+ if (box_module->get_bool_attribute(ID::abc9_flop)) {
box_inputs++;
Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
if (!holes_wire) {
@@ -402,13 +402,13 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
continue;
if (!inst_module->get_blackbox_attribute())
continue;
- if (inst_module->attributes.count(ID(abc9_box)))
+ if (inst_module->attributes.count(ID::abc9_box))
continue;
IdString derived_type = inst_module->derive(design, cell->parameters);
inst_module = design->module(derived_type);
log_assert(inst_module);
- if (dff_mode && inst_module->get_bool_attribute(ID(abc9_flop))) {
+ if (dff_mode && inst_module->get_bool_attribute(ID::abc9_flop)) {
flops.insert(inst_module);
continue; // do not add $__ABC9_DELAY boxes to flops
// as delays will be captured in the flop box
@@ -434,6 +434,9 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
auto &t = timing.at(derived_type).required;
for (auto &conn : cell->connections_) {
auto port_wire = inst_module->wire(conn.first);
+ if (!port_wire)
+ log_error("Port %s in cell %s (type %s) of module %s does not actually exist",
+ log_id(conn.first), log_id(cell->name), log_id(cell->type), log_id(module->name));
if (!port_wire->port_input)
continue;
@@ -451,9 +454,9 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
}
#endif
auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY));
- box->setPort(ID(I), conn.second[i]);
- box->setPort(ID(O), O[i]);
- box->setParam(ID(DELAY), d);
+ box->setPort(ID::I, conn.second[i]);
+ box->setPort(ID::O, O[i]);
+ box->setParam(ID::DELAY, d);
conn.second[i] = O[i];
}
}
@@ -466,7 +469,7 @@ void prep_lut(RTLIL::Design *design, int maxlut)
std::vector<std::tuple<int, IdString, int, std::vector<int>>> table;
for (auto module : design->modules()) {
- auto it = module->attributes.find(ID(abc9_lut));
+ auto it = module->attributes.find(ID::abc9_lut);
if (it == module->attributes.end())
continue;
@@ -527,7 +530,7 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
std::stringstream ss;
int abc9_box_id = 1;
for (auto module : design->modules()) {
- auto it = module->attributes.find(ID(abc9_box_id));
+ auto it = module->attributes.find(ID::abc9_box_id);
if (it == module->attributes.end())
continue;
abc9_box_id = std::max(abc9_box_id, it->second.as_int());
@@ -535,9 +538,9 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
dict<IdString,std::vector<IdString>> box_ports;
for (auto module : design->modules()) {
- auto abc9_flop = module->get_bool_attribute(ID(abc9_flop));
+ auto abc9_flop = module->get_bool_attribute(ID::abc9_flop);
if (abc9_flop) {
- auto r = module->attributes.insert(ID(abc9_box_id));
+ auto r = module->attributes.insert(ID::abc9_box_id);
if (!r.second)
continue;
r.first->second = abc9_box_id++;
@@ -604,10 +607,10 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
}
}
else {
- if (!module->attributes.erase(ID(abc9_box)))
+ if (!module->attributes.erase(ID::abc9_box))
continue;
- auto r = module->attributes.insert(ID(abc9_box_id));
+ auto r = module->attributes.insert(ID::abc9_box_id);
if (!r.second)
continue;
r.first->second = abc9_box_id++;
@@ -621,7 +624,7 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
for (const auto &port_name : module->ports) {
auto w = module->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
log_assert(w->port_input != w->port_output);
if (w->port_input)
carry_in = port_name;
@@ -650,7 +653,7 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
outputs.emplace_back(wire, i);
}
- ss << log_id(module) << " " << module->attributes.at(ID(abc9_box_id)).as_int();
+ ss << log_id(module) << " " << module->attributes.at(ID::abc9_box_id).as_int();
ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl;
@@ -727,7 +730,7 @@ void reintegrate(RTLIL::Module *module)
dict<IdString,std::vector<IdString>> box_ports;
for (auto m : design->modules()) {
- if (!m->attributes.count(ID(abc9_box_id)))
+ if (!m->attributes.count(ID::abc9_box_id))
continue;
auto r = box_ports.insert(m->name);
@@ -740,7 +743,7 @@ void reintegrate(RTLIL::Module *module)
for (const auto &port_name : m->ports) {
auto w = m->wire(port_name);
log_assert(w);
- if (w->get_bool_attribute("\\abc9_carry")) {
+ if (w->get_bool_attribute(ID::abc9_carry)) {
log_assert(w->port_input != w->port_output);
if (w->port_input)
carry_in = port_name;
@@ -763,7 +766,7 @@ void reintegrate(RTLIL::Module *module)
continue;
if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_)))
module->remove(cell);
- else if (cell->attributes.erase("\\abc9_box_seq"))
+ else if (cell->attributes.erase(ID::abc9_box_seq))
boxes.emplace_back(cell);
}
@@ -874,7 +877,7 @@ void reintegrate(RTLIL::Module *module)
IdString derived_type = box_module->derive(design, existing_cell->parameters);
RTLIL::Module* derived_module = design->module(derived_type);
log_assert(derived_module);
- log_assert(mapped_cell->type == stringf("$__boxid%d", derived_module->attributes.at("\\abc9_box_id").as_int()));
+ log_assert(mapped_cell->type == stringf("$__boxid%d", derived_module->attributes.at(ID::abc9_box_id).as_int()));
mapped_cell->type = existing_cell->type;
RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
@@ -882,16 +885,16 @@ void reintegrate(RTLIL::Module *module)
cell->attributes = existing_cell->attributes;
module->swap_names(cell, existing_cell);
- auto jt = mapped_cell->connections_.find("\\i");
+ auto jt = mapped_cell->connections_.find(ID(i));
log_assert(jt != mapped_cell->connections_.end());
SigSpec inputs = std::move(jt->second);
mapped_cell->connections_.erase(jt);
- jt = mapped_cell->connections_.find("\\o");
+ jt = mapped_cell->connections_.find(ID(o));
log_assert(jt != mapped_cell->connections_.end());
SigSpec outputs = std::move(jt->second);
mapped_cell->connections_.erase(jt);
- auto abc9_flop = box_module->attributes.count("\\abc9_flop");
+ auto abc9_flop = box_module->attributes.count(ID::abc9_flop);
if (!abc9_flop) {
for (const auto &i : inputs)
bit_users[i].insert(mapped_cell->name);
@@ -966,7 +969,7 @@ void reintegrate(RTLIL::Module *module)
RTLIL::Wire *mapped_wire = mapped_mod->wire(port);
RTLIL::Wire *wire = module->wire(port);
log_assert(wire);
- wire->attributes.erase(ID(abc9_scc));
+ wire->attributes.erase(ID::abc9_scc);
RTLIL::Wire *remap_wire = module->wire(remap_name(port));
RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire));
@@ -1033,7 +1036,7 @@ void reintegrate(RTLIL::Module *module)
// Push downstream LUTs past inverter
for (auto sink_cell : jt->second) {
SigSpec A = sink_cell->getPort(ID::A);
- RTLIL::Const mask = sink_cell->getParam(ID(LUT));
+ RTLIL::Const mask = sink_cell->getParam(ID::LUT);
int index = 0;
for (; index < GetSize(A); index++)
if (A[index] == a_bit)
@@ -1047,7 +1050,7 @@ void reintegrate(RTLIL::Module *module)
}
A[index] = y_bit;
sink_cell->setPort(ID::A, A);
- sink_cell->setParam(ID(LUT), mask);
+ sink_cell->setParam(ID::LUT, mask);
}
// Since we have rewritten all sinks (which we know
@@ -1056,7 +1059,7 @@ void reintegrate(RTLIL::Module *module)
// that the original driving LUT will become dangling
// and get cleaned away
clone_lut:
- driver_mask = driver_lut->getParam(ID(LUT));
+ driver_mask = driver_lut->getParam(ID::LUT);
for (auto &b : driver_mask.bits) {
if (b == RTLIL::State::S0) b = RTLIL::State::S1;
else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
@@ -1228,7 +1231,7 @@ struct Abc9OpsPass : public Pass {
prep_box(design, dff_mode);
for (auto mod : design->selected_modules()) {
- if (mod->get_bool_attribute("\\abc9_holes"))
+ if (mod->get_bool_attribute(ID::abc9_holes))
continue;
if (mod->processes.size() > 0) {
diff --git a/passes/techmap/alumacc.cc b/passes/techmap/alumacc.cc
index 034731b87..1925145d3 100644
--- a/passes/techmap/alumacc.cc
+++ b/passes/techmap/alumacc.cc
@@ -72,7 +72,7 @@ struct AlumaccWorker
RTLIL::SigSpec get_eq() {
if (GetSize(cached_eq) == 0)
- cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID(X)), false, alu_cell->get_src_attribute());
+ cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID::X), false, alu_cell->get_src_attribute());
return cached_eq;
}
@@ -84,7 +84,7 @@ struct AlumaccWorker
RTLIL::SigSpec get_cf() {
if (GetSize(cached_cf) == 0) {
- cached_cf = alu_cell->getPort(ID(CO));
+ cached_cf = alu_cell->getPort(ID::CO);
log_assert(GetSize(cached_cf) >= 1);
cached_cf = alu_cell->module->Not(NEW_ID, cached_cf[GetSize(cached_cf)-1], false, alu_cell->get_src_attribute());
}
@@ -93,7 +93,7 @@ struct AlumaccWorker
RTLIL::SigSpec get_of() {
if (GetSize(cached_of) == 0) {
- cached_of = {alu_cell->getPort(ID(CO)), alu_cell->getPort(ID(CI))};
+ cached_of = {alu_cell->getPort(ID::CO), alu_cell->getPort(ID::CI)};
log_assert(GetSize(cached_of) >= 2);
cached_of = alu_cell->module->Xor(NEW_ID, cached_of[GetSize(cached_of)-1], cached_of[GetSize(cached_of)-2]);
}
@@ -154,7 +154,7 @@ struct AlumaccWorker
if (cell->type.in(ID($pos), ID($neg)))
{
new_port.in_a = sigmap(cell->getPort(ID::A));
- new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
new_port.do_subtract = cell->type == ID($neg);
n->macc.ports.push_back(new_port);
}
@@ -162,12 +162,12 @@ struct AlumaccWorker
if (cell->type.in(ID($add), ID($sub)))
{
new_port.in_a = sigmap(cell->getPort(ID::A));
- new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
new_port.do_subtract = false;
n->macc.ports.push_back(new_port);
new_port.in_a = sigmap(cell->getPort(ID::B));
- new_port.is_signed = cell->getParam(ID(B_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::B_SIGNED).as_bool();
new_port.do_subtract = cell->type == ID($sub);
n->macc.ports.push_back(new_port);
}
@@ -176,7 +176,7 @@ struct AlumaccWorker
{
new_port.in_a = sigmap(cell->getPort(ID::A));
new_port.in_b = sigmap(cell->getPort(ID::B));
- new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
new_port.do_subtract = false;
n->macc.ports.push_back(new_port);
}
@@ -399,7 +399,7 @@ struct AlumaccWorker
bool cmp_less = cell->type.in(ID($lt), ID($le));
bool cmp_equal = cell->type.in(ID($le), ID($ge));
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
@@ -439,7 +439,7 @@ struct AlumaccWorker
for (auto cell : eq_cells)
{
bool cmp_equal = cell->type.in(ID($eq), ID($eqx));
- bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
@@ -495,11 +495,11 @@ struct AlumaccWorker
n->alu_cell->setPort(ID::A, n->a);
n->alu_cell->setPort(ID::B, n->b);
- n->alu_cell->setPort(ID(CI), GetSize(n->c) ? n->c : State::S0);
- n->alu_cell->setPort(ID(BI), n->invert_b ? State::S1 : State::S0);
+ n->alu_cell->setPort(ID::CI, GetSize(n->c) ? n->c : State::S0);
+ n->alu_cell->setPort(ID::BI, n->invert_b ? State::S1 : State::S0);
n->alu_cell->setPort(ID::Y, n->y);
- n->alu_cell->setPort(ID(X), module->addWire(NEW_ID, GetSize(n->y)));
- n->alu_cell->setPort(ID(CO), module->addWire(NEW_ID, GetSize(n->y)));
+ n->alu_cell->setPort(ID::X, module->addWire(NEW_ID, GetSize(n->y)));
+ n->alu_cell->setPort(ID::CO, module->addWire(NEW_ID, GetSize(n->y)));
n->alu_cell->fixup_parameters(n->is_signed, n->is_signed);
for (auto &it : n->cmp)
diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc
index b9cd68883..3f4b6aa66 100644
--- a/passes/techmap/clkbufmap.cc
+++ b/passes/techmap/clkbufmap.cc
@@ -129,13 +129,13 @@ struct ClkbufmapPass : public Pass {
if (module->get_blackbox_attribute()) {
for (auto port : module->ports) {
auto wire = module->wire(port);
- if (wire->get_bool_attribute("\\clkbuf_driver"))
+ if (wire->get_bool_attribute(ID::clkbuf_driver))
for (int i = 0; i < GetSize(wire); i++)
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
- if (wire->get_bool_attribute("\\clkbuf_sink"))
+ if (wire->get_bool_attribute(ID::clkbuf_sink))
for (int i = 0; i < GetSize(wire); i++)
sink_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
- auto it = wire->attributes.find("\\clkbuf_inv");
+ auto it = wire->attributes.find(ID::clkbuf_inv);
if (it != wire->attributes.end()) {
IdString in_name = RTLIL::escape_id(it->second.decode_string());
for (int i = 0; i < GetSize(wire); i++) {
@@ -215,7 +215,7 @@ struct ClkbufmapPass : public Pass {
if (wire->port_input && wire->port_output)
continue;
bool process_wire = module->selected(wire);
- if (!select && wire->get_bool_attribute("\\clkbuf_inhibit"))
+ if (!select && wire->get_bool_attribute(ID::clkbuf_inhibit))
process_wire = false;
if (!process_wire) {
// This wire is supposed to be bypassed, so make sure we don't buffer it in
@@ -238,7 +238,7 @@ struct ClkbufmapPass : public Pass {
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
} else if (!sink_wire_bits.count(mapped_wire_bit)) {
// Nothing to do.
- } else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute("\\top"))) {
+ } else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute(ID::top))) {
// Clock network not yet buffered, driven by one of
// our cells or a top-level input -- buffer it.
@@ -247,7 +247,7 @@ struct ClkbufmapPass : public Pass {
Wire *iwire = module->addWire(NEW_ID);
cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit);
cell->setPort(RTLIL::escape_id(buf_portname2), iwire);
- if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute("\\top")) {
+ if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top)) {
log("Inserting %s on %s.%s[%d].\n", inpad_celltype.c_str(), log_id(module), log_id(wire), i);
RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype));
cell2->setPort(RTLIL::escape_id(inpad_portname), iwire);
diff --git a/passes/techmap/deminout.cc b/passes/techmap/deminout.cc
index 35d43b106..a7dce9c81 100644
--- a/passes/techmap/deminout.cc
+++ b/passes/techmap/deminout.cc
@@ -113,7 +113,7 @@ struct DeminoutPass : public Pass {
{
if (bits_numports[bit] > 1 || bits_inout.count(bit))
new_input = true, new_output = true;
- if (bit == State::S0 || bit == State::S1)
+ if (!bit.wire)
new_output = true;
if (bits_written.count(bit)) {
new_output = true;
diff --git a/passes/techmap/dff2dffe.cc b/passes/techmap/dff2dffe.cc
index 0242256e5..aa9bbfe17 100644
--- a/passes/techmap/dff2dffe.cc
+++ b/passes/techmap/dff2dffe.cc
@@ -88,7 +88,7 @@ struct Dff2dffeWorker
cell_int_t mux_cell_int = bit2mux.at(d);
RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID::A));
RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID::B));
- RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID(S)));
+ RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID::S));
int width = GetSize(sig_a), index = mux_cell_int.second;
for (int i = 0; i < GetSize(sig_s); i++)
@@ -185,8 +185,8 @@ struct Dff2dffeWorker
void handle_dff_cell(RTLIL::Cell *dff_cell)
{
- RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID(D)));
- RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID(Q)));
+ RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID::D));
+ RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID::Q));
std::map<patterns_t, std::set<int>> grouped_patterns;
std::set<int> remaining_indices;
@@ -208,15 +208,15 @@ struct Dff2dffeWorker
}
if (!direct_dict.empty()) {
log(" converting %s cell %s to %s for %s -> %s.\n", log_id(dff_cell->type), log_id(dff_cell), log_id(direct_dict.at(dff_cell->type)), log_signal(new_sig_d), log_signal(new_sig_q));
- dff_cell->setPort(ID(E), make_patterns_logic(it.first, true));
+ dff_cell->setPort(ID::E, make_patterns_logic(it.first, true));
dff_cell->type = direct_dict.at(dff_cell->type);
} else
if (dff_cell->type == ID($dff)) {
- RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID(CLK)), make_patterns_logic(it.first, false),
- new_sig_d, new_sig_q, dff_cell->getParam(ID(CLK_POLARITY)).as_bool(), true);
+ RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID::CLK), make_patterns_logic(it.first, false),
+ new_sig_d, new_sig_q, dff_cell->getParam(ID::CLK_POLARITY).as_bool(), true);
log(" created $dffe cell %s for %s -> %s.\n", log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
} else {
- RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID(C)), make_patterns_logic(it.first, true),
+ RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID::C), make_patterns_logic(it.first, true),
new_sig_d, new_sig_q, dff_cell->type == ID($_DFF_P_), true);
log(" created %s cell %s for %s -> %s.\n", log_id(new_cell->type), log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
}
@@ -235,9 +235,9 @@ struct Dff2dffeWorker
new_sig_d.append(sig_d[i]);
new_sig_q.append(sig_q[i]);
}
- dff_cell->setPort(ID(D), new_sig_d);
- dff_cell->setPort(ID(Q), new_sig_q);
- dff_cell->setParam(ID(WIDTH), GetSize(remaining_indices));
+ dff_cell->setPort(ID::D, new_sig_d);
+ dff_cell->setPort(ID::Q, new_sig_q);
+ dff_cell->setParam(ID::WIDTH, GetSize(remaining_indices));
}
}
@@ -361,19 +361,19 @@ struct Dff2dffePass : public Pass {
for (auto cell_other : mod->selected_cells()) {
if (cell_other->type != cell->type)
continue;
- if (sigmap(cell->getPort(ID(EN))) == sigmap(cell_other->getPort(ID(EN))))
+ if (sigmap(cell->getPort(ID::EN)) == sigmap(cell_other->getPort(ID::EN)))
ce_use++;
}
if (ce_use >= min_ce_use)
continue;
}
- RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID(D))));
- mod->addDff(NEW_ID, cell->getPort(ID(CLK)), tmp, cell->getPort(ID(Q)), cell->getParam(ID(CLK_POLARITY)).as_bool());
- if (cell->getParam(ID(EN_POLARITY)).as_bool())
- mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(EN)), tmp);
+ RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID::D)));
+ mod->addDff(NEW_ID, cell->getPort(ID::CLK), tmp, cell->getPort(ID::Q), cell->getParam(ID::CLK_POLARITY).as_bool());
+ if (cell->getParam(ID::EN_POLARITY).as_bool())
+ mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::EN), tmp);
else
- mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(EN)), tmp);
+ mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::EN), tmp);
mod->remove(cell);
continue;
}
@@ -383,7 +383,7 @@ struct Dff2dffePass : public Pass {
for (auto cell_other : mod->selected_cells()) {
if (cell_other->type != cell->type)
continue;
- if (sigmap(cell->getPort(ID(E))) == sigmap(cell_other->getPort(ID(E))))
+ if (sigmap(cell->getPort(ID::E)) == sigmap(cell_other->getPort(ID::E)))
ce_use++;
}
if (ce_use >= min_ce_use)
@@ -393,11 +393,11 @@ struct Dff2dffePass : public Pass {
bool clk_pol = cell->type.compare(7, 1, "P") == 0;
bool en_pol = cell->type.compare(8, 1, "P") == 0;
RTLIL::SigSpec tmp = mod->addWire(NEW_ID);
- mod->addDff(NEW_ID, cell->getPort(ID(C)), tmp, cell->getPort(ID(Q)), clk_pol);
+ mod->addDff(NEW_ID, cell->getPort(ID::C), tmp, cell->getPort(ID::Q), clk_pol);
if (en_pol)
- mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(E)), tmp);
+ mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::E), tmp);
else
- mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(E)), tmp);
+ mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::E), tmp);
mod->remove(cell);
continue;
}
diff --git a/passes/techmap/dff2dffs.cc b/passes/techmap/dff2dffs.cc
index 3fa1ed5cf..c155297d9 100644
--- a/passes/techmap/dff2dffs.cc
+++ b/passes/techmap/dff2dffs.cc
@@ -90,7 +90,7 @@ struct Dff2dffsPass : public Pass {
for (auto cell : ff_cells)
{
- SigSpec sig_d = cell->getPort(ID(D));
+ SigSpec sig_d = cell->getPort(ID::D);
if (GetSize(sig_d) < 1)
continue;
@@ -103,7 +103,7 @@ struct Dff2dffsPass : public Pass {
Cell *mux_cell = sr_muxes.at(bit_d);
SigBit bit_a = sigmap(mux_cell->getPort(ID::A));
SigBit bit_b = sigmap(mux_cell->getPort(ID::B));
- SigBit bit_s = sigmap(mux_cell->getPort(ID(S)));
+ SigBit bit_s = sigmap(mux_cell->getPort(ID::S));
SigBit sr_val, sr_sig;
bool invert_sr;
@@ -120,9 +120,9 @@ struct Dff2dffsPass : public Pass {
}
if (match_init) {
- SigBit bit_q = cell->getPort(ID(Q));
+ SigBit bit_q = cell->getPort(ID::Q);
if (bit_q.wire) {
- auto it = bit_q.wire->attributes.find(ID(init));
+ auto it = bit_q.wire->attributes.find(ID::init);
if (it != bit_q.wire->attributes.end()) {
auto init_val = it->second[bit_q.offset];
if (init_val == State::S1 && sr_val != State::S1)
@@ -155,8 +155,8 @@ struct Dff2dffsPass : public Pass {
else cell->type = ID($__DFFS_PP0_);
}
}
- cell->setPort(ID(R), sr_sig);
- cell->setPort(ID(D), bit_d);
+ cell->setPort(ID::R, sr_sig);
+ cell->setPort(ID::D, bit_d);
}
}
}
diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc
index cf9301442..35645582b 100644
--- a/passes/techmap/dffinit.cc
+++ b/passes/techmap/dffinit.cc
@@ -99,8 +99,8 @@ struct DffinitPass : public Pass {
pool<SigBit> used_bits;
for (auto wire : module->selected_wires()) {
- if (wire->attributes.count(ID(init))) {
- Const value = wire->attributes.at(ID(init));
+ if (wire->attributes.count(ID::init)) {
+ Const value = wire->attributes.at(ID::init);
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++)
if (value[i] != State::Sx)
init_bits[sigmap(SigBit(wire, i))] = value[i];
@@ -154,15 +154,17 @@ struct DffinitPass : public Pass {
value = Const(low_string);
}
- log("Setting %s.%s.%s (port=%s, net=%s) to %s.\n", log_id(module), log_id(cell), log_id(it.second),
- log_id(it.first), log_signal(sig), log_signal(value));
- cell->setParam(it.second, value);
+ if (value.size() != 0) {
+ log("Setting %s.%s.%s (port=%s, net=%s) to %s.\n", log_id(module), log_id(cell), log_id(it.second),
+ log_id(it.first), log_signal(sig), log_signal(value));
+ cell->setParam(it.second, value);
+ }
}
}
for (auto wire : module->selected_wires())
- if (wire->attributes.count(ID(init))) {
- Const &value = wire->attributes.at(ID(init));
+ if (wire->attributes.count(ID::init)) {
+ Const &value = wire->attributes.at(ID::init);
bool do_cleanup = true;
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) {
SigBit bit = sigmap(SigBit(wire, i));
@@ -173,7 +175,7 @@ struct DffinitPass : public Pass {
}
if (do_cleanup) {
log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire));
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
}
}
}
diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc
index b15109cd3..aa344cf8a 100644
--- a/passes/techmap/dfflibmap.cc
+++ b/passes/techmap/dfflibmap.cc
@@ -78,7 +78,7 @@ static void logmap_all()
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
{
- if (cell == NULL || attr == NULL || attr->value.empty())
+ if (cell == nullptr || attr == nullptr || attr->value.empty())
return false;
std::string value = attr->value;
@@ -117,7 +117,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name,
static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode)
{
- LibertyAst *best_cell = NULL;
+ LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
int best_cell_pins = 0;
bool best_cell_noninv = false;
@@ -132,11 +132,11 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
continue;
LibertyAst *dn = cell->find("dont_use");
- if (dn != NULL && dn->value == "true")
+ if (dn != nullptr && dn->value == "true")
continue;
LibertyAst *ff = cell->find("ff");
- if (ff == NULL)
+ if (ff == nullptr)
continue;
std::string cell_clk_pin, cell_rst_pin, cell_next_pin;
@@ -163,7 +163,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
double area = 0;
LibertyAst *ar = cell->find("area");
- if (ar != NULL && !ar->value.empty())
+ if (ar != nullptr && !ar->value.empty())
area = atof(ar->value.c_str());
int num_pins = 0;
@@ -175,7 +175,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
continue;
LibertyAst *dir = pin->find("direction");
- if (dir == NULL || dir->value == "internal")
+ if (dir == nullptr || dir->value == "internal")
continue;
num_pins++;
@@ -183,7 +183,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
goto continue_cell_loop;
LibertyAst *func = pin->find("function");
- if (dir->value == "output" && func != NULL) {
+ if (dir->value == "output" && func != nullptr) {
std::string value = func->value;
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
value.erase(pos, 1);
@@ -205,10 +205,10 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
this_cell_ports[pin->args[0]] = 0;
}
- if (!found_output || (best_cell != NULL && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
+ if (!found_output || (best_cell != nullptr && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
continue;
- if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
+ if (best_cell != nullptr && num_pins == best_cell_pins && area > best_cell_area)
continue;
best_cell = cell;
@@ -219,7 +219,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
continue_cell_loop:;
}
- if (best_cell != NULL) {
+ if (best_cell != nullptr) {
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
if (prepare_mode) {
@@ -238,7 +238,7 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode)
{
- LibertyAst *best_cell = NULL;
+ LibertyAst *best_cell = nullptr;
std::map<std::string, char> best_cell_ports;
int best_cell_pins = 0;
bool best_cell_noninv = false;
@@ -253,11 +253,11 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
continue;
LibertyAst *dn = cell->find("dont_use");
- if (dn != NULL && dn->value == "true")
+ if (dn != nullptr && dn->value == "true")
continue;
LibertyAst *ff = cell->find("ff");
- if (ff == NULL)
+ if (ff == nullptr)
continue;
std::string cell_clk_pin, cell_set_pin, cell_clr_pin, cell_next_pin;
@@ -280,7 +280,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
double area = 0;
LibertyAst *ar = cell->find("area");
- if (ar != NULL && !ar->value.empty())
+ if (ar != nullptr && !ar->value.empty())
area = atof(ar->value.c_str());
int num_pins = 0;
@@ -292,7 +292,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
continue;
LibertyAst *dir = pin->find("direction");
- if (dir == NULL || dir->value == "internal")
+ if (dir == nullptr || dir->value == "internal")
continue;
num_pins++;
@@ -300,7 +300,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
goto continue_cell_loop;
LibertyAst *func = pin->find("function");
- if (dir->value == "output" && func != NULL) {
+ if (dir->value == "output" && func != nullptr) {
std::string value = func->value;
for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
value.erase(pos, 1);
@@ -322,10 +322,10 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
this_cell_ports[pin->args[0]] = 0;
}
- if (!found_output || (best_cell != NULL && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
+ if (!found_output || (best_cell != nullptr && (num_pins > best_cell_pins || (best_cell_noninv && !found_noninv_output))))
continue;
- if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
+ if (best_cell != nullptr && num_pins == best_cell_pins && area > best_cell_area)
continue;
best_cell = cell;
@@ -336,7 +336,7 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
continue_cell_loop:;
}
- if (best_cell != NULL) {
+ if (best_cell != nullptr) {
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
if (prepare_mode) {
@@ -481,11 +481,11 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
SigMap sigmap(module);
std::vector<RTLIL::Cell*> cell_list;
- for (auto &it : module->cells_) {
- if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0)
- cell_list.push_back(it.second);
- if (it.second->type == ID($_NOT_))
- notmap[sigmap(it.second->getPort(ID::A))].insert(it.second);
+ for (auto cell : module->cells()) {
+ if (design->selected(module, cell) && cell_mappings.count(cell->type) > 0)
+ cell_list.push_back(cell);
+ if (cell->type == ID($_NOT_))
+ notmap[sigmap(cell->getPort(ID::A))].insert(cell);
}
std::map<std::string, int> stats;
@@ -663,9 +663,9 @@ struct DfflibmapPass : public Pass {
log(" final dff cell mappings:\n");
logmap_all();
- for (auto &it : design->modules_)
- if (design->selected(it.second) && !it.second->get_blackbox_attribute())
- dfflibmap(design, it.second, prepare_mode);
+ for (auto module : design->selected_modules())
+ if (!module->get_blackbox_attribute())
+ dfflibmap(design, module, prepare_mode);
cell_mappings.clear();
}
diff --git a/passes/techmap/dffsr2dff.cc b/passes/techmap/dffsr2dff.cc
deleted file mode 100644
index 61b06fdc1..000000000
--- a/passes/techmap/dffsr2dff.cc
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * yosys -- Yosys Open SYnthesis Suite
- *
- * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "kernel/yosys.h"
-#include "kernel/sigtools.h"
-
-USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
-
-void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
-{
- if (cell->type == ID($dffsr))
- {
- int width = cell->getParam(ID(WIDTH)).as_int();
- bool setpol = cell->getParam(ID(SET_POLARITY)).as_bool();
- bool clrpol = cell->getParam(ID(CLR_POLARITY)).as_bool();
-
- SigBit setunused = setpol ? State::S0 : State::S1;
- SigBit clrunused = clrpol ? State::S0 : State::S1;
-
- SigSpec setsig = sigmap(cell->getPort(ID(SET)));
- SigSpec clrsig = sigmap(cell->getPort(ID(CLR)));
-
- Const reset_val;
- SigSpec setctrl, clrctrl;
-
- for (int i = 0; i < width; i++)
- {
- SigBit setbit = setsig[i], clrbit = clrsig[i];
-
- if (setbit == setunused) {
- clrctrl.append(clrbit);
- reset_val.bits.push_back(State::S0);
- continue;
- }
-
- if (clrbit == clrunused) {
- setctrl.append(setbit);
- reset_val.bits.push_back(State::S1);
- continue;
- }
-
- return;
- }
-
- setctrl.sort_and_unify();
- clrctrl.sort_and_unify();
-
- if (GetSize(setctrl) > 1 || GetSize(clrctrl) > 1)
- return;
-
- if (GetSize(setctrl) == 0 && GetSize(clrctrl) == 0)
- return;
-
- if (GetSize(setctrl) == 1 && GetSize(clrctrl) == 1) {
- if (setpol != clrpol)
- return;
- if (setctrl != clrctrl)
- return;
- }
-
- log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));
-
- if (GetSize(setctrl) == 1) {
- cell->setPort(ID(ARST), setctrl);
- cell->setParam(ID(ARST_POLARITY), setpol);
- } else {
- cell->setPort(ID(ARST), clrctrl);
- cell->setParam(ID(ARST_POLARITY), clrpol);
- }
-
- cell->type = ID($adff);
- cell->unsetPort(ID(SET));
- cell->unsetPort(ID(CLR));
- cell->setParam(ID(ARST_VALUE), reset_val);
- cell->unsetParam(ID(SET_POLARITY));
- cell->unsetParam(ID(CLR_POLARITY));
-
- return;
- }
-
- if (cell->type.in(ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
- ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
- {
- char clkpol = cell->type.c_str()[8];
- char setpol = cell->type.c_str()[9];
- char clrpol = cell->type.c_str()[10];
-
- SigBit setbit = sigmap(cell->getPort(ID(S)));
- SigBit clrbit = sigmap(cell->getPort(ID(R)));
-
- SigBit setunused = setpol == 'P' ? State::S0 : State::S1;
- SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1;
-
- IdString oldtype = cell->type;
-
- if (setbit == setunused) {
- cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol);
- cell->unsetPort(ID(S));
- goto converted_gate;
- }
-
- if (clrbit == clrunused) {
- cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol);
- cell->setPort(ID(R), cell->getPort(ID(S)));
- cell->unsetPort(ID(S));
- goto converted_gate;
- }
-
- return;
-
- converted_gate:
- log("Converting %s cell %s.%s to %s.\n", log_id(oldtype), log_id(module), log_id(cell), log_id(cell->type));
- return;
- }
-}
-
-void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
-{
- if (cell->type == ID($adff))
- {
- bool rstpol = cell->getParam(ID(ARST_POLARITY)).as_bool();
- SigBit rstunused = rstpol ? State::S0 : State::S1;
- SigSpec rstsig = sigmap(cell->getPort(ID(ARST)));
-
- if (rstsig != rstunused)
- return;
-
- log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell));
-
- cell->type = ID($dff);
- cell->unsetPort(ID(ARST));
- cell->unsetParam(ID(ARST_VALUE));
- cell->unsetParam(ID(ARST_POLARITY));
-
- return;
- }
-
- if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
- ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)))
- {
- char clkpol = cell->type.c_str()[6];
- char rstpol = cell->type.c_str()[7];
-
- SigBit rstbit = sigmap(cell->getPort(ID(R)));
- SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1;
-
- if (rstbit != rstunused)
- return;
-
- IdString newtype = stringf("$_DFF_%c_", clkpol);
- log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype));
-
- cell->type = newtype;
- cell->unsetPort(ID(R));
-
- return;
- }
-}
-
-struct Dffsr2dffPass : public Pass {
- Dffsr2dffPass() : Pass("dffsr2dff", "convert DFFSR cells to simpler FF cell types") { }
- void help() YS_OVERRIDE
- {
- // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
- log("\n");
- log(" dffsr2dff [options] [selection]\n");
- log("\n");
- log("This pass converts DFFSR cells ($dffsr, $_DFFSR_???_) and ADFF cells ($adff,\n");
- log("$_DFF_???_) to simpler FF cell types when any of the set/reset inputs is unused.\n");
- log("\n");
- }
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
- {
- log_header(design, "Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs).\n");
-
- size_t argidx;
- for (argidx = 1; argidx < args.size(); argidx++)
- {
- // if (args[argidx] == "-v") {
- // continue;
- // }
- break;
- }
- extra_args(args, argidx, design);
-
- for (auto module : design->selected_modules()) {
- SigMap sigmap(module);
- for (auto cell : module->selected_cells()) {
- dffsr_worker(sigmap, module, cell);
- adff_worker(sigmap, module, cell);
- }
- }
- }
-} Dffsr2dffPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/passes/techmap/extract.cc b/passes/techmap/extract.cc
index f8798eea5..f29044790 100644
--- a/passes/techmap/extract.cc
+++ b/passes/techmap/extract.cc
@@ -29,8 +29,6 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-using RTLIL::id2cstr;
-
class SubCircuitSolver : public SubCircuit::Solver
{
public:
@@ -58,36 +56,36 @@ public:
return value;
#define param_bool(_n) if (param == _n) return value.as_bool();
- param_bool(ID(ARST_POLARITY));
- param_bool(ID(A_SIGNED));
- param_bool(ID(B_SIGNED));
- param_bool(ID(CLK_ENABLE));
- param_bool(ID(CLK_POLARITY));
- param_bool(ID(CLR_POLARITY));
- param_bool(ID(EN_POLARITY));
- param_bool(ID(SET_POLARITY));
- param_bool(ID(TRANSPARENT));
+ param_bool(ID::ARST_POLARITY);
+ param_bool(ID::A_SIGNED);
+ param_bool(ID::B_SIGNED);
+ param_bool(ID::CLK_ENABLE);
+ param_bool(ID::CLK_POLARITY);
+ param_bool(ID::CLR_POLARITY);
+ param_bool(ID::EN_POLARITY);
+ param_bool(ID::SET_POLARITY);
+ param_bool(ID::TRANSPARENT);
#undef param_bool
#define param_int(_n) if (param == _n) return value.as_int();
- param_int(ID(ABITS))
- param_int(ID(A_WIDTH))
- param_int(ID(B_WIDTH))
- param_int(ID(CTRL_IN_WIDTH))
- param_int(ID(CTRL_OUT_WIDTH))
- param_int(ID(OFFSET))
- param_int(ID(PRIORITY))
- param_int(ID(RD_PORTS))
- param_int(ID(SIZE))
- param_int(ID(STATE_BITS))
- param_int(ID(STATE_NUM))
- param_int(ID(STATE_NUM_LOG2))
- param_int(ID(STATE_RST))
- param_int(ID(S_WIDTH))
- param_int(ID(TRANS_NUM))
- param_int(ID(WIDTH))
- param_int(ID(WR_PORTS))
- param_int(ID(Y_WIDTH))
+ param_int(ID::ABITS)
+ param_int(ID::A_WIDTH)
+ param_int(ID::B_WIDTH)
+ param_int(ID::CTRL_IN_WIDTH)
+ param_int(ID::CTRL_OUT_WIDTH)
+ param_int(ID::OFFSET)
+ param_int(ID::PRIORITY)
+ param_int(ID::RD_PORTS)
+ param_int(ID::SIZE)
+ param_int(ID::STATE_BITS)
+ param_int(ID::STATE_NUM)
+ param_int(ID::STATE_NUM_LOG2)
+ param_int(ID::STATE_RST)
+ param_int(ID::S_WIDTH)
+ param_int(ID::TRANS_NUM)
+ param_int(ID::WIDTH)
+ param_int(ID::WR_PORTS)
+ param_int(ID::Y_WIDTH)
#undef param_int
return value;
@@ -121,8 +119,8 @@ public:
if (wire_attr.size() > 0)
{
- RTLIL::Wire *lastNeedleWire = NULL;
- RTLIL::Wire *lastHaystackWire = NULL;
+ RTLIL::Wire *lastNeedleWire = nullptr;
+ RTLIL::Wire *lastHaystackWire = nullptr;
dict<RTLIL::IdString, RTLIL::Const> emptyAttr;
for (auto &conn : needleCell->connections())
@@ -149,27 +147,27 @@ struct bit_ref_t {
int bit;
};
-bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, RTLIL::Design *sel = NULL,
- int max_fanout = -1, std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> *split = NULL)
+bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, RTLIL::Design *sel = nullptr,
+ int max_fanout = -1, std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> *split = nullptr)
{
SigMap sigmap(mod);
std::map<RTLIL::SigBit, bit_ref_t> sig_bit_ref;
if (sel && !sel->selected(mod)) {
- log(" Skipping module %s as it is not selected.\n", id2cstr(mod->name));
+ log(" Skipping module %s as it is not selected.\n", log_id(mod->name));
return false;
}
if (mod->processes.size() > 0) {
- log(" Skipping module %s as it contains unprocessed processes.\n", id2cstr(mod->name));
+ log(" Skipping module %s as it contains unprocessed processes.\n", log_id(mod->name));
return false;
}
if (constports) {
- graph.createNode("$const$0", "$const$0", NULL, true);
- graph.createNode("$const$1", "$const$1", NULL, true);
- graph.createNode("$const$x", "$const$x", NULL, true);
- graph.createNode("$const$z", "$const$z", NULL, true);
+ graph.createNode("$const$0", "$const$0", nullptr, true);
+ graph.createNode("$const$1", "$const$1", nullptr, true);
+ graph.createNode("$const$x", "$const$x", nullptr, true);
+ graph.createNode("$const$z", "$const$z", nullptr, true);
graph.createPort("$const$0", "\\Y", 1);
graph.createPort("$const$1", "\\Y", 1);
graph.createPort("$const$x", "\\Y", 1);
@@ -182,28 +180,26 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
std::map<std::pair<RTLIL::Wire*, int>, int> sig_use_count;
if (max_fanout > 0)
- for (auto &cell_it : mod->cells_)
+ for (auto cell : mod->cells())
{
- RTLIL::Cell *cell = cell_it.second;
if (!sel || sel->selected(mod, cell))
for (auto &conn : cell->connections()) {
RTLIL::SigSpec conn_sig = conn.second;
sigmap.apply(conn_sig);
for (auto &bit : conn_sig)
- if (bit.wire != NULL)
+ if (bit.wire != nullptr)
sig_use_count[std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset)]++;
}
}
// create graph nodes from cells
- for (auto &cell_it : mod->cells_)
+ for (auto cell : mod->cells())
{
- RTLIL::Cell *cell = cell_it.second;
if (sel && !sel->selected(mod, cell))
continue;
std::string type = cell->type.str();
- if (sel == NULL && type.compare(0, 2, "\\$") == 0)
+ if (sel == nullptr && type.compare(0, 2, "\\$") == 0)
type = type.substr(1);
graph.createNode(cell->name.str(), type, (void*)cell);
@@ -221,7 +217,7 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
{
auto &bit = conn_sig[i];
- if (bit.wire == NULL) {
+ if (bit.wire == nullptr) {
if (constports) {
std::string node = "$const$x";
if (bit == RTLIL::State::S0) node = "$const$0";
@@ -253,9 +249,8 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
}
// mark external signals (used in non-selected cells)
- for (auto &cell_it : mod->cells_)
+ for (auto cell : mod->cells())
{
- RTLIL::Cell *cell = cell_it.second;
if (sel && !sel->selected(mod, cell))
for (auto &conn : cell->connections())
{
@@ -271,9 +266,8 @@ bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports,
}
// mark external signals (used in module ports)
- for (auto &wire_it : mod->wires_)
+ for (auto wire : mod->wires())
{
- RTLIL::Wire *wire = wire_it.second;
if (wire->port_id > 0)
{
RTLIL::SigSpec conn_sig(wire);
@@ -300,8 +294,7 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), autoidx++), needle->name);
// create cell ports
- for (auto &it : needle->wires_) {
- RTLIL::Wire *wire = it.second;
+ for (auto wire : needle->wires()) {
if (wire->port_id > 0) {
for (int i = 0; i < wire->width; i++)
sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<RTLIL::IdString, int>(wire->name, i));
@@ -316,7 +309,7 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
RTLIL::Cell *needle_cell = (RTLIL::Cell*)mapping.needleUserData;
RTLIL::Cell *haystack_cell = (RTLIL::Cell*)mapping.haystackUserData;
- if (needle_cell == NULL)
+ if (needle_cell == nullptr)
continue;
for (auto &conn : needle_cell->connections()) {
@@ -341,10 +334,10 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right)
{
int left_idx = 0, right_idx = 0;
- if (left->attributes.count(ID(extract_order)) > 0)
- left_idx = left->attributes.at(ID(extract_order)).as_int();
- if (right->attributes.count(ID(extract_order)) > 0)
- right_idx = right->attributes.at(ID(extract_order)).as_int();
+ if (left->attributes.count(ID::extract_order) > 0)
+ left_idx = left->attributes.at(ID::extract_order).as_int();
+ if (right->attributes.count(ID::extract_order) > 0)
+ right_idx = right->attributes.at(ID::extract_order).as_int();
if (left_idx != right_idx)
return left_idx < right_idx;
return left->name < right->name;
@@ -587,7 +580,7 @@ struct ExtractPass : public Pass {
if (map_filenames.empty() && mine_outfile.empty())
log_cmd_error("Missing option -map <verilog_or_ilang_file> or -mine <output_ilang_file>.\n");
- RTLIL::Design *map = NULL;
+ RTLIL::Design *map = nullptr;
if (!mine_mode)
{
@@ -630,24 +623,24 @@ struct ExtractPass : public Pass {
log_header(design, "Creating graphs for SubCircuit library.\n");
if (!mine_mode)
- for (auto &mod_it : map->modules_) {
+ for (auto module : map->modules()) {
SubCircuit::Graph mod_graph;
- std::string graph_name = "needle_" + RTLIL::unescape_id(mod_it.first);
+ std::string graph_name = "needle_" + RTLIL::unescape_id(module->name);
log("Creating needle graph %s.\n", graph_name.c_str());
- if (module2graph(mod_graph, mod_it.second, constports)) {
+ if (module2graph(mod_graph, module, constports)) {
solver.addGraph(graph_name, mod_graph);
- needle_map[graph_name] = mod_it.second;
- needle_list.push_back(mod_it.second);
+ needle_map[graph_name] = module;
+ needle_list.push_back(module);
}
}
- for (auto &mod_it : design->modules_) {
+ for (auto module : design->modules()) {
SubCircuit::Graph mod_graph;
- std::string graph_name = "haystack_" + RTLIL::unescape_id(mod_it.first);
+ std::string graph_name = "haystack_" + RTLIL::unescape_id(module->name);
log("Creating haystack graph %s.\n", graph_name.c_str());
- if (module2graph(mod_graph, mod_it.second, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : NULL)) {
+ if (module2graph(mod_graph, module, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : nullptr)) {
solver.addGraph(graph_name, mod_graph);
- haystack_map[graph_name] = mod_it.second;
+ haystack_map[graph_name] = module;
}
}
@@ -680,7 +673,7 @@ struct ExtractPass : public Pass {
}
RTLIL::Cell *new_cell = replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result);
design->select(haystack_map.at(result.haystackGraphId), new_cell);
- log(" new cell: %s\n", id2cstr(new_cell->name));
+ log(" new cell: %s\n", log_id(new_cell->name));
}
}
}
@@ -697,12 +690,12 @@ struct ExtractPass : public Pass {
for (auto &result: results)
{
log("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits);
- log(" primary match in %s:", id2cstr(haystack_map.at(result.graphId)->name));
+ log(" primary match in %s:", log_id(haystack_map.at(result.graphId)->name));
for (auto &node : result.nodes)
log(" %s", RTLIL::unescape_id(node.nodeId).c_str());
log("\n");
for (auto &it : result.matchesPerGraph)
- log(" matches in %s: %d\n", id2cstr(haystack_map.at(it.first)->name), it.second);
+ log(" matches in %s: %d\n", log_id(haystack_map.at(it.first)->name), it.second);
RTLIL::Module *mod = haystack_map.at(result.graphId);
std::set<RTLIL::Cell*> cells;
@@ -717,12 +710,12 @@ struct ExtractPass : public Pass {
for (auto &conn : cell->connections()) {
RTLIL::SigSpec sig = sigmap(conn.second);
for (auto &chunk : sig.chunks())
- if (chunk.wire != NULL)
+ if (chunk.wire != nullptr)
wires.insert(chunk.wire);
}
RTLIL::Module *newMod = new RTLIL::Module;
- newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, id2cstr(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits);
+ newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, log_id(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits);
map->add(newMod);
for (auto wire : wires) {
@@ -739,8 +732,8 @@ struct ExtractPass : public Pass {
for (auto &conn : cell->connections()) {
std::vector<SigChunk> chunks = sigmap(conn.second);
for (auto &chunk : chunks)
- if (chunk.wire != NULL)
- chunk.wire = newMod->wires_.at(chunk.wire->name);
+ if (chunk.wire != nullptr)
+ chunk.wire = newMod->wire(chunk.wire->name);
newCell->setPort(conn.first, chunks);
}
}
diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc
index 639ae145b..68b338143 100644
--- a/passes/techmap/extract_counter.cc
+++ b/passes/techmap/extract_counter.cc
@@ -131,23 +131,23 @@ int counter_tryextract(
SigMap& sigmap = index.sigmap;
//Both inputs must be unsigned, so don't extract anything with a signed input
- bool a_sign = cell->getParam(ID(A_SIGNED)).as_bool();
- bool b_sign = cell->getParam(ID(B_SIGNED)).as_bool();
+ bool a_sign = cell->getParam(ID::A_SIGNED).as_bool();
+ bool b_sign = cell->getParam(ID::B_SIGNED).as_bool();
if(a_sign || b_sign)
return 3;
//CO and X must be unconnected (exactly one connection to each port)
- if(!is_unconnected(sigmap(cell->getPort(ID(CO))), index))
+ if(!is_unconnected(sigmap(cell->getPort(ID::CO)), index))
return 7;
- if(!is_unconnected(sigmap(cell->getPort(ID(X))), index))
+ if(!is_unconnected(sigmap(cell->getPort(ID::X)), index))
return 8;
//true if $alu is performing A - B, else A + B
bool alu_is_subtract;
//BI and CI must be both constant 0 or both constant 1 as well
- const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(BI)));
- const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(CI)));
+ const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID::BI));
+ const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID::CI));
if(bi_port.is_fully_const() && bi_port.as_int() == 1 &&
ci_port.is_fully_const() && ci_port.as_int() == 1)
{
@@ -169,8 +169,8 @@ int counter_tryextract(
if(alu_is_subtract)
{
- const int a_width = cell->getParam(ID(A_WIDTH)).as_int();
- const int b_width = cell->getParam(ID(B_WIDTH)).as_int();
+ const int a_width = cell->getParam(ID::A_WIDTH).as_int();
+ const int b_width = cell->getParam(ID::B_WIDTH).as_int();
const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
// down, cnt <= cnt - 1
@@ -197,8 +197,8 @@ int counter_tryextract(
}
else
{
- const int a_width = cell->getParam(ID(A_WIDTH)).as_int();
- const int b_width = cell->getParam(ID(B_WIDTH)).as_int();
+ const int a_width = cell->getParam(ID::A_WIDTH).as_int();
+ const int b_width = cell->getParam(ID::B_WIDTH).as_int();
const RTLIL::SigSpec a_port = sigmap(cell->getPort(ID::A));
const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
@@ -245,9 +245,9 @@ int counter_tryextract(
//Check if counter is an appropriate size
int count_width;
if (alu_port_use_a)
- count_width = cell->getParam(ID(A_WIDTH)).as_int();
+ count_width = cell->getParam(ID::A_WIDTH).as_int();
else
- count_width = cell->getParam(ID(B_WIDTH)).as_int();
+ count_width = cell->getParam(ID::B_WIDTH).as_int();
extract.width = count_width;
if( (count_width < settings.minwidth) || (count_width > settings.maxwidth) )
return 1;
@@ -283,7 +283,7 @@ int counter_tryextract(
//S connection of the mux must come from an inverter if down, eq if up
//(need not be the only load)
- const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID(S)));
+ const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID::S));
extract.outsig = muxsel;
pool<Cell*> muxsel_conns = get_other_cells(muxsel, index, count_mux);
Cell* overflow_cell = NULL;
@@ -293,7 +293,7 @@ int counter_tryextract(
continue;
if(!extract.count_is_up && c->type != ID($logic_not))
continue;
- if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID(S), true))
+ if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID::S, true))
continue;
overflow_cell = c;
@@ -324,17 +324,17 @@ int counter_tryextract(
return 24;
count_reg = *cey_loads.begin();
- if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID(D))))
+ if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID::D)))
return 24;
//Mux should have A driven by count Q, and B by muxy
//if A and B are swapped, CE polarity is inverted
if(sigmap(cemux->getPort(ID::B)) == muxy &&
- sigmap(cemux->getPort(ID::A)) == sigmap(count_reg->getPort(ID(Q))))
+ sigmap(cemux->getPort(ID::A)) == sigmap(count_reg->getPort(ID::Q)))
{
extract.ce_inverted = false;
}
else if(sigmap(cemux->getPort(ID::A)) == muxy &&
- sigmap(cemux->getPort(ID::B)) == sigmap(count_reg->getPort(ID(Q))))
+ sigmap(cemux->getPort(ID::B)) == sigmap(count_reg->getPort(ID::Q)))
{
extract.ce_inverted = true;
}
@@ -345,7 +345,7 @@ int counter_tryextract(
//Select of the mux is our clock enable
extract.has_ce = true;
- extract.ce = sigmap(cemux->getPort(ID(S)));
+ extract.ce = sigmap(cemux->getPort(ID::S));
}
else
extract.has_ce = false;
@@ -361,10 +361,10 @@ int counter_tryextract(
extract.has_reset = true;
//Check polarity of reset - we may have to add an inverter later on!
- extract.rst_inverted = (count_reg->getParam(ID(ARST_POLARITY)).as_int() != 1);
+ extract.rst_inverted = (count_reg->getParam(ID::ARST_POLARITY).as_int() != 1);
//Verify ARST_VALUE is zero or full scale
- int rst_value = count_reg->getParam(ID(ARST_VALUE)).as_int();
+ int rst_value = count_reg->getParam(ID::ARST_VALUE).as_int();
if(rst_value == 0)
extract.rst_to_max = false;
else if(rst_value == extract.count_value)
@@ -373,7 +373,7 @@ int counter_tryextract(
return 23;
//Save the reset
- extract.rst = sigmap(count_reg->getPort(ID(ARST)));
+ extract.rst = sigmap(count_reg->getPort(ID::ARST));
}
//TODO: support synchronous reset
else
@@ -386,10 +386,10 @@ int counter_tryextract(
return 16;
if(extract.ce_inverted && !is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::A))
return 16;
- if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID(D)))
+ if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID::D))
return 16;
}
- else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID(D)))
+ else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID::D))
return 16;
//TODO: Verify count_reg CLK_POLARITY is 1
@@ -397,7 +397,7 @@ int counter_tryextract(
//Register output must have exactly two loads, the inverter and ALU
//(unless we have a parallel output!)
//If we have a clock enable, 3 is OK
- const RTLIL::SigSpec qport = count_reg->getPort(ID(Q));
+ const RTLIL::SigSpec qport = count_reg->getPort(ID::Q);
extract.poutsig = qport;
extract.has_pout = false;
const RTLIL::SigSpec cnout = sigmap(qport);
@@ -450,12 +450,12 @@ int counter_tryextract(
}
if(!extract.count_is_up)
{
- if(!is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::A, true))
+ if(!is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::A, true))
return 18;
}
else
{
- if(is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::A, true))
+ if(is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::A, true))
{
// B must be the overflow value
const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::B));
@@ -463,7 +463,7 @@ int counter_tryextract(
return 12;
extract.count_value = overflow.as_int();
}
- else if(is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::B, true))
+ else if(is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::B, true))
{
// A must be the overflow value
const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::A));
@@ -476,21 +476,21 @@ int counter_tryextract(
return 18;
}
}
- if(alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::A, true))
+ if(alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID::Q, cell, ID::A, true))
return 19;
- if(!alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::B, true))
+ if(!alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID::Q, cell, ID::B, true))
return 19;
//Look up the clock from the register
- extract.clk = sigmap(count_reg->getPort(ID(CLK)));
+ extract.clk = sigmap(count_reg->getPort(ID::CLK));
if(!extract.count_is_up)
{
//Register output net must have an INIT attribute equal to the count value
extract.rwire = cnout.as_wire();
- if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
+ if(extract.rwire->attributes.find(ID::init) == extract.rwire->attributes.end())
return 20;
- int rinit = extract.rwire->attributes[ID(init)].as_int();
+ int rinit = extract.rwire->attributes[ID::init].as_int();
if(rinit != extract.count_value)
return 21;
}
@@ -498,9 +498,9 @@ int counter_tryextract(
{
//Register output net must not have an INIT attribute or it must be zero
extract.rwire = cnout.as_wire();
- if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
+ if(extract.rwire->attributes.find(ID::init) == extract.rwire->attributes.end())
return 0;
- int rinit = extract.rwire->attributes[ID(init)].as_int();
+ int rinit = extract.rwire->attributes[ID::init].as_int();
if(rinit != 0)
return 21;
}
@@ -534,7 +534,7 @@ void counter_worker(
RTLIL::Wire* port_wire = port.as_wire();
bool force_extract = false;
bool never_extract = false;
- string count_reg_src = port_wire->attributes[ID(src)].decode_string().c_str();
+ string count_reg_src = port_wire->attributes[ID::src].decode_string().c_str();
if(port_wire->attributes.find(ID(COUNT_EXTRACT)) != port_wire->attributes.end())
{
pool<string> sa = port_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
@@ -618,16 +618,16 @@ void counter_worker(
//Wipe all of the old connections to the ALU
cell->unsetPort(ID::A);
cell->unsetPort(ID::B);
- cell->unsetPort(ID(BI));
- cell->unsetPort(ID(CI));
- cell->unsetPort(ID(CO));
- cell->unsetPort(ID(X));
+ cell->unsetPort(ID::BI);
+ cell->unsetPort(ID::CI);
+ cell->unsetPort(ID::CO);
+ cell->unsetPort(ID::X);
cell->unsetPort(ID::Y);
- cell->unsetParam(ID(A_SIGNED));
- cell->unsetParam(ID(A_WIDTH));
- cell->unsetParam(ID(B_SIGNED));
- cell->unsetParam(ID(B_WIDTH));
- cell->unsetParam(ID(Y_WIDTH));
+ cell->unsetParam(ID::A_SIGNED);
+ cell->unsetParam(ID::A_WIDTH);
+ cell->unsetParam(ID::B_SIGNED);
+ cell->unsetParam(ID::B_WIDTH);
+ cell->unsetParam(ID::Y_WIDTH);
//Change the cell type
cell->type = ID($__COUNT_);
@@ -657,8 +657,8 @@ void counter_worker(
//Hook up other stuff
//cell->setParam(ID(CLKIN_DIVIDE), RTLIL::Const(1));
cell->setParam(ID(COUNT_TO), RTLIL::Const(extract.count_value));
- cell->setParam(ID(WIDTH), RTLIL::Const(extract.width));
- cell->setPort(ID(CLK), extract.clk);
+ cell->setParam(ID::WIDTH, RTLIL::Const(extract.width));
+ cell->setPort(ID::CLK, extract.clk);
cell->setPort(ID(OUT), extract.outsig);
//Hook up clock enable
@@ -747,7 +747,7 @@ void counter_worker(
int newbits = ceil(log2(extract.count_value));
if(extract.width != newbits)
{
- cell->setParam(ID(WIDTH), RTLIL::Const(newbits));
+ cell->setParam(ID::WIDTH, RTLIL::Const(newbits));
log(" Optimizing out %d unused high-order bits (new width is %d)\n",
extract.width - newbits,
newbits);
diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc
index 9f3bb525b..9023d8687 100644
--- a/passes/techmap/extract_fa.cc
+++ b/passes/techmap/extract_fa.cc
@@ -262,7 +262,7 @@ struct ExtractFaWorker
pool<SigBit> new_leaves = leaves;
new_leaves.erase(bit);
- for (auto port : {ID::A, ID::B, ID(C), ID(D)}) {
+ for (auto port : {ID::A, ID::B, ID::C, ID::D}) {
if (!cell->hasPort(port))
continue;
auto bit = sigmap(SigBit(cell->getPort(port)));
@@ -395,18 +395,18 @@ struct ExtractFaWorker
else
{
Cell *cell = module->addCell(NEW_ID, ID($fa));
- cell->setParam(ID(WIDTH), 1);
+ cell->setParam(ID::WIDTH, 1);
log(" Created $fa cell %s.\n", log_id(cell));
cell->setPort(ID::A, f3i.inv_a ? module->NotGate(NEW_ID, A) : A);
cell->setPort(ID::B, f3i.inv_b ? module->NotGate(NEW_ID, B) : B);
- cell->setPort(ID(C), f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
+ cell->setPort(ID::C, f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
X = module->addWire(NEW_ID);
Y = module->addWire(NEW_ID);
- cell->setPort(ID(X), X);
+ cell->setPort(ID::X, X);
cell->setPort(ID::Y, Y);
facache[fakey] = make_tuple(X, Y, cell);
@@ -501,18 +501,18 @@ struct ExtractFaWorker
else
{
Cell *cell = module->addCell(NEW_ID, ID($fa));
- cell->setParam(ID(WIDTH), 1);
+ cell->setParam(ID::WIDTH, 1);
log(" Created $fa cell %s.\n", log_id(cell));
cell->setPort(ID::A, f2i.inv_a ? module->NotGate(NEW_ID, A) : A);
cell->setPort(ID::B, f2i.inv_b ? module->NotGate(NEW_ID, B) : B);
- cell->setPort(ID(C), State::S0);
+ cell->setPort(ID::C, State::S0);
X = module->addWire(NEW_ID);
Y = module->addWire(NEW_ID);
- cell->setPort(ID(X), X);
+ cell->setPort(ID::X, X);
cell->setPort(ID::Y, Y);
}
diff --git a/passes/techmap/extract_reduce.cc b/passes/techmap/extract_reduce.cc
index 11cfddcd9..2d63e413f 100644
--- a/passes/techmap/extract_reduce.cc
+++ b/passes/techmap/extract_reduce.cc
@@ -286,7 +286,7 @@ struct ExtractReducePass : public Pass
SigSpec input;
for (auto b : input_pool)
if (input_pool_intermed.count(b) == 0)
- input.append_bit(b);
+ input.append(b);
SigBit output = sigmap(head_cell->getPort(ID::Y)[0]);
@@ -294,9 +294,9 @@ struct ExtractReducePass : public Pass
gt == GateType::And ? ID($reduce_and) :
gt == GateType::Or ? ID($reduce_or) :
gt == GateType::Xor ? ID($reduce_xor) : "");
- new_reduce_cell->setParam(ID(A_SIGNED), 0);
- new_reduce_cell->setParam(ID(A_WIDTH), input.size());
- new_reduce_cell->setParam(ID(Y_WIDTH), 1);
+ new_reduce_cell->setParam(ID::A_SIGNED, 0);
+ new_reduce_cell->setParam(ID::A_WIDTH, input.size());
+ new_reduce_cell->setParam(ID::Y_WIDTH, 1);
new_reduce_cell->setPort(ID::A, input);
new_reduce_cell->setPort(ID::Y, output);
diff --git a/passes/techmap/extractinv.cc b/passes/techmap/extractinv.cc
index dda71f12a..269fe5c6c 100644
--- a/passes/techmap/extractinv.cc
+++ b/passes/techmap/extractinv.cc
@@ -90,7 +90,7 @@ struct ExtractinvPass : public Pass {
auto cell_wire = cell_module->wire(port.first);
if (!cell_wire)
continue;
- auto it = cell_wire->attributes.find("\\invertible_pin");
+ auto it = cell_wire->attributes.find(ID::invertible_pin);
if (it == cell_wire->attributes.end())
continue;
IdString param_name = RTLIL::escape_id(it->second.decode_string());
diff --git a/passes/techmap/flowmap.cc b/passes/techmap/flowmap.cc
index a2ad87f7d..72947237b 100644
--- a/passes/techmap/flowmap.cc
+++ b/passes/techmap/flowmap.cc
@@ -1405,7 +1405,7 @@ struct FlowmapWorker
RTLIL::SigSpec lut_a, lut_y = node;
for (auto input_node : input_nodes)
- lut_a.append_bit(input_node);
+ lut_a.append(input_node);
lut_a.append(RTLIL::Const(State::Sx, minlut - input_nodes.size()));
RTLIL::Cell *lut = module->addLut(NEW_ID, lut_a, lut_y, lut_table);
@@ -1413,7 +1413,7 @@ struct FlowmapWorker
for (auto gate_node : lut_gates[node])
{
auto gate_origin = node_origins[gate_node];
- lut->add_strpool_attribute(ID(src), gate_origin.cell->get_strpool_attribute(ID(src)));
+ lut->add_strpool_attribute(ID::src, gate_origin.cell->get_strpool_attribute(ID::src));
packed_count++;
}
lut_count++;
diff --git a/passes/techmap/hilomap.cc b/passes/techmap/hilomap.cc
index 9ec651aef..5aeb5ea79 100644
--- a/passes/techmap/hilomap.cc
+++ b/passes/techmap/hilomap.cc
@@ -105,13 +105,9 @@ struct HilomapPass : public Pass {
}
extra_args(args, argidx, design);
- for (auto &it : design->modules_)
+ for (auto mod : design->selected_modules())
{
- module = it.second;
-
- if (!design->selected(module))
- continue;
-
+ module = mod;
last_hi = RTLIL::State::Sm;
last_lo = RTLIL::State::Sm;
diff --git a/passes/techmap/insbuf.cc b/passes/techmap/insbuf.cc
index 2173049b4..0686c0f2b 100644
--- a/passes/techmap/insbuf.cc
+++ b/passes/techmap/insbuf.cc
@@ -41,16 +41,16 @@ struct InsbufPass : public Pass {
{
log_header(design, "Executing INSBUF pass (insert buffer cells for connected wires).\n");
- std::string celltype = "$_BUF_", in_portname = "\\A", out_portname = "\\Y";
+ IdString celltype = ID($_BUF_), in_portname = ID::A, out_portname = ID::Y;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
std::string arg = args[argidx];
if (arg == "-buf" && argidx+3 < args.size()) {
- celltype = args[++argidx];
- in_portname = args[++argidx];
- out_portname = args[++argidx];
+ celltype = RTLIL::escape_id(args[++argidx]);
+ in_portname = RTLIL::escape_id(args[++argidx]);
+ out_portname = RTLIL::escape_id(args[++argidx]);
continue;
}
break;
@@ -76,9 +76,9 @@ struct InsbufPass : public Pass {
continue;
}
- Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype));
- cell->setPort(RTLIL::escape_id(in_portname), rhs);
- cell->setPort(RTLIL::escape_id(out_portname), lhs);
+ Cell *cell = module->addCell(NEW_ID, celltype);
+ cell->setPort(in_portname, rhs);
+ cell->setPort(out_portname, lhs);
log("Added %s.%s: %s -> %s\n", log_id(module), log_id(cell), log_signal(rhs), log_signal(lhs));
}
diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc
index 8b1862237..a18d02652 100644
--- a/passes/techmap/iopadmap.cc
+++ b/passes/techmap/iopadmap.cc
@@ -203,7 +203,7 @@ struct IopadmapPass : public Pass {
// Collect explicitly-marked already-buffered SigBits.
for (auto wire : module->wires())
- if (wire->get_bool_attribute("\\iopad_external_pin") || ignore.count(make_pair(module->name, wire->name)))
+ if (wire->get_bool_attribute(ID::iopad_external_pin) || ignore.count(make_pair(module->name, wire->name)))
for (int i = 0; i < GetSize(wire); i++)
buf_bits.insert(sigmap(SigBit(wire, i)));
@@ -229,11 +229,13 @@ struct IopadmapPass : public Pass {
for (auto module : design->selected_modules())
{
dict<Wire *, dict<int, pair<Cell *, IdString>>> rewrite_bits;
+ pool<SigSig> remove_conns;
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
{
dict<SigBit, Cell *> tbuf_bits;
pool<SigBit> driven_bits;
+ dict<SigBit, SigSig> z_conns;
// Gather tristate buffers and always-on drivers.
for (auto cell : module->cells())
@@ -252,8 +254,10 @@ struct IopadmapPass : public Pass {
for (int i = 0; i < GetSize(conn.first); i++) {
SigBit dstbit = conn.first[i];
SigBit srcbit = conn.second[i];
- if (!srcbit.wire && srcbit.data == State::Sz)
+ if (!srcbit.wire && srcbit.data == State::Sz) {
+ z_conns[dstbit] = conn;
continue;
+ }
driven_bits.insert(dstbit);
}
@@ -287,7 +291,7 @@ struct IopadmapPass : public Pass {
if (tbuf_cell != nullptr) {
// Found a tristate buffer — use it.
- en_sig = tbuf_cell->getPort(ID(E)).as_bit();
+ en_sig = tbuf_cell->getPort(ID::E).as_bit();
data_sig = tbuf_cell->getPort(ID::A).as_bit();
} else if (is_driven) {
// No tristate buffer, but an always-on driver is present.
@@ -302,6 +306,8 @@ struct IopadmapPass : public Pass {
// enable.
en_sig = SigBit(State::S0);
data_sig = SigBit(State::Sx);
+ if (z_conns.count(wire_bit))
+ remove_conns.insert(z_conns[wire_bit]);
}
if (wire->port_input)
@@ -454,6 +460,14 @@ struct IopadmapPass : public Pass {
}
}
+ if (!remove_conns.empty()) {
+ std::vector<SigSig> new_conns;
+ for (auto &conn : module->connections())
+ if (!remove_conns.count(conn))
+ new_conns.push_back(conn);
+ module->new_connections(new_conns);
+ }
+
for (auto &it : rewrite_bits) {
RTLIL::Wire *wire = it.first;
RTLIL::Wire *new_wire = module->addWire(
@@ -476,10 +490,10 @@ struct IopadmapPass : public Pass {
}
if (wire->port_output) {
- auto jt = new_wire->attributes.find(ID(init));
+ auto jt = new_wire->attributes.find(ID::init);
// For output ports, move \init attributes from old wire to new wire
if (jt != new_wire->attributes.end()) {
- wire->attributes[ID(init)] = std::move(jt->second);
+ wire->attributes[ID::init] = std::move(jt->second);
new_wire->attributes.erase(jt);
}
}
diff --git a/passes/techmap/lut2mux.cc b/passes/techmap/lut2mux.cc
index c6618fc9d..703bf6ff6 100644
--- a/passes/techmap/lut2mux.cc
+++ b/passes/techmap/lut2mux.cc
@@ -27,7 +27,7 @@ int lut2mux(Cell *cell)
{
SigSpec sig_a = cell->getPort(ID::A);
SigSpec sig_y = cell->getPort(ID::Y);
- Const lut = cell->getParam(ID(LUT));
+ Const lut = cell->getParam(ID::LUT);
int count = 1;
if (GetSize(sig_a) == 1)
diff --git a/passes/techmap/maccmap.cc b/passes/techmap/maccmap.cc
index 09f61927c..3bb929009 100644
--- a/passes/techmap/maccmap.cc
+++ b/passes/techmap/maccmap.cc
@@ -112,12 +112,12 @@ struct MaccmapWorker
RTLIL::Wire *w2 = module->addWire(NEW_ID, width);
RTLIL::Cell *cell = module->addCell(NEW_ID, ID($fa));
- cell->setParam(ID(WIDTH), width);
+ cell->setParam(ID::WIDTH, width);
cell->setPort(ID::A, in1);
cell->setPort(ID::B, in2);
- cell->setPort(ID(C), in3);
+ cell->setPort(ID::C, in3);
cell->setPort(ID::Y, w1);
- cell->setPort(ID(X), w2);
+ cell->setPort(ID::X, w2);
out1 = {out_zeros_msb, w1, out_zeros_lsb};
out2 = {out_zeros_msb, w2, out_zeros_lsb};
@@ -240,15 +240,15 @@ struct MaccmapWorker
RTLIL::Cell *c = module->addCell(NEW_ID, ID($alu));
c->setPort(ID::A, summands.front());
c->setPort(ID::B, summands.back());
- c->setPort(ID(CI), State::S0);
- c->setPort(ID(BI), State::S0);
+ c->setPort(ID::CI, State::S0);
+ c->setPort(ID::BI, State::S0);
c->setPort(ID::Y, module->addWire(NEW_ID, width));
- c->setPort(ID(X), module->addWire(NEW_ID, width));
- c->setPort(ID(CO), module->addWire(NEW_ID, width));
+ c->setPort(ID::X, module->addWire(NEW_ID, width));
+ c->setPort(ID::CO, module->addWire(NEW_ID, width));
c->fixup_parameters();
if (!tree_sum_bits.empty()) {
- c->setPort(ID(CI), tree_sum_bits.back());
+ c->setPort(ID::CI, tree_sum_bits.back());
tree_sum_bits.pop_back();
}
log_assert(tree_sum_bits.empty());
diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc
index 5541b6122..bd049d86d 100644
--- a/passes/techmap/muxcover.cc
+++ b/passes/techmap/muxcover.cc
@@ -116,7 +116,7 @@ struct MuxcoverWorker
if (!cell->input(conn.first))
continue;
for (auto bit : sigmap(conn.second)) {
- if (used_once.count(bit) || cell->type != ID($_MUX_) || conn.first == ID(S))
+ if (used_once.count(bit) || cell->type != ID($_MUX_) || conn.first == ID::S)
roots.insert(bit);
used_once.insert(bit);
}
@@ -519,7 +519,7 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(S), mux.selects[0]);
+ cell->setPort(ID::S, mux.selects[0]);
cell->setPort(ID::Y, bit);
return;
}
@@ -529,10 +529,10 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX4_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(C), mux.inputs[2]);
- cell->setPort(ID(D), mux.inputs[3]);
- cell->setPort(ID(S), mux.selects[0]);
- cell->setPort(ID(T), mux.selects[1]);
+ cell->setPort(ID::C, mux.inputs[2]);
+ cell->setPort(ID::D, mux.inputs[3]);
+ cell->setPort(ID::S, mux.selects[0]);
+ cell->setPort(ID::T, mux.selects[1]);
cell->setPort(ID::Y, bit);
return;
}
@@ -542,15 +542,15 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX8_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(C), mux.inputs[2]);
- cell->setPort(ID(D), mux.inputs[3]);
- cell->setPort(ID(E), mux.inputs[4]);
- cell->setPort(ID(F), mux.inputs[5]);
- cell->setPort(ID(G), mux.inputs[6]);
- cell->setPort(ID(H), mux.inputs[7]);
- cell->setPort(ID(S), mux.selects[0]);
- cell->setPort(ID(T), mux.selects[1]);
- cell->setPort(ID(U), mux.selects[2]);
+ cell->setPort(ID::C, mux.inputs[2]);
+ cell->setPort(ID::D, mux.inputs[3]);
+ cell->setPort(ID::E, mux.inputs[4]);
+ cell->setPort(ID::F, mux.inputs[5]);
+ cell->setPort(ID::G, mux.inputs[6]);
+ cell->setPort(ID::H, mux.inputs[7]);
+ cell->setPort(ID::S, mux.selects[0]);
+ cell->setPort(ID::T, mux.selects[1]);
+ cell->setPort(ID::U, mux.selects[2]);
cell->setPort(ID::Y, bit);
return;
}
@@ -560,24 +560,24 @@ struct MuxcoverWorker
Cell *cell = module->addCell(NEW_ID, ID($_MUX16_));
cell->setPort(ID::A, mux.inputs[0]);
cell->setPort(ID::B, mux.inputs[1]);
- cell->setPort(ID(C), mux.inputs[2]);
- cell->setPort(ID(D), mux.inputs[3]);
- cell->setPort(ID(E), mux.inputs[4]);
- cell->setPort(ID(F), mux.inputs[5]);
- cell->setPort(ID(G), mux.inputs[6]);
- cell->setPort(ID(H), mux.inputs[7]);
- cell->setPort(ID(I), mux.inputs[8]);
- cell->setPort(ID(J), mux.inputs[9]);
- cell->setPort(ID(K), mux.inputs[10]);
- cell->setPort(ID(L), mux.inputs[11]);
- cell->setPort(ID(M), mux.inputs[12]);
- cell->setPort(ID(N), mux.inputs[13]);
- cell->setPort(ID(O), mux.inputs[14]);
- cell->setPort(ID(P), mux.inputs[15]);
- cell->setPort(ID(S), mux.selects[0]);
- cell->setPort(ID(T), mux.selects[1]);
- cell->setPort(ID(U), mux.selects[2]);
- cell->setPort(ID(V), mux.selects[3]);
+ cell->setPort(ID::C, mux.inputs[2]);
+ cell->setPort(ID::D, mux.inputs[3]);
+ cell->setPort(ID::E, mux.inputs[4]);
+ cell->setPort(ID::F, mux.inputs[5]);
+ cell->setPort(ID::G, mux.inputs[6]);
+ cell->setPort(ID::H, mux.inputs[7]);
+ cell->setPort(ID::I, mux.inputs[8]);
+ cell->setPort(ID::J, mux.inputs[9]);
+ cell->setPort(ID::K, mux.inputs[10]);
+ cell->setPort(ID::L, mux.inputs[11]);
+ cell->setPort(ID::M, mux.inputs[12]);
+ cell->setPort(ID::N, mux.inputs[13]);
+ cell->setPort(ID::O, mux.inputs[14]);
+ cell->setPort(ID::P, mux.inputs[15]);
+ cell->setPort(ID::S, mux.selects[0]);
+ cell->setPort(ID::T, mux.selects[1]);
+ cell->setPort(ID::U, mux.selects[2]);
+ cell->setPort(ID::V, mux.selects[3]);
cell->setPort(ID::Y, bit);
return;
}
diff --git a/passes/techmap/pmuxtree.cc b/passes/techmap/pmuxtree.cc
index 31ab13cec..2810b7f2d 100644
--- a/passes/techmap/pmuxtree.cc
+++ b/passes/techmap/pmuxtree.cc
@@ -93,7 +93,7 @@ struct PmuxtreePass : public Pass {
continue;
SigSpec sig_data = cell->getPort(ID::B);
- SigSpec sig_sel = cell->getPort(ID(S));
+ SigSpec sig_sel = cell->getPort(ID::S);
if (!cell->getPort(ID::A).is_fully_undef()) {
sig_data.append(cell->getPort(ID::A));
diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc
index be00e5030..d7a381e0a 100644
--- a/passes/techmap/shregmap.cc
+++ b/passes/techmap/shregmap.cc
@@ -71,12 +71,12 @@ struct ShregmapTechGreenpak4 : ShregmapTech
bool fixup(Cell *cell, dict<int, SigBit> &taps)
{
- auto D = cell->getPort(ID(D));
- auto C = cell->getPort(ID(C));
+ auto D = cell->getPort(ID::D);
+ auto C = cell->getPort(ID::C);
auto newcell = cell->module->addCell(NEW_ID, ID(GP_SHREG));
newcell->setPort(ID(nRST), State::S1);
- newcell->setPort(ID(CLK), C);
+ newcell->setPort(ID::CLK, C);
newcell->setPort(ID(IN), D);
int i = 0;
@@ -117,9 +117,9 @@ struct ShregmapWorker
sigbit_with_non_chain_users.insert(bit);
}
- if (wire->attributes.count(ID(init))) {
+ if (wire->attributes.count(ID::init)) {
SigSpec initsig = sigmap(wire);
- Const initval = wire->attributes.at(ID(init));
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
if (initval[i] == State::S0 && !opts.zinit)
sigbit_init[initsig[i]] = false;
@@ -319,7 +319,7 @@ struct ShregmapWorker
initval.push_back(State::S0);
remove_init.insert(bit);
}
- first_cell->setParam(ID(INIT), initval);
+ first_cell->setParam(ID::INIT, initval);
}
if (opts.zinit)
@@ -348,7 +348,7 @@ struct ShregmapWorker
first_cell->type = shreg_cell_type_str;
first_cell->setPort(q_port, last_cell->getPort(q_port));
- first_cell->setParam(ID(DEPTH), depth);
+ first_cell->setParam(ID::DEPTH, depth);
if (opts.tech != nullptr && !opts.tech->fixup(first_cell, taps_dict))
remove_cells.insert(first_cell);
@@ -366,18 +366,18 @@ struct ShregmapWorker
for (auto wire : module->wires())
{
- if (wire->attributes.count(ID(init)) == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec initsig = sigmap(wire);
- Const &initval = wire->attributes.at(ID(init));
+ Const &initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
if (remove_init.count(initsig[i]))
initval[i] = State::Sx;
if (SigSpec(initval).is_fully_undef())
- wire->attributes.erase(ID(init));
+ wire->attributes.erase(ID::init);
}
remove_cells.clear();
@@ -548,19 +548,19 @@ struct ShregmapPass : public Pass {
bool en_neg = enpol == "neg" || enpol == "any" || enpol == "any_or_none";
if (clk_pos && en_none)
- opts.ffcells[ID($_DFF_P_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFF_P_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_neg && en_none)
- opts.ffcells[ID($_DFF_N_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFF_N_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_pos && en_pos)
- opts.ffcells[ID($_DFFE_PP_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_PP_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_pos && en_neg)
- opts.ffcells[ID($_DFFE_PN_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_PN_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_neg && en_pos)
- opts.ffcells[ID($_DFFE_NP_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_NP_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (clk_neg && en_neg)
- opts.ffcells[ID($_DFFE_NN_)] = make_pair(IdString(ID(D)), IdString(ID(Q)));
+ opts.ffcells[ID($_DFFE_NN_)] = make_pair(IdString(ID::D), IdString(ID::Q));
if (en_pos || en_neg)
opts.ffe = true;
diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc
index 91574f3c6..b65b3e972 100644
--- a/passes/techmap/simplemap.cc
+++ b/passes/techmap/simplemap.cc
@@ -31,11 +31,11 @@ void simplemap_not(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
+ sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::Y, sig_y[i]);
}
@@ -46,7 +46,7 @@ void simplemap_pos(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
+ sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
module->connect(RTLIL::SigSig(sig_y, sig_a));
}
@@ -57,8 +57,8 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID(A_SIGNED)).as_bool());
- sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID(B_SIGNED)).as_bool());
+ sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
+ sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID::B_SIGNED).as_bool());
if (cell->type == ID($xnor))
{
@@ -66,7 +66,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_t[i]);
gate->setPort(ID::Y, sig_y[i]);
}
@@ -83,7 +83,7 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_b[i]);
gate->setPort(ID::Y, sig_y[i]);
@@ -134,7 +134,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
}
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_a[i+1]);
gate->setPort(ID::Y, sig_t[i/2]);
@@ -147,7 +147,7 @@ void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell)
if (cell->type == ID($reduce_xnor)) {
RTLIL::SigSpec sig_t = module->addWire(NEW_ID);
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a);
gate->setPort(ID::Y, sig_t);
last_output_cell = gate;
@@ -175,7 +175,7 @@ static void logic_reduce(RTLIL::Module *module, RTLIL::SigSpec &sig, RTLIL::Cell
}
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_OR_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig[i]);
gate->setPort(ID::B, sig[i+1]);
gate->setPort(ID::Y, sig_t[i/2]);
@@ -204,7 +204,7 @@ void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell)
}
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_NOT_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a);
gate->setPort(ID::Y, sig_y);
}
@@ -233,7 +233,7 @@ void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell)
log_assert(!gate_type.empty());
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a);
gate->setPort(ID::B, sig_b);
gate->setPort(ID::Y, sig_y);
@@ -244,24 +244,24 @@ void simplemap_eqne(RTLIL::Module *module, RTLIL::Cell *cell)
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
- bool is_signed = cell->parameters.at(ID(A_SIGNED)).as_bool();
+ bool is_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
bool is_ne = cell->type.in(ID($ne), ID($nex));
RTLIL::SigSpec xor_out = module->addWire(NEW_ID, max(GetSize(sig_a), GetSize(sig_b)));
RTLIL::Cell *xor_cell = module->addXor(NEW_ID, sig_a, sig_b, xor_out, is_signed);
- xor_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ xor_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_bitop(module, xor_cell);
module->remove(xor_cell);
RTLIL::SigSpec reduce_out = is_ne ? sig_y : module->addWire(NEW_ID);
RTLIL::Cell *reduce_cell = module->addReduceOr(NEW_ID, xor_out, reduce_out);
- reduce_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ reduce_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_reduce(module, reduce_cell);
module->remove(reduce_cell);
if (!is_ne) {
RTLIL::Cell *not_cell = module->addLogicNot(NEW_ID, reduce_out, sig_y);
- not_cell->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ not_cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
simplemap_lognot(module, not_cell);
module->remove(not_cell);
}
@@ -275,10 +275,10 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
gate->setPort(ID::B, sig_b[i]);
- gate->setPort(ID(S), cell->getPort(ID(S)));
+ gate->setPort(ID::S, cell->getPort(ID::S));
gate->setPort(ID::Y, sig_y[i]);
}
}
@@ -286,14 +286,14 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
{
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
- RTLIL::SigSpec sig_e = cell->getPort(ID(EN));
+ RTLIL::SigSpec sig_e = cell->getPort(ID::EN);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
for (int i = 0; i < GetSize(sig_y); i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_TBUF_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, sig_a[i]);
- gate->setPort(ID(E), sig_e);
+ gate->setPort(ID::E, sig_e);
gate->setPort(ID::Y, sig_y[i]);
}
}
@@ -301,18 +301,18 @@ void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
{
SigSpec lut_ctrl = cell->getPort(ID::A);
- SigSpec lut_data = cell->getParam(ID(LUT));
- lut_data.extend_u0(1 << cell->getParam(ID(WIDTH)).as_int());
+ SigSpec lut_data = cell->getParam(ID::LUT);
+ lut_data.extend_u0(1 << cell->getParam(ID::WIDTH).as_int());
for (int idx = 0; GetSize(lut_data) > 1; idx++) {
SigSpec sig_s = lut_ctrl[idx];
SigSpec new_lut_data = module->addWire(NEW_ID, GetSize(lut_data)/2);
for (int i = 0; i < GetSize(lut_data); i += 2) {
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
gate->setPort(ID::A, lut_data[i]);
gate->setPort(ID::B, lut_data[i+1]);
- gate->setPort(ID(S), lut_ctrl[idx]);
+ gate->setPort(ID::S, lut_ctrl[idx]);
gate->setPort(ID::Y, new_lut_data[i/2]);
}
lut_data = new_lut_data;
@@ -324,10 +324,10 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell)
{
SigSpec ctrl = cell->getPort(ID::A);
- SigSpec table = cell->getParam(ID(TABLE));
+ SigSpec table = cell->getParam(ID::TABLE);
- int width = cell->getParam(ID(WIDTH)).as_int();
- int depth = cell->getParam(ID(DEPTH)).as_int();
+ int width = cell->getParam(ID::WIDTH).as_int();
+ int depth = cell->getParam(ID::DEPTH).as_int();
table.extend_u0(2 * width * depth);
SigSpec products;
@@ -353,7 +353,7 @@ void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int offset = cell->parameters.at(ID(OFFSET)).as_int();
+ int offset = cell->parameters.at(ID::OFFSET).as_int();
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
module->connect(RTLIL::SigSig(sig_y, sig_a.extract(offset, sig_y.size())));
@@ -369,156 +369,156 @@ void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell)
void simplemap_sr(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char set_pol = cell->parameters.at(ID(SET_POLARITY)).as_bool() ? 'P' : 'N';
- char clr_pol = cell->parameters.at(ID(CLR_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N';
+ char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
- RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_s = cell->getPort(ID::SET);
+ RTLIL::SigSpec sig_r = cell->getPort(ID::CLR);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
std::string gate_type = stringf("$_SR_%c%c_", set_pol, clr_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(S), sig_s[i]);
- gate->setPort(ID(R), sig_r[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::S, sig_s[i]);
+ gate->setPort(ID::R, sig_r[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_ff(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
+ int width = cell->parameters.at(ID::WIDTH).as_int();
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = ID($_FF_);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dff(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DFF_%c_", clk_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dffe(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
- char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
+ char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_en = cell->getPort(ID::EN);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DFFE_%c%c_", clk_pol, en_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(E), sig_en);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::E, sig_en);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dffsr(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
- char set_pol = cell->parameters.at(ID(SET_POLARITY)).as_bool() ? 'P' : 'N';
- char clr_pol = cell->parameters.at(ID(CLR_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
+ char set_pol = cell->parameters.at(ID::SET_POLARITY).as_bool() ? 'P' : 'N';
+ char clr_pol = cell->parameters.at(ID::CLR_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_s = cell->getPort(ID(SET));
- RTLIL::SigSpec sig_r = cell->getPort(ID(CLR));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_s = cell->getPort(ID::SET);
+ RTLIL::SigSpec sig_r = cell->getPort(ID::CLR);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DFFSR_%c%c%c_", clk_pol, set_pol, clr_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(S), sig_s[i]);
- gate->setPort(ID(R), sig_r[i]);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::S, sig_s[i]);
+ gate->setPort(ID::R, sig_r[i]);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_adff(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char clk_pol = cell->parameters.at(ID(CLK_POLARITY)).as_bool() ? 'P' : 'N';
- char rst_pol = cell->parameters.at(ID(ARST_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char clk_pol = cell->parameters.at(ID::CLK_POLARITY).as_bool() ? 'P' : 'N';
+ char rst_pol = cell->parameters.at(ID::ARST_POLARITY).as_bool() ? 'P' : 'N';
- std::vector<RTLIL::State> rst_val = cell->parameters.at(ID(ARST_VALUE)).bits;
+ std::vector<RTLIL::State> rst_val = cell->parameters.at(ID::ARST_VALUE).bits;
while (int(rst_val.size()) < width)
rst_val.push_back(RTLIL::State::S0);
- RTLIL::SigSpec sig_clk = cell->getPort(ID(CLK));
- RTLIL::SigSpec sig_rst = cell->getPort(ID(ARST));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_clk = cell->getPort(ID::CLK);
+ RTLIL::SigSpec sig_rst = cell->getPort(ID::ARST);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type_0 = stringf("$_DFF_%c%c0_", clk_pol, rst_pol);
IdString gate_type_1 = stringf("$_DFF_%c%c1_", clk_pol, rst_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, rst_val.at(i) == RTLIL::State::S1 ? gate_type_1 : gate_type_0);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(C), sig_clk);
- gate->setPort(ID(R), sig_rst);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::C, sig_clk);
+ gate->setPort(ID::R, sig_rst);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
void simplemap_dlatch(RTLIL::Module *module, RTLIL::Cell *cell)
{
- int width = cell->parameters.at(ID(WIDTH)).as_int();
- char en_pol = cell->parameters.at(ID(EN_POLARITY)).as_bool() ? 'P' : 'N';
+ int width = cell->parameters.at(ID::WIDTH).as_int();
+ char en_pol = cell->parameters.at(ID::EN_POLARITY).as_bool() ? 'P' : 'N';
- RTLIL::SigSpec sig_en = cell->getPort(ID(EN));
- RTLIL::SigSpec sig_d = cell->getPort(ID(D));
- RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
+ RTLIL::SigSpec sig_en = cell->getPort(ID::EN);
+ RTLIL::SigSpec sig_d = cell->getPort(ID::D);
+ RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
IdString gate_type = stringf("$_DLATCH_%c_", en_pol);
for (int i = 0; i < width; i++) {
RTLIL::Cell *gate = module->addCell(NEW_ID, gate_type);
- gate->add_strpool_attribute(ID(src), cell->get_strpool_attribute(ID(src)));
- gate->setPort(ID(E), sig_en);
- gate->setPort(ID(D), sig_d[i]);
- gate->setPort(ID(Q), sig_q[i]);
+ gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
+ gate->setPort(ID::E, sig_en);
+ gate->setPort(ID::D, sig_d[i]);
+ gate->setPort(ID::Q, sig_q[i]);
}
}
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index 10001baaa..a554be257 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -146,7 +146,7 @@ struct TechmapWorker
record.value = it.second;
result[p].push_back(record);
it.second->attributes[ID::keep] = RTLIL::Const(1);
- it.second->attributes[ID(_techmap_special_)] = RTLIL::Const(1);
+ it.second->attributes[ID::_techmap_special_] = RTLIL::Const(1);
}
}
@@ -175,12 +175,12 @@ struct TechmapWorker
}
std::string orig_cell_name;
- pool<string> extra_src_attrs = cell->get_strpool_attribute(ID(src));
+ pool<string> extra_src_attrs = cell->get_strpool_attribute(ID::src);
orig_cell_name = cell->name.str();
if (!flatten_mode) {
for (auto &it : tpl->cells_)
- if (it.first == ID(_TECHMAP_REPLACE_)) {
+ if (it.first == ID::_TECHMAP_REPLACE_) {
module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
break;
}
@@ -197,8 +197,8 @@ struct TechmapWorker
m->start_offset = it.second->start_offset;
m->size = it.second->size;
m->attributes = it.second->attributes;
- if (m->attributes.count(ID(src)))
- m->add_strpool_attribute(ID(src), extra_src_attrs);
+ if (m->attributes.count(ID::src))
+ m->add_strpool_attribute(ID::src, extra_src_attrs);
module->memories[m->name] = m;
memory_renames[it.first] = m->name;
design->select(module, m);
@@ -215,7 +215,7 @@ struct TechmapWorker
IdString posportname = stringf("$%d", it.second->port_id);
positional_ports[posportname] = it.first;
- if (!flatten_mode && it.second->get_bool_attribute(ID(techmap_autopurge)) &&
+ if (!flatten_mode && it.second->get_bool_attribute(ID::techmap_autopurge) &&
(!cell->hasPort(it.second->name) || !GetSize(cell->getPort(it.second->name))) &&
(!cell->hasPort(posportname) || !GetSize(cell->getPort(posportname))))
{
@@ -231,12 +231,12 @@ struct TechmapWorker
apply_prefix(cell->name, w_name);
RTLIL::Wire *w = module->wire(w_name);
if (w != nullptr) {
- if (!flatten_mode || !w->get_bool_attribute(ID(hierconn))) {
+ if (!flatten_mode || !w->get_bool_attribute(ID::hierconn)) {
temp_renamed_wires[w] = w->name;
module->rename(w, NEW_ID);
w = nullptr;
} else {
- w->attributes.erase(ID(hierconn));
+ w->attributes.erase(ID::hierconn);
if (GetSize(w) < GetSize(it.second)) {
log_warning("Widening signal %s.%s to match size of %s.%s (via %s.%s).\n", log_id(module), log_id(w),
log_id(tpl), log_id(it.second), log_id(module), log_id(cell));
@@ -250,11 +250,11 @@ struct TechmapWorker
w->port_output = false;
w->port_id = 0;
if (!flatten_mode)
- w->attributes.erase(ID(techmap_autopurge));
- if (it.second->get_bool_attribute(ID(_techmap_special_)))
+ w->attributes.erase(ID::techmap_autopurge);
+ if (it.second->get_bool_attribute(ID::_techmap_special_))
w->attributes.clear();
- if (w->attributes.count(ID(src)))
- w->add_strpool_attribute(ID(src), extra_src_attrs);
+ if (w->attributes.count(ID::src))
+ w->add_strpool_attribute(ID::src, extra_src_attrs);
}
design->select(module, w);
@@ -363,7 +363,7 @@ struct TechmapWorker
}
for (auto &attr : w->attributes) {
- if (attr.first == ID(src))
+ if (attr.first == ID::src)
continue;
auto lhs = GetSize(extra_connect.first);
auto rhs = GetSize(extra_connect.second);
@@ -380,7 +380,7 @@ struct TechmapWorker
for (auto &it : tpl->cells_)
{
IdString c_name = it.second->name.str();
- bool techmap_replace_cell = (!flatten_mode) && (c_name == ID(_TECHMAP_REPLACE_));
+ bool techmap_replace_cell = (!flatten_mode) && (c_name == ID::_TECHMAP_REPLACE_);
if (techmap_replace_cell)
c_name = orig_cell_name;
@@ -421,19 +421,19 @@ struct TechmapWorker
c->unsetPort(it2);
if (c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
- IdString memid = c->getParam(ID(MEMID)).decode_string();
+ IdString memid = c->getParam(ID::MEMID).decode_string();
log_assert(memory_renames.count(memid) != 0);
- c->setParam(ID(MEMID), Const(memory_renames[memid].str()));
+ c->setParam(ID::MEMID, Const(memory_renames[memid].str()));
}
if (c->type == ID($mem)) {
- IdString memid = c->getParam(ID(MEMID)).decode_string();
+ IdString memid = c->getParam(ID::MEMID).decode_string();
apply_prefix(cell->name, memid);
- c->setParam(ID(MEMID), Const(memid.c_str()));
+ c->setParam(ID::MEMID, Const(memid.c_str()));
}
- if (c->attributes.count(ID(src)))
- c->add_strpool_attribute(ID(src), extra_src_attrs);
+ if (c->attributes.count(ID::src))
+ c->add_strpool_attribute(ID::src, extra_src_attrs);
if (techmap_replace_cell)
for (auto attr : cell->attributes)
@@ -481,8 +481,8 @@ struct TechmapWorker
pool<SigBit> remove_init_bits;
for (auto wire : module->wires()) {
- if (wire->attributes.count("\\init")) {
- Const value = wire->attributes.at("\\init");
+ if (wire->attributes.count(ID::init)) {
+ Const value = wire->attributes.at(ID::init);
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++)
if (value[i] != State::Sx)
init_bits[sigmap(SigBit(wire, i))] = value[i];
@@ -509,9 +509,9 @@ struct TechmapWorker
}
if (flatten_mode) {
- bool keepit = cell->get_bool_attribute(ID(keep_hierarchy));
+ bool keepit = cell->get_bool_attribute(ID::keep_hierarchy);
for (auto &tpl_name : celltypeMap.at(cell_type))
- if (map->modules_[tpl_name]->get_bool_attribute(ID(keep_hierarchy)))
+ if (map->modules_[tpl_name]->get_bool_attribute(ID::keep_hierarchy))
keepit = true;
if (keepit) {
if (!flatten_keep_list[cell]) {
@@ -577,13 +577,13 @@ struct TechmapWorker
{
std::string extmapper_name;
- if (tpl->get_bool_attribute(ID(techmap_simplemap)))
+ if (tpl->get_bool_attribute(ID::techmap_simplemap))
extmapper_name = "simplemap";
- if (tpl->get_bool_attribute(ID(techmap_maccmap)))
+ if (tpl->get_bool_attribute(ID::techmap_maccmap))
extmapper_name = "maccmap";
- if (tpl->attributes.count(ID(techmap_wrap)))
+ if (tpl->attributes.count(ID::techmap_wrap))
extmapper_name = "wrap";
if (!extmapper_name.empty())
@@ -598,7 +598,7 @@ struct TechmapWorker
m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second));
if (extmapper_name == "wrap")
- m_name += ":" + sha1(tpl->attributes.at(ID(techmap_wrap)).decode_string());
+ m_name += ":" + sha1(tpl->attributes.at(ID::techmap_wrap).decode_string());
RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design;
RTLIL::Module *extmapper_module = extmapper_design->module(m_name);
@@ -613,7 +613,7 @@ struct TechmapWorker
int port_counter = 1;
for (auto &c : extmapper_cell->connections_) {
RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second));
- if (w->name.in(ID::Y, ID(Q)))
+ if (w->name.in(ID::Y, ID::Q))
w->port_output = true;
else
w->port_input = true;
@@ -641,7 +641,7 @@ struct TechmapWorker
}
if (extmapper_name == "wrap") {
- std::string cmd_string = tpl->attributes.at(ID(techmap_wrap)).decode_string();
+ std::string cmd_string = tpl->attributes.at(ID::techmap_wrap).decode_string();
log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module));
mkdebug.on();
Pass::call_on_module(extmapper_design, extmapper_module, cmd_string);
@@ -709,8 +709,8 @@ struct TechmapWorker
continue;
}
- if (tpl->avail_parameters.count(ID(_TECHMAP_CELLTYPE_)) != 0)
- parameters[ID(_TECHMAP_CELLTYPE_)] = RTLIL::unescape_id(cell->type);
+ if (tpl->avail_parameters.count(ID::_TECHMAP_CELLTYPE_) != 0)
+ parameters[ID::_TECHMAP_CELLTYPE_] = RTLIL::unescape_id(cell->type);
for (auto conn : cell->connections()) {
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) {
@@ -760,8 +760,8 @@ struct TechmapWorker
bits = i;
// Increment index by one to get number of bits
bits++;
- if (tpl->avail_parameters.count(ID(_TECHMAP_BITS_CONNMAP_)))
- parameters[ID(_TECHMAP_BITS_CONNMAP_)] = bits;
+ if (tpl->avail_parameters.count(ID::_TECHMAP_BITS_CONNMAP_))
+ parameters[ID::_TECHMAP_BITS_CONNMAP_] = bits;
for (auto conn : cell->connections())
if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) {
@@ -906,8 +906,8 @@ struct TechmapWorker
RTLIL::SigSig port_conn;
for (auto &it : port_connmap) {
- port_conn.first.append_bit(it.first);
- port_conn.second.append_bit(it.second);
+ port_conn.first.append(it.first);
+ port_conn.second.append(it.second);
}
tpl->connect(port_conn);
@@ -1030,8 +1030,8 @@ struct TechmapWorker
if (!remove_init_bits.empty()) {
for (auto wire : module->wires())
- if (wire->attributes.count("\\init")) {
- Const &value = wire->attributes.at("\\init");
+ if (wire->attributes.count(ID::init)) {
+ Const &value = wire->attributes.at(ID::init);
bool do_cleanup = true;
for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) {
SigBit bit = sigmap(SigBit(wire, i));
@@ -1042,7 +1042,7 @@ struct TechmapWorker
}
if (do_cleanup) {
log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire));
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
}
}
@@ -1282,7 +1282,7 @@ struct TechmapPass : public Pass {
if (fn.compare(0, 1, "%") == 0) {
if (!saved_designs.count(fn.substr(1))) {
delete map;
- log_cmd_error("Can't saved design `%s'.\n", fn.c_str()+1);
+ log_cmd_error("Can't open saved design `%s'.\n", fn.c_str()+1);
}
for (auto mod : saved_designs.at(fn.substr(1))->modules())
if (!map->has(mod->name))
@@ -1302,8 +1302,8 @@ struct TechmapPass : public Pass {
std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
for (auto &it : map->modules_) {
- if (it.second->attributes.count(ID(techmap_celltype)) && !it.second->attributes.at(ID(techmap_celltype)).bits.empty()) {
- char *p = strdup(it.second->attributes.at(ID(techmap_celltype)).decode_string().c_str());
+ if (it.second->attributes.count(ID::techmap_celltype) && !it.second->attributes.at(ID::techmap_celltype).bits.empty()) {
+ char *p = strdup(it.second->attributes.at(ID::techmap_celltype).decode_string().c_str());
for (char *q = strtok(p, " \t\r\n"); q; q = strtok(NULL, " \t\r\n"))
celltypeMap[RTLIL::escape_id(q)].insert(it.first);
free(p);
@@ -1389,7 +1389,7 @@ struct FlattenPass : public Pass {
RTLIL::Module *top_mod = NULL;
if (design->full_selection())
for (auto mod : design->modules())
- if (mod->get_bool_attribute(ID(top)))
+ if (mod->get_bool_attribute(ID::top))
top_mod = mod;
std::set<RTLIL::Cell*> handled_cells;
diff --git a/passes/techmap/tribuf.cc b/passes/techmap/tribuf.cc
index decf9a202..90f3a9d6f 100644
--- a/passes/techmap/tribuf.cc
+++ b/passes/techmap/tribuf.cc
@@ -71,7 +71,7 @@ struct TribufWorker {
if (cell->type.in(ID($mux), ID($_MUX_)))
{
- IdString en_port = cell->type == ID($mux) ? ID(EN) : ID(E);
+ IdString en_port = cell->type == ID($mux) ? ID::EN : ID::E;
IdString tri_type = cell->type == ID($mux) ? ID($tribuf) : ID($_TBUF_);
if (is_all_z(cell->getPort(ID::A)) && is_all_z(cell->getPort(ID::B))) {
@@ -81,9 +81,9 @@ struct TribufWorker {
if (is_all_z(cell->getPort(ID::A))) {
cell->setPort(ID::A, cell->getPort(ID::B));
- cell->setPort(en_port, cell->getPort(ID(S)));
+ cell->setPort(en_port, cell->getPort(ID::S));
cell->unsetPort(ID::B);
- cell->unsetPort(ID(S));
+ cell->unsetPort(ID::S);
cell->type = tri_type;
tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
module->design->scratchpad_set_bool("tribuf.added_something", true);
@@ -91,9 +91,9 @@ struct TribufWorker {
}
if (is_all_z(cell->getPort(ID::B))) {
- cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID(S))));
+ cell->setPort(en_port, module->Not(NEW_ID, cell->getPort(ID::S)));
cell->unsetPort(ID::B);
- cell->unsetPort(ID(S));
+ cell->unsetPort(ID::S);
cell->type = tri_type;
tribuf_cells[sigmap(cell->getPort(ID::Y))].push_back(cell);
module->design->scratchpad_set_bool("tribuf.added_something", true);
@@ -121,9 +121,9 @@ struct TribufWorker {
SigSpec pmux_b, pmux_s;
for (auto cell : it.second) {
if (cell->type == ID($tribuf))
- pmux_s.append(cell->getPort(ID(EN)));
+ pmux_s.append(cell->getPort(ID::EN));
else
- pmux_s.append(cell->getPort(ID(E)));
+ pmux_s.append(cell->getPort(ID::E));
pmux_b.append(cell->getPort(ID::A));
module->remove(cell);
}
diff --git a/passes/techmap/zinit.cc b/passes/techmap/zinit.cc
index ac3d4ed4a..9eb47ff6d 100644
--- a/passes/techmap/zinit.cc
+++ b/passes/techmap/zinit.cc
@@ -57,17 +57,15 @@ struct ZinitPass : public Pass {
for (auto module : design->selected_modules())
{
SigMap sigmap(module);
- dict<SigBit, State> initbits;
- pool<SigBit> donebits;
+ dict<SigBit, std::pair<State,SigBit>> initbits;
for (auto wire : module->selected_wires())
{
- if (wire->attributes.count(ID(init)) == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec wirebits = sigmap(wire);
- Const initval = wire->attributes.at(ID(init));
- wire->attributes.erase(ID(init));
+ Const initval = wire->attributes.at(ID::init);
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
{
@@ -78,22 +76,25 @@ struct ZinitPass : public Pass {
continue;
if (initbits.count(bit)) {
- if (initbits.at(bit) != val)
+ if (initbits.at(bit).first != val)
log_error("Conflicting init values for signal %s (%s = %s != %s).\n",
log_signal(bit), log_signal(SigBit(wire, i)),
- log_signal(val), log_signal(initbits.at(bit)));
+ log_signal(val), log_signal(initbits.at(bit).first));
continue;
}
- initbits[bit] = val;
+ initbits[bit] = std::make_pair(val,SigBit(wire,i));
}
}
pool<IdString> dff_types = {
- ID($ff), ID($dff), ID($dffe), ID($dffsr), ID($adff),
+ // FIXME: It would appear that supporting
+ // $dffsr/$_DFFSR_* would require a new
+ // cell type where S has priority over R
+ ID($ff), ID($dff), ID($dffe), /*ID($dffsr),*/ ID($adff),
ID($_FF_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_),
- ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
- ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),
+ /*ID($_DFFSR_NNN_), ID($_DFFSR_NNP_), ID($_DFFSR_NPN_), ID($_DFFSR_NPP_),
+ ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_),*/
ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)
};
@@ -103,8 +104,8 @@ struct ZinitPass : public Pass {
if (!dff_types.count(cell->type))
continue;
- SigSpec sig_d = sigmap(cell->getPort(ID(D)));
- SigSpec sig_q = sigmap(cell->getPort(ID(Q)));
+ SigSpec sig_d = sigmap(cell->getPort(ID::D));
+ SigSpec sig_q = sigmap(cell->getPort(ID::Q));
if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
continue;
@@ -113,21 +114,23 @@ struct ZinitPass : public Pass {
for (int i = 0; i < GetSize(sig_q); i++) {
if (initbits.count(sig_q[i])) {
- initval.bits.push_back(initbits.at(sig_q[i]));
- donebits.insert(sig_q[i]);
+ const auto &d = initbits.at(sig_q[i]);
+ initval.bits.push_back(d.first);
+ const auto &b = d.second;
+ b.wire->attributes.at(ID::init)[b.offset] = State::Sx;
} else
initval.bits.push_back(all_mode ? State::S0 : State::Sx);
}
Wire *initwire = module->addWire(NEW_ID, GetSize(initval));
- initwire->attributes[ID(init)] = initval;
+ initwire->attributes[ID::init] = initval;
for (int i = 0; i < GetSize(initwire); i++)
- if (initval.bits.at(i) == State::S1)
+ if (initval[i] == State::S1)
{
sig_d[i] = module->NotGate(NEW_ID, sig_d[i]);
module->addNotGate(NEW_ID, SigSpec(initwire, i), sig_q[i]);
- initwire->attributes[ID(init)].bits.at(i) = State::S0;
+ initwire->attributes[ID::init][i] = State::S0;
}
else
{
@@ -137,13 +140,26 @@ struct ZinitPass : public Pass {
log("FF init value for cell %s (%s): %s = %s\n", log_id(cell), log_id(cell->type),
log_signal(sig_q), log_signal(initval));
- cell->setPort(ID(D), sig_d);
- cell->setPort(ID(Q), initwire);
- }
+ cell->setPort(ID::D, sig_d);
+ cell->setPort(ID::Q, initwire);
- for (auto &it : initbits)
- if (donebits.count(it.first) == 0)
- log_error("Failed to handle init bit %s = %s.\n", log_signal(it.first), log_signal(it.second));
+ if (cell->type == ID($adff)) {
+ auto val = cell->getParam(ID::ARST_VALUE);
+ for (int i = 0; i < GetSize(initwire); i++)
+ if (initval[i] == State::S1)
+ val[i] = (val[i] == State::S1 ? State::S0 : State::S1);
+ cell->setParam(ID::ARST_VALUE, std::move(val));
+ }
+ else if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
+ ID($_DFF_PN0_), ID($_DFF_PN1_), ID($_DFF_PP0_), ID($_DFF_PP1_)))
+ {
+ if (initval == State::S1) {
+ std::string t = cell->type.str();
+ t[8] = (t[8] == '0' ? '1' : '0');
+ cell->type = t;
+ }
+ }
+ }
}
}
} ZinitPass;
diff --git a/passes/tests/test_abcloop.cc b/passes/tests/test_abcloop.cc
index 5d5466afe..894610e2b 100644
--- a/passes/tests/test_abcloop.cc
+++ b/passes/tests/test_abcloop.cc
@@ -55,7 +55,7 @@ static void test_abcloop()
while (1)
{
- module = design->addModule("\\uut");
+ module = design->addModule(ID(UUT));
create_cycles++;
in_sig = {};
diff --git a/passes/tests/test_autotb.cc b/passes/tests/test_autotb.cc
index 2b6a86c25..42e8a61ea 100644
--- a/passes/tests/test_autotb.cc
+++ b/passes/tests/test_autotb.cc
@@ -85,7 +85,7 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int s
f << stringf("reg [31:0] xorshift128_x = 123456789;\n");
f << stringf("reg [31:0] xorshift128_y = 362436069;\n");
f << stringf("reg [31:0] xorshift128_z = 521288629;\n");
- f << stringf("reg [31:0] xorshift128_w = %u; // <-- seed value\n", seed ? seed : int(time(NULL)));
+ f << stringf("reg [31:0] xorshift128_w = %u; // <-- seed value\n", seed ? seed : int(time(nullptr)));
f << stringf("reg [31:0] xorshift128_t;\n\n");
f << stringf("task xorshift128;\n");
f << stringf("begin\n");
@@ -97,29 +97,26 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int s
f << stringf("end\n");
f << stringf("endtask\n\n");
- for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it)
+ for (auto mod : design->modules())
{
std::map<std::string, int> signal_in;
std::map<std::string, std::string> signal_const;
std::map<std::string, int> signal_clk;
std::map<std::string, int> signal_out;
- RTLIL::Module *mod = it->second;
-
- if (mod->get_bool_attribute("\\gentb_skip"))
+ if (mod->get_bool_attribute(ID::gentb_skip))
continue;
int count_ports = 0;
- log("Generating test bench for module `%s'.\n", it->first.c_str());
- for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); ++it2) {
- RTLIL::Wire *wire = it2->second;
+ log("Generating test bench for module `%s'.\n", mod->name.c_str());
+ for (auto wire : mod->wires()) {
if (wire->port_output) {
count_ports++;
signal_out[idy("sig", mod->name.str(), wire->name.str())] = wire->width;
f << stringf("wire [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str());
} else if (wire->port_input) {
count_ports++;
- bool is_clksignal = wire->get_bool_attribute("\\gentb_clock");
+ bool is_clksignal = wire->get_bool_attribute(ID::gentb_clock);
for (auto it3 = mod->processes.begin(); it3 != mod->processes.end(); ++it3)
for (auto it4 = it3->second->syncs.begin(); it4 != it3->second->syncs.end(); ++it4) {
if ((*it4)->type == RTLIL::ST0 || (*it4)->type == RTLIL::ST1)
@@ -129,19 +126,18 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int s
if (c.wire == wire)
is_clksignal = true;
}
- if (is_clksignal && wire->attributes.count("\\gentb_constant") == 0) {
+ if (is_clksignal && wire->attributes.count(ID::gentb_constant) == 0) {
signal_clk[idy("sig", mod->name.str(), wire->name.str())] = wire->width;
} else {
signal_in[idy("sig", mod->name.str(), wire->name.str())] = wire->width;
- if (wire->attributes.count("\\gentb_constant") != 0)
- signal_const[idy("sig", mod->name.str(), wire->name.str())] = wire->attributes["\\gentb_constant"].as_string();
+ if (wire->attributes.count(ID::gentb_constant) != 0)
+ signal_const[idy("sig", mod->name.str(), wire->name.str())] = wire->attributes[ID::gentb_constant].as_string();
}
f << stringf("reg [%d:0] %s;\n", wire->width-1, idy("sig", mod->name.str(), wire->name.str()).c_str());
}
}
f << stringf("%s %s(\n", id(mod->name.str()).c_str(), idy("uut", mod->name.str()).c_str());
- for (auto it2 = mod->wires_.begin(); it2 != mod->wires_.end(); ++it2) {
- RTLIL::Wire *wire = it2->second;
+ for (auto wire : mod->wires()) {
if (wire->port_output || wire->port_input)
f << stringf("\t.%s(%s)%s\n", id(wire->name.str()).c_str(),
idy("sig", mod->name.str(), wire->name.str()).c_str(), --count_ports ? "," : "");
@@ -312,9 +308,9 @@ static void autotest(std::ostream &f, RTLIL::Design *design, int num_iter, int s
f << stringf("\t// $dumpfile(\"testbench.vcd\");\n");
f << stringf("\t// $dumpvars(0, testbench);\n");
f << stringf("\tfile = $fopen(`outfile);\n");
- for (auto it = design->modules_.begin(); it != design->modules_.end(); ++it)
- if (!it->second->get_bool_attribute("\\gentb_skip"))
- f << stringf("\t%s;\n", idy(it->first.str(), "test").c_str());
+ for (auto module : design->modules())
+ if (!module->get_bool_attribute(ID::gentb_skip))
+ f << stringf("\t%s;\n", idy(module->name.str(), "test").c_str());
f << stringf("\t$fclose(file);\n");
f << stringf("\t$finish;\n");
f << stringf("end\n\n");
diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc
index 88116eeec..cdbe922b2 100644
--- a/passes/tests/test_cell.cc
+++ b/passes/tests/test_cell.cc
@@ -39,98 +39,98 @@ static uint32_t xorshift32(uint32_t limit) {
static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, std::string cell_type_flags, bool constmode, bool muxdiv)
{
- RTLIL::Module *module = design->addModule("\\gold");
- RTLIL::Cell *cell = module->addCell("\\UUT", cell_type);
+ RTLIL::Module *module = design->addModule(ID(gold));
+ RTLIL::Cell *cell = module->addCell(ID(UUT), cell_type);
RTLIL::Wire *wire;
- if (cell_type.in("$mux", "$pmux"))
+ if (cell_type.in(ID($mux), ID($pmux)))
{
int width = 1 + xorshift32(8);
- int swidth = cell_type == "$mux" ? 1 : 1 + xorshift32(8);
+ int swidth = cell_type == ID($mux) ? 1 : 1 + xorshift32(8);
- wire = module->addWire("\\A");
+ wire = module->addWire(ID::A);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\A", wire);
+ cell->setPort(ID::A, wire);
- wire = module->addWire("\\B");
+ wire = module->addWire(ID::B);
wire->width = width * swidth;
wire->port_input = true;
- cell->setPort("\\B", wire);
+ cell->setPort(ID::B, wire);
- wire = module->addWire("\\S");
+ wire = module->addWire(ID::S);
wire->width = swidth;
wire->port_input = true;
- cell->setPort("\\S", wire);
+ cell->setPort(ID::S, wire);
- wire = module->addWire("\\Y");
+ wire = module->addWire(ID::Y);
wire->width = width;
wire->port_output = true;
- cell->setPort("\\Y", wire);
+ cell->setPort(ID::Y, wire);
}
- if (cell_type == "$fa")
+ if (cell_type == ID($fa))
{
int width = 1 + xorshift32(8);
- wire = module->addWire("\\A");
+ wire = module->addWire(ID::A);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\A", wire);
+ cell->setPort(ID::A, wire);
- wire = module->addWire("\\B");
+ wire = module->addWire(ID::B);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\B", wire);
+ cell->setPort(ID::B, wire);
- wire = module->addWire("\\C");
+ wire = module->addWire(ID::C);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\C", wire);
+ cell->setPort(ID::C, wire);
- wire = module->addWire("\\X");
+ wire = module->addWire(ID::X);
wire->width = width;
wire->port_output = true;
- cell->setPort("\\X", wire);
+ cell->setPort(ID::X, wire);
- wire = module->addWire("\\Y");
+ wire = module->addWire(ID::Y);
wire->width = width;
wire->port_output = true;
- cell->setPort("\\Y", wire);
+ cell->setPort(ID::Y, wire);
}
- if (cell_type == "$lcu")
+ if (cell_type == ID($lcu))
{
int width = 1 + xorshift32(8);
- wire = module->addWire("\\P");
+ wire = module->addWire(ID::P);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\P", wire);
+ cell->setPort(ID::P, wire);
- wire = module->addWire("\\G");
+ wire = module->addWire(ID::G);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\G", wire);
+ cell->setPort(ID::G, wire);
- wire = module->addWire("\\CI");
+ wire = module->addWire(ID::CI);
wire->port_input = true;
- cell->setPort("\\CI", wire);
+ cell->setPort(ID::CI, wire);
- wire = module->addWire("\\CO");
+ wire = module->addWire(ID::CO);
wire->width = width;
wire->port_output = true;
- cell->setPort("\\CO", wire);
+ cell->setPort(ID::CO, wire);
}
- if (cell_type == "$macc")
+ if (cell_type == ID($macc))
{
Macc macc;
int width = 1 + xorshift32(8);
int depth = 1 + xorshift32(6);
int mulbits_a = 0, mulbits_b = 0;
- RTLIL::Wire *wire_a = module->addWire("\\A");
+ RTLIL::Wire *wire_a = module->addWire(ID::A);
wire_a->width = 0;
wire_a->port_input = true;
@@ -158,52 +158,52 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,
macc.ports.push_back(this_port);
}
- wire = module->addWire("\\B");
+ wire = module->addWire(ID::B);
wire->width = xorshift32(mulbits_a ? xorshift32(4)+1 : xorshift32(16)+1);
wire->port_input = true;
macc.bit_ports = wire;
- wire = module->addWire("\\Y");
+ wire = module->addWire(ID::Y);
wire->width = width;
wire->port_output = true;
- cell->setPort("\\Y", wire);
+ cell->setPort(ID::Y, wire);
macc.to_cell(cell);
}
- if (cell_type == "$lut")
+ if (cell_type == ID($lut))
{
int width = 1 + xorshift32(6);
- wire = module->addWire("\\A");
+ wire = module->addWire(ID::A);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\A", wire);
+ cell->setPort(ID::A, wire);
- wire = module->addWire("\\Y");
+ wire = module->addWire(ID::Y);
wire->port_output = true;
- cell->setPort("\\Y", wire);
+ cell->setPort(ID::Y, wire);
RTLIL::SigSpec config;
for (int i = 0; i < (1 << width); i++)
config.append(xorshift32(2) ? State::S1 : State::S0);
- cell->setParam("\\LUT", config.as_const());
+ cell->setParam(ID::LUT, config.as_const());
}
- if (cell_type == "$sop")
+ if (cell_type == ID($sop))
{
int width = 1 + xorshift32(8);
int depth = 1 + xorshift32(8);
- wire = module->addWire("\\A");
+ wire = module->addWire(ID::A);
wire->width = width;
wire->port_input = true;
- cell->setPort("\\A", wire);
+ cell->setPort(ID::A, wire);
- wire = module->addWire("\\Y");
+ wire = module->addWire(ID::Y);
wire->port_output = true;
- cell->setPort("\\Y", wire);
+ cell->setPort(ID::Y, wire);
RTLIL::SigSpec config;
for (int i = 0; i < width*depth; i++)
@@ -222,74 +222,74 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,
break;
}
- cell->setParam("\\DEPTH", depth);
- cell->setParam("\\TABLE", config.as_const());
+ cell->setParam(ID::DEPTH, depth);
+ cell->setParam(ID::TABLE, config.as_const());
}
if (cell_type_flags.find('A') != std::string::npos) {
- wire = module->addWire("\\A");
+ wire = module->addWire(ID::A);
wire->width = 1 + xorshift32(8);
wire->port_input = true;
- cell->setPort("\\A", wire);
+ cell->setPort(ID::A, wire);
}
if (cell_type_flags.find('B') != std::string::npos) {
- wire = module->addWire("\\B");
+ wire = module->addWire(ID::B);
if (cell_type_flags.find('h') != std::string::npos)
wire->width = 1 + xorshift32(6);
else
wire->width = 1 + xorshift32(8);
wire->port_input = true;
- cell->setPort("\\B", wire);
+ cell->setPort(ID::B, wire);
}
if (cell_type_flags.find('S') != std::string::npos && xorshift32(2)) {
if (cell_type_flags.find('A') != std::string::npos)
- cell->parameters["\\A_SIGNED"] = true;
+ cell->parameters[ID::A_SIGNED] = true;
if (cell_type_flags.find('B') != std::string::npos)
- cell->parameters["\\B_SIGNED"] = true;
+ cell->parameters[ID::B_SIGNED] = true;
}
if (cell_type_flags.find('s') != std::string::npos) {
if (cell_type_flags.find('A') != std::string::npos && xorshift32(2))
- cell->parameters["\\A_SIGNED"] = true;
+ cell->parameters[ID::A_SIGNED] = true;
if (cell_type_flags.find('B') != std::string::npos && xorshift32(2))
- cell->parameters["\\B_SIGNED"] = true;
+ cell->parameters[ID::B_SIGNED] = true;
}
if (cell_type_flags.find('Y') != std::string::npos) {
- wire = module->addWire("\\Y");
+ wire = module->addWire(ID::Y);
wire->width = 1 + xorshift32(8);
wire->port_output = true;
- cell->setPort("\\Y", wire);
+ cell->setPort(ID::Y, wire);
}
- if (muxdiv && cell_type.in("$div", "$mod")) {
- auto b_not_zero = module->ReduceBool(NEW_ID, cell->getPort("\\B"));
- auto div_out = module->addWire(NEW_ID, GetSize(cell->getPort("\\Y")));
- module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(div_out)), div_out, b_not_zero, cell->getPort("\\Y"));
- cell->setPort("\\Y", div_out);
+ if (muxdiv && cell_type.in(ID($div), ID($mod))) {
+ auto b_not_zero = module->ReduceBool(NEW_ID, cell->getPort(ID::B));
+ auto div_out = module->addWire(NEW_ID, GetSize(cell->getPort(ID::Y)));
+ module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(div_out)), div_out, b_not_zero, cell->getPort(ID::Y));
+ cell->setPort(ID::Y, div_out);
}
- if (cell_type == "$alu")
+ if (cell_type == ID($alu))
{
- wire = module->addWire("\\CI");
+ wire = module->addWire(ID::CI);
wire->port_input = true;
- cell->setPort("\\CI", wire);
+ cell->setPort(ID::CI, wire);
- wire = module->addWire("\\BI");
+ wire = module->addWire(ID::BI);
wire->port_input = true;
- cell->setPort("\\BI", wire);
+ cell->setPort(ID::BI, wire);
- wire = module->addWire("\\X");
- wire->width = GetSize(cell->getPort("\\Y"));
+ wire = module->addWire(ID::X);
+ wire->width = GetSize(cell->getPort(ID::Y));
wire->port_output = true;
- cell->setPort("\\X", wire);
+ cell->setPort(ID::X, wire);
- wire = module->addWire("\\CO");
- wire->width = GetSize(cell->getPort("\\Y"));
+ wire = module->addWire(ID::CO);
+ wire->width = GetSize(cell->getPort(ID::Y));
wire->port_output = true;
- cell->setPort("\\CO", wire);
+ cell->setPort(ID::CO, wire);
}
if (constmode)
@@ -421,8 +421,8 @@ static void run_eval_test(RTLIL::Design *design, bool verbose, bool nosat, std::
{
log("Eval testing:%c", verbose ? '\n' : ' ');
- RTLIL::Module *gold_mod = design->module("\\gold");
- RTLIL::Module *gate_mod = design->module("\\gate");
+ RTLIL::Module *gold_mod = design->module(ID(gold));
+ RTLIL::Module *gate_mod = design->module(ID(gate));
ConstEval gold_ce(gold_mod), gate_ce(gate_mod);
ezSatPtr ez1, ez2;
@@ -800,65 +800,65 @@ struct TestCellPass : public Pass {
log("Rng seed value: %d\n", int(xorshift32_state));
}
- std::map<std::string, std::string> cell_types;
- std::vector<std::string> selected_cell_types;
-
- cell_types["$not"] = "ASY";
- cell_types["$pos"] = "ASY";
- cell_types["$neg"] = "ASY";
-
- cell_types["$and"] = "ABSY";
- cell_types["$or"] = "ABSY";
- cell_types["$xor"] = "ABSY";
- cell_types["$xnor"] = "ABSY";
-
- cell_types["$reduce_and"] = "ASY";
- cell_types["$reduce_or"] = "ASY";
- cell_types["$reduce_xor"] = "ASY";
- cell_types["$reduce_xnor"] = "ASY";
- cell_types["$reduce_bool"] = "ASY";
-
- cell_types["$shl"] = "ABshY";
- cell_types["$shr"] = "ABshY";
- cell_types["$sshl"] = "ABshY";
- cell_types["$sshr"] = "ABshY";
- cell_types["$shift"] = "ABshY";
- cell_types["$shiftx"] = "ABshY";
-
- cell_types["$lt"] = "ABSY";
- cell_types["$le"] = "ABSY";
- cell_types["$eq"] = "ABSY";
- cell_types["$ne"] = "ABSY";
- // cell_types["$eqx"] = "ABSY";
- // cell_types["$nex"] = "ABSY";
- cell_types["$ge"] = "ABSY";
- cell_types["$gt"] = "ABSY";
-
- cell_types["$add"] = "ABSY";
- cell_types["$sub"] = "ABSY";
- cell_types["$mul"] = "ABSY";
- cell_types["$div"] = "ABSY";
- cell_types["$mod"] = "ABSY";
- // cell_types["$pow"] = "ABsY";
-
- cell_types["$logic_not"] = "ASY";
- cell_types["$logic_and"] = "ABSY";
- cell_types["$logic_or"] = "ABSY";
+ std::map<IdString, std::string> cell_types;
+ std::vector<IdString> selected_cell_types;
+
+ cell_types[ID($not)] = "ASY";
+ cell_types[ID($pos)] = "ASY";
+ cell_types[ID($neg)] = "ASY";
+
+ cell_types[ID($and)] = "ABSY";
+ cell_types[ID($or)] = "ABSY";
+ cell_types[ID($xor)] = "ABSY";
+ cell_types[ID($xnor)] = "ABSY";
+
+ cell_types[ID($reduce_and)] = "ASY";
+ cell_types[ID($reduce_or)] = "ASY";
+ cell_types[ID($reduce_xor)] = "ASY";
+ cell_types[ID($reduce_xnor)] = "ASY";
+ cell_types[ID($reduce_bool)] = "ASY";
+
+ cell_types[ID($shl)] = "ABshY";
+ cell_types[ID($shr)] = "ABshY";
+ cell_types[ID($sshl)] = "ABshY";
+ cell_types[ID($sshr)] = "ABshY";
+ cell_types[ID($shift)] = "ABshY";
+ cell_types[ID($shiftx)] = "ABshY";
+
+ cell_types[ID($lt)] = "ABSY";
+ cell_types[ID($le)] = "ABSY";
+ cell_types[ID($eq)] = "ABSY";
+ cell_types[ID($ne)] = "ABSY";
+ // cell_types[ID($eqx)] = "ABSY";
+ // cell_types[ID($nex)] = "ABSY";
+ cell_types[ID($ge)] = "ABSY";
+ cell_types[ID($gt)] = "ABSY";
+
+ cell_types[ID($add)] = "ABSY";
+ cell_types[ID($sub)] = "ABSY";
+ cell_types[ID($mul)] = "ABSY";
+ cell_types[ID($div)] = "ABSY";
+ cell_types[ID($mod)] = "ABSY";
+ // cell_types[ID($pow)] = "ABsY";
+
+ cell_types[ID($logic_not)] = "ASY";
+ cell_types[ID($logic_and)] = "ABSY";
+ cell_types[ID($logic_or)] = "ABSY";
if (edges) {
- cell_types["$mux"] = "*";
- cell_types["$pmux"] = "*";
+ cell_types[ID($mux)] = "*";
+ cell_types[ID($pmux)] = "*";
}
- // cell_types["$slice"] = "A";
- // cell_types["$concat"] = "A";
+ // cell_types[ID($slice)] = "A";
+ // cell_types[ID($concat)] = "A";
- cell_types["$lut"] = "*";
- cell_types["$sop"] = "*";
- cell_types["$alu"] = "ABSY";
- cell_types["$lcu"] = "*";
- cell_types["$macc"] = "*";
- cell_types["$fa"] = "*";
+ cell_types[ID($lut)] = "*";
+ cell_types[ID($sop)] = "*";
+ cell_types[ID($alu)] = "ABSY";
+ cell_types[ID($lcu)] = "*";
+ cell_types[ID($macc)] = "*";
+ cell_types[ID($fa)] = "*";
for (; argidx < GetSize(args); argidx++)
{
@@ -873,7 +873,7 @@ struct TestCellPass : public Pass {
}
if (args[argidx].compare(0, 1, "/") == 0) {
- std::vector<std::string> new_selected_cell_types;
+ std::vector<IdString> new_selected_cell_types;
for (auto it : selected_cell_types)
if (it != args[argidx].substr(1))
new_selected_cell_types.push_back(it);
@@ -886,10 +886,10 @@ struct TestCellPass : public Pass {
int charcount = 100;
for (auto &it : cell_types) {
if (charcount > 60) {
- cell_type_list += "\n" + it.first;
+ cell_type_list += stringf("\n%s", + log_id(it.first));
charcount = 0;
} else
- cell_type_list += " " + it.first;
+ cell_type_list += stringf(" %s", log_id(it.first));
charcount += GetSize(it.first);
}
log_cmd_error("The cell type `%s' is currently not supported. Try one of these:%s\n",
diff --git a/techlibs/achronix/synth_achronix.cc b/techlibs/achronix/synth_achronix.cc
index 1dc6bdb2f..262a5e700 100644
--- a/techlibs/achronix/synth_achronix.cc
+++ b/techlibs/achronix/synth_achronix.cc
@@ -144,7 +144,6 @@ struct SynthAchronixPass : public ScriptPass {
run("opt -fast -mux_undef -undriven -fine -full");
run("memory_map");
run("opt -undriven -fine");
- run("dffsr2dff");
run("dff2dffe -direct-match $_DFF_*");
run("opt -fine");
run("techmap -map +/techmap.v");
diff --git a/techlibs/anlogic/anlogic_eqn.cc b/techlibs/anlogic/anlogic_eqn.cc
index 070d39a20..e4fa4413f 100644
--- a/techlibs/anlogic/anlogic_eqn.cc
+++ b/techlibs/anlogic/anlogic_eqn.cc
@@ -74,34 +74,34 @@ struct AnlogicEqnPass : public Pass {
{
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\AL_MAP_LUT1")
+ if (cell->type == ID(AL_MAP_LUT1))
{
- cell->setParam("\\EQN", init2eqn(cell->getParam("\\INIT"),1));
+ cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT),1));
cnt++;
}
- if (cell->type == "\\AL_MAP_LUT2")
+ if (cell->type == ID(AL_MAP_LUT2))
{
- cell->setParam("\\EQN", init2eqn(cell->getParam("\\INIT"),2));
+ cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT),2));
cnt++;
}
- if (cell->type == "\\AL_MAP_LUT3")
+ if (cell->type == ID(AL_MAP_LUT3))
{
- cell->setParam("\\EQN", init2eqn(cell->getParam("\\INIT"),3));
+ cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT),3));
cnt++;
}
- if (cell->type == "\\AL_MAP_LUT4")
+ if (cell->type == ID(AL_MAP_LUT4))
{
- cell->setParam("\\EQN", init2eqn(cell->getParam("\\INIT"),4));
+ cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT),4));
cnt++;
}
- if (cell->type == "\\AL_MAP_LUT5")
+ if (cell->type == ID(AL_MAP_LUT5))
{
- cell->setParam("\\EQN", init2eqn(cell->getParam("\\INIT"),5));
+ cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT),5));
cnt++;
}
- if (cell->type == "\\AL_MAP_LUT6")
+ if (cell->type == ID(AL_MAP_LUT6))
{
- cell->setParam("\\EQN", init2eqn(cell->getParam("\\INIT"),6));
+ cell->setParam(ID(EQN), init2eqn(cell->getParam(ID::INIT),6));
cnt++;
}
}
diff --git a/techlibs/anlogic/anlogic_fixcarry.cc b/techlibs/anlogic/anlogic_fixcarry.cc
index 87164d375..f8e70260c 100644
--- a/techlibs/anlogic/anlogic_fixcarry.cc
+++ b/techlibs/anlogic/anlogic_fixcarry.cc
@@ -39,13 +39,13 @@ static void fix_carry_chain(Module *module)
for (auto cell : module->cells())
{
- if (cell->type == "\\AL_MAP_ADDER") {
- if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue;
- SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a"));
- SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b"));
+ if (cell->type == ID(AL_MAP_ADDER)) {
+ if (cell->getParam(ID(ALUTYPE)) != Const("ADD")) continue;
+ SigBit bit_i0 = get_bit_or_zero(cell->getPort(ID(a)));
+ SigBit bit_i1 = get_bit_or_zero(cell->getPort(ID(b)));
if (bit_i0 == State::S0 && bit_i1== State::S0) {
- SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c"));
- SigSpec o = cell->getPort("\\o");
+ SigBit bit_ci = get_bit_or_zero(cell->getPort(ID(c)));
+ SigSpec o = cell->getPort(ID(o));
if (GetSize(o) == 2) {
SigBit bit_o = o[0];
ci_bits.insert(bit_ci);
@@ -57,11 +57,11 @@ static void fix_carry_chain(Module *module)
vector<Cell*> adders_to_fix_cells;
for (auto cell : module->cells())
{
- if (cell->type == "\\AL_MAP_ADDER") {
- if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue;
- SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c"));
- SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a"));
- SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b"));
+ if (cell->type == ID(AL_MAP_ADDER)) {
+ if (cell->getParam(ID(ALUTYPE)) != Const("ADD")) continue;
+ SigBit bit_ci = get_bit_or_zero(cell->getPort(ID(c)));
+ SigBit bit_i0 = get_bit_or_zero(cell->getPort(ID(a)));
+ SigBit bit_i1 = get_bit_or_zero(cell->getPort(ID(b)));
SigBit canonical_bit = sigmap(bit_ci);
if (!ci_bits.count(canonical_bit))
continue;
@@ -75,23 +75,23 @@ static void fix_carry_chain(Module *module)
for (auto cell : adders_to_fix_cells)
{
- SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c"));
+ SigBit bit_ci = get_bit_or_zero(cell->getPort(ID(c)));
SigBit canonical_bit = sigmap(bit_ci);
auto bit = mapping_bits.at(canonical_bit);
log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell));
- Cell *c = module->addCell(NEW_ID, "\\AL_MAP_ADDER");
+ Cell *c = module->addCell(NEW_ID, ID(AL_MAP_ADDER));
SigBit new_bit = module->addWire(NEW_ID);
SigBit dummy_bit = module->addWire(NEW_ID);
SigSpec bits;
bits.append(dummy_bit);
bits.append(new_bit);
- c->setParam("\\ALUTYPE", Const("ADD_CARRY"));
- c->setPort("\\a", bit);
- c->setPort("\\b", State::S0);
- c->setPort("\\c", State::S0);
- c->setPort("\\o", bits);
+ c->setParam(ID(ALUTYPE), Const("ADD_CARRY"));
+ c->setPort(ID(a), bit);
+ c->setPort(ID(b), State::S0);
+ c->setPort(ID(c), State::S0);
+ c->setPort(ID(o), bits);
- cell->setPort("\\c", new_bit);
+ cell->setPort(ID(c), new_bit);
}
}
diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc
index 96a231286..791dc922f 100644
--- a/techlibs/anlogic/synth_anlogic.cc
+++ b/techlibs/anlogic/synth_anlogic.cc
@@ -182,7 +182,6 @@ struct SynthAnlogicPass : public ScriptPass
if (check_label("map_ffs"))
{
- run("dffsr2dff");
run("techmap -D NO_LUT -map +/anlogic/cells_map.v");
run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit");
run("opt_expr -mux_undef");
diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc
index d5e69a241..7b1e4b430 100644
--- a/techlibs/common/Makefile.inc
+++ b/techlibs/common/Makefile.inc
@@ -30,3 +30,4 @@ $(eval $(call add_share_file,share,techlibs/common/cmp2lut.v))
$(eval $(call add_share_file,share,techlibs/common/cells.lib))
$(eval $(call add_share_file,share,techlibs/common/mul2dsp.v))
$(eval $(call add_share_file,share,techlibs/common/abc9_model.v))
+$(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v))
diff --git a/techlibs/common/cmp2lcu.v b/techlibs/common/cmp2lcu.v
new file mode 100644
index 000000000..b6f4aeed6
--- /dev/null
+++ b/techlibs/common/cmp2lcu.v
@@ -0,0 +1,116 @@
+// This pass performs an optimisation that decomposes wide arithmetic
+// comparisons into LUT-size chunks (as guided by the `LUT_WIDTH
+// macro) connected to a single lookahead-carry-unit $lcu cell,
+// which is typically mapped to dedicated (and fast) FPGA
+// carry-chains.
+(* techmap_celltype = "$lt $le $gt $ge" *)
+module _80_lcu_cmp_ (A, B, Y);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 0;
+parameter B_WIDTH = 0;
+parameter Y_WIDTH = 0;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+output [Y_WIDTH-1:0] Y;
+
+parameter _TECHMAP_CELLTYPE_ = "";
+
+generate
+ if (_TECHMAP_CELLTYPE_ == "" || `LUT_WIDTH < 2)
+ wire _TECHMAP_FAIL_ = 1;
+ else if (_TECHMAP_CELLTYPE_ == "$lt") begin
+ // Transform $lt into $gt by swapping A and B
+ $gt #(.A_SIGNED(B_SIGNED), .B_SIGNED(A_SIGNED), .A_WIDTH(B_WIDTH), .B_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(B), .B(A), .Y(Y));
+ end
+ else if (_TECHMAP_CELLTYPE_ == "$le") begin
+ // Transform $le into $ge by swapping A and B
+ $ge #(.A_SIGNED(B_SIGNED), .B_SIGNED(A_SIGNED), .A_WIDTH(B_WIDTH), .B_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(B), .B(A), .Y(Y));
+ end
+ else begin
+ // Perform sign extension on A and B
+ localparam WIDTH = A_WIDTH > B_WIDTH ? A_WIDTH : B_WIDTH;
+ wire [WIDTH-1:0] AA = {{(WIDTH-A_WIDTH){A_SIGNED ? A[A_WIDTH-1] : 1'b0}}, A};
+ wire [WIDTH-1:0] BB = {{(WIDTH-B_WIDTH){B_SIGNED ? B[B_WIDTH-1] : 1'b0}}, B};
+ // For $ge operation, start with the assumption that A and B are
+ // equal (propagating this equality if A and B turn out to be so)
+ if (_TECHMAP_CELLTYPE_ == "$ge")
+ localparam CI = 1'b1;
+ else
+ localparam CI = 1'b0;
+ $__CMP2LCU #(.AB_WIDTH(WIDTH), .AB_SIGNED(A_SIGNED && B_SIGNED), .LCU_WIDTH(1), .BUDGET(`LUT_WIDTH), .CI(CI))
+ _TECHMAP_REPLACE_ (.A(AA), .B(BB), .P(1'b1), .G(1'b0), .Y(Y));
+ end
+endgenerate
+endmodule
+
+module $__CMP2LCU (A, B, P, G, Y);
+
+parameter AB_WIDTH = 0;
+parameter AB_SIGNED = 0;
+parameter LCU_WIDTH = 1;
+parameter BUDGET = 0;
+parameter CI = 0;
+
+input [AB_WIDTH-1:0] A; // A from original $gt/$ge
+input [AB_WIDTH-1:0] B; // B from original $gt/$ge
+input [LCU_WIDTH-1:0] P; // P of $lcu
+input [LCU_WIDTH-1:0] G; // G of $lcu
+output Y;
+
+parameter [AB_WIDTH-1:0] _TECHMAP_CONSTMSK_A_ = 0;
+parameter [AB_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
+parameter [LCU_WIDTH-1:0] _TECHMAP_CONSTMSK_P_ = 0;
+
+generate
+ if (AB_WIDTH == 0) begin
+ wire [LCU_WIDTH-1:0] CO;
+ $lcu #(.WIDTH(LCU_WIDTH)) _TECHMAP_REPLACE_ (.P(P), .G(G), .CI(CI), .CO(CO));
+ assign Y = CO[LCU_WIDTH-1];
+ end
+ else begin
+ if (_TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] && _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0])
+ localparam COST = 0;
+ else if (_TECHMAP_CONSTMSK_A_[AB_WIDTH-1:0] || _TECHMAP_CONSTMSK_B_[AB_WIDTH-1:0])
+ localparam COST = 1;
+ else
+ localparam COST = 2;
+
+ if (BUDGET < COST)
+ $__CMP2LCU #(.AB_WIDTH(AB_WIDTH), .AB_SIGNED(AB_SIGNED), .LCU_WIDTH(LCU_WIDTH+1), .BUDGET(`LUT_WIDTH), .CI(CI))
+ _TECHMAP_REPLACE_ (.A(A), .B(B), .P({P, 1'b1}), .G({G, 1'b0}), .Y(Y));
+ else begin
+ wire PP, GG;
+ // Bit-wise equality (xnor) of A and B
+ assign PP = A[AB_WIDTH-1] ^~ B[AB_WIDTH-1];
+ if (AB_SIGNED)
+ assign GG = ~A[AB_WIDTH-1] & B[AB_WIDTH-1];
+ else if (_TECHMAP_CONSTMSK_P_[LCU_WIDTH-1]) // First compare for LUT if P (and G) is constant
+ assign GG = A[AB_WIDTH-1] & ~B[AB_WIDTH-1];
+ else
+ // Priority "encoder" that checks A[i] == 1'b1 && B[i] == 1'b0
+ // from MSB down, deferring to less significant bits if the
+ // MSBs are equal
+ assign GG = P[0] & (A[AB_WIDTH-1] & ~B[AB_WIDTH-1]);
+ if (LCU_WIDTH == 1) begin
+ // Propagate only if all pairs are equal
+ // (inconclusive evidence to say A >= B)
+ wire P_ = P[0] & PP;
+ // Generate if any comparisons call for it
+ wire G_ = G[0] | GG;
+ end
+ else begin
+ // Propagate only if all pairs are equal
+ // (inconclusive evidence to say A >= B)
+ wire [LCU_WIDTH-1:0] P_ = {P[LCU_WIDTH-1:1], P[0] & PP};
+ // Generate if any comparisons call for it
+ wire [LCU_WIDTH-1:0] G_ = {G[LCU_WIDTH-1:1], G[0] | GG};
+ end
+ $__CMP2LCU #(.AB_WIDTH(AB_WIDTH-1), .AB_SIGNED(1'b0), .LCU_WIDTH(LCU_WIDTH), .BUDGET(BUDGET-COST), .CI(CI))
+ _TECHMAP_REPLACE_ (.A(A[AB_WIDTH-2:0]), .B(B[AB_WIDTH-2:0]), .P(P_), .G(G_), .Y(Y));
+ end
+ end
+endgenerate
+endmodule
diff --git a/techlibs/common/cmp2lut.v b/techlibs/common/cmp2lut.v
index 1c8192b85..8ecd356cc 100644
--- a/techlibs/common/cmp2lut.v
+++ b/techlibs/common/cmp2lut.v
@@ -57,10 +57,6 @@ function automatic [(1 << `LUT_WIDTH)-1:0] gen_lut;
o_bit = (lhs > rhs);
if (operation == 3)
o_bit = (lhs >= rhs);
- if (operation == 4)
- o_bit = (lhs == rhs);
- if (operation == 5)
- o_bit = (lhs != rhs);
gen_lut = gen_lut | (o_bit << n);
end
end
@@ -75,10 +71,6 @@ generate
localparam operation = 2;
if (_TECHMAP_CELLTYPE_ == "$ge")
localparam operation = 3;
- if (_TECHMAP_CELLTYPE_ == "$eq")
- localparam operation = 4;
- if (_TECHMAP_CELLTYPE_ == "$ne")
- localparam operation = 5;
if (A_WIDTH > `LUT_WIDTH || B_WIDTH > `LUT_WIDTH || Y_WIDTH != 1)
wire _TECHMAP_FAIL_ = 1;
diff --git a/techlibs/common/gen_fine_ffs.py b/techlibs/common/gen_fine_ffs.py
new file mode 100644
index 000000000..0abe48f61
--- /dev/null
+++ b/techlibs/common/gen_fine_ffs.py
@@ -0,0 +1,238 @@
+TEMPLATES = [
+"""
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_SR_{S:N|P}{R:N|P}_ (S, R, Q)
+//-
+//- A set-reset latch with {S:negative|positive} polarity SET and {R:negative|positive} polarity RESET.
+//-
+//- Truth table: S R | Q
+//- -----+---
+//- - {R:0|1} | 0
+//- {S:0|1} - | 1
+//- - - | q
+//-
+module \$_SR_{S:N|P}{R:N|P}_ (S, R, Q);
+input S, R;
+output reg Q;
+always @* begin
+ if (R == {R:0|1})
+ Q <= 0;
+ else if (S == {S:0|1})
+ Q <= 1;
+end
+endmodule
+""",
+"""
+`ifdef SIMCELLS_FF
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_FF_ (D, Q)
+//-
+//- A D-type flip-flop that is clocked from the implicit global clock. (This cell
+//- type is usually only used in netlists for formal verification.)
+//-
+module \$_FF_ (D, Q);
+input D;
+output reg Q;
+always @($global_clock) begin
+ Q <= D;
+end
+endmodule
+`endif
+""",
+"""
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_{C:N|P}_ (D, C, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop.
+//-
+//- Truth table: D C | Q
+//- -----+---
+//- d {C:\\|/} | d
+//- - - | q
+//-
+module \$_DFF_{C:N|P}_ (D, C, Q);
+input D, C;
+output reg Q;
+always @({C:neg|pos}edge C) begin
+ Q <= D;
+end
+endmodule
+""",
+"""
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFFE_{C:N|P}{E:N|P}_ (D, C, E, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {E:negative|positive} polarity enable.
+//-
+//- Truth table: D C E | Q
+//- -------+---
+//- d {C:\\|/} {E:0|1} | d
+//- - - - | q
+//-
+module \$_DFFE_{C:N|P}{E:N|P}_ (D, C, E, Q);
+input D, C, E;
+output reg Q;
+always @({C:neg|pos}edge C) begin
+ if ({E:!E|E}) Q <= D;
+end
+endmodule
+""",
+"""
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {R:negative|positive} polarity {V:reset|set}.
+//-
+//- Truth table: D C R | Q
+//- -------+---
+//- - - {R:0|1} | {V:0|1}
+//- d {C:\\|/} - | d
+//- - - - | q
+//-
+module \$_DFF_{C:N|P}{R:N|P}{V:0|1}_ (D, C, R, Q);
+input D, C, R;
+output reg Q;
+always @({C:neg|pos}edge C or {R:neg|pos}edge R) begin
+ if (R == {R:0|1})
+ Q <= {V:0|1};
+ else
+ Q <= D;
+end
+endmodule
+""",
+"""
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q)
+//-
+//- A {C:negative|positive} edge D-type flip-flop with {S:negative|positive} polarity set and {R:negative|positive}
+//- polarity reset.
+//-
+//- Truth table: C S R D | Q
+//- ---------+---
+//- - - {R:0|1} - | 0
+//- - {S:0|1} - - | 1
+//- {C:\\|/} - - d | d
+//- - - - - | q
+//-
+module \$_DFFSR_{C:N|P}{S:N|P}{R:N|P}_ (C, S, R, D, Q);
+input C, S, R, D;
+output reg Q;
+always @({C:neg|pos}edge C, {S:neg|pos}edge S, {R:neg|pos}edge R) begin
+ if (R == {R:0|1})
+ Q <= 0;
+ else if (S == {S:0|1})
+ Q <= 1;
+ else
+ Q <= D;
+end
+endmodule
+""",
+"""
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DLATCH_{E:N|P}_ (E, D, Q)
+//-
+//- A {E:negative|positive} enable D-type latch.
+//-
+//- Truth table: E D | Q
+//- -----+---
+//- {E:0|1} d | d
+//- - - | q
+//-
+module \$_DLATCH_{E:N|P}_ (E, D, Q);
+input E, D;
+output reg Q;
+always @* begin
+ if (E == {E:0|1})
+ Q <= D;
+end
+endmodule
+""",
+"""
+// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+//-
+//- $_DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q)
+//-
+//- A {E:negative|positive} enable D-type latch with {S:negative|positive} polarity set and {R:negative|positive}
+//- polarity reset.
+//-
+//- Truth table: E S R D | Q
+//- ---------+---
+//- - - {R:0|1} - | 0
+//- - {S:0|1} - - | 1
+//- {E:0|1} - - d | d
+//- - - - - | q
+//-
+module \$_DLATCHSR_{E:N|P}{S:N|P}{R:N|P}_ (E, S, R, D, Q);
+input E, S, R, D;
+output reg Q;
+always @* begin
+ if (R == {R:0|1})
+ Q <= 0;
+ else if (S == {S:0|1})
+ Q <= 1;
+ else if (E == {E:0|1})
+ Q <= D;
+end
+endmodule
+""",
+]
+
+lines = []
+with open('simcells.v') as f:
+ for l in f:
+ lines.append(l)
+ if 'START AUTOGENERATED CELL TYPES' in l:
+ break
+
+with open('simcells.v', 'w') as f:
+ for l in lines:
+ f.write(l)
+ for template in TEMPLATES:
+ chunks = []
+ vars = {}
+ pos = 0
+ while pos < len(template):
+ if template[pos] != '{':
+ np = template.find('{', pos)
+ if np == -1:
+ np = len(template)
+ chunks.append(template[pos:np])
+ pos = np
+ else:
+ np = template.index('}', pos)
+ sub = template[pos + 1:np]
+ pos = np + 1
+ var, _, vals = sub.partition(':')
+ if not vals:
+ raise ValueError(sub)
+ vals = vals.split('|')
+ if var not in vars:
+ vars[var] = len(vals)
+ else:
+ if vars[var] != len(vals):
+ raise ValueError(vars[var], vals)
+ chunks.append((var, vals))
+ combs = [{}]
+ for var in vars:
+ combs = [
+ {
+ var: i,
+ **comb,
+ }
+ for comb in combs
+ for i in range(vars[var])
+ ]
+ for comb in combs:
+ f.write(
+ ''.join(
+ c if isinstance(c, str) else c[1][comb[c[0]]]
+ for c in chunks
+ )
+ )
diff --git a/techlibs/common/simcells.v b/techlibs/common/simcells.v
index 64720e598..157e8d23b 100644
--- a/techlibs/common/simcells.v
+++ b/techlibs/common/simcells.v
@@ -456,23 +456,27 @@ output Y;
assign Y = E ? A : 1'bz;
endmodule
+// NOTE: the following cell types are autogenerated. DO NOT EDIT them manually,
+// instead edit the templates in gen_ff_types.py and rerun it.
+
+// START AUTOGENERATED CELL TYPES
+
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
//-
//- $_SR_NN_ (S, R, Q)
//-
-//- A set-reset latch with negative polarity SET and RESET.
+//- A set-reset latch with negative polarity SET and negative polarity RESET.
//-
//- Truth table: S R | Q
//- -----+---
-//- 0 0 | x
-//- 0 1 | 1
-//- 1 0 | 0
-//- 1 1 | y
+//- - 0 | 0
+//- 0 - | 1
+//- - - | q
//-
module \$_SR_NN_ (S, R, Q);
input S, R;
output reg Q;
-always @(negedge S, negedge R) begin
+always @* begin
if (R == 0)
Q <= 0;
else if (S == 0)
@@ -488,15 +492,14 @@ endmodule
//-
//- Truth table: S R | Q
//- -----+---
-//- 0 1 | x
-//- 0 0 | 1
-//- 1 1 | 0
-//- 1 0 | y
+//- - 1 | 0
+//- 0 - | 1
+//- - - | q
//-
module \$_SR_NP_ (S, R, Q);
input S, R;
output reg Q;
-always @(negedge S, posedge R) begin
+always @* begin
if (R == 1)
Q <= 0;
else if (S == 0)
@@ -512,15 +515,14 @@ endmodule
//-
//- Truth table: S R | Q
//- -----+---
-//- 1 0 | x
-//- 1 1 | 1
-//- 0 0 | 0
-//- 0 1 | y
+//- - 0 | 0
+//- 1 - | 1
+//- - - | q
//-
module \$_SR_PN_ (S, R, Q);
input S, R;
output reg Q;
-always @(posedge S, negedge R) begin
+always @* begin
if (R == 0)
Q <= 0;
else if (S == 1)
@@ -532,19 +534,18 @@ endmodule
//-
//- $_SR_PP_ (S, R, Q)
//-
-//- A set-reset latch with positive polarity SET and RESET.
+//- A set-reset latch with positive polarity SET and positive polarity RESET.
//-
//- Truth table: S R | Q
//- -----+---
-//- 1 1 | x
-//- 1 0 | 1
-//- 0 1 | 0
-//- 0 0 | y
+//- - 1 | 0
+//- 1 - | 1
+//- - - | q
//-
module \$_SR_PP_ (S, R, Q);
input S, R;
output reg Q;
-always @(posedge S, posedge R) begin
+always @* begin
if (R == 1)
Q <= 0;
else if (S == 1)
@@ -871,7 +872,8 @@ endmodule
//-
//- $_DFFSR_NNN_ (C, S, R, D, Q)
//-
-//- A negative edge D-type flip-flop with negative polarity set and reset.
+//- A negative edge D-type flip-flop with negative polarity set and negative
+//- polarity reset.
//-
//- Truth table: C S R D | Q
//- ---------+---
@@ -951,7 +953,8 @@ endmodule
//-
//- $_DFFSR_NPP_ (C, S, R, D, Q)
//-
-//- A negative edge D-type flip-flop with positive polarity set and reset.
+//- A negative edge D-type flip-flop with positive polarity set and positive
+//- polarity reset.
//-
//- Truth table: C S R D | Q
//- ---------+---
@@ -977,7 +980,8 @@ endmodule
//-
//- $_DFFSR_PNN_ (C, S, R, D, Q)
//-
-//- A positive edge D-type flip-flop with negative polarity set and reset.
+//- A positive edge D-type flip-flop with negative polarity set and negative
+//- polarity reset.
//-
//- Truth table: C S R D | Q
//- ---------+---
@@ -1057,7 +1061,8 @@ endmodule
//-
//- $_DFFSR_PPP_ (C, S, R, D, Q)
//-
-//- A positive edge D-type flip-flop with positive polarity set and reset.
+//- A positive edge D-type flip-flop with positive polarity set and positive
+//- polarity reset.
//-
//- Truth table: C S R D | Q
//- ---------+---
@@ -1123,7 +1128,8 @@ endmodule
//-
//- $_DLATCHSR_NNN_ (E, S, R, D, Q)
//-
-//- A negative enable D-type latch with negative polarity set and reset.
+//- A negative enable D-type latch with negative polarity set and negative
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1149,8 +1155,8 @@ endmodule
//-
//- $_DLATCHSR_NNP_ (E, S, R, D, Q)
//-
-//- A negative enable D-type latch with negative polarity set and positive polarity
-//- reset.
+//- A negative enable D-type latch with negative polarity set and positive
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1176,8 +1182,8 @@ endmodule
//-
//- $_DLATCHSR_NPN_ (E, S, R, D, Q)
//-
-//- A negative enable D-type latch with positive polarity set and negative polarity
-//- reset.
+//- A negative enable D-type latch with positive polarity set and negative
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1203,7 +1209,8 @@ endmodule
//-
//- $_DLATCHSR_NPP_ (E, S, R, D, Q)
//-
-//- A negative enable D-type latch with positive polarity set and reset.
+//- A negative enable D-type latch with positive polarity set and positive
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1229,7 +1236,8 @@ endmodule
//-
//- $_DLATCHSR_PNN_ (E, S, R, D, Q)
//-
-//- A positive enable D-type latch with negative polarity set and reset.
+//- A positive enable D-type latch with negative polarity set and negative
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1255,8 +1263,8 @@ endmodule
//-
//- $_DLATCHSR_PNP_ (E, S, R, D, Q)
//-
-//- A positive enable D-type latch with negative polarity set and positive polarity
-//- reset.
+//- A positive enable D-type latch with negative polarity set and positive
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1282,8 +1290,8 @@ endmodule
//-
//- $_DLATCHSR_PPN_ (E, S, R, D, Q)
//-
-//- A positive enable D-type latch with positive polarity set and negative polarity
-//- reset.
+//- A positive enable D-type latch with positive polarity set and negative
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1309,7 +1317,8 @@ endmodule
//-
//- $_DLATCHSR_PPP_ (E, S, R, D, Q)
//-
-//- A positive enable D-type latch with positive polarity set and reset.
+//- A positive enable D-type latch with positive polarity set and positive
+//- polarity reset.
//-
//- Truth table: E S R D | Q
//- ---------+---
@@ -1330,4 +1339,3 @@ always @* begin
Q <= D;
end
endmodule
-
diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v
index 7845a3fed..2cdddeabb 100644
--- a/techlibs/common/simlib.v
+++ b/techlibs/common/simlib.v
@@ -1633,7 +1633,7 @@ wire [WIDTH-1:0] pos_clr = CLR_POLARITY ? CLR : ~CLR;
genvar i;
generate
for (i = 0; i < WIDTH; i = i+1) begin:bitslices
- always @(posedge pos_set[i], posedge pos_clr[i])
+ always @*
if (pos_clr[i])
Q[i] <= 0;
else if (pos_set[i])
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc
index e7a192c07..d6dffdd7f 100644
--- a/techlibs/common/synth.cc
+++ b/techlibs/common/synth.cc
@@ -225,9 +225,9 @@ struct SynthPass : public ScriptPass
run("peepopt");
run("opt_clean");
if (help_mode)
- run("techmap -map +/cmp2lut.v", " (if -lut)");
- else
- run(stringf("techmap -map +/cmp2lut.v -D LUT_WIDTH=%d", lut));
+ run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)");
+ else if (lut)
+ run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut));
if (!noalumacc)
run("alumacc", " (unless -noalumacc)");
if (!noshare)
diff --git a/techlibs/coolrunner2/coolrunner2_fixup.cc b/techlibs/coolrunner2/coolrunner2_fixup.cc
index a71a1227e..8bbff9ba5 100644
--- a/techlibs/coolrunner2/coolrunner2_fixup.cc
+++ b/techlibs/coolrunner2/coolrunner2_fixup.cc
@@ -34,9 +34,9 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel
module->uniquify(stringf("$xc2fix$%s_BUF1_XOR_OUT", cellname)));
auto xor_cell = module->addCell(
module->uniquify(stringf("$xc2fix$%s_BUF1_XOR", cellname)),
- "\\MACROCELL_XOR");
- xor_cell->setParam("\\INVERT_OUT", true);
- xor_cell->setPort("\\OUT", outwire);
+ ID(MACROCELL_XOR));
+ xor_cell->setParam(ID(INVERT_OUT), true);
+ xor_cell->setPort(ID(OUT), outwire);
}
else if (inwire == SigBit(false))
{
@@ -45,9 +45,9 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel
module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname)));
auto xor_cell = module->addCell(
module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)),
- "\\MACROCELL_XOR");
- xor_cell->setParam("\\INVERT_OUT", false);
- xor_cell->setPort("\\OUT", outwire);
+ ID(MACROCELL_XOR));
+ xor_cell->setParam(ID(INVERT_OUT), false);
+ xor_cell->setPort(ID(OUT), outwire);
}
else if (inwire == SigBit(RTLIL::State::Sx))
{
@@ -57,9 +57,9 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel
module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname)));
auto xor_cell = module->addCell(
module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)),
- "\\MACROCELL_XOR");
- xor_cell->setParam("\\INVERT_OUT", false);
- xor_cell->setPort("\\OUT", outwire);
+ ID(MACROCELL_XOR));
+ xor_cell->setParam(ID(INVERT_OUT), false);
+ xor_cell->setPort(ID(OUT), outwire);
}
else
{
@@ -73,19 +73,19 @@ RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cel
auto and_cell = module->addCell(
module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)),
- "\\ANDTERM");
- and_cell->setParam("\\TRUE_INP", 1);
- and_cell->setParam("\\COMP_INP", 0);
- and_cell->setPort("\\OUT", and_to_xor_wire);
- and_cell->setPort("\\IN", inwire);
- and_cell->setPort("\\IN_B", SigSpec());
+ ID(ANDTERM));
+ and_cell->setParam(ID(TRUE_INP), 1);
+ and_cell->setParam(ID(COMP_INP), 0);
+ and_cell->setPort(ID(OUT), and_to_xor_wire);
+ and_cell->setPort(ID(IN), inwire);
+ and_cell->setPort(ID(IN_B), SigSpec());
auto xor_cell = module->addCell(
module->uniquify(stringf("$xc2fix$%s_BUF_XOR", inwire_name)),
- "\\MACROCELL_XOR");
- xor_cell->setParam("\\INVERT_OUT", false);
- xor_cell->setPort("\\IN_PTC", and_to_xor_wire);
- xor_cell->setPort("\\OUT", outwire);
+ ID(MACROCELL_XOR));
+ xor_cell->setParam(ID(INVERT_OUT), false);
+ xor_cell->setPort(ID(IN_PTC), and_to_xor_wire);
+ xor_cell->setPort(ID(OUT), outwire);
}
return outwire;
@@ -100,12 +100,12 @@ RTLIL::Wire *makeptermbuffer(RTLIL::Module *module, SigBit inwire)
auto and_cell = module->addCell(
module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)),
- "\\ANDTERM");
- and_cell->setParam("\\TRUE_INP", 1);
- and_cell->setParam("\\COMP_INP", 0);
- and_cell->setPort("\\OUT", outwire);
- and_cell->setPort("\\IN", inwire);
- and_cell->setPort("\\IN_B", SigSpec());
+ ID(ANDTERM));
+ and_cell->setParam(ID(TRUE_INP), 1);
+ and_cell->setParam(ID(COMP_INP), 0);
+ and_cell->setPort(ID(OUT), outwire);
+ and_cell->setPort(ID(IN), inwire);
+ and_cell->setPort(ID(IN_B), SigSpec());
return outwire;
}
@@ -133,10 +133,10 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_ff;
for (auto cell : module->selected_cells())
{
- if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
- "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ if (cell->type.in(ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(LDCP), ID(LDCP_N),
+ ID(FTCP), ID(FTCP_N), ID(FTDCP), ID(FDCPE), ID(FDCPE_N), ID(FDDCPE)))
{
- auto output = sigmap(cell->getPort("\\Q")[0]);
+ auto output = sigmap(cell->getPort(ID::Q)[0]);
sig_fed_by_ff.insert(output);
}
}
@@ -145,9 +145,9 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_xor;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\MACROCELL_XOR")
+ if (cell->type == ID(MACROCELL_XOR))
{
- auto output = sigmap(cell->getPort("\\OUT")[0]);
+ auto output = sigmap(cell->getPort(ID(OUT))[0]);
sig_fed_by_xor.insert(output);
}
}
@@ -156,10 +156,10 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_io;
for (auto cell : module->selected_cells())
{
- if (cell->type.in("\\IBUF", "\\IOBUFE"))
+ if (cell->type.in(ID(IBUF), ID(IOBUFE)))
{
- if (cell->hasPort("\\O")) {
- auto output = sigmap(cell->getPort("\\O")[0]);
+ if (cell->hasPort(ID::O)) {
+ auto output = sigmap(cell->getPort(ID::O)[0]);
sig_fed_by_io.insert(output);
}
}
@@ -169,9 +169,9 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_pterm;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\ANDTERM")
+ if (cell->type == ID(ANDTERM))
{
- auto output = sigmap(cell->getPort("\\OUT")[0]);
+ auto output = sigmap(cell->getPort(ID(OUT))[0]);
sig_fed_by_pterm.insert(output);
}
}
@@ -180,9 +180,9 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_bufg;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\BUFG")
+ if (cell->type == ID(BUFG))
{
- auto output = sigmap(cell->getPort("\\O")[0]);
+ auto output = sigmap(cell->getPort(ID::O)[0]);
sig_fed_by_bufg.insert(output);
}
}
@@ -191,9 +191,9 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_bufgsr;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\BUFGSR")
+ if (cell->type == ID(BUFGSR))
{
- auto output = sigmap(cell->getPort("\\O")[0]);
+ auto output = sigmap(cell->getPort(ID::O)[0]);
sig_fed_by_bufgsr.insert(output);
}
}
@@ -202,9 +202,9 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_bufgts;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\BUFGTS")
+ if (cell->type == ID(BUFGTS))
{
- auto output = sigmap(cell->getPort("\\O")[0]);
+ auto output = sigmap(cell->getPort(ID::O)[0]);
sig_fed_by_bufgts.insert(output);
}
}
@@ -213,9 +213,9 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> sig_fed_by_ibuf;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\IBUF")
+ if (cell->type == ID(IBUF))
{
- auto output = sigmap(cell->getPort("\\O")[0]);
+ auto output = sigmap(cell->getPort(ID::O)[0]);
sig_fed_by_ibuf.insert(output);
}
}
@@ -254,15 +254,15 @@ struct Coolrunner2FixupPass : public Pass {
// the pad-to-zia path has to be used up and the register
// can't be packed with the ibuf.
if (fanout_count == 1 && maybe_ff_cell->type.in(
- "\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
- "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(LDCP), ID(LDCP_N),
+ ID(FTCP), ID(FTCP_N), ID(FTDCP), ID(FDCPE), ID(FDCPE_N), ID(FDDCPE)))
{
SigBit input;
- if (maybe_ff_cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
- input = sigmap(maybe_ff_cell->getPort("\\T")[0]);
+ if (maybe_ff_cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP)))
+ input = sigmap(maybe_ff_cell->getPort(ID::T)[0]);
else
- input = sigmap(maybe_ff_cell->getPort("\\D")[0]);
- SigBit output = sigmap(maybe_ff_cell->getPort("\\Q")[0]);
+ input = sigmap(maybe_ff_cell->getPort(ID::D)[0]);
+ SigBit output = sigmap(maybe_ff_cell->getPort(ID::Q)[0]);
if (input == ibuf_out_wire)
{
@@ -279,17 +279,17 @@ struct Coolrunner2FixupPass : public Pass {
for (auto cell : module->selected_cells())
{
- if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\LDCP", "\\LDCP_N",
- "\\FTCP", "\\FTCP_N", "\\FTDCP", "\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ if (cell->type.in(ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(LDCP), ID(LDCP_N),
+ ID(FTCP), ID(FTCP_N), ID(FTDCP), ID(FDCPE), ID(FDCPE_N), ID(FDDCPE)))
{
// Buffering FF inputs. FF inputs can only come from either
// an IO pin or from an XOR. Otherwise AND/XOR cells need
// to be inserted.
SigBit input;
- if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
- input = sigmap(cell->getPort("\\T")[0]);
+ if (cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP)))
+ input = sigmap(cell->getPort(ID::T)[0]);
else
- input = sigmap(cell->getPort("\\D")[0]);
+ input = sigmap(cell->getPort(ID::D)[0]);
// If the input wasn't an XOR nor an IO, then a buffer
// definitely needs to be added.
@@ -302,10 +302,10 @@ struct Coolrunner2FixupPass : public Pass {
auto xor_to_ff_wire = makexorbuffer(module, input, cell->name.c_str());
- if (cell->type.in("\\FTCP", "\\FTCP_N", "\\FTDCP"))
- cell->setPort("\\T", xor_to_ff_wire);
+ if (cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP)))
+ cell->setPort(ID::T, xor_to_ff_wire);
else
- cell->setPort("\\D", xor_to_ff_wire);
+ cell->setPort(ID::D, xor_to_ff_wire);
}
// Buffering FF clocks. FF clocks can only come from either
@@ -313,10 +313,10 @@ struct Coolrunner2FixupPass : public Pass {
// in coolrunner2_sop (e.g. if clock is generated from
// AND-ing two signals) but not in all cases.
SigBit clock;
- if (cell->type.in("\\LDCP", "\\LDCP_N"))
- clock = sigmap(cell->getPort("\\G")[0]);
+ if (cell->type.in(ID(LDCP), ID(LDCP_N)))
+ clock = sigmap(cell->getPort(ID::G)[0]);
else
- clock = sigmap(cell->getPort("\\C")[0]);
+ clock = sigmap(cell->getPort(ID::C)[0]);
if (!sig_fed_by_pterm[clock] && !sig_fed_by_bufg[clock])
{
@@ -324,16 +324,16 @@ struct Coolrunner2FixupPass : public Pass {
auto pterm_to_ff_wire = makeptermbuffer(module, clock);
- if (cell->type.in("\\LDCP", "\\LDCP_N"))
- cell->setPort("\\G", pterm_to_ff_wire);
+ if (cell->type.in(ID(LDCP), ID(LDCP_N)))
+ cell->setPort(ID::G, pterm_to_ff_wire);
else
- cell->setPort("\\C", pterm_to_ff_wire);
+ cell->setPort(ID::C, pterm_to_ff_wire);
}
// Buffering FF set/reset. This can only come from either
// a pterm or a bufgsr.
SigBit set;
- set = sigmap(cell->getPort("\\PRE")[0]);
+ set = sigmap(cell->getPort(ID(PRE))[0]);
if (set != SigBit(false))
{
if (!sig_fed_by_pterm[set] && !sig_fed_by_bufgsr[set])
@@ -342,12 +342,12 @@ struct Coolrunner2FixupPass : public Pass {
auto pterm_to_ff_wire = makeptermbuffer(module, set);
- cell->setPort("\\PRE", pterm_to_ff_wire);
+ cell->setPort(ID(PRE), pterm_to_ff_wire);
}
}
SigBit reset;
- reset = sigmap(cell->getPort("\\CLR")[0]);
+ reset = sigmap(cell->getPort(ID::CLR)[0]);
if (reset != SigBit(false))
{
if (!sig_fed_by_pterm[reset] && !sig_fed_by_bufgsr[reset])
@@ -356,24 +356,24 @@ struct Coolrunner2FixupPass : public Pass {
auto pterm_to_ff_wire = makeptermbuffer(module, reset);
- cell->setPort("\\CLR", pterm_to_ff_wire);
+ cell->setPort(ID::CLR, pterm_to_ff_wire);
}
}
// Buffering FF clock enable
// FIXME: This doesn't fully fix PTC conflicts
// FIXME: Need to ensure constant enables are optimized out
- if (cell->type.in("\\FDCPE", "\\FDCPE_N", "\\FDDCPE"))
+ if (cell->type.in(ID(FDCPE), ID(FDCPE_N), ID(FDDCPE)))
{
SigBit ce;
- ce = sigmap(cell->getPort("\\CE")[0]);
+ ce = sigmap(cell->getPort(ID(CE))[0]);
if (!sig_fed_by_pterm[ce])
{
log("Buffering clock enable to \"%s\"\n", cell->name.c_str());
auto pterm_to_ff_wire = makeptermbuffer(module, ce);
- cell->setPort("\\CE", pterm_to_ff_wire);
+ cell->setPort(ID(CE), pterm_to_ff_wire);
}
}
}
@@ -381,10 +381,10 @@ struct Coolrunner2FixupPass : public Pass {
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\IOBUFE")
+ if (cell->type == ID(IOBUFE))
{
// Buffer IOBUFE inputs. This can only be fed from an XOR or FF.
- SigBit input = sigmap(cell->getPort("\\I")[0]);
+ SigBit input = sigmap(cell->getPort(ID::I)[0]);
if ((!sig_fed_by_xor[input] && !sig_fed_by_ff[input]) ||
packed_reg_out[input])
@@ -393,22 +393,22 @@ struct Coolrunner2FixupPass : public Pass {
auto xor_to_io_wire = makexorbuffer(module, input, cell->name.c_str());
- cell->setPort("\\I", xor_to_io_wire);
+ cell->setPort(ID::I, xor_to_io_wire);
}
// Buffer IOBUFE enables. This can only be fed from a pterm
// or a bufgts.
- if (cell->hasPort("\\E"))
+ if (cell->hasPort(ID::E))
{
SigBit oe;
- oe = sigmap(cell->getPort("\\E")[0]);
+ oe = sigmap(cell->getPort(ID::E)[0]);
if (!sig_fed_by_pterm[oe] && !sig_fed_by_bufgts[oe])
{
log("Buffering output enable to \"%s\"\n", cell->name.c_str());
auto pterm_to_oe_wire = makeptermbuffer(module, oe);
- cell->setPort("\\E", pterm_to_oe_wire);
+ cell->setPort(ID::E, pterm_to_oe_wire);
}
}
}
@@ -422,9 +422,9 @@ struct Coolrunner2FixupPass : public Pass {
dict<SigBit, RTLIL::Cell *> xor_out_to_xor_cell;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\MACROCELL_XOR")
+ if (cell->type == ID(MACROCELL_XOR))
{
- auto output = sigmap(cell->getPort("\\OUT")[0]);
+ auto output = sigmap(cell->getPort(ID(OUT))[0]);
xor_out_to_xor_cell[output] = cell;
}
}
@@ -433,7 +433,7 @@ struct Coolrunner2FixupPass : public Pass {
pool<SigBit> xor_fanout_once;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\ANDTERM")
+ if (cell->type == ID(ANDTERM))
continue;
for (auto &conn : cell->connections())
@@ -456,7 +456,7 @@ struct Coolrunner2FixupPass : public Pass {
module->uniquify(xor_cell->name), xor_cell);
auto new_wire = module->addWire(
module->uniquify(wire_in.wire->name));
- new_xor_cell->setPort("\\OUT", new_wire);
+ new_xor_cell->setPort(ID(OUT), new_wire);
cell->setPort(conn.first, new_wire);
}
xor_fanout_once.insert(wire_in);
@@ -473,9 +473,9 @@ struct Coolrunner2FixupPass : public Pass {
dict<SigBit, RTLIL::Cell *> or_out_to_or_cell;
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\ORTERM")
+ if (cell->type == ID(ORTERM))
{
- auto output = sigmap(cell->getPort("\\OUT")[0]);
+ auto output = sigmap(cell->getPort(ID(OUT))[0]);
or_out_to_or_cell[output] = cell;
}
}
@@ -504,7 +504,7 @@ struct Coolrunner2FixupPass : public Pass {
module->uniquify(or_cell->name), or_cell);
auto new_wire = module->addWire(
module->uniquify(wire_in.wire->name));
- new_or_cell->setPort("\\OUT", new_wire);
+ new_or_cell->setPort(ID(OUT), new_wire);
cell->setPort(conn.first, new_wire);
}
or_fanout_once.insert(wire_in);
diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc
index 581477473..045c73978 100644
--- a/techlibs/coolrunner2/coolrunner2_sop.cc
+++ b/techlibs/coolrunner2/coolrunner2_sop.cc
@@ -47,52 +47,52 @@ struct Coolrunner2SopPass : public Pass {
dict<SigBit, tuple<SigBit, Cell*>> not_cells;
for (auto cell : module->selected_cells())
{
- if (cell->type == "$_NOT_")
+ if (cell->type == ID($_NOT_))
{
- auto not_input = sigmap(cell->getPort("\\A")[0]);
- auto not_output = sigmap(cell->getPort("\\Y")[0]);
+ auto not_input = sigmap(cell->getPort(ID::A)[0]);
+ auto not_output = sigmap(cell->getPort(ID::Y)[0]);
not_cells[not_input] = tuple<SigBit, Cell*>(not_output, cell);
}
}
// Find wires that need to become special product terms
- dict<SigBit, pool<tuple<Cell*, std::string>>> special_pterms_no_inv;
- dict<SigBit, pool<tuple<Cell*, std::string>>> special_pterms_inv;
+ dict<SigBit, pool<tuple<Cell*, IdString>>> special_pterms_no_inv;
+ dict<SigBit, pool<tuple<Cell*, IdString>>> special_pterms_inv;
for (auto cell : module->selected_cells())
{
- if (cell->type.in("\\FDCP", "\\FDCP_N", "\\FDDCP", "\\FTCP", "\\FTCP_N", "\\FTDCP",
- "\\FDCPE", "\\FDCPE_N", "\\FDDCPE", "\\LDCP", "\\LDCP_N"))
+ if (cell->type.in(ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(FTCP), ID(FTCP_N), ID(FTDCP),
+ ID(FDCPE), ID(FDCPE_N), ID(FDDCPE), ID(LDCP), ID(LDCP_N)))
{
- if (cell->hasPort("\\PRE"))
- special_pterms_no_inv[sigmap(cell->getPort("\\PRE")[0])].insert(
- tuple<Cell*, const char *>(cell, "\\PRE"));
- if (cell->hasPort("\\CLR"))
- special_pterms_no_inv[sigmap(cell->getPort("\\CLR")[0])].insert(
- tuple<Cell*, const char *>(cell, "\\CLR"));
- if (cell->hasPort("\\CE"))
- special_pterms_no_inv[sigmap(cell->getPort("\\CE")[0])].insert(
- tuple<Cell*, const char *>(cell, "\\CE"));
-
- if (cell->hasPort("\\C"))
- special_pterms_inv[sigmap(cell->getPort("\\C")[0])].insert(
- tuple<Cell*, const char *>(cell, "\\C"));
- if (cell->hasPort("\\G"))
- special_pterms_inv[sigmap(cell->getPort("\\G")[0])].insert(
- tuple<Cell*, const char *>(cell, "\\G"));
+ if (cell->hasPort(ID(PRE)))
+ special_pterms_no_inv[sigmap(cell->getPort(ID(PRE))[0])].insert(
+ make_tuple(cell, ID(PRE)));
+ if (cell->hasPort(ID::CLR))
+ special_pterms_no_inv[sigmap(cell->getPort(ID::CLR)[0])].insert(
+ make_tuple(cell, ID::CLR));
+ if (cell->hasPort(ID(CE)))
+ special_pterms_no_inv[sigmap(cell->getPort(ID(CE))[0])].insert(
+ make_tuple(cell, ID(CE)));
+
+ if (cell->hasPort(ID::C))
+ special_pterms_inv[sigmap(cell->getPort(ID::C)[0])].insert(
+ make_tuple(cell, ID::C));
+ if (cell->hasPort(ID::G))
+ special_pterms_inv[sigmap(cell->getPort(ID::G)[0])].insert(
+ make_tuple(cell, ID::G));
}
}
// Process $sop cells
for (auto cell : module->selected_cells())
{
- if (cell->type == "$sop")
+ if (cell->type == ID($sop))
{
// Read the inputs/outputs/parameters of the $sop cell
- auto sop_inputs = sigmap(cell->getPort("\\A"));
- auto sop_output = sigmap(cell->getPort("\\Y"))[0];
- auto sop_depth = cell->getParam("\\DEPTH").as_int();
- auto sop_width = cell->getParam("\\WIDTH").as_int();
- auto sop_table = cell->getParam("\\TABLE");
+ auto sop_inputs = sigmap(cell->getPort(ID::A));
+ auto sop_output = sigmap(cell->getPort(ID::Y))[0];
+ auto sop_depth = cell->getParam(ID::DEPTH).as_int();
+ auto sop_width = cell->getParam(ID::WIDTH).as_int();
+ auto sop_table = cell->getParam(ID::TABLE);
auto sop_output_wire_name = sop_output.wire->name.c_str();
@@ -139,12 +139,12 @@ struct Coolrunner2SopPass : public Pass {
// Construct the cell
auto and_cell = module->addCell(
module->uniquify(stringf("$xc2sop$%s_AND%d", sop_output_wire_name, i)),
- "\\ANDTERM");
- and_cell->setParam("\\TRUE_INP", GetSize(and_in_true));
- and_cell->setParam("\\COMP_INP", GetSize(and_in_comp));
- and_cell->setPort("\\OUT", and_out);
- and_cell->setPort("\\IN", and_in_true);
- and_cell->setPort("\\IN_B", and_in_comp);
+ ID(ANDTERM));
+ and_cell->setParam(ID(TRUE_INP), GetSize(and_in_true));
+ and_cell->setParam(ID(COMP_INP), GetSize(and_in_comp));
+ and_cell->setPort(ID(OUT), and_out);
+ and_cell->setPort(ID(IN), and_in_true);
+ and_cell->setPort(ID(IN_B), and_in_comp);
}
if (sop_depth == 1)
@@ -152,17 +152,17 @@ struct Coolrunner2SopPass : public Pass {
// If there is only one term, don't construct an OR cell. Directly construct the XOR gate
auto xor_cell = module->addCell(
module->uniquify(stringf("$xc2sop$%s_XOR", sop_output_wire_name)),
- "\\MACROCELL_XOR");
- xor_cell->setParam("\\INVERT_OUT", has_invert);
- xor_cell->setPort("\\IN_PTC", *intermed_wires.begin());
- xor_cell->setPort("\\OUT", sop_output);
+ ID(MACROCELL_XOR));
+ xor_cell->setParam(ID(INVERT_OUT), has_invert);
+ xor_cell->setPort(ID(IN_PTC), *intermed_wires.begin());
+ xor_cell->setPort(ID(OUT), sop_output);
// Special P-term handling
if (is_special_pterm)
{
// Can always connect the P-term directly if it's going
// into something invert-capable
- for (auto x : special_pterms_inv[sop_output])
+ for (const auto &x : special_pterms_inv[sop_output])
{
std::get<0>(x)->setPort(std::get<1>(x), *intermed_wires.begin());
@@ -170,14 +170,14 @@ struct Coolrunner2SopPass : public Pass {
if (has_invert)
{
auto cell = std::get<0>(x);
- if (cell->type == "\\FDCP") cell->type = "\\FDCP_N";
- else if (cell->type == "\\FDCP_N") cell->type = "\\FDCP";
- else if (cell->type == "\\FTCP") cell->type = "\\FTCP_N";
- else if (cell->type == "\\FTCP_N") cell->type = "\\FTCP";
- else if (cell->type == "\\FDCPE") cell->type = "\\FDCPE_N";
- else if (cell->type == "\\FDCPE_N") cell->type = "\\FDCPE";
- else if (cell->type == "\\LDCP") cell->type = "\\LDCP_N";
- else if (cell->type == "\\LDCP_N") cell->type = "\\LDCP";
+ if (cell->type == ID(FDCP)) cell->type = ID(FDCP_N);
+ else if (cell->type == ID(FDCP_N)) cell->type = ID(FDCP);
+ else if (cell->type == ID(FTCP)) cell->type = ID(FTCP_N);
+ else if (cell->type == ID(FTCP_N)) cell->type = ID(FTCP);
+ else if (cell->type == ID(FDCPE)) cell->type = ID(FDCPE_N);
+ else if (cell->type == ID(FDCPE_N)) cell->type = ID(FDCPE);
+ else if (cell->type == ID(LDCP)) cell->type = ID(LDCP_N);
+ else if (cell->type == ID(LDCP_N)) cell->type = ID(LDCP);
else log_assert(!"Internal error! Bad cell type!");
}
}
@@ -203,18 +203,18 @@ struct Coolrunner2SopPass : public Pass {
// Construct the OR cell
auto or_cell = module->addCell(
module->uniquify(stringf("$xc2sop$%s_OR", sop_output_wire_name)),
- "\\ORTERM");
- or_cell->setParam("\\WIDTH", sop_depth);
- or_cell->setPort("\\IN", intermed_wires);
- or_cell->setPort("\\OUT", or_to_xor_wire);
+ ID(ORTERM));
+ or_cell->setParam(ID::WIDTH, sop_depth);
+ or_cell->setPort(ID(IN), intermed_wires);
+ or_cell->setPort(ID(OUT), or_to_xor_wire);
// Construct the XOR cell
auto xor_cell = module->addCell(
module->uniquify(stringf("$xc2sop$%s_XOR", sop_output_wire_name)),
- "\\MACROCELL_XOR");
- xor_cell->setParam("\\INVERT_OUT", has_invert);
- xor_cell->setPort("\\IN_ORTERM", or_to_xor_wire);
- xor_cell->setPort("\\OUT", sop_output);
+ ID(MACROCELL_XOR));
+ xor_cell->setParam(ID(INVERT_OUT), has_invert);
+ xor_cell->setPort(ID(IN_ORTERM), or_to_xor_wire);
+ xor_cell->setPort(ID(OUT), sop_output);
}
// Finally, remove the $sop cell
diff --git a/techlibs/ecp5/brams.txt b/techlibs/ecp5/brams.txt
index 777ccaa2e..d34d9ec07 100644
--- a/techlibs/ecp5/brams.txt
+++ b/techlibs/ecp5/brams.txt
@@ -37,7 +37,17 @@ bram $__ECP5_DP16KD
clkpol 2 3
endbram
+# The syn_* attributes are described in:
+# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
+attr_icase 1
+
match $__ECP5_PDPW16KD
+ # implicitly requested RAM or ROM
+ attribute !syn_ramstyle syn_ramstyle=auto
+ attribute !syn_romstyle syn_romstyle=auto
+ attribute !ram_block
+ attribute !rom_block
+ attribute !logic_block
min bits 2048
min efficiency 5
shuffle_enable A
@@ -45,8 +55,60 @@ match $__ECP5_PDPW16KD
or_next_if_better
endmatch
+match $__ECP5_PDPW16KD
+ # explicitly requested RAM
+ attribute syn_ramstyle=block_ram ram_block
+ attribute !syn_romstyle
+ attribute !rom_block
+ attribute !logic_block
+ min wports 1
+ shuffle_enable A
+ make_transp
+ or_next_if_better
+endmatch
+
+match $__ECP5_PDPW16KD
+ # explicitly requested ROM
+ attribute syn_romstyle=ebr rom_block
+ attribute !syn_ramstyle
+ attribute !ram_block
+ attribute !logic_block
+ max wports 0
+ shuffle_enable A
+ make_transp
+ or_next_if_better
+endmatch
+
match $__ECP5_DP16KD
+ # implicitly requested RAM or ROM
+ attribute !syn_ramstyle syn_ramstyle=auto
+ attribute !syn_romstyle syn_romstyle=auto
+ attribute !ram_block
+ attribute !rom_block
+ attribute !logic_block
min bits 2048
min efficiency 5
shuffle_enable A
+ or_next_if_better
+endmatch
+
+match $__ECP5_DP16KD
+ # explicitly requested RAM
+ attribute syn_ramstyle=block_ram ram_block
+ attribute !syn_romstyle
+ attribute !rom_block
+ attribute !logic_block
+ min wports 1
+ shuffle_enable A
+ or_next_if_better
+endmatch
+
+match $__ECP5_DP16KD
+ # explicitly requested ROM
+ attribute syn_romstyle=ebr rom_block
+ attribute !syn_ramstyle
+ attribute !ram_block
+ attribute !logic_block
+ max wports 0
+ shuffle_enable A
endmatch
diff --git a/techlibs/ecp5/ecp5_ffinit.cc b/techlibs/ecp5/ecp5_ffinit.cc
index dbd16cac9..e85bee64e 100644
--- a/techlibs/ecp5/ecp5_ffinit.cc
+++ b/techlibs/ecp5/ecp5_ffinit.cc
@@ -63,11 +63,11 @@ struct Ecp5FfinitPass : public Pass {
for (auto wire : module->selected_wires())
{
- if (wire->attributes.count("\\init") == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec wirebits = sigmap(wire);
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
init_wires.insert(wire);
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
@@ -94,11 +94,11 @@ struct Ecp5FfinitPass : public Pass {
}
for (auto cell : module->selected_cells())
{
- if (cell->type != "\\TRELLIS_FF")
+ if (cell->type != ID(TRELLIS_FF))
continue;
- SigSpec sig_d = cell->getPort("\\DI");
- SigSpec sig_q = cell->getPort("\\Q");
- SigSpec sig_lsr = cell->getPort("\\LSR");
+ SigSpec sig_d = cell->getPort(ID(DI));
+ SigSpec sig_q = cell->getPort(ID::Q);
+ SigSpec sig_lsr = cell->getPort(ID(LSR));
if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
continue;
@@ -107,8 +107,8 @@ struct Ecp5FfinitPass : public Pass {
SigBit bit_q = sigmap(sig_q[0]);
std::string regset = "RESET";
- if (cell->hasParam("\\REGSET"))
- regset = cell->getParam("\\REGSET").decode_string();
+ if (cell->hasParam(ID(REGSET)))
+ regset = cell->getParam(ID(REGSET)).decode_string();
State resetState;
if (regset == "SET")
resetState = State::S1;
@@ -136,8 +136,8 @@ struct Ecp5FfinitPass : public Pass {
if (GetSize(sig_lsr) >= 1 && sig_lsr[0] != State::S0) {
std::string srmode = "LSR_OVER_CE";
- if (cell->hasParam("\\SRMODE"))
- srmode = cell->getParam("\\SRMODE").decode_string();
+ if (cell->hasParam(ID(SRMODE)))
+ srmode = cell->getParam(ID(SRMODE)).decode_string();
if (srmode == "ASYNC") {
log("Async reset value %c for FF cell %s inconsistent with init value %c.\n",
resetState != State::S0 ? '1' : '0', log_id(cell), val != State::S0 ? '1' : '0');
@@ -150,14 +150,14 @@ struct Ecp5FfinitPass : public Pass {
module->addOrGate(NEW_ID, bit_d, bit_lsr, new_bit_d);
}
- cell->setPort("\\DI", new_bit_d);
- cell->setPort("\\LSR", State::S0);
+ cell->setPort(ID(DI), new_bit_d);
+ cell->setPort(ID(LSR), State::S0);
- if(cell->hasPort("\\CE")) {
+ if(cell->hasPort(ID(CE))) {
std::string cemux = "CE";
- if (cell->hasParam("\\CEMUX"))
- cemux = cell->getParam("\\CEMUX").decode_string();
- SigSpec sig_ce = cell->getPort("\\CE");
+ if (cell->hasParam(ID(CEMUX)))
+ cemux = cell->getParam(ID(CEMUX)).decode_string();
+ SigSpec sig_ce = cell->getPort(ID(CE));
if (GetSize(sig_ce) >= 1) {
SigBit bit_ce = sigmap(sig_ce[0]);
Wire *new_bit_ce = module->addWire(NEW_ID);
@@ -165,25 +165,25 @@ struct Ecp5FfinitPass : public Pass {
module->addAndnotGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce);
else
module->addOrGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce);
- cell->setPort("\\CE", new_bit_ce);
+ cell->setPort(ID(CE), new_bit_ce);
}
}
- cell->setParam("\\REGSET", val != State::S0 ? Const("SET") : Const("RESET"));
+ cell->setParam(ID(REGSET), val != State::S0 ? Const("SET") : Const("RESET"));
handled_initbits.insert(bit_q);
}
} else {
- cell->setParam("\\REGSET", val != State::S0 ? Const("SET") : Const("RESET"));
+ cell->setParam(ID(REGSET), val != State::S0 ? Const("SET") : Const("RESET"));
handled_initbits.insert(bit_q);
}
}
for (auto wire : init_wires)
{
- if (wire->attributes.count("\\init") == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec wirebits = sigmap(wire);
- Const &initval = wire->attributes.at("\\init");
+ Const &initval = wire->attributes.at(ID::init);
bool remove_attribute = true;
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) {
@@ -194,7 +194,7 @@ struct Ecp5FfinitPass : public Pass {
}
if (remove_attribute)
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
}
}
diff --git a/techlibs/ecp5/ecp5_gsr.cc b/techlibs/ecp5/ecp5_gsr.cc
index 2bc714b6f..d1503f71f 100644
--- a/techlibs/ecp5/ecp5_gsr.cc
+++ b/techlibs/ecp5/ecp5_gsr.cc
@@ -85,7 +85,7 @@ struct Ecp5GsrPass : public Pass {
continue;
bool gsren = found_gsr;
- if (cell->get_bool_attribute("\\nogsr"))
+ if (cell->get_bool_attribute(ID(nogsr)))
gsren = false;
cell->setParam(ID(GSR), gsren ? Const("ENABLED") : Const("DISABLED"));
@@ -102,7 +102,7 @@ struct Ecp5GsrPass : public Pass {
{
if (cell->type != ID($_NOT_))
continue;
- SigSpec sig_a = cell->getPort(ID(A)), sig_y = cell->getPort(ID(Y));
+ SigSpec sig_a = cell->getPort(ID::A), sig_y = cell->getPort(ID::Y);
if (GetSize(sig_a) < 1 || GetSize(sig_y) < 1)
continue;
SigBit a = sigmap(sig_a[0]);
diff --git a/techlibs/ecp5/lutrams.txt b/techlibs/ecp5/lutrams.txt
index b94357429..9e6a23eba 100644
--- a/techlibs/ecp5/lutrams.txt
+++ b/techlibs/ecp5/lutrams.txt
@@ -11,7 +11,16 @@ bram $__TRELLIS_DPR16X4
clkpol 0 2
endbram
+# The syn_* attributes are described in:
+# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
+attr_icase 1
+
match $__TRELLIS_DPR16X4
+ attribute !syn_ramstyle syn_ramstyle=auto syn_ramstyle=distributed
+ attribute !syn_romstyle syn_romstyle=auto
+ attribute !ram_block
+ attribute !rom_block
+ attribute !logic_block
make_outreg
min wports 1
endmatch
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index 9916fdafb..ab740ea0d 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -279,7 +279,9 @@ struct SynthEcp5Pass : public ScriptPass
if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
- run("memory_map");
+ run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
+ "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
+ "-attr syn_romstyle=auto -attr syn_romstyle=logic");
run("opt -undriven -fine");
}
@@ -296,7 +298,6 @@ struct SynthEcp5Pass : public ScriptPass
if (check_label("map_ffs"))
{
- run("dffsr2dff");
run("dff2dffs");
run("opt_clean");
if (!nodffe)
diff --git a/techlibs/efinix/efinix_fixcarry.cc b/techlibs/efinix/efinix_fixcarry.cc
index b7cd995b8..1a1733a17 100644
--- a/techlibs/efinix/efinix_fixcarry.cc
+++ b/techlibs/efinix/efinix_fixcarry.cc
@@ -39,12 +39,12 @@ static void fix_carry_chain(Module *module)
for (auto cell : module->cells())
{
- if (cell->type == "\\EFX_ADD") {
- SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0"));
- SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1"));
+ if (cell->type == ID(EFX_ADD)) {
+ SigBit bit_i0 = get_bit_or_zero(cell->getPort(ID(I0)));
+ SigBit bit_i1 = get_bit_or_zero(cell->getPort(ID(I1)));
if (bit_i0 == State::S0 && bit_i1== State::S0) {
- SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI"));
- SigBit bit_o = sigmap(cell->getPort("\\O"));
+ SigBit bit_ci = get_bit_or_zero(cell->getPort(ID::CI));
+ SigBit bit_o = sigmap(cell->getPort(ID::O));
ci_bits.insert(bit_ci);
mapping_bits[bit_ci] = bit_o;
}
@@ -54,10 +54,10 @@ static void fix_carry_chain(Module *module)
vector<Cell*> adders_to_fix_cells;
for (auto cell : module->cells())
{
- if (cell->type == "\\EFX_ADD") {
- SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI"));
- SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0"));
- SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1"));
+ if (cell->type == ID(EFX_ADD)) {
+ SigBit bit_ci = get_bit_or_zero(cell->getPort(ID::CI));
+ SigBit bit_i0 = get_bit_or_zero(cell->getPort(ID(I0)));
+ SigBit bit_i1 = get_bit_or_zero(cell->getPort(ID(I1)));
SigBit canonical_bit = sigmap(bit_ci);
if (!ci_bits.count(canonical_bit))
continue;
@@ -71,20 +71,20 @@ static void fix_carry_chain(Module *module)
for (auto cell : adders_to_fix_cells)
{
- SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI"));
+ SigBit bit_ci = get_bit_or_zero(cell->getPort(ID::CI));
SigBit canonical_bit = sigmap(bit_ci);
auto bit = mapping_bits.at(canonical_bit);
log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell));
- Cell *c = module->addCell(NEW_ID, "\\EFX_ADD");
+ Cell *c = module->addCell(NEW_ID, ID(EFX_ADD));
SigBit new_bit = module->addWire(NEW_ID);
- c->setParam("\\I0_POLARITY", State::S1);
- c->setParam("\\I1_POLARITY", State::S1);
- c->setPort("\\I0", bit);
- c->setPort("\\I1", State::S1);
- c->setPort("\\CI", State::S0);
- c->setPort("\\CO", new_bit);
+ c->setParam(ID(I0_POLARITY), State::S1);
+ c->setParam(ID(I1_POLARITY), State::S1);
+ c->setPort(ID(I0), bit);
+ c->setPort(ID(I1), State::S1);
+ c->setPort(ID::CI, State::S0);
+ c->setPort(ID::CO, new_bit);
- cell->setPort("\\CI", new_bit);
+ cell->setPort(ID::CI, new_bit);
}
}
@@ -101,7 +101,7 @@ struct EfinixCarryFixPass : public Pass {
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- log_header(design, "Executing efinix_fixcarry pass (fix invalid carry chain).\n");
+ log_header(design, "Executing EFINIX_FIXCARRY pass (fix invalid carry chain).\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
diff --git a/techlibs/efinix/efinix_gbuf.cc b/techlibs/efinix/efinix_gbuf.cc
index e75fb3f4d..55dfb3c79 100644
--- a/techlibs/efinix/efinix_gbuf.cc
+++ b/techlibs/efinix/efinix_gbuf.cc
@@ -34,14 +34,14 @@ static void handle_gbufs(Module *module)
for (auto cell : module->cells())
{
- if (cell->type == "\\EFX_FF") {
- for (auto bit : sigmap(cell->getPort("\\CLK")))
+ if (cell->type == ID(EFX_FF)) {
+ for (auto bit : sigmap(cell->getPort(ID::CLK)))
clk_bits.insert(bit);
}
- if (cell->type == "\\EFX_RAM_5K") {
- for (auto bit : sigmap(cell->getPort("\\RCLK")))
+ if (cell->type == ID(EFX_RAM_5K)) {
+ for (auto bit : sigmap(cell->getPort(ID(RCLK))))
clk_bits.insert(bit);
- for (auto bit : sigmap(cell->getPort("\\WCLK")))
+ for (auto bit : sigmap(cell->getPort(ID(WCLK))))
clk_bits.insert(bit);
}
}
@@ -59,11 +59,11 @@ static void handle_gbufs(Module *module)
if (!clk_bits.count(canonical_bit))
continue;
- Cell *c = module->addCell(NEW_ID, "\\EFX_GBUFCE");
+ Cell *c = module->addCell(NEW_ID, ID(EFX_GBUFCE));
SigBit new_bit = module->addWire(NEW_ID);
- c->setParam("\\CE_POLARITY", State::S1);
- c->setPort("\\O", new_bit);
- c->setPort("\\CE", State::S1);
+ c->setParam(ID(CE_POLARITY), State::S1);
+ c->setPort(ID::O, new_bit);
+ c->setPort(ID(CE), State::S1);
pad_bits.push_back(make_pair(c, bit));
rewrite_bits[canonical_bit] = new_bit;
@@ -82,7 +82,7 @@ static void handle_gbufs(Module *module)
module->rewrite_sigspecs(rewrite_function);
for (auto &it : pad_bits)
- it.first->setPort("\\I", it.second);
+ it.first->setPort(ID::I, it.second);
}
struct EfinixGbufPass : public Pass {
diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc
index 637d7c00d..f9a7ef865 100644
--- a/techlibs/efinix/synth_efinix.cc
+++ b/techlibs/efinix/synth_efinix.cc
@@ -182,7 +182,6 @@ struct SynthEfinixPass : public ScriptPass
if (check_label("map_ffs"))
{
- run("dffsr2dff");
run("techmap -D NO_LUT -map +/efinix/cells_map.v");
run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit");
run("opt_expr -mux_undef");
diff --git a/techlibs/gowin/determine_init.cc b/techlibs/gowin/determine_init.cc
index d9a0880f6..18a64e451 100644
--- a/techlibs/gowin/determine_init.cc
+++ b/techlibs/gowin/determine_init.cc
@@ -55,12 +55,12 @@ struct DetermineInitPass : public Pass {
{
for (auto cell : module->selected_cells())
{
- if (cell->type == "\\RAM16S4")
+ if (cell->type == ID(RAM16S4))
{
- cell->setParam("\\INIT_0", determine_init(cell->getParam("\\INIT_0")));
- cell->setParam("\\INIT_1", determine_init(cell->getParam("\\INIT_1")));
- cell->setParam("\\INIT_2", determine_init(cell->getParam("\\INIT_2")));
- cell->setParam("\\INIT_3", determine_init(cell->getParam("\\INIT_3")));
+ cell->setParam(ID(INIT_0), determine_init(cell->getParam(ID(INIT_0))));
+ cell->setParam(ID(INIT_1), determine_init(cell->getParam(ID(INIT_1))));
+ cell->setParam(ID(INIT_2), determine_init(cell->getParam(ID(INIT_2))));
+ cell->setParam(ID(INIT_3), determine_init(cell->getParam(ID(INIT_3))));
cnt++;
}
}
diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc
index 86ec9cdc2..dd965c0b8 100644
--- a/techlibs/gowin/synth_gowin.cc
+++ b/techlibs/gowin/synth_gowin.cc
@@ -219,7 +219,6 @@ struct SynthGowinPass : public ScriptPass
if (check_label("map_ffs"))
{
- run("dffsr2dff");
run("dff2dffs -match-init");
run("opt_clean");
if (!nodffe)
diff --git a/techlibs/greenpak4/greenpak4_dffinv.cc b/techlibs/greenpak4/greenpak4_dffinv.cc
index d57e978a0..62057318b 100644
--- a/techlibs/greenpak4/greenpak4_dffinv.cc
+++ b/techlibs/greenpak4/greenpak4_dffinv.cc
@@ -33,37 +33,37 @@ void invert_gp_dff(Cell *cell, bool invert_input)
if (!invert_input)
{
- Const initval = cell->getParam("\\INIT");
+ Const initval = cell->getParam(ID::INIT);
if (GetSize(initval) >= 1) {
if (initval.bits[0] == State::S0)
initval.bits[0] = State::S1;
else if (initval.bits[0] == State::S1)
initval.bits[0] = State::S0;
- cell->setParam("\\INIT", initval);
+ cell->setParam(ID::INIT, initval);
}
if (cell_type_r && cell_type_s)
{
- Const srmode = cell->getParam("\\SRMODE");
+ Const srmode = cell->getParam(ID(SRMODE));
if (GetSize(srmode) >= 1) {
if (srmode.bits[0] == State::S0)
srmode.bits[0] = State::S1;
else if (srmode.bits[0] == State::S1)
srmode.bits[0] = State::S0;
- cell->setParam("\\SRMODE", srmode);
+ cell->setParam(ID(SRMODE), srmode);
}
}
else
{
if (cell_type_r) {
- cell->setPort("\\nSET", cell->getPort("\\nRST"));
- cell->unsetPort("\\nRST");
+ cell->setPort(ID(nSET), cell->getPort(ID(nRST)));
+ cell->unsetPort(ID(nRST));
cell_type_r = false;
cell_type_s = true;
} else
if (cell_type_s) {
- cell->setPort("\\nRST", cell->getPort("\\nSET"));
- cell->unsetPort("\\nSET");
+ cell->setPort(ID(nRST), cell->getPort(ID(nSET)));
+ cell->unsetPort(ID(nSET));
cell_type_r = true;
cell_type_s = false;
}
@@ -71,12 +71,12 @@ void invert_gp_dff(Cell *cell, bool invert_input)
}
if (cell_type_i) {
- cell->setPort("\\Q", cell->getPort("\\nQ"));
- cell->unsetPort("\\nQ");
+ cell->setPort(ID::Q, cell->getPort(ID(nQ)));
+ cell->unsetPort(ID(nQ));
cell_type_i = false;
} else {
- cell->setPort("\\nQ", cell->getPort("\\Q"));
- cell->unsetPort("\\Q");
+ cell->setPort(ID(nQ), cell->getPort(ID::Q));
+ cell->unsetPort(ID::Q);
cell_type_i = true;
}
@@ -115,23 +115,23 @@ struct Greenpak4DffInvPass : public Pass {
extra_args(args, argidx, design);
pool<IdString> gp_dff_types;
- gp_dff_types.insert("\\GP_DFF");
- gp_dff_types.insert("\\GP_DFFI");
- gp_dff_types.insert("\\GP_DFFR");
- gp_dff_types.insert("\\GP_DFFRI");
- gp_dff_types.insert("\\GP_DFFS");
- gp_dff_types.insert("\\GP_DFFSI");
- gp_dff_types.insert("\\GP_DFFSR");
- gp_dff_types.insert("\\GP_DFFSRI");
-
- gp_dff_types.insert("\\GP_DLATCH");
- gp_dff_types.insert("\\GP_DLATCHI");
- gp_dff_types.insert("\\GP_DLATCHR");
- gp_dff_types.insert("\\GP_DLATCHRI");
- gp_dff_types.insert("\\GP_DLATCHS");
- gp_dff_types.insert("\\GP_DLATCHSI");
- gp_dff_types.insert("\\GP_DLATCHSR");
- gp_dff_types.insert("\\GP_DLATCHSRI");
+ gp_dff_types.insert(ID(GP_DFF));
+ gp_dff_types.insert(ID(GP_DFFI));
+ gp_dff_types.insert(ID(GP_DFFR));
+ gp_dff_types.insert(ID(GP_DFFRI));
+ gp_dff_types.insert(ID(GP_DFFS));
+ gp_dff_types.insert(ID(GP_DFFSI));
+ gp_dff_types.insert(ID(GP_DFFSR));
+ gp_dff_types.insert(ID(GP_DFFSRI));
+
+ gp_dff_types.insert(ID(GP_DLATCH));
+ gp_dff_types.insert(ID(GP_DLATCHI));
+ gp_dff_types.insert(ID(GP_DLATCHR));
+ gp_dff_types.insert(ID(GP_DLATCHRI));
+ gp_dff_types.insert(ID(GP_DLATCHS));
+ gp_dff_types.insert(ID(GP_DLATCHSI));
+ gp_dff_types.insert(ID(GP_DLATCHSR));
+ gp_dff_types.insert(ID(GP_DLATCHSRI));
for (auto module : design->selected_modules())
{
@@ -163,9 +163,9 @@ struct Greenpak4DffInvPass : public Pass {
continue;
}
- if (cell->type == "\\GP_INV") {
- SigBit in_bit = sigmap(cell->getPort("\\IN"));
- SigBit out_bit = sigmap(cell->getPort("\\OUT"));
+ if (cell->type == ID(GP_INV)) {
+ SigBit in_bit = sigmap(cell->getPort(ID(IN)));
+ SigBit out_bit = sigmap(cell->getPort(ID(OUT)));
inv_in2out[in_bit] = out_bit;
inv_out2in[out_bit] = in_bit;
inv_in2cell[in_bit] = cell;
@@ -175,15 +175,15 @@ struct Greenpak4DffInvPass : public Pass {
for (auto cell : dff_cells)
{
- SigBit d_bit = sigmap(cell->getPort("\\D"));
- SigBit q_bit = sigmap(cell->hasPort("\\Q") ? cell->getPort("\\Q") : cell->getPort("\\nQ"));
+ SigBit d_bit = sigmap(cell->getPort(ID::D));
+ SigBit q_bit = sigmap(cell->hasPort(ID::Q) ? cell->getPort(ID::Q) : cell->getPort(ID(nQ)));
while (inv_out2in.count(d_bit))
{
sig_use_cnt[d_bit]--;
invert_gp_dff(cell, true);
d_bit = inv_out2in.at(d_bit);
- cell->setPort("\\D", d_bit);
+ cell->setPort(ID::D, d_bit);
sig_use_cnt[d_bit]++;
}
@@ -197,10 +197,10 @@ struct Greenpak4DffInvPass : public Pass {
inv_in2cell.erase(q_bit);
invert_gp_dff(cell, false);
- if (cell->hasPort("\\Q"))
- cell->setPort("\\Q", new_q_bit);
+ if (cell->hasPort(ID::Q))
+ cell->setPort(ID::Q, new_q_bit);
else
- cell->setPort("\\nQ", new_q_bit);
+ cell->setPort(ID(nQ), new_q_bit);
}
}
}
diff --git a/techlibs/ice40/brams.txt b/techlibs/ice40/brams.txt
index 03d596111..36dfddab2 100644
--- a/techlibs/ice40/brams.txt
+++ b/techlibs/ice40/brams.txt
@@ -28,13 +28,73 @@ bram $__ICE40_RAM4K_M123
clkpol 2 3
endbram
+# The syn_* attributes are described in:
+# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
+attr_icase 1
+
match $__ICE40_RAM4K_M0
+ # implicitly requested RAM or ROM
+ attribute !syn_ramstyle syn_ramstyle=auto
+ attribute !syn_romstyle syn_romstyle=auto
+ attribute !ram_block
+ attribute !rom_block
+ attribute !logic_block
min efficiency 2
make_transp
or_next_if_better
endmatch
+match $__ICE40_RAM4K_M0
+ # explicitly requested RAM
+ attribute syn_ramstyle=block_ram ram_block
+ attribute !syn_romstyle
+ attribute !rom_block
+ attribute !logic_block
+ min wports 1
+ make_transp
+ or_next_if_better
+endmatch
+
+match $__ICE40_RAM4K_M0
+ # explicitly requested ROM
+ attribute syn_romstyle=ebr rom_block
+ attribute !syn_ramstyle
+ attribute !ram_block
+ attribute !logic_block
+ max wports 0
+ make_transp
+ or_next_if_better
+endmatch
+
match $__ICE40_RAM4K_M123
+ # implicitly requested RAM or ROM
+ attribute !syn_ramstyle syn_ramstyle=auto
+ attribute !syn_romstyle syn_romstyle=auto
+ attribute !ram_block
+ attribute !rom_block
+ attribute !logic_block
min efficiency 2
make_transp
+ or_next_if_better
+endmatch
+
+match $__ICE40_RAM4K_M123
+ # explicitly requested RAM
+ attribute syn_ramstyle=block_ram ram_block
+ attribute !syn_romstyle
+ attribute !rom_block
+ attribute !logic_block
+ min wports 1
+ make_transp
+ or_next_if_better
+endmatch
+
+match $__ICE40_RAM4K_M123
+ # explicitly requested ROM
+ attribute syn_romstyle=ebr rom_block
+ attribute !syn_ramstyle
+ attribute !ram_block
+ attribute !logic_block
+ max wports 0
+ make_transp
endmatch
diff --git a/techlibs/ice40/ice40_braminit.cc b/techlibs/ice40/ice40_braminit.cc
index 1a139ffea..936c189ea 100644
--- a/techlibs/ice40/ice40_braminit.cc
+++ b/techlibs/ice40/ice40_braminit.cc
@@ -33,15 +33,15 @@ static void run_ice40_braminit(Module *module)
uint16_t mem[256];
/* Only consider cells we're interested in */
- if (cell->type != "\\SB_RAM40_4K" &&
- cell->type != "\\SB_RAM40_4KNR" &&
- cell->type != "\\SB_RAM40_4KNW" &&
- cell->type != "\\SB_RAM40_4KNRNW")
+ if (cell->type != ID(SB_RAM40_4K) &&
+ cell->type != ID(SB_RAM40_4KNR) &&
+ cell->type != ID(SB_RAM40_4KNW) &&
+ cell->type != ID(SB_RAM40_4KNRNW))
continue;
- if (!cell->hasParam("\\INIT_FILE"))
+ if (!cell->hasParam(ID(INIT_FILE)))
continue;
- std::string init_file = cell->getParam("\\INIT_FILE").decode_string();
- cell->unsetParam("\\INIT_FILE");
+ std::string init_file = cell->getParam(ID(INIT_FILE)).decode_string();
+ cell->unsetParam(ID(INIT_FILE));
if (init_file == "")
continue;
diff --git a/techlibs/ice40/ice40_ffinit.cc b/techlibs/ice40/ice40_ffinit.cc
index c098736e9..d7715135e 100644
--- a/techlibs/ice40/ice40_ffinit.cc
+++ b/techlibs/ice40/ice40_ffinit.cc
@@ -62,11 +62,11 @@ struct Ice40FfinitPass : public Pass {
for (auto wire : module->selected_wires())
{
- if (wire->attributes.count("\\init") == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec wirebits = sigmap(wire);
- Const initval = wire->attributes.at("\\init");
+ Const initval = wire->attributes.at(ID::init);
init_wires.insert(wire);
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
@@ -93,9 +93,9 @@ struct Ice40FfinitPass : public Pass {
}
pool<IdString> sb_dff_types = {
- "\\SB_DFF", "\\SB_DFFE", "\\SB_DFFSR", "\\SB_DFFR", "\\SB_DFFSS", "\\SB_DFFS", "\\SB_DFFESR",
- "\\SB_DFFER", "\\SB_DFFESS", "\\SB_DFFES", "\\SB_DFFN", "\\SB_DFFNE", "\\SB_DFFNSR", "\\SB_DFFNR",
- "\\SB_DFFNSS", "\\SB_DFFNS", "\\SB_DFFNESR", "\\SB_DFFNER", "\\SB_DFFNESS", "\\SB_DFFNES"
+ ID(SB_DFF), ID(SB_DFFE), ID(SB_DFFSR), ID(SB_DFFR), ID(SB_DFFSS), ID(SB_DFFS), ID(SB_DFFESR),
+ ID(SB_DFFER), ID(SB_DFFESS), ID(SB_DFFES), ID(SB_DFFN), ID(SB_DFFNE), ID(SB_DFFNSR), ID(SB_DFFNR),
+ ID(SB_DFFNSS), ID(SB_DFFNS), ID(SB_DFFNESR), ID(SB_DFFNER), ID(SB_DFFNESS), ID(SB_DFFNES)
};
for (auto cell : module->selected_cells())
@@ -103,8 +103,8 @@ struct Ice40FfinitPass : public Pass {
if (!sb_dff_types.count(cell->type))
continue;
- SigSpec sig_d = cell->getPort("\\D");
- SigSpec sig_q = cell->getPort("\\Q");
+ SigSpec sig_d = cell->getPort(ID::D);
+ SigSpec sig_q = cell->getPort(ID::Q);
if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
continue;
@@ -133,14 +133,14 @@ struct Ice40FfinitPass : public Pass {
if (type_str.back() == 'S') {
type_str.back() = 'R';
cell->type = type_str;
- cell->setPort("\\R", cell->getPort("\\S"));
- cell->unsetPort("\\S");
+ cell->setPort(ID::R, cell->getPort(ID::S));
+ cell->unsetPort(ID::S);
} else
if (type_str.back() == 'R') {
type_str.back() = 'S';
cell->type = type_str;
- cell->setPort("\\S", cell->getPort("\\R"));
- cell->unsetPort("\\R");
+ cell->setPort(ID::S, cell->getPort(ID::R));
+ cell->unsetPort(ID::R);
}
Wire *new_bit_d = module->addWire(NEW_ID);
@@ -149,17 +149,17 @@ struct Ice40FfinitPass : public Pass {
module->addNotGate(NEW_ID, bit_d, new_bit_d);
module->addNotGate(NEW_ID, new_bit_q, bit_q);
- cell->setPort("\\D", new_bit_d);
- cell->setPort("\\Q", new_bit_q);
+ cell->setPort(ID::D, new_bit_d);
+ cell->setPort(ID::Q, new_bit_q);
}
for (auto wire : init_wires)
{
- if (wire->attributes.count("\\init") == 0)
+ if (wire->attributes.count(ID::init) == 0)
continue;
SigSpec wirebits = sigmap(wire);
- Const &initval = wire->attributes.at("\\init");
+ Const &initval = wire->attributes.at(ID::init);
bool remove_attribute = true;
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) {
@@ -170,7 +170,7 @@ struct Ice40FfinitPass : public Pass {
}
if (remove_attribute)
- wire->attributes.erase("\\init");
+ wire->attributes.erase(ID::init);
}
}
}
diff --git a/techlibs/ice40/ice40_ffssr.cc b/techlibs/ice40/ice40_ffssr.cc
index a7649d7a0..ffb8c74b1 100644
--- a/techlibs/ice40/ice40_ffssr.cc
+++ b/techlibs/ice40/ice40_ffssr.cc
@@ -49,10 +49,10 @@ struct Ice40FfssrPass : public Pass {
extra_args(args, argidx, design);
pool<IdString> sb_dff_types;
- sb_dff_types.insert("\\SB_DFF");
- sb_dff_types.insert("\\SB_DFFE");
- sb_dff_types.insert("\\SB_DFFN");
- sb_dff_types.insert("\\SB_DFFNE");
+ sb_dff_types.insert(ID(SB_DFF));
+ sb_dff_types.insert(ID(SB_DFFE));
+ sb_dff_types.insert(ID(SB_DFFN));
+ sb_dff_types.insert(ID(SB_DFFNE));
for (auto module : design->selected_modules())
{
@@ -69,22 +69,22 @@ struct Ice40FfssrPass : public Pass {
continue;
}
- if (cell->type != "$_MUX_")
+ if (cell->type != ID($_MUX_))
continue;
- SigBit bit_a = sigmap(cell->getPort("\\A"));
- SigBit bit_b = sigmap(cell->getPort("\\B"));
+ SigBit bit_a = sigmap(cell->getPort(ID::A));
+ SigBit bit_b = sigmap(cell->getPort(ID::B));
if (bit_a.wire == nullptr || bit_b.wire == nullptr)
- sr_muxes[sigmap(cell->getPort("\\Y"))] = cell;
+ sr_muxes[sigmap(cell->getPort(ID::Y))] = cell;
}
for (auto cell : ff_cells)
{
- if (cell->get_bool_attribute("\\dont_touch"))
+ if (cell->get_bool_attribute(ID(dont_touch)))
continue;
- SigSpec sig_d = cell->getPort("\\D");
+ SigSpec sig_d = cell->getPort(ID::D);
if (GetSize(sig_d) < 1)
continue;
@@ -95,9 +95,9 @@ struct Ice40FfssrPass : public Pass {
continue;
Cell *mux_cell = sr_muxes.at(bit_d);
- SigBit bit_a = sigmap(mux_cell->getPort("\\A"));
- SigBit bit_b = sigmap(mux_cell->getPort("\\B"));
- SigBit bit_s = sigmap(mux_cell->getPort("\\S"));
+ SigBit bit_a = sigmap(mux_cell->getPort(ID::A));
+ SigBit bit_b = sigmap(mux_cell->getPort(ID::B));
+ SigBit bit_s = sigmap(mux_cell->getPort(ID::S));
log(" Merging %s (A=%s, B=%s, S=%s) into %s (%s).\n", log_id(mux_cell),
log_signal(bit_a), log_signal(bit_b), log_signal(bit_s), log_id(cell), log_id(cell->type));
@@ -116,12 +116,12 @@ struct Ice40FfssrPass : public Pass {
if (sr_val == State::S1) {
cell->type = cell->type.str() + "SS";
- cell->setPort("\\S", sr_sig);
- cell->setPort("\\D", bit_d);
+ cell->setPort(ID::S, sr_sig);
+ cell->setPort(ID::D, bit_d);
} else {
cell->type = cell->type.str() + "SR";
- cell->setPort("\\R", sr_sig);
- cell->setPort("\\D", bit_d);
+ cell->setPort(ID::R, sr_sig);
+ cell->setPort(ID::D, bit_d);
}
}
}
diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc
index 925ab31bb..18c1a58cf 100644
--- a/techlibs/ice40/ice40_opt.cc
+++ b/techlibs/ice40/ice40_opt.cc
@@ -41,26 +41,26 @@ static void run_ice40_opts(Module *module)
for (auto cell : module->selected_cells())
{
- if (!cell->type.in("\\SB_LUT4", "\\SB_CARRY", "$__ICE40_CARRY_WRAPPER"))
+ if (!cell->type.in(ID(SB_LUT4), ID(SB_CARRY), ID($__ICE40_CARRY_WRAPPER)))
continue;
if (cell->has_keep_attr())
continue;
- if (cell->type == "\\SB_LUT4")
+ if (cell->type == ID(SB_LUT4))
{
sb_lut_cells.push_back(cell);
continue;
}
- if (cell->type == "\\SB_CARRY")
+ if (cell->type == ID(SB_CARRY))
{
SigSpec non_const_inputs, replacement_output;
int count_zeros = 0, count_ones = 0;
SigBit inbit[3] = {
- get_bit_or_zero(cell->getPort("\\I0")),
- get_bit_or_zero(cell->getPort("\\I1")),
- get_bit_or_zero(cell->getPort("\\CI"))
+ get_bit_or_zero(cell->getPort(ID(I0))),
+ get_bit_or_zero(cell->getPort(ID(I1))),
+ get_bit_or_zero(cell->getPort(ID::CI))
};
for (int i = 0; i < 3; i++)
if (inbit[i].wire == nullptr) {
@@ -79,8 +79,8 @@ static void run_ice40_opts(Module *module)
replacement_output = non_const_inputs;
if (GetSize(replacement_output)) {
- optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
- module->connect(cell->getPort("\\CO")[0], replacement_output);
+ optimized_co.insert(sigmap(cell->getPort(ID::CO)[0]));
+ module->connect(cell->getPort(ID::CO)[0], replacement_output);
module->design->scratchpad_set_bool("opt.did_something", true);
log("Optimized away SB_CARRY cell %s.%s: CO=%s\n",
log_id(module), log_id(cell), log_signal(replacement_output));
@@ -89,15 +89,15 @@ static void run_ice40_opts(Module *module)
continue;
}
- if (cell->type == "$__ICE40_CARRY_WRAPPER")
+ if (cell->type == ID($__ICE40_CARRY_WRAPPER))
{
SigSpec non_const_inputs, replacement_output;
int count_zeros = 0, count_ones = 0;
SigBit inbit[3] = {
- cell->getPort("\\A"),
- cell->getPort("\\B"),
- cell->getPort("\\CI")
+ cell->getPort(ID::A),
+ cell->getPort(ID::B),
+ cell->getPort(ID::CI)
};
for (int i = 0; i < 3; i++)
if (inbit[i].wire == nullptr) {
@@ -116,7 +116,7 @@ static void run_ice40_opts(Module *module)
replacement_output = non_const_inputs;
if (GetSize(replacement_output)) {
- optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
+ optimized_co.insert(sigmap(cell->getPort(ID::CO)[0]));
auto it = cell->attributes.find(ID(SB_LUT4.name));
if (it != cell->attributes.end()) {
module->rename(cell, it->second.decode_string());
@@ -124,9 +124,9 @@ static void run_ice40_opts(Module *module)
for (const auto &a : cell->attributes)
if (a.first.begins_with("\\SB_LUT4.\\"))
new_attr[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second;
- else if (a.first == ID(src))
+ else if (a.first == ID::src)
new_attr.insert(std::make_pair(a.first, a.second));
- else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived)))
+ else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID::module_not_derived))
continue;
else if (a.first.begins_with("\\SB_CARRY.\\"))
continue;
@@ -134,22 +134,22 @@ static void run_ice40_opts(Module *module)
log_abort();
cell->attributes = std::move(new_attr);
}
- module->connect(cell->getPort("\\CO")[0], replacement_output);
+ module->connect(cell->getPort(ID::CO)[0], replacement_output);
module->design->scratchpad_set_bool("opt.did_something", true);
log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n",
log_id(module), log_id(cell), log_signal(replacement_output));
- cell->type = "$lut";
- auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3)));
- cell->setPort("\\A", { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort("\\I0")) });
- cell->setPort("\\Y", cell->getPort("\\O"));
- cell->unsetPort("\\B");
- cell->unsetPort("\\CI");
- cell->unsetPort("\\I0");
- cell->unsetPort("\\I3");
- cell->unsetPort("\\CO");
- cell->unsetPort("\\O");
- cell->setParam("\\WIDTH", 4);
- cell->unsetParam("\\I3_IS_CI");
+ cell->type = ID($lut);
+ auto I3 = get_bit_or_zero(cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3)));
+ cell->setPort(ID::A, { I3, inbit[1], inbit[0], get_bit_or_zero(cell->getPort(ID(I0))) });
+ cell->setPort(ID::Y, cell->getPort(ID::O));
+ cell->unsetPort(ID::B);
+ cell->unsetPort(ID::CI);
+ cell->unsetPort(ID(I0));
+ cell->unsetPort(ID(I3));
+ cell->unsetPort(ID::CO);
+ cell->unsetPort(ID::O);
+ cell->setParam(ID::WIDTH, 4);
+ cell->unsetParam(ID(I3_IS_CI));
}
continue;
}
@@ -159,10 +159,10 @@ static void run_ice40_opts(Module *module)
{
SigSpec inbits;
- inbits.append(get_bit_or_zero(cell->getPort("\\I0")));
- inbits.append(get_bit_or_zero(cell->getPort("\\I1")));
- inbits.append(get_bit_or_zero(cell->getPort("\\I2")));
- inbits.append(get_bit_or_zero(cell->getPort("\\I3")));
+ inbits.append(get_bit_or_zero(cell->getPort(ID(I0))));
+ inbits.append(get_bit_or_zero(cell->getPort(ID(I1))));
+ inbits.append(get_bit_or_zero(cell->getPort(ID(I2))));
+ inbits.append(get_bit_or_zero(cell->getPort(ID(I3))));
sigmap.apply(inbits);
if (optimized_co.count(inbits[0])) goto remap_lut;
@@ -177,23 +177,23 @@ static void run_ice40_opts(Module *module)
module->design->scratchpad_set_bool("opt.did_something", true);
log("Mapping SB_LUT4 cell %s.%s back to logic.\n", log_id(module), log_id(cell));
- cell->type ="$lut";
- cell->setParam("\\WIDTH", 4);
- cell->setParam("\\LUT", cell->getParam("\\LUT_INIT"));
- cell->unsetParam("\\LUT_INIT");
+ cell->type = ID($lut);
+ cell->setParam(ID::WIDTH, 4);
+ cell->setParam(ID::LUT, cell->getParam(ID(LUT_INIT)));
+ cell->unsetParam(ID(LUT_INIT));
- cell->setPort("\\A", SigSpec({
- get_bit_or_zero(cell->getPort("\\I3")),
- get_bit_or_zero(cell->getPort("\\I2")),
- get_bit_or_zero(cell->getPort("\\I1")),
- get_bit_or_zero(cell->getPort("\\I0"))
+ cell->setPort(ID::A, SigSpec({
+ get_bit_or_zero(cell->getPort(ID(I3))),
+ get_bit_or_zero(cell->getPort(ID(I2))),
+ get_bit_or_zero(cell->getPort(ID(I1))),
+ get_bit_or_zero(cell->getPort(ID(I0)))
}));
- cell->setPort("\\Y", cell->getPort("\\O")[0]);
- cell->unsetPort("\\I0");
- cell->unsetPort("\\I1");
- cell->unsetPort("\\I2");
- cell->unsetPort("\\I3");
- cell->unsetPort("\\O");
+ cell->setPort(ID::Y, cell->getPort(ID::O)[0]);
+ cell->unsetPort(ID(I0));
+ cell->unsetPort(ID(I1));
+ cell->unsetPort(ID(I2));
+ cell->unsetPort(ID(I3));
+ cell->unsetPort(ID::O);
cell->check();
simplemap_lut(module, cell);
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index b8aedaadf..9724b7dd5 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -96,9 +96,9 @@ struct SynthIce40Pass : public ScriptPass
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
- log(" -flowmap\n");
- log(" use FlowMap LUT techmapping instead of abc (EXPERIMENTAL)\n");
- log("\n");
+ log(" -flowmap\n");
+ log(" use FlowMap LUT techmapping instead of abc (EXPERIMENTAL)\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -126,7 +126,7 @@ struct SynthIce40Pass : public ScriptPass
abc2 = false;
vpr = false;
abc9 = false;
- flowmap = false;
+ flowmap = false;
device_opt = "hx";
}
@@ -319,7 +319,9 @@ struct SynthIce40Pass : public ScriptPass
if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
- run("memory_map");
+ run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
+ "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
+ "-attr syn_romstyle=auto -attr syn_romstyle=logic");
run("opt -undriven -fine");
}
@@ -339,7 +341,6 @@ struct SynthIce40Pass : public ScriptPass
if (check_label("map_ffs"))
{
- run("dffsr2dff");
if (!nodffe)
run("dff2dffe -direct-match $_DFF_*");
if (min_ce_use >= 0) {
diff --git a/techlibs/intel/Makefile.inc b/techlibs/intel/Makefile.inc
index d97a9b58f..f751e341f 100644
--- a/techlibs/intel/Makefile.inc
+++ b/techlibs/intel/Makefile.inc
@@ -11,4 +11,3 @@ families := max10 arria10gx cyclonev cyclone10lp cycloneiv cycloneive
$(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_sim.v)))
$(foreach family,$(families), $(eval $(call add_share_file,share/intel/$(family),techlibs/intel/$(family)/cells_map.v)))
#$(eval $(call add_share_file,share/intel/cycloneive,techlibs/intel/cycloneive/arith_map.v))
-
diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc
index 3689df70e..8601ebb37 100644
--- a/techlibs/intel/synth_intel.cc
+++ b/techlibs/intel/synth_intel.cc
@@ -202,7 +202,6 @@ struct SynthIntelPass : public ScriptPass {
run("opt -fast -mux_undef -undriven -fine -full");
run("memory_map");
run("opt -undriven -fine");
- run("dffsr2dff");
run("dff2dffe -direct-match $_DFF_*");
run("opt -fine");
run("techmap -map +/techmap.v");
diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc
new file mode 100644
index 000000000..66204c8fc
--- /dev/null
+++ b/techlibs/intel_alm/Makefile.inc
@@ -0,0 +1,23 @@
+
+OBJS += techlibs/intel_alm/synth_intel_alm.o
+
+# Techmap
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_map.v))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/alm_sim.v))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/arith_alm_map.v))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dff_map.v))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dff_sim.v))
+
+# RAM
+bramtypes := m10k m20k
+$(foreach bramtype, $(bramtypes), $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_$(bramtype).txt)))
+$(foreach bramtype, $(bramtypes), $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/bram_$(bramtype)_map.v)))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/lutram_mlab.txt))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/lutram_mlab_map.v))
+
+families := cyclonev cyclone10gx
+
+# Miscellaneous
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/megafunction_bb.v))
+$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/quartus_rename.v))
+$(foreach family, $(families), $(eval $(call add_share_file,share/intel_alm/$(family),techlibs/intel_alm/$(family)/quartus_rename.v)))
diff --git a/techlibs/intel_alm/common/alm_map.v b/techlibs/intel_alm/common/alm_map.v
new file mode 100644
index 000000000..fe646c5d6
--- /dev/null
+++ b/techlibs/intel_alm/common/alm_map.v
@@ -0,0 +1,56 @@
+module \$lut (A, Y);
+
+parameter WIDTH = 1;
+parameter LUT = 0;
+
+input [WIDTH-1:0] A;
+output Y;
+
+generate
+ if (WIDTH == 1) begin
+ generate
+ if (LUT == 2'b00) begin
+ assign Y = 1'b0;
+ end
+ else if (LUT == 2'b01) begin
+ MISTRAL_NOT _TECHMAP_REPLACE_(
+ .A(A[0]), .Q(Y)
+ );
+ end
+ else if (LUT == 2'b10) begin
+ assign Y = A;
+ end
+ else if (LUT == 2'b11) begin
+ assign Y = 1'b1;
+ end
+ endgenerate
+ end else
+ if (WIDTH == 2) begin
+ MISTRAL_ALUT2 #(.LUT(LUT)) _TECHMAP_REPLACE_(
+ .A(A[0]), .B(A[1]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 3) begin
+ MISTRAL_ALUT3 #(.LUT(LUT)) _TECHMAP_REPLACE_(
+ .A(A[0]), .B(A[1]), .C(A[2]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 4) begin
+ MISTRAL_ALUT4 #(.LUT(LUT)) _TECHMAP_REPLACE_(
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 5) begin
+ MISTRAL_ALUT5 #(.LUT(LUT)) _TECHMAP_REPLACE_ (
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .E(A[4]), .Q(Y)
+ );
+ end else
+ if (WIDTH == 6) begin
+ MISTRAL_ALUT6 #(.LUT(LUT)) _TECHMAP_REPLACE_ (
+ .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]), .E(A[4]), .F(A[5]), .Q(Y)
+ );
+ end else begin
+ wire _TECHMAP_FAIL_ = 1'b1;
+ end
+endgenerate
+endmodule
diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v
new file mode 100644
index 000000000..69768d9f7
--- /dev/null
+++ b/techlibs/intel_alm/common/alm_sim.v
@@ -0,0 +1,482 @@
+`default_nettype none
+
+(* abc9_lut=2, lib_whitebox *)
+module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q);
+
+parameter [63:0] LUT = 64'h0000_0000_0000_0000;
+
+`ifdef cyclonev
+specify
+ (A => Q) = 602;
+ (B => Q) = 584;
+ (C => Q) = 510;
+ (D => Q) = 510;
+ (E => Q) = 339;
+ (F => Q) = 94;
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (A => Q) = 275;
+ (B => Q) = 272;
+ (C => Q) = 175;
+ (D => Q) = 165;
+ (E => Q) = 162;
+ (F => Q) = 53;
+endspecify
+`endif
+
+assign Q = LUT >> {F, E, D, C, B, A};
+
+endmodule
+
+
+(* abc9_lut=1, lib_whitebox *)
+module MISTRAL_ALUT5(input A, B, C, D, E, output Q);
+
+parameter [31:0] LUT = 32'h0000_0000;
+
+`ifdef cyclonev
+specify
+ (A => Q) = 584;
+ (B => Q) = 510;
+ (C => Q) = 510;
+ (D => Q) = 339;
+ (E => Q) = 94;
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (A => Q) = 272;
+ (B => Q) = 175;
+ (C => Q) = 165;
+ (D => Q) = 162;
+ (E => Q) = 53;
+endspecify
+`endif
+
+assign Q = LUT >> {E, D, C, B, A};
+
+endmodule
+
+
+(* abc9_lut=1, lib_whitebox *)
+module MISTRAL_ALUT4(input A, B, C, D, output Q);
+
+parameter [15:0] LUT = 16'h0000;
+
+`ifdef cyclonev
+specify
+ (A => Q) = 510;
+ (B => Q) = 510;
+ (C => Q) = 339;
+ (D => Q) = 94;
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (A => Q) = 175;
+ (B => Q) = 165;
+ (C => Q) = 162;
+ (D => Q) = 53;
+endspecify
+`endif
+
+assign Q = LUT >> {D, C, B, A};
+
+endmodule
+
+
+(* abc9_lut=1, lib_whitebox *)
+module MISTRAL_ALUT3(input A, B, C, output Q);
+
+parameter [7:0] LUT = 8'h00;
+
+`ifdef cyclonev
+specify
+ (A => Q) = 510;
+ (B => Q) = 339;
+ (C => Q) = 94;
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (A => Q) = 165;
+ (B => Q) = 162;
+ (C => Q) = 53;
+endspecify
+`endif
+
+assign Q = LUT >> {C, B, A};
+
+endmodule
+
+
+(* abc9_lut=1, lib_whitebox *)
+module MISTRAL_ALUT2(input A, B, output Q);
+
+parameter [3:0] LUT = 4'h0;
+
+`ifdef cyclonev
+specify
+ (A => Q) = 339;
+ (B => Q) = 94;
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (A => Q) = 162;
+ (B => Q) = 53;
+endspecify
+`endif
+
+assign Q = LUT >> {B, A};
+
+endmodule
+
+
+(* abc9_lut=1, lib_whitebox *)
+module MISTRAL_NOT(input A, output Q);
+
+`ifdef cyclonev
+specify
+ (A => Q) = 94;
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (A => Q) = 53;
+endspecify
+`endif
+
+assign Q = ~A;
+
+endmodule
+
+(* abc9_box, lib_whitebox *)
+module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, (* abc9_carry *) input CI, output SO, (* abc9_carry *) output CO);
+
+parameter LUT0 = 16'h0000;
+parameter LUT1 = 16'h0000;
+
+`ifdef cyclonev
+specify
+ (A => SO) = 1283;
+ (B => SO) = 1167;
+ (C => SO) = 866;
+ (D0 => SO) = 756;
+ (D1 => SO) = 756;
+ (CI => SO) = 355;
+ (A => CO) = 950;
+ (B => CO) = 1039;
+ (C => CO) = 820;
+ (D0 => CO) = 1006;
+ (D1 => CO) = 1006;
+ (CI => CO) = 23;
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (A => SO) = 644;
+ (B => SO) = 477;
+ (C => SO) = 416;
+ (D0 => SO) = 380;
+ (D1 => SO) = 431;
+ (CI => SO) = 276;
+ (A => CO) = 525;
+ (B => CO) = 433;
+ (C => CO) = 712;
+ (D0 => CO) = 653;
+ (D1 => CO) = 593;
+ (CI => CO) = 16;
+endspecify
+`endif
+
+wire q0, q1;
+
+assign q0 = LUT0 >> {D0, C, B, A};
+assign q1 = LUT1 >> {D1, C, B, A};
+
+assign {CO, SO} = q0 + !q1 + CI;
+
+endmodule
+
+
+/*
+// A, B, C0, C1, E0, E1, F0, F1: data inputs
+// CARRYIN: carry input
+// SHAREIN: shared-arithmetic input
+// CLK0, CLK1, CLK2: clock inputs
+//
+// COMB0, COMB1: combinational outputs
+// FF0, FF1, FF2, FF3: DFF outputs
+// SUM0, SUM1: adder outputs
+// CARRYOUT: carry output
+// SHAREOUT: shared-arithmetic output
+module MISTRAL_ALM(
+ input A, B, C0, C1, E0, E1, F0, F1, CARRYIN, SHAREIN, // LUT path
+ input CLK0, CLK1, CLK2, AC0, AC1, // FF path
+ output COMB0, COMB1, SUM0, SUM1, CARRYOUT, SHAREOUT,
+ output FF0, FF1, FF2, FF3
+);
+
+parameter LUT0 = 16'b0000;
+parameter LUT1 = 16'b0000;
+parameter LUT2 = 16'b0000;
+parameter LUT3 = 16'b0000;
+
+parameter INIT0 = 1'b0;
+parameter INIT1 = 1'b0;
+parameter INIT2 = 1'b0;
+parameter INIT3 = 1'b0;
+
+parameter C0_MUX = "C0";
+parameter C1_MUX = "C1";
+
+parameter F0_MUX = "VCC";
+parameter F1_MUX = "GND";
+
+parameter FEEDBACK0 = "FF0";
+parameter FEEDBACK1 = "FF2";
+
+parameter ADD_MUX = "LUT";
+
+parameter DFF01_DATA_MUX = "COMB";
+parameter DFF23_DATA_MUX = "COMB";
+
+parameter DFF0_CLK = "CLK0";
+parameter DFF1_CLK = "CLK0";
+parameter DFF2_CLK = "CLK0";
+parameter DFF3_CLK = "CLK0";
+
+parameter DFF0_AC = "AC0";
+parameter DFF1_AC = "AC0";
+parameter DFF2_AC = "AC0";
+parameter DFF3_AC = "AC0";
+
+// Feedback muxes from the flip-flop outputs.
+wire ff_feedback_mux0, ff_feedback_mux1;
+
+// C-input muxes which can be set to also use the F-input.
+wire c0_input_mux, c1_input_mux;
+
+// F-input muxes which can be set to a constant to allow LUT5 use.
+wire f0_input_mux, f1_input_mux;
+
+// Adder input muxes to select between shared-arithmetic mode and arithmetic mode.
+wire add0_input_mux, add1_input_mux;
+
+// Combinational-output muxes for LUT #1 and LUT #3
+wire lut1_comb_mux, lut3_comb_mux;
+
+// Sum-output muxes for LUT #1 and LUT #3
+wire lut1_sum_mux, lut3_sum_mux;
+
+// DFF data-input muxes
+wire dff01_data_mux, dff23_data_mux;
+
+// DFF clock selectors
+wire dff0_clk, dff1_clk, dff2_clk, dff3_clk;
+
+// DFF asynchronous-clear selectors
+wire dff0_ac, dff1_ac, dff2_ac, dff3_ac;
+
+// LUT, DFF and adder output wires for routing.
+wire lut0_out, lut1a_out, lut1b_out, lut2_out, lut3a_out, lut3b_out;
+wire dff0_out, dff1_out, dff2_out, dff3_out;
+wire add0_sum, add1_sum, add0_carry, add1_carry;
+
+generate
+ if (FEEDBACK0 === "FF0")
+ assign ff_feedback_mux0 = dff0_out;
+ else if (FEEDBACK0 === "FF1")
+ assign ff_feedback_mux0 = dff1_out;
+ else
+ $error("Invalid FEEDBACK0 setting!");
+
+ if (FEEDBACK1 == "FF2")
+ assign ff_feedback_mux1 = dff2_out;
+ else if (FEEDBACK1 == "FF3")
+ assign ff_feedback_mux1 = dff3_out;
+ else
+ $error("Invalid FEEDBACK1 setting!");
+
+ if (C0_MUX === "C0")
+ assign c0_input_mux = C0;
+ else if (C0_MUX === "F1")
+ assign c0_input_mux = F1;
+ else if (C0_MUX === "FEEDBACK1")
+ assign c0_input_mux = ff_feedback_mux1;
+ else
+ $error("Invalid C0_MUX setting!");
+
+ if (C1_MUX === "C1")
+ assign c1_input_mux = C1;
+ else if (C1_MUX === "F0")
+ assign c1_input_mux = F0;
+ else if (C1_MUX === "FEEDBACK0")
+ assign c1_input_mux = ff_feedback_mux0;
+ else
+ $error("Invalid C1_MUX setting!");
+
+ // F0 == VCC is LUT5
+ // F0 == F0 is LUT6
+ // F0 == FEEDBACK is unknown
+ if (F0_MUX === "VCC")
+ assign f0_input_mux = 1'b1;
+ else if (F0_MUX === "F0")
+ assign f0_input_mux = F0;
+ else if (F0_MUX === "FEEDBACK0")
+ assign f0_input_mux = ff_feedback_mux0;
+ else
+ $error("Invalid F0_MUX setting!");
+
+ // F1 == GND is LUT5
+ // F1 == F1 is LUT6
+ // F1 == FEEDBACK is unknown
+ if (F1_MUX === "GND")
+ assign f1_input_mux = 1'b0;
+ else if (F1_MUX === "F1")
+ assign f1_input_mux = F1;
+ else if (F1_MUX === "FEEDBACK1")
+ assign f1_input_mux = ff_feedback_mux1;
+ else
+ $error("Invalid F1_MUX setting!");
+
+ if (ADD_MUX === "LUT") begin
+ assign add0_input_mux = ~lut1_sum_mux;
+ assign add1_input_mux = ~lut3_sum_mux;
+ end else if (ADD_MUX === "SHARE") begin
+ assign add0_input_mux = SHAREIN;
+ assign add1_input_mux = lut1_comb_mux;
+ end else
+ $error("Invalid ADD_MUX setting!");
+
+ if (DFF01_DATA_MUX === "COMB")
+ assign dff01_data_mux = COMB0;
+ else if (DFF01_DATA_MUX === "SUM")
+ assign dff01_data_mux = SUM0;
+ else
+ $error("Invalid DFF01_DATA_MUX setting!");
+
+ if (DFF23_DATA_MUX === "COMB")
+ assign dff23_data_mux = COMB0;
+ else if (DFF23_DATA_MUX === "SUM")
+ assign dff23_data_mux = SUM0;
+ else
+ $error("Invalid DFF23_DATA_MUX setting!");
+
+ if (DFF0_CLK === "CLK0")
+ assign dff0_clk = CLK0;
+ else if (DFF0_CLK === "CLK1")
+ assign dff0_clk = CLK1;
+ else if (DFF0_CLK === "CLK2")
+ assign dff0_clk = CLK2;
+ else
+ $error("Invalid DFF0_CLK setting!");
+
+ if (DFF1_CLK === "CLK0")
+ assign dff1_clk = CLK0;
+ else if (DFF1_CLK === "CLK1")
+ assign dff1_clk = CLK1;
+ else if (DFF1_CLK === "CLK2")
+ assign dff1_clk = CLK2;
+ else
+ $error("Invalid DFF1_CLK setting!");
+
+ if (DFF2_CLK === "CLK0")
+ assign dff2_clk = CLK0;
+ else if (DFF2_CLK === "CLK1")
+ assign dff2_clk = CLK1;
+ else if (DFF2_CLK === "CLK2")
+ assign dff2_clk = CLK2;
+ else
+ $error("Invalid DFF2_CLK setting!");
+
+ if (DFF3_CLK === "CLK0")
+ assign dff3_clk = CLK0;
+ else if (DFF3_CLK === "CLK1")
+ assign dff3_clk = CLK1;
+ else if (DFF3_CLK === "CLK2")
+ assign dff3_clk = CLK2;
+ else
+ $error("Invalid DFF3_CLK setting!");
+
+ if (DFF0_AC === "AC0")
+ assign dff0_ac = AC0;
+ else if (DFF0_AC === "AC1")
+ assign dff0_ac = AC1;
+ else
+ $error("Invalid DFF0_AC setting!");
+
+ if (DFF1_AC === "AC0")
+ assign dff1_ac = AC0;
+ else if (DFF1_AC === "AC1")
+ assign dff1_ac = AC1;
+ else
+ $error("Invalid DFF1_AC setting!");
+
+ if (DFF2_AC === "AC0")
+ assign dff2_ac = AC0;
+ else if (DFF2_AC === "AC1")
+ assign dff2_ac = AC1;
+ else
+ $error("Invalid DFF2_AC setting!");
+
+ if (DFF3_AC === "AC0")
+ assign dff3_ac = AC0;
+ else if (DFF3_AC === "AC1")
+ assign dff3_ac = AC1;
+ else
+ $error("Invalid DFF3_AC setting!");
+
+endgenerate
+
+// F0 on the Quartus diagram
+MISTRAL_ALUT4 #(.LUT(LUT0)) lut0 (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut0_out));
+
+// F2 on the Quartus diagram
+MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_comb (.A(A), .B(B), .C(C0), .D(c1_input_mux), .Q(lut1_comb_mux));
+MISTRAL_ALUT4 #(.LUT(LUT1)) lut1_sum (.A(A), .B(B), .C(C0), .D(E0), .Q(lut1_sum_mux));
+
+// F1 on the Quartus diagram
+MISTRAL_ALUT4 #(.LUT(LUT2)) lut2 (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut2_out));
+
+// F3 on the Quartus diagram
+MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_comb (.A(A), .B(B), .C(C1), .D(c0_input_mux), .Q(lut3_comb_mux));
+MISTRAL_ALUT4 #(.LUT(LUT3)) lut3_sum (.A(A), .B(B), .C(C1), .D(E1), .Q(lut3_sum_mux));
+
+MISTRAL_FF #(.INIT(INIT0)) dff0 (.D(dff01_data_mux), .CLK(dff0_clk), .ACn(dff0_ac), .Q(dff0_out));
+MISTRAL_FF #(.INIT(INIT1)) dff1 (.D(dff01_data_mux), .CLK(dff1_clk), .ACn(dff1_ac), .Q(dff1_out));
+MISTRAL_FF #(.INIT(INIT2)) dff2 (.D(dff23_data_mux), .CLK(dff2_clk), .ACn(dff2_ac), .Q(dff2_out));
+MISTRAL_FF #(.INIT(INIT3)) dff3 (.D(dff23_data_mux), .CLK(dff3_clk), .ACn(dff3_ac), .Q(dff3_out));
+
+// Adders
+assign {add0_carry, add0_sum} = CARRYIN + lut0_out + lut1_sum_mux;
+assign {add1_carry, add1_sum} = add0_carry + lut2_out + lut3_sum_mux;
+
+// COMBOUT outputs on the Quartus diagram
+assign COMB0 = E0 ? (f0_input_mux ? lut3_comb_mux : lut1_comb_mux)
+ : (f0_input_mux ? lut2_out : lut0_out);
+
+assign COMB1 = E1 ? (f1_input_mux ? lut3_comb_mux : lut1_comb_mux)
+ : (f1_input_mux ? lut2_out : lut0_out);
+
+// SUMOUT output on the Quartus diagram
+assign SUM0 = add0_sum;
+assign SUM1 = add1_sum;
+
+// COUT output on the Quartus diagram
+assign CARRYOUT = add1_carry;
+
+// SHAREOUT output on the Quartus diagram
+assign SHAREOUT = lut3_comb_mux;
+
+// REGOUT outputs on the Quartus diagram
+assign FF0 = dff0_out;
+assign FF1 = dff1_out;
+assign FF2 = dff2_out;
+assign FF3 = dff3_out;
+
+endmodule
+*/
diff --git a/techlibs/intel_alm/common/arith_alm_map.v b/techlibs/intel_alm/common/arith_alm_map.v
new file mode 100644
index 000000000..ddf81d9d0
--- /dev/null
+++ b/techlibs/intel_alm/common/arith_alm_map.v
@@ -0,0 +1,64 @@
+`default_nettype none
+
+module \$alu (A, B, CI, BI, X, Y, CO);
+
+parameter A_SIGNED = 0;
+parameter B_SIGNED = 0;
+parameter A_WIDTH = 1;
+parameter B_WIDTH = 1;
+parameter Y_WIDTH = 1;
+
+parameter _TECHMAP_CONSTMSK_CI_ = 0;
+parameter _TECHMAP_CONSTVAL_CI_ = 0;
+
+input [A_WIDTH-1:0] A;
+input [B_WIDTH-1:0] B;
+input CI, BI;
+output [Y_WIDTH-1:0] X, Y, CO;
+
+wire [Y_WIDTH-1:0] A_buf, B_buf;
+\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
+\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
+
+wire [Y_WIDTH-1:0] AA = A_buf;
+wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
+wire [Y_WIDTH-1:0] BX = B_buf;
+wire [Y_WIDTH:0] ALM_CARRY;
+
+// Start of carry chain
+generate
+ if (_TECHMAP_CONSTMSK_CI_ == 1) begin
+ assign ALM_CARRY[0] = _TECHMAP_CONSTVAL_CI_;
+ end else begin
+ MISTRAL_ALUT_ARITH #(
+ .LUT0(16'b1010_1010_1010_1010), // Q = A
+ .LUT1(16'b0000_0000_0000_0000), // Q = 0 (LUT1's input to the adder is inverted)
+ ) alm_start (
+ .A(CI), .B(1'b1), .C(1'b1), .D0(1'b1), .D1(1'b1),
+ .CI(1'b0),
+ .CO(ALM_CARRY[0])
+ );
+ end
+endgenerate
+
+// Carry chain
+genvar i;
+generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
+ // TODO: mwk suggests that a pass could merge pre-adder logic into this.
+ MISTRAL_ALUT_ARITH #(
+ .LUT0(16'b1010_1010_1010_1010), // Q = A
+ .LUT1(16'b1100_0011_1100_0011), // Q = C ? B : ~B (LUT1's input to the adder is inverted)
+ ) alm_i (
+ .A(AA[i]), .B(BX[i]), .C(BI), .D0(1'b1), .D1(1'b1),
+ .CI(ALM_CARRY[i]),
+ .SO(Y[i]),
+ .CO(ALM_CARRY[i+1])
+ );
+
+ // ALM carry chain is not directly accessible, so calculate the carry through soft logic if really needed.
+ assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i]));
+end endgenerate
+
+assign X = AA ^ BB;
+
+endmodule
diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt
new file mode 100644
index 000000000..837e3a330
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m10k.txt
@@ -0,0 +1,33 @@
+bram __MISTRAL_M10K_SDP
+ init 0 # TODO: Re-enable when I figure out how BRAM init works
+ abits 13 @D8192x1
+ dbits 1 @D8192x1
+ abits 12 @D4096x2
+ dbits 2 @D4096x2
+ abits 11 @D2048x4 @D2048x5
+ dbits 4 @D2048x4
+ dbits 5 @D2048x5
+ abits 10 @D1024x8 @D1024x10
+ dbits 8 @D1024x8
+ dbits 10 @D1024x10
+ abits 9 @D512x16 @D512x20
+ dbits 16 @D512x16
+ dbits 20 @D512x20
+ abits 8 @D256x32 @D256x40
+ dbits 32 @D256x32
+ dbits 40 @D256x40
+ groups 2
+ ports 1 1
+ wrmode 1 0
+ # read enable; write enable + byte enables (only for multiples of 8)
+ enable 1 1
+ transp 0 0
+ clocks 1 1
+ clkpol 1 1
+endbram
+
+
+match __MISTRAL_M10K_SDP
+ min efficiency 5
+ make_transp
+endmatch
diff --git a/techlibs/intel_alm/common/bram_m10k_map.v b/techlibs/intel_alm/common/bram_m10k_map.v
new file mode 100644
index 000000000..e5566010d
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m10k_map.v
@@ -0,0 +1,31 @@
+module __MISTRAL_M10K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+parameter CFG_ABITS = 10;
+parameter CFG_DBITS = 10;
+parameter CFG_ENABLE_A = 1;
+parameter CFG_ENABLE_B = 1;
+
+input CLK1;
+input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
+input [CFG_DBITS-1:0] A1DATA;
+output [CFG_DBITS-1:0] B1DATA;
+input [CFG_ENABLE_A-1:0] A1EN, B1EN;
+
+altsyncram #(
+ .operation_mode("dual_port"),
+ .ram_block_type("m10k"),
+ .widthad_a(CFG_ABITS),
+ .width_a(CFG_DBITS),
+ .widthad_b(CFG_ABITS),
+ .width_b(CFG_DBITS),
+) _TECHMAP_REPLACE_ (
+ .address_a(A1ADDR),
+ .data_a(A1DATA),
+ .wren_a(A1EN),
+ .address_b(B1ADDR),
+ .q_b(B1DATA),
+ .clock0(CLK1),
+ .clock1(CLK1)
+);
+
+endmodule
diff --git a/techlibs/intel_alm/common/bram_m20k.txt b/techlibs/intel_alm/common/bram_m20k.txt
new file mode 100644
index 000000000..b4c5a5372
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m20k.txt
@@ -0,0 +1,33 @@
+bram __MISTRAL_M20K_SDP
+ init 1 # TODO: Re-enable when I figure out how BRAM init works
+ abits 14 @D16384x1
+ dbits 1 @D16384x1
+ abits 13 @D8192x2
+ dbits 2 @D8192x2
+ abits 12 @D4096x4 @D4096x5
+ dbits 4 @D4096x4
+ dbits 5 @D4096x5
+ abits 11 @D2048x8 @D2048x10
+ dbits 8 @D2048x8
+ dbits 10 @D2048x10
+ abits 10 @D1024x16 @D1024x20
+ dbits 16 @D1024x16
+ dbits 20 @D1024x20
+ abits 9 @D512x32 @D512x40
+ dbits 32 @D512x32
+ dbits 40 @D512x40
+ groups 2
+ ports 1 1
+ wrmode 1 0
+ # read enable; write enable + byte enables (only for multiples of 8)
+ enable 1 1
+ transp 0 0
+ clocks 1 1
+ clkpol 1 1
+endbram
+
+
+match __MISTRAL_M20K_SDP
+ min efficiency 5
+ make_transp
+endmatch
diff --git a/techlibs/intel_alm/common/bram_m20k_map.v b/techlibs/intel_alm/common/bram_m20k_map.v
new file mode 100644
index 000000000..92f41310f
--- /dev/null
+++ b/techlibs/intel_alm/common/bram_m20k_map.v
@@ -0,0 +1,31 @@
+module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
+
+parameter CFG_ABITS = 10;
+parameter CFG_DBITS = 20;
+parameter CFG_ENABLE_A = 1;
+parameter CFG_ENABLE_B = 1;
+
+input CLK1;
+input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
+input [CFG_DBITS-1:0] A1DATA;
+output [CFG_DBITS-1:0] B1DATA;
+input [CFG_ENABLE_A-1:0] A1EN, B1EN;
+
+altsyncram #(
+ .operation_mode("dual_port"),
+ .ram_block_type("m20k"),
+ .widthad_a(CFG_ABITS),
+ .width_a(CFG_DBITS),
+ .widthad_b(CFG_ABITS),
+ .width_b(CFG_DBITS),
+) _TECHMAP_REPLACE_ (
+ .address_a(A1ADDR),
+ .data_a(A1DATA),
+ .wren_a(A1EN),
+ .address_b(B1ADDR),
+ .q_b(B1DATA),
+ .clock0(CLK1),
+ .clock1(CLK1)
+);
+
+endmodule
diff --git a/techlibs/intel_alm/common/dff_map.v b/techlibs/intel_alm/common/dff_map.v
new file mode 100644
index 000000000..f7f2fe3c3
--- /dev/null
+++ b/techlibs/intel_alm/common/dff_map.v
@@ -0,0 +1,124 @@
+`default_nettype none
+
+// D flip-flops
+module \$_DFF_P_ (input D, C, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_P_ with INIT=1");
+endmodule
+
+module \$_DFF_N_ (input D, C, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_N_ with INIT=1");
+endmodule
+
+// D flip-flops with reset
+module \$_DFF_PP0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_PP0_ with INIT=1");
+endmodule
+
+module \$_DFF_PN0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_PN0_ with INIT=1");
+endmodule
+
+module \$_DFF_NP0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_NP0_ with INIT=1");
+endmodule
+
+module \$_DFF_NN0_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFF_NN0_ with INIT=1");
+endmodule
+
+// D flip-flops with set
+module \$_DFF_PP1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+ assign Q = ~Q_tmp;
+end else $error("Unsupported flop: $_DFF_PP1_ with INIT=0");
+endmodule
+
+module \$_DFF_PN1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+end else $error("Unsupported flop: $_DFF_PN1_ with INIT=0");
+endmodule
+
+module \$_DFF_NP1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(~R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+ assign Q = ~Q_tmp;
+end else $error("Unsupported flop: $_DFF_NP1_ with INIT=0");
+endmodule
+
+module \$_DFF_NN1_ (input D, C, R, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b1;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b0) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ wire Q_tmp;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(~D), .CLK(~C), .ACLR(R), .ENA(1'b1), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q_tmp));
+ assign Q = ~Q_tmp;
+end else $error("Unsupported flop: $_DFF_NN1_ with INIT=0");
+endmodule
+
+// D flip-flops with clock enable
+module \$_DFFE_PP_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_PP_ with INIT=1");
+endmodule
+
+module \$_DFFE_PN_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_PN_ with INIT=1");
+endmodule
+
+module \$_DFFE_NP_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_NP_ with INIT=1");
+endmodule
+
+module \$_DFFE_NN_ (input D, C, E, output Q);
+parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
+if (_TECHMAP_WIREINIT_Q_ !== 1'b1) begin
+ wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
+ MISTRAL_FF _TECHMAP_REPLACE_(.DATAIN(D), .CLK(~C), .ACLR(1'b1), .ENA(~E), .SCLR(1'b0), .SLOAD(1'b0), .SDATA(1'b0), .Q(Q));
+end else $error("Unsupported flop: $_DFFE_NN_ with INIT=1");
+endmodule
diff --git a/techlibs/intel_alm/common/dff_sim.v b/techlibs/intel_alm/common/dff_sim.v
new file mode 100644
index 000000000..07865905f
--- /dev/null
+++ b/techlibs/intel_alm/common/dff_sim.v
@@ -0,0 +1,48 @@
+// DATAIN: synchronous data input
+// CLK: clock input (positive edge)
+// ACLR: asynchronous clear (negative-true)
+// ENA: clock-enable
+// SCLR: synchronous clear
+// SLOAD: synchronous load
+// SDATA: synchronous load data
+//
+// Q: data output
+//
+// Note: the DFFEAS primitive is mostly emulated; it does not reflect what the hardware implements.
+module MISTRAL_FF(
+ input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA,
+ output reg Q
+);
+
+`ifdef cyclonev
+specify
+ (posedge CLK => (Q : DATAIN)) = 262;
+ $setup(DATAIN, posedge CLK, 522);
+endspecify
+`endif
+`ifdef cyclone10gx
+specify
+ (posedge CLK => (Q : DATAIN)) = 219;
+ $setup(DATAIN, posedge CLK, 268);
+endspecify
+`endif
+
+initial begin
+ // Altera flops initialise to zero.
+ Q = 0;
+end
+
+always @(posedge CLK, negedge ACLR) begin
+ // Asynchronous clear
+ if (!ACLR) Q <= 0;
+ // Clock-enable
+ else if (ENA) begin
+ // Synchronous clear
+ if (SCLR) Q <= 0;
+ // Synchronous load
+ else if (SLOAD) Q <= SDATA;
+ else Q <= DATAIN;
+ end
+end
+
+endmodule
diff --git a/techlibs/intel_alm/common/lutram_mlab.txt b/techlibs/intel_alm/common/lutram_mlab.txt
new file mode 100644
index 000000000..1d6174d85
--- /dev/null
+++ b/techlibs/intel_alm/common/lutram_mlab.txt
@@ -0,0 +1,20 @@
+bram __MISTRAL_MLAB
+ init 0 # TODO: Re-enable when I figure out how LUTRAM init works
+ abits 5
+ dbits 16 @D32x16
+ dbits 18 @D32x18
+ dbits 20 @D32x20
+ groups 2
+ ports 1 1
+ wrmode 1 0
+ # read enable
+ enable 1 0
+ transp 1 0
+ clocks 1 2
+ clkpol 1 1
+endbram
+
+match __MISTRAL_MLAB
+ min efficiency 5
+ make_outreg
+endmatch
diff --git a/techlibs/intel_alm/common/lutram_mlab_map.v b/techlibs/intel_alm/common/lutram_mlab_map.v
new file mode 100644
index 000000000..3a9c8590e
--- /dev/null
+++ b/techlibs/intel_alm/common/lutram_mlab_map.v
@@ -0,0 +1,29 @@
+module __MISTRAL_MLAB(CLK1, CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA);
+
+parameter CFG_ABITS = 5;
+parameter CFG_DBITS = 20;
+
+input CLK1, CLK2;
+input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
+input [CFG_DBITS-1:0] A1DATA;
+input A1EN;
+output [CFG_DBITS-1:0] B1DATA;
+
+altsyncram #(
+ .operation_mode("dual_port"),
+ .ram_block_type("mlab"),
+ .widthad_a(CFG_ABITS),
+ .width_a(CFG_DBITS),
+ .widthad_b(CFG_ABITS),
+ .width_b(CFG_DBITS),
+) _TECHMAP_REPLACE_ (
+ .address_a(A1ADDR),
+ .data_a(A1DATA),
+ .wren_a(A1EN),
+ .address_b(B1ADDR),
+ .q_b(B1DATA),
+ .clock0(CLK1),
+ .clock1(CLK1),
+);
+
+endmodule
diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v
new file mode 100644
index 000000000..21ba73a09
--- /dev/null
+++ b/techlibs/intel_alm/common/megafunction_bb.v
@@ -0,0 +1,108 @@
+// Intel megafunction declarations, to avoid Yosys complaining.
+`default_nettype none
+
+(* blackbox *)
+module altera_std_synchronizer(clk, din, dout, reset_n);
+
+parameter depth = 2;
+
+input clk;
+input reset_n;
+input din;
+output dout;
+
+endmodule
+
+(* blackbox *)
+module altiobuf_in(datain, dataout);
+
+parameter enable_bus_hold = "FALSE";
+parameter use_differential_mode = "FALSE";
+parameter number_of_channels = 1;
+
+input [number_of_channels-1:0] datain;
+output [number_of_channels-1:0] dataout;
+
+endmodule
+
+(* blackbox *)
+module altiobuf_out(datain, dataout);
+
+parameter enable_bus_hold = "FALSE";
+parameter use_differential_mode = "FALSE";
+parameter use_oe = "FALSE";
+parameter number_of_channels = 1;
+
+input [number_of_channels-1:0] datain;
+output [number_of_channels-1:0] dataout;
+
+endmodule
+
+(* blackbox *)
+module altiobuf_bidir(dataio, oe, datain, dataout);
+
+parameter number_of_channels = 1;
+parameter enable_bus_hold = "OFF";
+
+inout [number_of_channels-1:0] dataio;
+input [number_of_channels-1:0] datain;
+output [number_of_channels-1:0] dataout;
+input [number_of_channels-1:0] oe;
+
+endmodule
+
+(* blackbox *)
+module altsyncram(clock0, clock1, address_a, data_a, rden_a, wren_a, byteena_a, q_a, addressstall_a, address_b, data_b, rden_b, wren_b, byteena_b, q_b, addressstall_b, clocken0, clocken1, clocken2, clocken3, aclr0, aclr1, eccstatus);
+
+parameter lpm_type = "altsyncram";
+parameter operation_mode = "dual_port";
+parameter ram_block_type = "auto";
+parameter intended_device_family = "auto";
+parameter power_up_uninitialized = "false";
+parameter read_during_write_mode_mixed_ports = "dontcare";
+parameter byte_size = 8;
+parameter widthad_a = 1;
+parameter width_a = 1;
+parameter width_byteena_a = 1;
+parameter numwords_a = 1;
+parameter clock_enable_input_a = "clocken0";
+parameter widthad_b = 1;
+parameter width_b = 1;
+parameter numwords_b = 1;
+parameter address_aclr_b = "aclr0";
+parameter address_reg_b = "";
+parameter outdata_aclr_b = "aclr0";
+parameter outdata_reg_b = "";
+parameter clock_enable_input_b = "clocken0";
+parameter clock_enable_output_b = "clocken0";
+
+input clock0, clock1;
+input [widthad_a-1:0] address_a;
+input [width_a-1:0] data_a;
+input rden_a;
+input wren_a;
+input [(width_a/8)-1:0] byteena_a;
+input addressstall_a;
+
+output [width_a-1:0] q_a;
+
+input wren_b;
+input rden_b;
+input [widthad_b-1:0] address_b;
+input [width_b-1:0] data_b;
+input [(width_b/8)-1:0] byteena_b;
+input addressstall_b;
+
+output [width_b-1:0] q_b;
+
+input clocken0;
+input clocken1;
+input clocken2;
+input clocken3;
+
+input aclr0;
+input aclr1;
+
+output eccstatus;
+
+endmodule
diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v
new file mode 100644
index 000000000..d9961c174
--- /dev/null
+++ b/techlibs/intel_alm/common/quartus_rename.v
@@ -0,0 +1,19 @@
+module __MISTRAL_VCC(output Q);
+
+MISTRAL_ALUT2 #(.LUT(4'b1111)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q));
+
+endmodule
+
+
+module __MISTRAL_GND(output Q);
+
+MISTRAL_ALUT2 #(.LUT(4'b0000)) _TECHMAP_REPLACE_ (.A(1'b1), .B(1'b1), .Q(Q));
+
+endmodule
+
+
+module MISTRAL_FF(input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA, output reg Q);
+
+dffeas #(.power_up("low"), .is_wysiwyg("true")) _TECHMAP_REPLACE_ (.d(DATAIN), .clk(CLK), .clrn(ACLR), .ena(ENA), .sclr(SCLR), .sload(SLOAD), .asdata(SDATA), .q(Q));
+
+endmodule
diff --git a/techlibs/intel_alm/cyclone10gx/quartus_rename.v b/techlibs/intel_alm/cyclone10gx/quartus_rename.v
new file mode 100644
index 000000000..3fbc508ed
--- /dev/null
+++ b/techlibs/intel_alm/cyclone10gx/quartus_rename.v
@@ -0,0 +1,54 @@
+module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q);
+parameter LUT = 64'h0000_0000_0000_0000;
+
+cyclone10gx_lcell_comb #(.lut_mask(LUT)) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .dataf(F), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT5(input A, B, C, D, E, output Q);
+parameter LUT = 32'h0000_0000;
+
+cyclone10gx_lcell_comb #(.lut_mask({2{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT4(input A, B, C, D, output Q);
+parameter LUT = 16'h0000;
+
+cyclone10gx_lcell_comb #(.lut_mask({4{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT3(input A, B, C, output Q);
+parameter LUT = 8'h00;
+
+cyclone10gx_lcell_comb #(.lut_mask({8{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT2(input A, B, output Q);
+parameter LUT = 4'h0;
+
+cyclone10gx_lcell_comb #(.lut_mask({16{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_NOT(input A, output Q);
+
+NOT _TECHMAP_REPLACE_ (.IN(A), .OUT(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, CI, output SO, CO);
+parameter LUT0 = 16'h0000;
+parameter LUT1 = 16'h0000;
+
+cyclone10gx_lcell_comb #(.lut_mask({16'h0, LUT1, 16'h0, LUT0})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D0), .dataf(D1), .cin(CI), .sumout(SO), .cout(CO));
+
+endmodule
diff --git a/techlibs/intel_alm/cyclonev/quartus_rename.v b/techlibs/intel_alm/cyclonev/quartus_rename.v
new file mode 100644
index 000000000..6eff375e1
--- /dev/null
+++ b/techlibs/intel_alm/cyclonev/quartus_rename.v
@@ -0,0 +1,54 @@
+module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q);
+parameter LUT = 64'h0000_0000_0000_0000;
+
+cyclonev_lcell_comb #(.lut_mask(LUT)) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .dataf(F), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT5(input A, B, C, D, E, output Q);
+parameter LUT = 32'h0000_0000;
+
+cyclonev_lcell_comb #(.lut_mask({2{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .datae(E), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT4(input A, B, C, D, output Q);
+parameter LUT = 16'h0000;
+
+cyclonev_lcell_comb #(.lut_mask({4{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT3(input A, B, C, output Q);
+parameter LUT = 8'h00;
+
+cyclonev_lcell_comb #(.lut_mask({8{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT2(input A, B, output Q);
+parameter LUT = 4'h0;
+
+cyclonev_lcell_comb #(.lut_mask({16{LUT}})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .combout(Q));
+
+endmodule
+
+
+module MISTRAL_NOT(input A, output Q);
+
+NOT _TECHMAP_REPLACE_ (.IN(A), .OUT(Q));
+
+endmodule
+
+
+module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, CI, output SO, CO);
+parameter LUT0 = 16'h0000;
+parameter LUT1 = 16'h0000;
+
+cyclonev_lcell_comb #(.lut_mask({16'h0, LUT1, 16'h0, LUT0})) _TECHMAP_REPLACE_ (.dataa(A), .datab(B), .datac(C), .datad(D0), .dataf(D1), .cin(CI), .sumout(SO), .cout(CO));
+
+endmodule
diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc
new file mode 100644
index 000000000..47aa11500
--- /dev/null
+++ b/techlibs/intel_alm/synth_intel_alm.cc
@@ -0,0 +1,241 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Claire Wolf <claire@symbioticeda.com>
+ * Copyright (C) 2019 Dan Ravensloft <dan.ravensloft@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/celltypes.h"
+#include "kernel/log.h"
+#include "kernel/register.h"
+#include "kernel/rtlil.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct SynthIntelALMPass : public ScriptPass {
+ SynthIntelALMPass() : ScriptPass("synth_intel_alm", "synthesis for ALM-based Intel (Altera) FPGAs.") {}
+
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" synth_intel_alm [options]\n");
+ log("\n");
+ log("This command runs synthesis for ALM-based Intel FPGAs.\n");
+ log("\n");
+ log(" -top <module>\n");
+ log(" use the specified module as top module (default='top')\n");
+ log("\n");
+ log(" -family <family>\n");
+ log(" target one of:\n");
+ log(" \"cyclonev\" - Cyclone V (default)\n");
+ log(" \"cyclone10gx\" - Cyclone 10GX\n");
+ log("\n");
+ log(" -quartus\n");
+ log(" output a netlist using Quartus cells instead of MISTRAL_* cells\n");
+ log("\n");
+ log(" -vqm <file>\n");
+ log(" write the design to the specified Verilog Quartus Mapping File. Writing of an\n");
+ log(" output file is omitted if this parameter is not specified. Implies -quartus.\n");
+ log("\n");
+ log(" -run <from_label>:<to_label>\n");
+ log(" only run the commands between the labels (see below). an empty\n");
+ log(" from label is synonymous to 'begin', and empty to label is\n");
+ log(" synonymous to the end of the command list.\n");
+ log("\n");
+ log(" -nolutram\n");
+ log(" do not use LUT RAM cells in output netlist\n");
+ log("\n");
+ log(" -nobram\n");
+ log(" do not use block RAM cells in output netlist\n");
+ log("\n");
+ log(" -noflatten\n");
+ log(" do not flatten design before synthesis\n");
+ log("\n");
+ log("The following commands are executed by this synthesis command:\n");
+ help_script();
+ log("\n");
+ }
+
+ string top_opt, family_opt, bram_type, vout_file;
+ bool flatten, quartus, nolutram, nobram;
+
+ void clear_flags() YS_OVERRIDE
+ {
+ top_opt = "-auto-top";
+ family_opt = "cyclonev";
+ bram_type = "m10k";
+ vout_file = "";
+ flatten = true;
+ quartus = false;
+ nolutram = false;
+ nobram = false;
+ }
+
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ string run_from, run_to;
+ clear_flags();
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ if (args[argidx] == "-family" && argidx + 1 < args.size()) {
+ family_opt = args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-top" && argidx + 1 < args.size()) {
+ top_opt = "-top " + args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-vqm" && argidx + 1 < args.size()) {
+ quartus = true;
+ vout_file = args[++argidx];
+ continue;
+ }
+ if (args[argidx] == "-run" && argidx + 1 < args.size()) {
+ size_t pos = args[argidx + 1].find(':');
+ if (pos == std::string::npos)
+ break;
+ run_from = args[++argidx].substr(0, pos);
+ run_to = args[argidx].substr(pos + 1);
+ continue;
+ }
+ if (args[argidx] == "-quartus") {
+ quartus = true;
+ continue;
+ }
+ if (args[argidx] == "-nolutram") {
+ nolutram = true;
+ continue;
+ }
+ if (args[argidx] == "-nobram") {
+ nobram = true;
+ continue;
+ }
+ if (args[argidx] == "-noflatten") {
+ flatten = false;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ if (!design->full_selection())
+ log_cmd_error("This command only operates on fully selected designs!\n");
+
+ if (family_opt == "cyclonev") {
+ bram_type = "m10k";
+ } else if (family_opt == "cyclone10gx") {
+ bram_type = "m20k";
+ } else {
+ log_cmd_error("Invalid family specified: '%s'\n", family_opt.c_str());
+ }
+
+ log_header(design, "Executing SYNTH_INTEL_ALM pass.\n");
+ log_push();
+
+ run_script(design, run_from, run_to);
+
+ log_pop();
+ }
+
+ void script() YS_OVERRIDE
+ {
+ if (help_mode) {
+ family_opt = "<family>";
+ bram_type = "<bram_type>";
+ }
+
+ if (check_label("begin")) {
+ run(stringf("read_verilog -sv -lib +/intel/%s/cells_sim.v", family_opt.c_str()));
+ run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/alm_sim.v", family_opt.c_str()));
+ run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str()));
+
+ // Misc and common cells
+ run("read_verilog -lib +/intel/common/altpll_bb.v");
+ run("read_verilog -lib +/intel_alm/common/megafunction_bb.v");
+ run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
+ }
+
+ if (flatten && check_label("flatten", "(unless -noflatten)")) {
+ run("proc");
+ run("flatten");
+ run("tribuf -logic");
+ run("deminout");
+ }
+
+ if (check_label("coarse")) {
+ run("synth -run coarse -lut 6");
+ run("techmap -map +/intel_alm/common/arith_alm_map.v");
+ }
+
+ if (!nobram && check_label("map_bram", "(skip if -nobram)")) {
+ run(stringf("memory_bram -rules +/intel_alm/common/bram_%s.txt", bram_type.c_str()));
+ run(stringf("techmap -map +/intel_alm/common/bram_%s_map.v", bram_type.c_str()));
+ }
+
+ if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) {
+ run("memory_bram -rules +/intel_alm/common/lutram_mlab.txt", "(for Cyclone V / Cyclone 10GX)");
+ run("techmap -map +/intel_alm/common/lutram_mlab_map.v", "(for Cyclone V / Cyclone 10GX)");
+ }
+
+ if (check_label("map_ffram")) {
+ run("memory_map");
+ run("opt -full");
+ }
+
+ if (check_label("map_ffs")) {
+ run("dff2dffe -direct-match $_DFF_*");
+ run("zinit");
+ run("techmap -map +/techmap.v -map +/intel_alm/common/dff_map.v");
+ run("opt -full -undriven -mux_undef");
+ run("clean -purge");
+ }
+
+ if (check_label("map_luts")) {
+ run("read_verilog -icells -specify -lib +/abc9_model.v");
+ run("abc9 -maxlut 6 -W 200");
+ run("techmap -map +/intel_alm/common/alm_map.v");
+ run("opt -fast");
+ run("autoname");
+ run("clean");
+ }
+
+ if (check_label("check")) {
+ run("hierarchy -check");
+ run("stat");
+ run("check");
+ }
+
+ if (check_label("quartus")) {
+ if (quartus || help_mode) {
+ run("setundef -zero");
+ run("hilomap -singleton -hicell __MISTRAL_VCC Q -locell __MISTRAL_GND Q");
+ run("techmap -map +/intel_alm/common/quartus_rename.v");
+ run(stringf("techmap -map +/intel_alm/%s/quartus_rename.v", family_opt.c_str()));
+ }
+ }
+
+ if (check_label("vqm")) {
+ if (!vout_file.empty() || help_mode) {
+ run(stringf("write_verilog -attr2comment -defparam -nohex -decimal %s", help_mode ? "<file-name>" : vout_file.c_str()));
+ }
+ }
+ }
+} SynthIntelALMPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc
index 3d43332e2..619888d38 100644
--- a/techlibs/sf2/sf2_iobs.cc
+++ b/techlibs/sf2/sf2_iobs.cc
@@ -34,14 +34,14 @@ static void handle_iobufs(Module *module, bool clkbuf_mode)
for (auto cell : module->cells())
{
- if (clkbuf_mode && cell->type == "\\SLE") {
- for (auto bit : sigmap(cell->getPort("\\CLK")))
+ if (clkbuf_mode && cell->type == ID(SLE)) {
+ for (auto bit : sigmap(cell->getPort(ID::CLK)))
clk_bits.insert(bit);
}
- if (cell->type.in("\\INBUF", "\\OUTBUF", "\\TRIBUFF", "\\BIBUF", "\\CLKBUF", "\\CLKBIBUF",
- "\\INBUF_DIFF", "\\OUTBUF_DIFF", "\\BIBUFF_DIFF", "\\TRIBUFF_DIFF", "\\CLKBUF_DIFF",
- "\\GCLKBUF", "\\GCLKBUF_DIFF", "\\GCLKBIBUF")) {
- for (auto bit : sigmap(cell->getPort("\\PAD")))
+ if (cell->type.in(ID(INBUF), ID(OUTBUF), ID(TRIBUFF), ID(BIBUF), ID(CLKBUF), ID(CLKBIBUF),
+ ID(INBUF_DIFF), ID(OUTBUF_DIFF), ID(BIBUFF_DIFF), ID(TRIBUFF_DIFF), ID(CLKBUF_DIFF),
+ ID(GCLKBUF), ID(GCLKBUF_DIFF), ID(GCLKBIBUF))) {
+ for (auto bit : sigmap(cell->getPort(ID(PAD))))
handled_io_bits.insert(bit);
}
}
@@ -65,14 +65,14 @@ static void handle_iobufs(Module *module, bool clkbuf_mode)
IdString buf_type, buf_port;
if (wire->port_output) {
- buf_type = "\\OUTBUF";
- buf_port = "\\D";
+ buf_type = ID(OUTBUF);
+ buf_port = ID::D;
} else if (clkbuf_mode && clk_bits.count(canonical_bit)) {
- buf_type = "\\CLKBUF";
- buf_port = "\\Y";
+ buf_type = ID(CLKBUF);
+ buf_port = ID::Y;
} else {
- buf_type = "\\INBUF";
- buf_port = "\\Y";
+ buf_type = ID(INBUF);
+ buf_port = ID::Y;
}
Cell *c = module->addCell(NEW_ID, buf_type);
@@ -96,7 +96,7 @@ static void handle_iobufs(Module *module, bool clkbuf_mode)
module->rewrite_sigspecs(rewrite_function);
for (auto &it : pad_bits)
- it.first->setPort("\\PAD", it.second);
+ it.first->setPort(ID(PAD), it.second);
}
static void handle_clkint(Module *module)
@@ -108,13 +108,13 @@ static void handle_clkint(Module *module)
for (auto cell : module->cells())
{
- if (cell->type == "\\SLE") {
- for (auto bit : sigmap(cell->getPort("\\CLK")))
+ if (cell->type == ID(SLE)) {
+ for (auto bit : sigmap(cell->getPort(ID::CLK)))
clk_bits.insert(bit);
}
- if (cell->type.in("\\CLKBUF", "\\CLKBIBUF", "\\CLKBUF_DIFF", "\\GCLKBUF", "\\GCLKBUF_DIFF", "\\GCLKBIBUF",
- "\\CLKINT", "\\CLKINT_PRESERVE", "\\GCLKINT", "\\RCLKINT", "\\RGCLKINT")) {
- for (auto bit : sigmap(cell->getPort("\\Y")))
+ if (cell->type.in(ID(CLKBUF), ID(CLKBIBUF), ID(CLKBUF_DIFF), ID(GCLKBUF), ID(GCLKBUF_DIFF), ID(GCLKBIBUF),
+ ID(CLKINT), ID(CLKINT_PRESERVE), ID(GCLKINT), ID(RCLKINT), ID(RGCLKINT))) {
+ for (auto bit : sigmap(cell->getPort(ID::Y)))
handled_clk_bits.push_back(bit);
}
}
@@ -134,10 +134,10 @@ static void handle_clkint(Module *module)
for (auto &bit : sig) {
SigBit canonical_bit = sigmap(bit);
if (clk_bits.count(canonical_bit)) {
- Cell *c = module->addCell(NEW_ID, "\\CLKINT");
+ Cell *c = module->addCell(NEW_ID, ID(CLKINT));
SigBit new_bit = module->addWire(NEW_ID);
- c->setPort("\\A", new_bit);
- c->setPort("\\Y", bit);
+ c->setPort(ID::A, new_bit);
+ c->setPort(ID::Y, bit);
log("Added %s cell %s for clock signal %s.\n", log_id(c->type), log_id(c), log_signal(bit));
clk_bits.erase(canonical_bit);
did_something = true;
diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc
index 5efa005c8..34a7e68be 100644
--- a/techlibs/sf2/synth_sf2.cc
+++ b/techlibs/sf2/synth_sf2.cc
@@ -187,7 +187,6 @@ struct SynthSf2Pass : public ScriptPass
if (check_label("map_ffs"))
{
- run("dffsr2dff");
run("techmap -D NO_LUT -map +/sf2/cells_map.v");
run("opt_expr -mux_undef");
run("simplemap");
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 8553efd6b..1c190d37e 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -393,8 +393,6 @@ struct SynthXilinxPass : public ScriptPass
run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')");
run("clean", " (skip if '-nosrl' and '-widemux=0')");
}
-
- run("techmap -map +/cmp2lut.v -D LUT_WIDTH=" + lut_size_s);
}
if (check_label("map_dsp", "(skip if '-nodsp')")) {
@@ -460,6 +458,7 @@ struct SynthXilinxPass : public ScriptPass
}
if (check_label("coarse")) {
+ run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=" + lut_size_s);
run("alumacc");
run("share");
run("opt");
@@ -523,10 +522,9 @@ struct SynthXilinxPass : public ScriptPass
}
if (check_label("map_ffram")) {
- // Required for dffsr2dff to work.
+ // Required for dff2dffs to work.
run("simplemap t:$dff t:$adff t:$mux");
// Needs to be done before opt -mux_bool happens.
- run("dffsr2dff");
if (help_mode)
run("dff2dffs [-match-init]", "(-match-init for xc6s only)");
else if (family == "xc6s")
diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc
index 13a0b9b83..ac9b57fe1 100644
--- a/techlibs/xilinx/xilinx_dffopt.cc
+++ b/techlibs/xilinx/xilinx_dffopt.cc
@@ -146,12 +146,12 @@ struct XilinxDffOptPass : public Pass {
if (cell->get_bool_attribute(ID::keep))
continue;
if (cell->type == ID(INV)) {
- SigBit sigout = sigmap(cell->getPort(ID(O)));
- SigBit sigin = sigmap(cell->getPort(ID(I)));
+ SigBit sigout = sigmap(cell->getPort(ID::O));
+ SigBit sigin = sigmap(cell->getPort(ID::I));
bit_to_lut[sigout] = make_pair(LutData(Const(1, 2), {sigin}), cell);
} else if (cell->type.in(ID(LUT1), ID(LUT2), ID(LUT3), ID(LUT4), ID(LUT5), ID(LUT6))) {
- SigBit sigout = sigmap(cell->getPort(ID(O)));
- const Const &init = cell->getParam(ID(INIT));
+ SigBit sigout = sigmap(cell->getPort(ID::O));
+ const Const &init = cell->getParam(ID::INIT);
std::vector<SigBit> sigin;
sigin.push_back(sigmap(cell->getPort(ID(I0))));
if (cell->type == ID(LUT1))
@@ -199,7 +199,7 @@ lut_sigin_done:
continue;
// Don't bother if D has more than one use.
- SigBit sig_D = sigmap(cell->getPort(ID(D)));
+ SigBit sig_D = sigmap(cell->getPort(ID::D));
if (bit_uses[sig_D] > 2)
continue;
@@ -223,7 +223,7 @@ lut_sigin_done:
bool worthy_post_r = false;
// First, unmap CE.
- SigBit sig_Q = sigmap(cell->getPort(ID(Q)));
+ SigBit sig_Q = sigmap(cell->getPort(ID::Q));
SigBit sig_CE = sigmap(cell->getPort(ID(CE)));
LutData lut_ce = LutData(Const(2, 2), {sig_CE});
auto it_CE = bit_to_lut.find(sig_CE);
@@ -247,7 +247,7 @@ lut_sigin_done:
// Second, unmap S, if any.
lut_d_post_s = lut_d_post_ce;
if (has_s) {
- SigBit sig_S = sigmap(cell->getPort(ID(S)));
+ SigBit sig_S = sigmap(cell->getPort(ID::S));
LutData lut_s = LutData(Const(2, 2), {sig_S});
bool inv_s = cell->hasParam(ID(IS_S_INVERTED)) && cell->getParam(ID(IS_S_INVERTED)).as_bool();
auto it_S = bit_to_lut.find(sig_S);
@@ -269,7 +269,7 @@ lut_sigin_done:
// Third, unmap R, if any.
lut_d_post_r = lut_d_post_s;
if (has_r) {
- SigBit sig_R = sigmap(cell->getPort(ID(R)));
+ SigBit sig_R = sigmap(cell->getPort(ID::R));
LutData lut_r = LutData(Const(2, 2), {sig_R});
bool inv_r = cell->hasParam(ID(IS_R_INVERTED)) && cell->getParam(ID(IS_R_INVERTED)).as_bool();
auto it_R = bit_to_lut.find(sig_R);
@@ -307,11 +307,11 @@ unmap:
// Okay, we're doing it. Unmap ports.
if (worthy_post_r) {
cell->unsetParam(ID(IS_R_INVERTED));
- cell->setPort(ID(R), Const(0, 1));
+ cell->setPort(ID::R, Const(0, 1));
}
if (has_s && (worthy_post_r || worthy_post_s)) {
cell->unsetParam(ID(IS_S_INVERTED));
- cell->setPort(ID(S), Const(0, 1));
+ cell->setPort(ID::S, Const(0, 1));
}
cell->setPort(ID(CE), Const(1, 1));
cell->unsetParam(ID(IS_D_INVERTED));
@@ -342,9 +342,9 @@ unmap:
}
lut_cell->attributes = cell_d->attributes;
Wire *lut_out = module->addWire(NEW_ID);
- lut_cell->setParam(ID(INIT), final_lut.first);
- cell->setPort(ID(D), lut_out);
- lut_cell->setPort(ID(O), lut_out);
+ lut_cell->setParam(ID::INIT, final_lut.first);
+ cell->setPort(ID::D, lut_out);
+ lut_cell->setPort(ID::O, lut_out);
lut_cell->setPort(ID(I0), final_lut.second[0]);
if (GetSize(final_lut.second) >= 2)
lut_cell->setPort(ID(I1), final_lut.second[1]);
diff --git a/tests/arch/anlogic/fsm.ys b/tests/arch/anlogic/fsm.ys
index 0bcc4e011..eb94177ad 100644
--- a/tests/arch/anlogic/fsm.ys
+++ b/tests/arch/anlogic/fsm.ys
@@ -10,9 +10,6 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd fsm # Constrain all select calls below inside the top module
-select -assert-count 1 t:AL_MAP_LUT2
-select -assert-count 5 t:AL_MAP_LUT5
-select -assert-count 1 t:AL_MAP_LUT6
select -assert-count 6 t:AL_MAP_SEQ
-select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT5 t:AL_MAP_LUT6 t:AL_MAP_SEQ %% t:* %D
+select -assert-none t:AL_MAP_LUT* t:AL_MAP_SEQ %% t:* %D
diff --git a/tests/arch/common/blockram.v b/tests/arch/common/blockram.v
index dbc6ca65c..5ed0736d0 100644
--- a/tests/arch/common/blockram.v
+++ b/tests/arch/common/blockram.v
@@ -5,19 +5,20 @@ module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
input wire [ADDRESS_WIDTH-1:0] address_in,
output wire [DATA_WIDTH-1:0] data_out);
- localparam WORD = (DATA_WIDTH-1);
- localparam DEPTH = (2**ADDRESS_WIDTH-1);
+ localparam WORD = (DATA_WIDTH-1);
+ localparam DEPTH = (2**ADDRESS_WIDTH-1);
- reg [WORD:0] data_out_r;
- reg [WORD:0] memory [0:DEPTH];
+ reg [WORD:0] data_out_r;
+ reg [WORD:0] memory [0:DEPTH];
- always @(posedge clk) begin
- if (write_enable)
- memory[address_in] <= data_in;
- data_out_r <= memory[address_in];
- end
+ always @(posedge clk) begin
+ if (write_enable)
+ memory[address_in] <= data_in;
+ data_out_r <= memory[address_in];
+ end
+
+ assign data_out = data_out_r;
- assign data_out = data_out_r;
endmodule // sync_ram_sp
@@ -28,18 +29,19 @@ module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
input wire [ADDRESS_WIDTH-1:0] address_in_r, address_in_w,
output wire [DATA_WIDTH-1:0] data_out);
- localparam WORD = (DATA_WIDTH-1);
- localparam DEPTH = (2**ADDRESS_WIDTH-1);
+ localparam WORD = (DATA_WIDTH-1);
+ localparam DEPTH = (2**ADDRESS_WIDTH-1);
+
+ reg [WORD:0] data_out_r;
+ reg [WORD:0] memory [0:DEPTH];
- reg [WORD:0] data_out_r;
- reg [WORD:0] memory [0:DEPTH];
+ always @(posedge clk) begin
+ if (write_enable)
+ memory[address_in_w] <= data_in;
+ data_out_r <= memory[address_in_r];
+ end
- always @(posedge clk) begin
- if (write_enable)
- memory[address_in_w] <= data_in;
- data_out_r <= memory[address_in_r];
- end
+ assign data_out = data_out_r;
- assign data_out = data_out_r;
endmodule // sync_ram_sdp
diff --git a/tests/arch/common/blockrom.v b/tests/arch/common/blockrom.v
new file mode 100644
index 000000000..93f5c9ddf
--- /dev/null
+++ b/tests/arch/common/blockrom.v
@@ -0,0 +1,31 @@
+`default_nettype none
+module sync_rom #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
+ (input wire clk,
+ input wire [ADDRESS_WIDTH-1:0] address_in,
+ output wire [DATA_WIDTH-1:0] data_out);
+
+ localparam WORD = (DATA_WIDTH-1);
+ localparam DEPTH = (2**ADDRESS_WIDTH-1);
+
+ reg [WORD:0] data_out_r;
+ reg [WORD:0] memory [0:DEPTH];
+
+ integer i,j = 64'hF4B1CA8127865242;
+ initial
+ for (i = 0; i <= DEPTH; i++) begin
+ // In case this ROM will be implemented in fabric: fill the memory with some data
+ // uncorrelated with the address, or Yosys might see through the ruse and e.g. not
+ // emit any LUTs at all for `memory[i] = i;`, just a latch.
+ memory[i] = j * 64'h2545F4914F6CDD1D;
+ j = j ^ (j >> 12);
+ j = j ^ (j << 25);
+ j = j ^ (j >> 27);
+ end
+
+ always @(posedge clk) begin
+ data_out_r <= memory[address_in];
+ end
+
+ assign data_out = data_out_r;
+
+endmodule // sync_rom
diff --git a/tests/arch/ecp5/memories.ys b/tests/arch/ecp5/memories.ys
new file mode 100644
index 000000000..e1f748e26
--- /dev/null
+++ b/tests/arch/ecp5/memories.ys
@@ -0,0 +1,330 @@
+# ================================ RAM ================================
+# RAM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:PDPW16KD
+
+## With parameters
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:PDPW16KD # too inefficient
+select -assert-count 9 t:TRELLIS_DPR16X4
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:PDPW16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set syn_ramstyle "Block_RAM" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:PDPW16KD # any case works
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set ram_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:PDPW16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set syn_ramstyle "registers" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly
+select -assert-count 180 t:TRELLIS_FF
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set logic_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:PDPW16KD # requested FFRAM explicitly
+select -assert-count 180 t:TRELLIS_FF
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set syn_romstyle "ebr" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BROM but this is a RAM
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set rom_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BROM but this is a RAM
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_ram_sdp
+setattr -set ram_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
+
+# RAM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 9 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 12 -set DATA_WIDTH 4 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 13 -set DATA_WIDTH 2 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD
+
+## With parameters
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:DP16KD # too inefficient
+select -assert-count 5 t:TRELLIS_DPR16X4
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set syn_ramstyle "Block_RAM" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD # any case works
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set ram_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set syn_ramstyle "registers" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:DP16KD # requested FFRAM explicitly
+select -assert-count 90 t:TRELLIS_FF
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set logic_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:DP16KD # requested FFRAM explicitly
+select -assert-count 90 t:TRELLIS_FF
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set syn_romstyle "ebr" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BROM but this is a RAM
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set rom_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BROM but this is a RAM
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_ram_sdp
+setattr -set ram_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp -nobram; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
+
+# RAM bits <= 64; Data width <= 4; Address width <= 4: -> DPR16X4
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:TRELLIS_DPR16X4
+
+## With parameters
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
+setattr -set syn_ramstyle "distributed" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:TRELLIS_DPR16X4
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
+setattr -set syn_ramstyle "registers" m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly
+select -assert-count 68 t:TRELLIS_FF
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
+setattr -set logic_block 1 m:memory
+synth_ecp5 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:TRELLIS_DPR16X4 # requested FFRAM explicitly
+select -assert-count 68 t:TRELLIS_FF
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 4 -set DATA_WIDTH 4 sync_ram_sdp
+setattr -set syn_ramstyle "distributed" m:memory
+synth_ecp5 -top sync_ram_sdp -nolutram; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested LUTRAM but LUTRAM is disabled
+
+# ================================ ROM ================================
+# ROM bits <= 18K; Data width <= 36; Address width <= 9: -> PDPW16KD
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_rom
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:PDPW16KD
+
+## With parameters
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
+write_ilang
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 0 t:PDPW16KD # too inefficient
+select -assert-min 18 t:LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
+setattr -set syn_romstyle "ebr" m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:PDPW16KD
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
+setattr -set rom_block 1 m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:PDPW16KD
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
+setattr -set syn_romstyle "logic" m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly
+select -assert-min 18 t:LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 36 sync_rom
+setattr -set logic_block 1 m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 0 t:PDPW16KD # requested LUTROM explicitly
+select -assert-min 18 t:LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:$mem # requested BRAM but this is a ROM
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
+setattr -set ram_block 1 m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:$mem # requested BRAM but this is a ROM
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
+setattr -set syn_ramstyle "block_rom" m:memory
+synth_ecp5 -top sync_rom -nobram; cd sync_rom
+select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 36 sync_rom
+setattr -set rom_block 1 m:memory
+synth_ecp5 -top sync_rom -nobram; cd sync_rom
+select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
+
+# ROM bits <= 18K; Data width <= 18; Address width <= 10: -> DP16KD
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 18 sync_rom
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:DP16KD
+
+## With parameters
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom
+write_ilang
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 0 t:DP16KD # too inefficient
+select -assert-min 9 t:LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
+setattr -set syn_romstyle "ebr" m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
+setattr -set rom_block 1 m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:DP16KD
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom
+setattr -set syn_romstyle "logic" m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 0 t:DP16KD # requested LUTROM explicitly
+select -assert-min 9 t:LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 3 -set DATA_WIDTH 18 sync_rom
+setattr -set logic_block 1 m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 0 t:DP16KD # requested LUTROM explicitly
+select -assert-min 9 t:LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:$mem # requested BRAM but this is a ROM
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
+setattr -set ram_block 1 m:memory
+synth_ecp5 -top sync_rom; cd sync_rom
+select -assert-count 1 t:$mem # requested BRAM but this is a ROM
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
+setattr -set syn_ramstyle "block_rom" m:memory
+synth_ecp5 -top sync_rom -nobram; cd sync_rom
+select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 18 sync_rom
+setattr -set rom_block 1 m:memory
+synth_ecp5 -top sync_rom -nobram; cd sync_rom
+select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
diff --git a/tests/arch/efinix/fsm.ys b/tests/arch/efinix/fsm.ys
index a2db2ad98..aef720d46 100644
--- a/tests/arch/efinix/fsm.ys
+++ b/tests/arch/efinix/fsm.ys
@@ -10,7 +10,6 @@ sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd fsm # Constrain all select calls below inside the top module
-select -assert-count 1 t:EFX_GBUFCE
-select -assert-count 6 t:EFX_FF
-select -assert-count 15 t:EFX_LUT4
+select -assert-count 1 t:EFX_GBUFCE
+select -assert-count 6 t:EFX_FF
select -assert-none t:EFX_GBUFCE t:EFX_FF t:EFX_LUT4 %% t:* %D
diff --git a/tests/arch/ice40/lutram.ys b/tests/arch/ice40/lutram.ys
deleted file mode 100644
index 1ba40f8ec..000000000
--- a/tests/arch/ice40/lutram.ys
+++ /dev/null
@@ -1,15 +0,0 @@
-read_verilog ../common/lutram.v
-hierarchy -top lutram_1w1r
-proc
-memory -nomap
-equiv_opt -run :prove -map +/ice40/cells_sim.v synth_ice40
-memory
-opt -full
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
-
-design -load postopt
-cd lutram_1w1r
-select -assert-count 1 t:SB_RAM40_4K
-select -assert-none t:SB_RAM40_4K %% t:* %D
diff --git a/tests/arch/ice40/memories.ys b/tests/arch/ice40/memories.ys
new file mode 100644
index 000000000..571edec1d
--- /dev/null
+++ b/tests/arch/ice40/memories.ys
@@ -0,0 +1,168 @@
+# ================================ RAM ================================
+# RAM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 2 sync_ram_sdp
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 4 sync_ram_sdp
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 8 sync_ram_sdp
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 16 sync_ram_sdp
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:SB_RAM40_4K
+
+## With parameters
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:SB_RAM40_4K # too inefficient
+select -assert-min 1 t:SB_DFFE
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set syn_ramstyle "Block_RAM" m:memory
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:SB_RAM40_4K # any case works
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set ram_block 1 m:memory
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set syn_ramstyle "registers" m:memory
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly
+select -assert-min 1 t:SB_DFFE
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set logic_block 1 m:memory
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly
+select -assert-min 1 t:SB_DFFE
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set syn_romstyle "ebr" m:memory
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BROM but this is a RAM
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set rom_block 1 m:memory
+synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BROM but this is a RAM
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
+
+design -reset; read_verilog ../common/blockram.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
+setattr -set ram_block 1 m:memory
+synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
+select -assert-count 1 t:$mem # requested BRAM but BRAM is disabled
+
+# ================================ ROM ================================
+# ROM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 11 -set DATA_WIDTH 2 sync_rom
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 4 sync_rom
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 8 sync_rom
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 16 sync_rom
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:SB_RAM40_4K
+
+## With parameters
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+write_ilang
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 0 t:SB_RAM40_4K # too inefficient
+select -assert-min 1 t:SB_LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set syn_romstyle "ebr" m:memory
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set rom_block 1 m:memory
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:SB_RAM40_4K
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set syn_romstyle "logic" m:memory
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly
+select -assert-min 1 t:SB_LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set logic_block 1 m:memory
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly
+select -assert-min 1 t:SB_LUT4
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set syn_ramstyle "block_ram" m:memory
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:$mem # requested BRAM but this is a ROM
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set ram_block 1 m:memory
+synth_ice40 -top sync_rom; cd sync_rom
+select -assert-count 1 t:$mem # requested BRAM but this is a ROM
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set syn_romstyle "ebr" m:memory
+synth_ice40 -top sync_rom -nobram; cd sync_rom
+select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
+
+design -reset; read_verilog ../common/blockrom.v
+chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
+setattr -set rom_block 1 m:memory
+synth_ice40 -top sync_rom -nobram; cd sync_rom
+select -assert-count 1 t:$mem # requested BROM but BRAM is disabled
diff --git a/tests/arch/intel_alm/add_sub.ys b/tests/arch/intel_alm/add_sub.ys
new file mode 100644
index 000000000..4cb2c2e0d
--- /dev/null
+++ b/tests/arch/intel_alm/add_sub.ys
@@ -0,0 +1,8 @@
+read_verilog ../common/add_sub.v
+hierarchy -top top
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+stat
+select -assert-count 8 t:MISTRAL_ALUT_ARITH
+select -assert-none t:MISTRAL_ALUT_ARITH %% t:* %D
diff --git a/tests/arch/intel_alm/adffs.ys b/tests/arch/intel_alm/adffs.ys
new file mode 100644
index 000000000..5d8d3a220
--- /dev/null
+++ b/tests/arch/intel_alm/adffs.ys
@@ -0,0 +1,48 @@
+read_verilog ../common/adffs.v
+design -save read
+
+hierarchy -top adff
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd adff # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+select -assert-count 1 t:MISTRAL_NOT
+
+select -assert-none t:MISTRAL_FF t:MISTRAL_NOT %% t:* %D
+
+
+design -load read
+hierarchy -top adffn
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd adffn # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+
+select -assert-none t:MISTRAL_FF %% t:* %D
+
+
+design -load read
+hierarchy -top dffs
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd dffs # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+select -assert-count 1 t:MISTRAL_ALUT2
+
+select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 %% t:* %D
+
+
+design -load read
+hierarchy -top ndffnr
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd ndffnr # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+select -assert-count 1 t:MISTRAL_NOT
+select -assert-count 1 t:MISTRAL_ALUT2
+
+select -assert-none t:MISTRAL_FF t:MISTRAL_NOT t:MISTRAL_ALUT2 %% t:* %D
diff --git a/tests/arch/intel_alm/counter.ys b/tests/arch/intel_alm/counter.ys
new file mode 100644
index 000000000..945c318d8
--- /dev/null
+++ b/tests/arch/intel_alm/counter.ys
@@ -0,0 +1,13 @@
+read_verilog ../common/counter.v
+hierarchy -top top
+proc
+flatten
+equiv_opt -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+
+select -assert-count 2 t:MISTRAL_NOT
+select -assert-count 8 t:MISTRAL_ALUT_ARITH
+select -assert-count 8 t:MISTRAL_FF
+
+select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D
diff --git a/tests/arch/intel_alm/dffs.ys b/tests/arch/intel_alm/dffs.ys
new file mode 100644
index 000000000..cf29ad8e0
--- /dev/null
+++ b/tests/arch/intel_alm/dffs.ys
@@ -0,0 +1,22 @@
+read_verilog ../common/dffs.v
+design -save read
+
+hierarchy -top dff
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd dff # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+
+select -assert-none t:MISTRAL_FF %% t:* %D
+
+design -load read
+hierarchy -top dffe
+proc
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd dffe # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_FF
+select -assert-count 1 t:MISTRAL_ALUT3
+
+select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT3 %% t:* %D
diff --git a/tests/arch/intel_alm/fsm.ys b/tests/arch/intel_alm/fsm.ys
new file mode 100644
index 000000000..8bb0ebab2
--- /dev/null
+++ b/tests/arch/intel_alm/fsm.ys
@@ -0,0 +1,18 @@
+read_verilog ../common/fsm.v
+hierarchy -top fsm
+proc
+flatten
+
+equiv_opt -run :prove -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev
+async2sync
+miter -equiv -make_assert -flatten gold gate miter
+sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
+
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd fsm # Constrain all select calls below inside the top module
+
+select -assert-count 6 t:MISTRAL_FF
+select -assert-max 2 t:MISTRAL_ALUT2 # Clang returns 2, GCC returns 1
+select -assert-count 5 t:MISTRAL_ALUT5
+select -assert-count 1 t:MISTRAL_ALUT6
+select -assert-none t:MISTRAL_FF t:MISTRAL_ALUT2 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
diff --git a/tests/arch/intel_alm/logic.ys b/tests/arch/intel_alm/logic.ys
new file mode 100644
index 000000000..fad45db74
--- /dev/null
+++ b/tests/arch/intel_alm/logic.ys
@@ -0,0 +1,11 @@
+read_verilog ../common/logic.v
+hierarchy -top top
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+
+select -assert-count 1 t:MISTRAL_NOT
+select -assert-count 6 t:MISTRAL_ALUT2
+select -assert-count 2 t:MISTRAL_ALUT4
+select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT2 t:MISTRAL_ALUT4 %% t:* %D
diff --git a/tests/arch/intel_alm/mux.ys b/tests/arch/intel_alm/mux.ys
new file mode 100644
index 000000000..308e45268
--- /dev/null
+++ b/tests/arch/intel_alm/mux.ys
@@ -0,0 +1,45 @@
+read_verilog ../common/mux.v
+design -save read
+
+hierarchy -top mux2
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux2 # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_ALUT3
+
+select -assert-none t:MISTRAL_ALUT3 %% t:* %D
+
+design -load read
+hierarchy -top mux4
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux4 # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_ALUT6
+
+select -assert-none t:MISTRAL_ALUT6 %% t:* %D
+
+design -load read
+hierarchy -top mux8
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux8 # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_ALUT3
+select -assert-count 1 t:MISTRAL_ALUT5
+select -assert-count 2 t:MISTRAL_ALUT6
+
+select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
+
+design -load read
+hierarchy -top mux16
+proc
+equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd mux16 # Constrain all select calls below inside the top module
+select -assert-count 1 t:MISTRAL_ALUT3
+select -assert-count 2 t:MISTRAL_ALUT5
+select -assert-count 4 t:MISTRAL_ALUT6
+
+select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D
diff --git a/tests/arch/intel_alm/run-test.sh b/tests/arch/intel_alm/run-test.sh
new file mode 100755
index 000000000..bf19b887d
--- /dev/null
+++ b/tests/arch/intel_alm/run-test.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+set -e
+{
+echo "all::"
+for x in *.ys; do
+ echo "all:: run-$x"
+ echo "run-$x:"
+ echo " @echo 'Running $x..'"
+ echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x"
+done
+for s in *.sh; do
+ if [ "$s" != "run-test.sh" ]; then
+ echo "all:: run-$s"
+ echo "run-$s:"
+ echo " @echo 'Running $s..'"
+ echo " @bash $s"
+ fi
+done
+} > run-test.mk
+exec ${MAKE:-make} -f run-test.mk
diff --git a/tests/arch/intel_alm/shifter.ys b/tests/arch/intel_alm/shifter.ys
new file mode 100644
index 000000000..014dbd1a8
--- /dev/null
+++ b/tests/arch/intel_alm/shifter.ys
@@ -0,0 +1,10 @@
+read_verilog ../common/shifter.v
+hierarchy -top top
+proc
+flatten
+equiv_opt -async2sync -assert -map +/intel_alm/common/alm_sim.v -map +/intel_alm/common/dff_sim.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd top # Constrain all select calls below inside the top module
+select -assert-count 8 t:MISTRAL_FF
+
+select -assert-none t:MISTRAL_FF %% t:* %D
diff --git a/tests/arch/intel_alm/tribuf.ys b/tests/arch/intel_alm/tribuf.ys
new file mode 100644
index 000000000..71b05a747
--- /dev/null
+++ b/tests/arch/intel_alm/tribuf.ys
@@ -0,0 +1,13 @@
+read_verilog ../common/tribuf.v
+hierarchy -top tristate
+proc
+tribuf
+flatten
+synth
+equiv_opt -assert -map +/simcells.v synth_intel_alm -family cyclonev # equivalency check
+design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
+cd tristate # Constrain all select calls below inside the top module
+#Internal cell type used. Need support it.
+select -assert-count 1 t:$_TBUF_
+
+select -assert-none t:$_TBUF_ %% t:* %D
diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys
index e0acead82..7c446afd1 100644
--- a/tests/opt/opt_expr.ys
+++ b/tests/opt/opt_expr.ys
@@ -291,3 +291,31 @@ check
equiv_opt -assert opt_expr -keepdc
design -load postopt
select -assert-count 1 t:$shift r:A_WIDTH=13 %i
+
+###########
+
+design -reset
+read_verilog -icells <<EOT
+module opt_expr_mul_low_bits(input [2:0] a, input [2:0] b, output [7:0] y);
+ \$mul #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(4), .Y_WIDTH(8)) mul (.A({a, 1'b0}), .B({b, 1'b0}), .Y(y));
+endmodule
+EOT
+check
+
+equiv_opt -assert opt_expr
+design -load postopt
+select -assert-count 1 t:$mul r:A_WIDTH=3 %i r:B_WIDTH=3 %i r:Y_WIDTH=6 %i
+
+###########
+
+design -reset
+read_verilog -icells <<EOT
+module opt_expr_mul_low_bits(input [2:0] a, input [2:0] b, output [7:0] y);
+ \$mul #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(4), .Y_WIDTH(8)) mul (.A({a, 1'b0}), .B({b, 1'b0}), .Y(y));
+endmodule
+EOT
+check
+
+equiv_opt -assert opt_expr -keepdc
+design -load postopt
+select -assert-count 1 t:$mul r:A_WIDTH=4 %i r:B_WIDTH=4 %i r:Y_WIDTH=8 %i
diff --git a/tests/opt/opt_expr_alu.ys b/tests/opt/opt_expr_alu.ys
new file mode 100644
index 000000000..e288bcea6
--- /dev/null
+++ b/tests/opt/opt_expr_alu.ys
@@ -0,0 +1,111 @@
+read_verilog <<EOT
+module test(input a, output [1:0] y);
+assign y = {a,1'b0} + 1'b1;
+endmodule
+EOT
+
+alumacc
+equiv_opt -assert opt_expr -fine
+design -load postopt
+select -assert-count 1 t:$pos
+select -assert-count none t:$pos t:* %D
+
+
+design -reset
+read_verilog <<EOT
+module test(input a, output [1:0] y);
+assign y = {a,1'b1} + 1'b1;
+endmodule
+EOT
+
+alumacc
+select -assert-count 1 t:$alu
+select -assert-count none t:$alu t:* %D
+
+
+design -reset
+read_verilog <<EOT
+module test(input a, output [1:0] y);
+assign y = {a,1'b1} - 1'b1;
+endmodule
+EOT
+
+equiv_opt -assert opt_expr -fine
+design -load postopt
+select -assert-count 1 t:$pos
+select -assert-count none t:$pos t:* %D
+
+
+design -reset
+read_verilog <<EOT
+module test(input a, output [3:0] y);
+assign y = {a,3'b101} - 1'b1;
+endmodule
+EOT
+
+equiv_opt -assert opt_expr -fine
+design -load postopt
+select -assert-count 1 t:$pos
+select -assert-count none t:$pos t:* %D
+
+
+design -reset
+read_verilog <<EOT
+module test(input a, output [3:0] y);
+assign y = {a,3'b101} - 1'b1;
+endmodule
+EOT
+
+alumacc
+equiv_opt -assert opt_expr -fine
+design -load postopt
+select -assert-count 1 t:$pos
+select -assert-count none t:$pos t:* %D
+
+
+design -reset
+read_verilog <<EOT
+module test(input [1:0] a, output [3:0] y);
+assign y = -{a[1], 2'b10, a[0]};
+endmodule
+EOT
+
+alumacc
+equiv_opt -assert opt -fine
+design -load postopt
+select -assert-count 1 t:$alu
+select -assert-count 1 t:$alu r:Y_WIDTH=3 %i
+select -assert-count 1 t:$not
+select -assert-count none t:$alu t:$not t:* %D %D
+
+
+design -reset
+read_verilog <<EOT
+module test(input [3:0] a, input [2:0] b, output [5:0] y);
+assign y = {a[3:2], 1'b1, a[1:0]} + {b[2], 2'b11, b[1:0]};
+endmodule
+EOT
+
+alumacc
+equiv_opt -assert opt -fine
+design -load postopt
+dump
+select -assert-count 2 t:$alu
+select -assert-count 1 t:$alu r:Y_WIDTH=2 %i
+select -assert-count 1 t:$alu r:Y_WIDTH=3 %i
+select -assert-count none t:$alu t:* %D
+
+
+design -reset
+read_verilog <<EOT
+module test(input [3:0] a, input [3:0] b, output [5:0] y);
+assign y = {a[3:2], 1'b0, a[1:0]} + {b[3:2], 1'b0, b[1:0]};
+endmodule
+EOT
+
+alumacc
+equiv_opt -assert opt -fine
+design -load postopt
+select -assert-count 2 t:$alu
+select -assert-count 2 t:$alu r:Y_WIDTH=3 %i
+select -assert-count none t:$alu t:* %D
diff --git a/tests/opt/opt_expr_xor.ys b/tests/opt/opt_expr_xor.ys
new file mode 100644
index 000000000..21439fd53
--- /dev/null
+++ b/tests/opt/opt_expr_xor.ys
@@ -0,0 +1,52 @@
+read_verilog <<EOT
+module top(input a, output [3:0] y);
+assign y[0] = a^1'b0;
+assign y[1] = 1'b1^a;
+assign y[2] = a~^1'b0;
+assign y[3] = 1'b1^~a;
+endmodule
+EOT
+design -save read
+select -assert-count 2 t:$xor
+select -assert-count 2 t:$xnor
+
+equiv_opt opt_expr
+design -load postopt
+select -assert-none t:$xor
+select -assert-none t:$xnor
+select -assert-count 2 t:$not
+
+
+design -load read
+simplemap
+equiv_opt opt_expr
+design -load postopt
+select -assert-none t:$_XOR_
+select -assert-none t:$_XNOR_ # NB: simplemap does $xnor -> $_XOR_+$_NOT_
+select -assert-count 3 t:$_NOT_
+
+
+design -reset
+read_verilog -icells <<EOT
+module top(input a, output [1:0] y);
+$_XNOR_ u0(.A(a), .B(1'b0), .Y(y[0]));
+$_XNOR_ u1(.A(1'b1), .B(a), .Y(y[1]));
+endmodule
+EOT
+select -assert-count 2 t:$_XNOR_
+equiv_opt opt_expr
+design -load postopt
+select -assert-none t:$_XNOR_ # NB: simplemap does $xnor -> $_XOR_+$_NOT_
+select -assert-count 1 t:$_NOT_
+
+
+design -reset
+read_verilog <<EOT
+module top(input a, output [1:0] w, x, y, z);
+assign w = a^1'b0;
+assign x = a^1'b1;
+assign y = a~^1'b0;
+assign z = a~^1'b1;
+endmodule
+EOT
+equiv_opt opt_expr
diff --git a/tests/opt/opt_merge_init.ys b/tests/opt/opt_merge_init.ys
index a29c29df6..0176f09c7 100644
--- a/tests/opt/opt_merge_init.ys
+++ b/tests/opt/opt_merge_init.ys
@@ -20,6 +20,7 @@ endmodule
EOT
opt_merge
+select -assert-count 1 t:$dff
select -assert-count 1 a:init=1'0
@@ -46,4 +47,31 @@ endmodule
EOT
opt_merge
+select -assert-count 1 t:$dff
select -assert-count 1 a:init=2'bx1
+
+
+design -reset
+read_verilog -icells <<EOT
+module top(input clk, i, (* init = 1'b0 *) output o, /* NB: no init here! */ output p);
+ \$dff #(
+ .CLK_POLARITY(1'h1),
+ .WIDTH(32'd1)
+ ) ffo (
+ .CLK(clk),
+ .D(i),
+ .Q(o)
+ );
+ \$dff #(
+ .CLK_POLARITY(1'h1),
+ .WIDTH(32'd1)
+ ) ffp (
+ .CLK(clk),
+ .D(i),
+ .Q(p)
+ );
+endmodule
+EOT
+
+opt_merge
+select -assert-count 2 t:$dff
diff --git a/tests/opt/opt_merge_keep.ys b/tests/opt/opt_merge_keep.ys
new file mode 100644
index 000000000..2a9202901
--- /dev/null
+++ b/tests/opt/opt_merge_keep.ys
@@ -0,0 +1,64 @@
+read_verilog -icells <<EOT
+module top(input clk, i, output o, p);
+ (* keep *)
+ \$_DFF_P_ ffo (
+ .C(clk),
+ .D(i),
+ .Q(o)
+ );
+ \$_DFF_P_ ffp (
+ .C(clk),
+ .D(i),
+ .Q(p)
+ );
+endmodule
+EOT
+
+opt_merge
+select -assert-count 1 t:$_DFF_P_
+select -assert-count 1 a:keep
+
+
+design -reset
+read_verilog -icells <<EOT
+module top(input clk, i, output o, p);
+ \$_DFF_P_ ffo (
+ .C(clk),
+ .D(i),
+ .Q(o)
+ );
+ (* keep *)
+ \$_DFF_P_ ffp (
+ .C(clk),
+ .D(i),
+ .Q(p)
+ );
+endmodule
+EOT
+
+opt_merge
+select -assert-count 1 t:$_DFF_P_
+select -assert-count 1 a:keep
+
+
+design -reset
+read_verilog -icells <<EOT
+module top(input clk, i, output o, p);
+ (* keep *)
+ \$_DFF_P_ ffo (
+ .C(clk),
+ .D(i),
+ .Q(o)
+ );
+ (* keep *)
+ \$_DFF_P_ ffp (
+ .C(clk),
+ .D(i),
+ .Q(p)
+ );
+endmodule
+EOT
+
+opt_merge
+select -assert-count 2 t:$_DFF_P_
+select -assert-count 2 a:keep
diff --git a/tests/select/.gitignore b/tests/select/.gitignore
new file mode 100644
index 000000000..50e13221d
--- /dev/null
+++ b/tests/select/.gitignore
@@ -0,0 +1 @@
+/*.log
diff --git a/tests/simple/dynslice.v b/tests/simple/dynslice.v
new file mode 100644
index 000000000..7236ac3a5
--- /dev/null
+++ b/tests/simple/dynslice.v
@@ -0,0 +1,12 @@
+module dynslice (
+ input clk ,
+ input [9:0] ctrl ,
+ input [15:0] din ,
+ input [3:0] sel ,
+ output reg [127:0] dout
+);
+always @(posedge clk)
+begin
+ dout[ctrl*sel+:16] <= din ;
+end
+endmodule
diff --git a/tests/svtypes/typedef_package.sv b/tests/svtypes/typedef_package.sv
index 57a78c53a..2d83742c5 100644
--- a/tests/svtypes/typedef_package.sv
+++ b/tests/svtypes/typedef_package.sv
@@ -1,6 +1,9 @@
package pkg;
typedef logic [7:0] uint8_t;
- typedef enum logic [7:0] {bb=8'hBB} enum8_t;
+ typedef enum logic [7:0] {bb=8'hBB, cc=8'hCC} enum8_t;
+
+ localparam uint8_t PCONST = cc;
+ parameter uint8_t PCONST_COPY = PCONST;
endpackage
module top;
@@ -8,7 +11,9 @@ module top;
(* keep *) pkg::uint8_t a = 8'hAA;
(* keep *) pkg::enum8_t b_enum = pkg::bb;
- always @* assert(a == 8'hAA);
- always @* assert(b_enum == 8'hBB);
+ always_comb assert(a == 8'hAA);
+ always_comb assert(b_enum == 8'hBB);
+ always_comb assert(pkg::PCONST == pkg::cc);
+ always_comb assert(pkg::PCONST_COPY == pkg::cc);
endmodule
diff --git a/tests/techmap/cmp2lcu.ys b/tests/techmap/cmp2lcu.ys
new file mode 100644
index 000000000..7c8a63692
--- /dev/null
+++ b/tests/techmap/cmp2lcu.ys
@@ -0,0 +1,52 @@
+read_verilog <<EOT
+module top(input [12:0] a, b, output gtu, gts, ltu, lts, geu, ges, leu, les);
+assign gtu = a > b;
+assign gts = $signed(a) > $signed(b);
+assign ltu = a < b;
+assign lts = $signed(a) < $signed(b);
+assign geu = a >= b;
+assign ges = $signed(a) >= $signed(b);
+assign leu = a <= b;
+assign les = $signed(a) <= $signed(b);
+endmodule
+EOT
+
+equiv_opt -assert techmap -map +/cmp2lcu.v -D LUT_WIDTH=6
+design -load postopt
+select -assert-count 8 t:$lcu r:WIDTH=5 %i
+select -assert-none t:$gt t:$ge t:$lt t:$le
+
+design -load preopt
+equiv_opt -assert techmap -map +/cmp2lcu.v -D LUT_WIDTH=4
+design -load postopt
+select -assert-count 8 t:$lcu r:WIDTH=7 %i
+select -assert-none t:$gt t:$ge t:$lt t:$le
+
+
+design -reset
+read_verilog <<EOT
+module top(input [8:0] a, b, output gtu, gts, ltu, lts, geu, ges, leu, les);
+wire [13:0] c = {a[8:6], 3'b101, a[5:4], 2'b11, a[3:0]};
+wire [13:0] d = {b[8], 3'b101, b[7:4], 2'b01, b[3:0]};
+assign gtu = c > d;
+assign gts = $signed(c) > $signed(d);
+assign ltu = c < d;
+assign lts = $signed(c) < $signed(d);
+assign geu = c >= d;
+assign ges = $signed(c) >= $signed(d);
+assign leu = c <= d;
+assign les = $signed(c) <= $signed(d);
+endmodule
+EOT
+design -save gold
+
+equiv_opt -assert techmap -map +/cmp2lcu.v -D LUT_WIDTH=5
+design -load postopt
+select -assert-count 8 t:$lcu r:WIDTH=2 %i
+select -assert-none t:$gt t:$ge t:$lt t:$le
+
+design -load preopt
+equiv_opt -assert techmap -map +/cmp2lcu.v -D LUT_WIDTH=3
+design -load postopt
+select -assert-count 8 t:$lcu r:WIDTH=4 %i
+select -assert-none t:$gt t:$ge t:$lt t:$le
diff --git a/tests/techmap/dffinit.ys b/tests/techmap/dffinit.ys
new file mode 100644
index 000000000..218d411f8
--- /dev/null
+++ b/tests/techmap/dffinit.ys
@@ -0,0 +1,25 @@
+read_verilog <<EOT
+
+module ff(...);
+input d;
+output q;
+
+endmodule
+
+module top(...);
+input d;
+output q1;
+(* init = 1'b1 *)
+output q2;
+
+ff my_ff1(.d(d), .q(q1));
+ff my_ff2(.d(d), .q(q2));
+
+endmodule
+
+EOT
+
+dffinit -ff ff q init
+select -assert-count 2 t:ff
+select -assert-count 1 t:ff r:init %i
+select -assert-count 1 t:ff r:init=1'b1 %i
diff --git a/tests/techmap/iopadmap.ys b/tests/techmap/iopadmap.ys
index 25ea94dfc..df029b3a0 100644
--- a/tests/techmap/iopadmap.ys
+++ b/tests/techmap/iopadmap.ys
@@ -55,13 +55,19 @@ obuf b (.i(i), .o(tmp));
assign o = tmp;
endmodule
+module k(inout o, o2);
+assign o = 1'bz;
+endmodule
+
EOT
opt_clean
tribuf
simplemap
-iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j
+iopadmap -bits -inpad ibuf o:i -outpad obuf i:o -toutpad obuft oe:i:o -tinoutpad iobuf oe:o:i:io a b c d e f g h i j k
opt_clean
+hierarchy -check
+check
select -assert-count 1 a/t:ibuf
select -assert-count 1 a/t:obuf
@@ -140,6 +146,8 @@ select -assert-count 0 i/t:obuf
select -assert-count 1 j/t:ibuf
select -assert-count 1 j/t:obuf
+select -assert-count 2 k/t:iobuf
+
# Check that \init attributes get moved from output buffer
# to buffer input
diff --git a/tests/techmap/zinit.ys b/tests/techmap/zinit.ys
new file mode 100644
index 000000000..18b17621f
--- /dev/null
+++ b/tests/techmap/zinit.ys
@@ -0,0 +1,57 @@
+read_verilog -icells <<EOT
+module top(input C, R, input [1:0] D, (* init = {2'b10, 2'b01, 1'b1, {8{1'b1}}} *) output [12:0] Q);
+
+(* init = 1'b1 *)
+wire unused;
+
+$_DFF_NN0_ dff0 (.C(C), .D(D[0]), .R(R), .Q(Q[0]));
+$_DFF_NN1_ dff1 (.C(C), .D(D[0]), .R(R), .Q(Q[1]));
+$_DFF_NP0_ dff2 (.C(C), .D(D[0]), .R(R), .Q(Q[2]));
+$_DFF_NP1_ dff3 (.C(C), .D(D[0]), .R(R), .Q(Q[3]));
+$_DFF_PN0_ dff4 (.C(C), .D(D[0]), .R(R), .Q(Q[4]));
+$_DFF_PN1_ dff5 (.C(C), .D(D[0]), .R(R), .Q(Q[5]));
+$_DFF_PP0_ dff6 (.C(C), .D(D[0]), .R(R), .Q(Q[6]));
+$_DFF_PP1_ dff7 (.C(C), .D(D[0]), .R(R), .Q(Q[7]));
+
+$adff #(.WIDTH(2), .CLK_POLARITY(1), .ARST_POLARITY(1'b0), .ARST_VALUE(2'b10)) dff8 (.CLK(C), .ARST(R), .D(D), .Q(Q[10:9]));
+$adff #(.WIDTH(2), .CLK_POLARITY(0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'b01)) dff9 (.CLK(C), .ARST(R), .D(D), .Q(Q[12:11]));
+endmodule
+EOT
+equiv_opt -assert -map +/simcells.v -multiclock zinit
+design -load postopt
+
+select -assert-count 20 t:$_NOT_
+select -assert-count 1 w:unused a:init %i
+select -assert-count 1 w:Q a:init=13'bxxxx1xxxxxxxx %i
+select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFF_??1_ %i
+select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFF_??0_ %i
+
+
+design -reset
+read_verilog -icells <<EOT
+module top(input C, R, input [1:0] D, (* init = {2'bx0, 2'b0x, 1'b1, {8{1'b0}}} *) output [12:0] Q);
+
+(* init = 1'b1 *)
+wire unused;
+
+$_DFF_NN0_ dff0 (.C(C), .D(D[0]), .R(R), .Q(Q[0]));
+$_DFF_NN1_ dff1 (.C(C), .D(D[0]), .R(R), .Q(Q[1]));
+$_DFF_NP0_ dff2 (.C(C), .D(D[0]), .R(R), .Q(Q[2]));
+$_DFF_NP1_ dff3 (.C(C), .D(D[0]), .R(R), .Q(Q[3]));
+$_DFF_PN0_ dff4 (.C(C), .D(D[0]), .R(R), .Q(Q[4]));
+$_DFF_PN1_ dff5 (.C(C), .D(D[0]), .R(R), .Q(Q[5]));
+$_DFF_PP0_ dff6 (.C(C), .D(D[0]), .R(R), .Q(Q[6]));
+$_DFF_PP1_ dff7 (.C(C), .D(D[0]), .R(R), .Q(Q[7]));
+
+$adff #(.WIDTH(2), .CLK_POLARITY(1), .ARST_POLARITY(1'b0), .ARST_VALUE(2'b10)) dff8 (.CLK(C), .ARST(R), .D(D), .Q(Q[10:9]));
+$adff #(.WIDTH(2), .CLK_POLARITY(0), .ARST_POLARITY(1'b1), .ARST_VALUE(2'b01)) dff9 (.CLK(C), .ARST(R), .D(D), .Q(Q[12:11]));
+endmodule
+EOT
+equiv_opt -assert -map +/simcells.v -multiclock zinit
+design -load postopt
+
+select -assert-count 0 t:$_NOT_
+select -assert-count 1 w:unused a:init %i
+select -assert-count 1 w:Q a:init=13'bxxxx1xxxxxxxx %i
+select -assert-count 4 c:dff0 c:dff2 c:dff4 c:dff6 %% t:$_DFF_??0_ %i
+select -assert-count 4 c:dff1 c:dff3 c:dff5 c:dff7 %% t:$_DFF_??1_ %i
diff --git a/tests/various/.gitignore b/tests/various/.gitignore
index 4b286fd61..12d4e5048 100644
--- a/tests/various/.gitignore
+++ b/tests/various/.gitignore
@@ -3,3 +3,4 @@
/write_gzip.v
/write_gzip.v.gz
/run-test.mk
+/plugin.so
diff --git a/tests/various/bug1876.ys b/tests/various/bug1876.ys
new file mode 100644
index 000000000..7995eedcf
--- /dev/null
+++ b/tests/various/bug1876.ys
@@ -0,0 +1,60 @@
+read_verilog <<EOT
+module expression_00032(b5, y15);
+ input signed [5:0] b5;
+ output [3:0] y15;
+ assign y15 = (0 ? b5 : b5) > 0;
+endmodule
+EOT
+
+
+design -reset
+read_verilog <<EOT
+module expression_00057(a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5, y8);
+ input [3:0] a0;
+ input [4:0] a1;
+ input [5:0] a2;
+ input signed [3:0] a3;
+ input signed [4:0] a4;
+ input signed [5:0] a5;
+
+ input [3:0] b0;
+ input [4:0] b1;
+ input [5:0] b2;
+ input signed [3:0] b3;
+ input signed [4:0] b4;
+ input signed [5:0] b5;
+
+ output [5:0] y8;
+
+ localparam signed [4:0] p4 = ((2'd3)||(-4'sd1));
+ localparam signed [3:0] p9 = {3{(((2'sd0)^~(5'd20))>((-3'sd0)>>(4'sd2)))}};
+
+ assign y8 = (-(!($signed({3{p9}})<(p4?b4:b5))));
+endmodule
+EOT
+
+
+design -reset
+read_verilog <<EOT
+module expression_00354(a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5, y4);
+ input [3:0] a0;
+ input [4:0] a1;
+ input [5:0] a2;
+ input signed [3:0] a3;
+ input signed [4:0] a4;
+ input signed [5:0] a5;
+
+ input [3:0] b0;
+ input [4:0] b1;
+ input [5:0] b2;
+ input signed [3:0] b3;
+ input signed [4:0] b4;
+ input signed [5:0] b5;
+
+ output wire signed [4:0] y4;
+
+ localparam signed [4:0] p10 = ((3'd0)?(2'd1):(-2'sd1));
+
+ assign y4 = ((p10?a4:b4)&$signed(b3));
+endmodule
+EOT
diff --git a/tests/various/plugin.cc b/tests/various/plugin.cc
new file mode 100644
index 000000000..be305fbda
--- /dev/null
+++ b/tests/various/plugin.cc
@@ -0,0 +1,15 @@
+#include "kernel/rtlil.h"
+
+YOSYS_NAMESPACE_BEGIN
+
+struct TestPass : public Pass {
+ TestPass() : Pass("test", "test") { }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ size_t argidx = 1;
+ extra_args(args, argidx, design);
+ log("Plugin test passed!\n");
+ }
+} TestPass;
+
+YOSYS_NAMESPACE_END
diff --git a/tests/various/plugin.sh b/tests/various/plugin.sh
new file mode 100644
index 000000000..d6d4aee59
--- /dev/null
+++ b/tests/various/plugin.sh
@@ -0,0 +1,6 @@
+set -e
+rm -f plugin.so
+CXXFLAGS=$(../../yosys-config --cxxflags)
+CXXFLAGS=${CXXFLAGS// -I\/usr\/local\/share\/yosys\/include/ -I..\/..\/share\/include}
+../../yosys-config --exec --cxx ${CXXFLAGS} --ldflags -shared -o plugin.so plugin.cc
+../../yosys -m ./plugin.so -p "test" | grep -q "Plugin test passed!"