diff options
-rw-r--r-- | Makefile | 75 | ||||
-rw-r--r-- | backends/smt2/Makefile.inc | 14 | ||||
-rw-r--r-- | backends/smt2/smtbmc.py | 3 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 1 | ||||
-rw-r--r-- | kernel/yosys.cc | 11 | ||||
-rw-r--r-- | kernel/yosys.h | 1 | ||||
-rw-r--r-- | misc/yosys-config.in | 8 | ||||
-rw-r--r-- | passes/memory/memory_bram.cc | 42 | ||||
-rw-r--r-- | passes/memory/memory_map.cc | 119 | ||||
-rw-r--r-- | passes/techmap/Makefile.inc | 6 | ||||
-rw-r--r-- | passes/techmap/abc.cc | 10 | ||||
-rw-r--r-- | passes/techmap/abc9.cc | 4 | ||||
-rw-r--r-- | passes/techmap/abc9_exe.cc | 8 | ||||
-rw-r--r-- | techlibs/ecp5/brams.txt | 62 | ||||
-rw-r--r-- | techlibs/ecp5/lutrams.txt | 9 | ||||
-rw-r--r-- | techlibs/ecp5/synth_ecp5.cc | 4 | ||||
-rw-r--r-- | techlibs/ice40/brams.txt | 60 | ||||
-rw-r--r-- | techlibs/ice40/synth_ice40.cc | 4 | ||||
-rw-r--r-- | tests/arch/common/blockram.v | 42 | ||||
-rw-r--r-- | tests/arch/common/blockrom.v | 31 | ||||
-rw-r--r-- | tests/arch/ecp5/memories.ys | 330 | ||||
-rw-r--r-- | tests/arch/ice40/lutram.ys | 15 | ||||
-rw-r--r-- | tests/arch/ice40/memories.ys | 168 | ||||
-rw-r--r-- | tests/select/.gitignore | 1 |
24 files changed, 912 insertions, 116 deletions
@@ -42,6 +42,7 @@ SANITIZER = # SANITIZER = undefined # SANITIZER = cfi +PROGRAM_PREFIX := OS := $(shell uname -s) PREFIX ?= /usr/local @@ -56,15 +57,15 @@ 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 @@ -249,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) @@ -463,7 +464,7 @@ LDLIBS += -lpthread endif else ifeq ($(ABCEXTERNAL),) -TARGETS += yosys-abc$(EXE) +TARGETS += $(PROGRAM_PREFIX)yosys-abc$(EXE) endif endif endif @@ -513,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 @@ -552,7 +553,7 @@ OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/cal 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 @@ -605,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) @@ -617,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 @@ -660,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) @@ -691,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)" @@ -775,14 +776,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)/. @@ -791,9 +792,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 @@ -803,14 +804,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 @@ -836,13 +837,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 @@ -868,9 +869,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/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/smtbmc.py b/backends/smt2/smtbmc.py index 630464419..5e6f43277 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -53,8 +53,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/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 3bffa3986..bd51aa12b 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1735,7 +1735,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: diff --git a/kernel/yosys.cc b/kernel/yosys.cc index b416c2b74..01131601f 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -835,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 @@ -848,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 = ""; diff --git a/kernel/yosys.h b/kernel/yosys.h index 6aed7c96a..5ad47054c 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -324,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/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/memory/memory_bram.cc b/passes/memory/memory_bram.cc index 52ee1e99d..a25b4536a 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -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; @@ -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() << "\""; @@ -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"); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index da0673c8f..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; @@ -98,6 +119,36 @@ 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(ID::WR_CLK); RTLIL::Const clocks_pol = cell->parameters[ID::WR_CLK_POLARITY]; @@ -339,7 +390,7 @@ 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()) @@ -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/techmap/Makefile.inc b/passes/techmap/Makefile.inc index c16db0d57..bb3f6da98 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -59,10 +59,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 78ecab1e7..0ee495abd 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -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); @@ -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 diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 9757b1539..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"); @@ -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..303b04402 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -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/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/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..6f5790a14 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"); } 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/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 59ada8bae..463e80ee2 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -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"); } 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/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/select/.gitignore b/tests/select/.gitignore new file mode 100644 index 000000000..50e13221d --- /dev/null +++ b/tests/select/.gitignore @@ -0,0 +1 @@ +/*.log |