From 8c9a0b51d4aa8c6029811c2947dcf4dac55a1f95 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 22 May 2023 10:13:17 +1200 Subject: [PATCH 001/119] yosys-witness concat yw trace files Intended for use with SCY to combine sequential cover traces. Arbitrary number of inputs, will load all and attempt to join them. Each trace will be replayed one after the other, in the same order as the files are provided. Mismatch in init_only fields seems to work fine, with values in subsequent traces being assigned in the initial only if they weren't previously defined. Uncertain if a mismatch in non init_only fields will cause problems. Fixes WitnessSig.__eq__(). Adds helper functions to WitnessValues and ReadWitness classes. --- backends/smt2/witness.py | 46 +++++++++++++++++++++++++++++----------- backends/smt2/ywio.py | 29 +++++++++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py index 8d0cc8112d1..8e13cba277b 100644 --- a/backends/smt2/witness.py +++ b/backends/smt2/witness.py @@ -84,26 +84,48 @@ def stats(input): Transform a Yosys witness trace. Currently no transformations are implemented, so it is only useful for testing. +If two or more inputs are provided they will be concatenated together into the output. """) -@click.argument("input", type=click.File("r")) +@click.argument("inputs", type=click.File("r"), nargs=-1) @click.argument("output", type=click.File("w")) -def yw2yw(input, output): - click.echo(f"Copying yosys witness trace from {input.name!r} to {output.name!r}...") - inyw = ReadWitness(input) +def yw2yw(inputs, output): outyw = WriteWitness(output, "yosys-witness yw2yw") + join_inputs = len(inputs) > 1 + inyws = {} + for input in inputs: + if (join_inputs): + click.echo(f"Loading signals from yosys witness trace {input.name!r}...") + inyw = ReadWitness(input) + inyws[input] = inyw + for clock in inyw.clocks: + if clock not in outyw.clocks: + outyw.add_clock(clock["path"], clock["offset"], clock["edge"]) + + for sig in inyw.signals: + if sig not in outyw.signals: + outyw.add_sig(sig.path, sig.offset, sig.width, sig.init_only) + + init_values = sum([inyw.init_step() for inyw in inyws.values()], start=WitnessValues()) + + first_witness = True + for (input, inyw) in inyws.items(): + click.echo(f"Copying yosys witness trace from {input.name!r} to {output.name!r}...") + + if first_witness: + outyw.step(init_values) + else: + outyw.step(inyw.first_step()) - for clock in inyw.clocks: - outyw.add_clock(clock["path"], clock["offset"], clock["edge"]) - - for sig in inyw.signals: - outyw.add_sig(sig.path, sig.offset, sig.width, sig.init_only) + for t, values in inyw.steps(1): + outyw.step(values) - for t, values in inyw.steps(): - outyw.step(values) + click.echo(f"Copied {t + 1} time steps.") + first_witness = False outyw.end_trace() - click.echo(f"Copied {outyw.t + 1} time steps.") + if join_inputs: + click.echo(f"Copied {outyw.t} total time steps.") class AigerMap: diff --git a/backends/smt2/ywio.py b/backends/smt2/ywio.py index 39cfac41e25..2b897200fa3 100644 --- a/backends/smt2/ywio.py +++ b/backends/smt2/ywio.py @@ -165,8 +165,8 @@ def pretty(self): else: return f"{pretty_path(self.path)}[{self.offset}]" - def __eq__(self): - return self.sort_key + def __eq__(self, other): + return self.sort_key == other.sort_key def __hash__(self): return hash(self.sort_key) @@ -294,6 +294,16 @@ def present_signals(self, sigmap): return sorted(signals), missing_signals + def __add__(self, other: "WitnessValues"): + new = WitnessValues() + new += self + new += other + return new + + def __iadd__(self, other: "WitnessValues"): + for key, value in other.values.items(): + self.values.setdefault(key, value) + return self class WriteWitness: def __init__(self, f, generator): @@ -380,13 +390,24 @@ def __init__(self, f): self.bits = [step["bits"] for step in data["steps"]] + def init_step(self): + return self.step(0) + + def first_step(self): + values = WitnessValues() + if len(self.bits) <= 1: + raise NotImplementedError("ReadWitness.first_step() not supported for less than 2 steps") + non_init_bits = len(self.bits[1]) + values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-non_init_bits:]) + return values + def step(self, t): values = WitnessValues() values.unpack(self.sigmap, self.bits[t]) return values - def steps(self): - for i in range(len(self.bits)): + def steps(self, start=0): + for i in range(start, len(self.bits)): yield i, self.step(i) def __len__(self): From 18b44a1e84da3768056e23dca66ea62f36f044c3 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 22 May 2023 11:44:19 +1200 Subject: [PATCH 002/119] yosys-witness: add append option to yw2yw Can now append a user defined number of steps to input traces when joining. If the number of steps is +ve, inputs are all set to 0. If -ve then steps are skipped. If all of steps are skipped (including init step) then the input trace will not be copied. If more than one input trace is provided, the append option will need to be provided the same number of times as there are input traces. --- backends/smt2/witness.py | 23 ++++++++++++++++++++--- backends/smt2/ywio.py | 20 ++++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py index 8e13cba277b..baac3176db9 100644 --- a/backends/smt2/witness.py +++ b/backends/smt2/witness.py @@ -88,14 +88,31 @@ def stats(input): """) @click.argument("inputs", type=click.File("r"), nargs=-1) @click.argument("output", type=click.File("w")) -def yw2yw(inputs, output): +@click.option("--append", "-p", type=int, multiple=True, + help="Number of steps (+ve or -ve) to append to end of input trace. " + +"Can be defined multiple times, following the same order as input traces. ") +def yw2yw(inputs, output, append): outyw = WriteWitness(output, "yosys-witness yw2yw") join_inputs = len(inputs) > 1 inyws = {} - for input in inputs: + + if not append: + # default to 0 + append = [0] * len(inputs) + if len(append) != len(inputs): + print(f"Mismatch in number of --append values ({len(append)}) and input traces ({len(inputs)}).") + sys.exit(1) + + for (input, p) in zip(inputs, append): if (join_inputs): click.echo(f"Loading signals from yosys witness trace {input.name!r}...") inyw = ReadWitness(input) + if p: + click.echo(f" appending {p} steps") + if (p + len(inyw) <= 0): + click.echo(f" skipping {input.name!r} (only {len(inyw)} steps to skip)") + continue + inyw.append_steps(p) inyws[input] = inyw for clock in inyw.clocks: if clock not in outyw.clocks: @@ -119,7 +136,7 @@ def yw2yw(inputs, output): for t, values in inyw.steps(1): outyw.step(values) - click.echo(f"Copied {t + 1} time steps.") + click.echo(f" copied {t + 1} time steps.") first_witness = False outyw.end_trace() diff --git a/backends/smt2/ywio.py b/backends/smt2/ywio.py index 2b897200fa3..4e95f8c33d2 100644 --- a/backends/smt2/ywio.py +++ b/backends/smt2/ywio.py @@ -393,12 +393,16 @@ def __init__(self, f): def init_step(self): return self.step(0) + def non_init_bits(self): + if len(self) > 1: + return len(self.bits[1]) + else: + return sum([sig.width for sig in self.signals if not sig.init_only]) + def first_step(self): values = WitnessValues() - if len(self.bits) <= 1: - raise NotImplementedError("ReadWitness.first_step() not supported for less than 2 steps") - non_init_bits = len(self.bits[1]) - values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-non_init_bits:]) + # may have issues when non_init_bits is 0 + values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-self.non_init_bits():]) return values def step(self, t): @@ -410,5 +414,13 @@ def steps(self, start=0): for i in range(start, len(self.bits)): yield i, self.step(i) + def append_steps(self, t): + if not t: + pass + elif t < 0: + self.bits = self.bits[:t] + else: + self.bits.extend(["0"*self.non_init_bits()]*t) + def __len__(self): return len(self.bits) From 77c7355d537f620a18ca6cf39243850bdc885807 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 1 Aug 2023 17:19:29 +0200 Subject: [PATCH 003/119] smtbmc: Avoid quadratic behavior when scanning s-exprs The previous implementation for finding the end of a top-level s-expr exhibited quadratic behavior as it would re-scan the complete input for the current expression for every new line. For large designs with trivial properties this could easily take seconds and dominate the runtime over the actual solving. This change remembers the current nesting level between lines, avoiding the re-scanning. --- backends/smt2/smtio.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 8094747bc14..0ec7f08f4dc 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -245,6 +245,7 @@ def setup(self): self.logic_uf = False self.unroll_idcnt = 0 self.unroll_buffer = "" + self.unroll_level = 0 self.unroll_sorts = set() self.unroll_objs = set() self.unroll_decls = dict() @@ -420,13 +421,15 @@ def write(self, stmt, unroll=True): self.p_close() if unroll and self.unroll: - stmt = self.unroll_buffer + stmt - self.unroll_buffer = "" - s = re.sub(r"\|[^|]*\|", "", stmt) - if s.count("(") != s.count(")"): - self.unroll_buffer = stmt + " " + self.unroll_level += s.count("(") - s.count(")") + if self.unroll_level > 0: + self.unroll_buffer += stmt + self.unroll_buffer += " " return + else: + stmt = self.unroll_buffer + stmt + self.unroll_buffer = "" s = self.parse(stmt) From ff3c7873f5af5bf701fd331f16df2fe7cb3455b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 2 Aug 2023 20:10:18 +0200 Subject: [PATCH 004/119] wreduce: Group reconnections Group the reconnections, so that instead of producing connect $auto$wreduce.cc:455:run$24 [0] 1'0 connect $auto$wreduce.cc:455:run$23 [31] 1'0 connect $auto$wreduce.cc:455:run$23 [30] 1'0 ... (40 more lines) we produce connect $auto$wreduce.cc:461:run$23 [31:11] 21'000000000000000000000 connect $auto$wreduce.cc:461:run$24 [31:10] 22'0000000000000000000000 . --- passes/opt/wreduce.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 8fd4c788c92..87a5cb56d86 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -364,10 +364,16 @@ struct WreduceWorker if (cell->type == ID($mul)) max_y_size = a_size + b_size; - while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) { - module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : State::S0); - sig.remove(GetSize(sig)-1); - bits_removed++; + max_y_size = std::max(max_y_size, 1); + + if (GetSize(sig) > max_y_size) { + SigSpec extra_bits = sig.extract(max_y_size, GetSize(sig) - max_y_size); + + bits_removed += GetSize(extra_bits); + sig.remove(max_y_size, GetSize(extra_bits)); + + SigBit padbit = is_signed ? sig[GetSize(sig)-1] : State::S0; + module->connect(extra_bits, SigSpec(padbit, GetSize(extra_bits))); } } From e0ba07aed3118502e623139048a24a0cd433d85f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Aug 2023 00:16:43 +0000 Subject: [PATCH 005/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 44a420a3dc3..41fecf2c172 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+45 +YOSYS_VER := 0.31+49 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From fbab08acf14cc5e1fda6c33ba03094e348ea8953 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Aug 2023 08:22:52 +0200 Subject: [PATCH 006/119] Release version 0.32 --- CHANGELOG | 9 ++++++++- Makefile | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0b211771f0f..585605abcdd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,15 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.31 .. Yosys 0.32-dev +Yosys 0.31 .. Yosys 0.32 -------------------------- + * Verific support + - Added sub option "-lib" to reading commands for VHDL and + SystemVerilog, that will later import all units/modules from + marked files as blackboxes. + + * Various + - Added support for $lt, $le, $gt, $ge to the code generating AIGs. Yosys 0.30 .. Yosys 0.31 -------------------------- diff --git a/Makefile b/Makefile index 41fecf2c172..6d831e5665f 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+49 +YOSYS_VER := 0.32 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f3c6b41.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f3c6b41.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 105c447010cff8c408c719454901b32b51dac421 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Aug 2023 08:25:37 +0200 Subject: [PATCH 007/119] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 585605abcdd..027187b6d9f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.32 .. Yosys 0.33-dev +-------------------------- + Yosys 0.31 .. Yosys 0.32 -------------------------- * Verific support diff --git a/Makefile b/Makefile index 6d831e5665f..8ff1e43867d 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32 +YOSYS_VER := 0.32+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f3c6b41.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 389b8d0f94a24c30e5b9352866f0999b14312b23 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 00:16:52 +0000 Subject: [PATCH 008/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8ff1e43867d..c56cb0a3f6e 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+0 +YOSYS_VER := 0.32+1 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From f8e2c955fc9fe052c15d1215c5f7a7aab9fe77cc Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 02:40:36 +0000 Subject: [PATCH 009/119] read_verilog: set location of AST_TCALL. Useful for error reporting of $display() arguments, etc. --- frontends/verilog/verilog_parser.y | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 98bdbf9e5c5..1e82940bbbd 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1830,7 +1830,7 @@ struct_member_type: { astbuf1 = new AstNode(AST_STRUCT_ITEM); } member_type_toke ; member_type_token: - member_type + member_type | hierarchical_type_id { addWiretypeNode($1, astbuf1); } @@ -2721,6 +2721,7 @@ behavioral_stmt: ast_stack.push_back(node); append_attr(node, $1); } opt_arg_list ';'{ + SET_AST_NODE_LOC(ast_stack.back(), @2, @5); ast_stack.pop_back(); } | attr TOK_MSG_TASKS { @@ -2731,6 +2732,7 @@ behavioral_stmt: ast_stack.push_back(node); append_attr(node, $1); } opt_arg_list ';'{ + SET_AST_NODE_LOC(ast_stack.back(), @2, @5); ast_stack.pop_back(); } | attr TOK_BEGIN { From 9ea241711e15536bc1ee0c8bc156d39bfacb9768 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 08:16:43 +0000 Subject: [PATCH 010/119] kernel: add format string helpers, `fmt`. --- Makefile | 12 +- kernel/fmt.cc | 577 ++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/fmt.h | 90 ++++++++ 3 files changed, 673 insertions(+), 6 deletions(-) create mode 100644 kernel/fmt.cc create mode 100644 kernel/fmt.h diff --git a/Makefile b/Makefile index c56cb0a3f6e..dab83bcbe56 100644 --- a/Makefile +++ b/Makefile @@ -652,12 +652,7 @@ $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o OBJS += kernel/binding.o -ifeq ($(ENABLE_ABC),1) -ifneq ($(ABCEXTERNAL),) -kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' -endif -endif -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o +OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o ifeq ($(ENABLE_ZLIB),1) OBJS += kernel/fstdata.o endif @@ -669,6 +664,11 @@ endif kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' +ifeq ($(ENABLE_ABC),1) +ifneq ($(ABCEXTERNAL),) +kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' +endif +endif OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o diff --git a/kernel/fmt.cc b/kernel/fmt.cc new file mode 100644 index 00000000000..924a23a0c1e --- /dev/null +++ b/kernel/fmt.cc @@ -0,0 +1,577 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 whitequark + * + * 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 "libs/bigint/BigUnsigned.hh" +#include "kernel/fmt.h" + +USING_YOSYS_NAMESPACE + +void Fmt::append_string(const std::string &str) { + FmtPart part = {}; + part.type = FmtPart::STRING; + part.str = str; + parts.push_back(part); +} + +void Fmt::parse_rtlil(RTLIL::Cell *cell) { + std::string fmt = cell->getParam(ID(FORMAT)).decode_string(); + RTLIL::SigSpec args = cell->getPort(ID(ARGS)); + parts.clear(); + + FmtPart part; + for (size_t i = 0; i < fmt.size(); i++) { + if (fmt.substr(i, 2) == "}}") + part.str += '}'; + else if (fmt.substr(i, 2) == "{{") + part.str += '{'; + else if (fmt[i] == '}') + log_assert(false && "Unexpected '}' in format string"); + else if (fmt[i] == '{') { + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + part = {}; + } + + size_t arg_size = 0; + for (++i; i < fmt.size(); i++) { + if (fmt[i] >= '0' && fmt[i] <= '9') { + arg_size *= 10; + arg_size += fmt[i] - '0'; + } else if (fmt[i] == ':') { + break; + } else { + log_assert(false && "Unexpected character in format substitution"); + } + } + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + if ((size_t)args.size() < arg_size) + log_assert(false && "Format part overruns arguments"); + part.sig = args.extract(0, arg_size); + args.remove(0, arg_size); + + if (fmt[i] == '>') + part.justify = FmtPart::RIGHT; + else if (fmt[i] == '<') + part.justify = FmtPart::LEFT; + else + log_assert(false && "Unexpected justification in format substitution"); + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + if (fmt[i] == '0' || fmt[i] == ' ') + part.padding = fmt[i]; + else + log_assert(false && "Unexpected padding in format substitution"); + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + for (; i < fmt.size(); i++) { + if (fmt[i] >= '0' && fmt[i] <= '9') { + part.width *= 10; + part.width += fmt[i] - '0'; + continue; + } else if (fmt[i] == 'b') { + part.type = FmtPart::INTEGER; + part.base = 2; + } else if (fmt[i] == 'o') { + part.type = FmtPart::INTEGER; + part.base = 8; + } else if (fmt[i] == 'd') { + part.type = FmtPart::INTEGER; + part.base = 10; + } else if (fmt[i] == 'h') { + part.type = FmtPart::INTEGER; + part.base = 16; + } else if (fmt[i] == 'c') { + part.type = FmtPart::CHARACTER; + } else { + log_assert(false && "Unexpected character in format substitution"); + } + break; + } + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + if (part.type == FmtPart::INTEGER) { + if (fmt[i] == '+') { + part.plus = true; + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } + + if (fmt[i] == '0') { + part.lzero = true; + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } + + if (fmt[i] == 'u') + part.signed_ = false; + else if (fmt[i] == 's') + part.signed_ = true; + else + log_assert(false && "Unexpected character in format substitution"); + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } + + if (fmt[i] != '}') + log_assert(false && "Expected '}' after format substitution"); + + parts.push_back(part); + part = {}; + } else { + part.str += fmt[i]; + } + } + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + } +} + +void Fmt::emit_rtlil(RTLIL::Cell *cell) const { + std::string fmt; + RTLIL::SigSpec args; + + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + for (char c : part.str) { + if (c == '{') + fmt += "{{"; + else if (c == '}') + fmt += "}}"; + else + fmt += c; + } + break; + + case FmtPart::CHARACTER: + log_assert(part.sig.size() % 8 == 0); + YS_FALLTHROUGH + case FmtPart::INTEGER: + args.append(part.sig); + fmt += '{'; + fmt += std::to_string(part.sig.size()); + fmt += ':'; + if (part.justify == FmtPart::RIGHT) + fmt += '>'; + else if (part.justify == FmtPart::LEFT) + fmt += '<'; + else log_abort(); + log_assert(part.padding == '0' || part.padding == ' '); + fmt += part.padding; + fmt += std::to_string(part.width); + if (part.type == FmtPart::INTEGER) { + switch (part.base) { + case 2: fmt += 'b'; break; + case 8: fmt += 'o'; break; + case 10: fmt += 'd'; break; + case 16: fmt += 'h'; break; + default: log_abort(); + } + if (part.plus) + fmt += '+'; + if (part.lzero) + fmt += '0'; + fmt += part.signed_ ? 's' : 'u'; + } else if (part.type == FmtPart::CHARACTER) { + fmt += 'c'; + } else log_abort(); + fmt += '}'; + break; + + default: log_abort(); + } + } + + cell->setParam(ID(FORMAT), fmt); + cell->setParam(ID(ARGS_WIDTH), args.size()); + cell->setPort(ID(ARGS), args); +} + +static size_t compute_requried_decimal_places(size_t size, bool signed_) +{ + BigUnsigned max; + if (!signed_) + max.setBit(size, true); + else + max.setBit(size - 1, true); + size_t places = 0; + while (!max.isZero()) { + places++; + max /= 10; + } + if (signed_) + places++; + return places; +} + +static void apply_verilog_automatic_sizing(FmtPart &part) +{ + if (part.base == 10) { + size_t places = compute_requried_decimal_places(part.sig.size(), part.signed_); + part.padding = ' '; + part.width = std::max(part.width, places); + } else { + part.lzero = true; + } +} + +void Fmt::parse_verilog(const std::vector &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name) +{ + parts.clear(); + + auto arg = args.begin(); + for (; arg != args.end(); ++arg) { + switch (arg->type) { + case VerilogFmtArg::INTEGER: { + FmtPart part = {}; + part.type = FmtPart::INTEGER; + part.sig = arg->sig; + part.base = default_base; + part.signed_ = arg->signed_; + apply_verilog_automatic_sizing(part); + parts.push_back(part); + break; + } + + case VerilogFmtArg::STRING: { + if (arg == args.begin() || !sformat_like) { + const auto fmtarg = arg; + const std::string &fmt = fmtarg->str; + FmtPart part = {}; + for (size_t i = 0; i < fmt.size(); i++) { + if (fmt[i] != '%') { + part.str += fmt[i]; + } else if (fmt.substr(i, 2) == "%%") { + i++; + part.str += '%'; + } else if (fmt.substr(i, 2) == "%l" || fmt.substr(i, 2) == "%L") { + i++; + part.str += module_name.str(); + } else { + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + part = {}; + } + if (++i == fmt.size()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + + if (++arg == args.end()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + part.sig = arg->sig; + part.signed_ = arg->signed_; + + for (; i < fmt.size(); i++) { + if (fmt[i] == '-') { + // left justify; not in IEEE 1800-2017 or verilator but iverilog has it + part.justify = FmtPart::LEFT; + } else if (fmt[i] == '+') { + // always show sign; not in IEEE 1800-2017 or verilator but iverilog has it + part.plus = true; + } else break; + } + if (i == fmt.size()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + + bool has_leading_zero = false, has_width = false; + for (; i < fmt.size(); i++) { + if (fmt[i] >= '0' && fmt[i] <= '9') { + if (fmt[i] == '0' && !has_width) { + has_leading_zero = true; + } else { + has_width = true; + part.width *= 10; + part.width += fmt[i] - '0'; + } + continue; + } else if (fmt[i] == 'b' || fmt[i] == 'B') { + part.type = FmtPart::INTEGER; + part.base = 2; + } else if (fmt[i] == 'o' || fmt[i] == 'O') { + part.type = FmtPart::INTEGER; + part.base = 8; + } else if (fmt[i] == 'd' || fmt[i] == 'D') { + part.type = FmtPart::INTEGER; + part.base = 10; + } else if (fmt[i] == 'h' || fmt[i] == 'H' || + fmt[i] == 'x' || fmt[i] == 'X') { + // hex digits always printed in lowercase for %h%x as well as %H%X + part.type = FmtPart::INTEGER; + part.base = 16; + } else if (fmt[i] == 'c' || fmt[i] == 'C') { + part.type = FmtPart::CHARACTER; + part.sig.extend_u0(8); + // %10c and %010c not fully defined in IEEE 1800-2017 and do different things in iverilog + } else if (fmt[i] == 's' || fmt[i] == 'S') { + part.type = FmtPart::CHARACTER; + if ((part.sig.size() % 8) != 0) + part.sig.extend_u0((part.sig.size() + 7) / 8 * 8); + // %10s and %010s not fully defined in IEEE 1800-2017 and do the same thing in iverilog + part.padding = ' '; + } else { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); + } + break; + } + if (i == fmt.size()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + + if (part.padding == '\0') + part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' '; + + if (part.type == FmtPart::INTEGER) { + if (part.base != 10 && part.plus) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + if (!has_leading_zero) + apply_verilog_automatic_sizing(part); + } + + parts.push_back(part); + part = {}; + } + } + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + } + } else { + FmtPart part = {}; + part.type = FmtPart::STRING; + part.str = arg->str; + parts.push_back(part); + } + break; + } + + default: log_abort(); + } + } +} + +std::vector Fmt::emit_verilog() const +{ + std::vector args; + VerilogFmtArg fmt = {}; + fmt.type = VerilogFmtArg::STRING; + + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + for (char c : part.str) { + if (c == '%') + fmt.str += "%%"; + else + fmt.str += c; + } + break; + + case FmtPart::INTEGER: { + VerilogFmtArg arg = {}; + arg.type = VerilogFmtArg::INTEGER; + arg.sig = part.sig; + arg.signed_ = part.signed_; + args.push_back(arg); + + fmt.str += '%'; + if (part.plus) + fmt.str += '+'; + if (part.justify == FmtPart::LEFT) + fmt.str += '-'; + if (part.width == 0) { + if (!part.lzero) + fmt.str += '0'; + } else if (part.width > 0) { + log_assert(part.padding == ' ' || part.padding == '0'); + if (!part.lzero && part.base != 10) + fmt.str += '0'; + else if (part.padding == '0') + fmt.str += '0'; + fmt.str += std::to_string(part.width); + } + switch (part.base) { + case 2: fmt.str += 'b'; break; + case 8: fmt.str += 'o'; break; + case 10: fmt.str += 'd'; break; + case 16: fmt.str += 'h'; break; + default: log_abort(); + } + break; + } + + case FmtPart::CHARACTER: { + VerilogFmtArg arg; + arg.type = VerilogFmtArg::INTEGER; + arg.sig = part.sig; + args.push_back(arg); + + fmt.str += '%'; + if (part.justify == FmtPart::LEFT) + fmt.str += '-'; + if (part.sig.size() == 8) { + if (part.width > 0) { + log_assert(part.padding == '0' || part.padding == ' '); + if (part.padding == '0') + fmt.str += part.padding; + fmt.str += std::to_string(part.width); + } + fmt.str += 'c'; + } else { + log_assert(part.sig.size() % 8 == 0); + if (part.width > 0) { + log_assert(part.padding == ' '); // no zero padding + fmt.str += std::to_string(part.width); + } + fmt.str += 's'; + } + break; + } + } + } + + args.insert(args.begin(), fmt); + return args; +} + +std::string Fmt::render() const +{ + std::string str; + + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + str += part.str; + break; + + case FmtPart::INTEGER: + case FmtPart::CHARACTER: { + std::string buf; + if (part.type == FmtPart::INTEGER) { + RTLIL::Const value = part.sig.as_const(); + + if (!part.lzero && part.base != 10) { + size_t minimum_size = 0; + for (size_t index = 0; index < (size_t)value.size(); index++) + if (value[index] != State::S0) + minimum_size = index + 1; + value = value.extract(0, minimum_size); + } + + if (part.base == 2) { + buf = value.as_string(); + } else if (part.base == 8 || part.base == 16) { + size_t step = (part.base == 16) ? 4 : 3; + for (size_t index = 0; index < (size_t)value.size(); index += step) { + RTLIL::Const subvalue = value.extract(index, min(step, value.size() - index)); + bool has_x = false, all_x = true, has_z = false, all_z = true; + for (State bit : subvalue) { + if (bit == State::Sx) + has_x = true; + else + all_x = false; + if (bit == State::Sz) + has_z = true; + else + all_z = false; + } + if (all_x) + buf += 'x'; + else if (all_z) + buf += 'z'; + else if (has_x) + buf += 'X'; + else if (has_z) + buf += 'Z'; + else + buf += "0123456789abcdef"[subvalue.as_int()]; + } + std::reverse(buf.begin(), buf.end()); + } else if (part.base == 10) { + bool has_x = false, all_x = true, has_z = false, all_z = true; + for (State bit : value) { + if (bit == State::Sx) + has_x = true; + else + all_x = false; + if (bit == State::Sz) + has_z = true; + else + all_z = false; + } + if (all_x) + buf += 'x'; + else if (all_z) + buf += 'z'; + else if (has_x) + buf += 'X'; + else if (has_z) + buf += 'Z'; + else { + bool negative = part.signed_ && value[value.size() - 1]; + RTLIL::Const absvalue; + if (negative) + absvalue = RTLIL::const_neg(value, {}, part.signed_, {}, value.size() + 1); + else + absvalue = value; + log_assert(absvalue.is_fully_def()); + if (absvalue.is_fully_zero()) + buf += '0'; + while (!absvalue.is_fully_zero()) { + buf += '0' + RTLIL::const_mod(absvalue, 10, part.signed_, false, 4).as_int(); + absvalue = RTLIL::const_div(absvalue, 10, part.signed_, false, absvalue.size()); + } + if (negative || part.plus) + buf += negative ? '-' : '+'; + std::reverse(buf.begin(), buf.end()); + } + } else log_abort(); + } else if (part.type == FmtPart::CHARACTER) { + buf = part.sig.as_const().decode_string(); + } + + log_assert(part.width == 0 || part.padding != '\0'); + if (part.justify == FmtPart::RIGHT && buf.size() < part.width) { + size_t pad_width = part.width - buf.size(); + if (part.padding == '0' && (buf.front() == '+' || buf.front() == '-')) { + str += buf.front(); + buf.erase(0, 1); + } + str += std::string(pad_width, part.padding); + } + str += buf; + if (part.justify == FmtPart::LEFT && buf.size() < part.width) + str += std::string(part.width - buf.size(), part.padding); + break; + } + } + } + + return str; +} diff --git a/kernel/fmt.h b/kernel/fmt.h new file mode 100644 index 00000000000..c85da19c01b --- /dev/null +++ b/kernel/fmt.h @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 whitequark + * + * 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. + * + */ + +#ifndef FMT_H +#define FMT_H + +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +// Verilog format argument, such as the arguments in: +// $display("foo %d bar %01x", 4'b0, $signed(2'b11)) +struct VerilogFmtArg { + enum { + STRING = 0, + INTEGER = 1, + } type; + + // All types + std::string filename; + unsigned first_line; + + // STRING type + std::string str; + + // INTEGER type + RTLIL::SigSpec sig; + bool signed_ = false; +}; + +// RTLIL format part, such as the substitutions in: +// "foo {4: 4du} bar {2:01xs}" +struct FmtPart { + enum { + STRING = 0, + INTEGER = 1, + CHARACTER = 2, + } type; + + // STRING type + std::string str; + + // INTEGER/CHARACTER type + RTLIL::SigSpec sig; + enum { + RIGHT = 0, + LEFT = 1, + } justify = RIGHT; + char padding = '\0'; + size_t width = 0; + // INTEGER type + unsigned base = 10; + bool signed_ = false; + bool lzero = false; + bool plus = false; +}; + +struct Fmt { + std::vector parts; + + void append_string(const std::string &str); + + void parse_rtlil(RTLIL::Cell *cell); + void emit_rtlil(RTLIL::Cell *cell) const; + + void parse_verilog(const std::vector &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name); + std::vector emit_verilog() const; + + std::string render() const; +}; + +YOSYS_NAMESPACE_END + +#endif From 9f8e039a4b10e936457fd75d589eb7ec51f0292b Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 08:57:07 +0000 Subject: [PATCH 011/119] ast: use new format string helpers. --- frontends/ast/ast.h | 3 +- frontends/ast/simplify.cc | 206 +++++++----------------------- frontends/verilog/verilog_lexer.l | 2 +- tests/various/sformatf.ys | 2 +- 4 files changed, 50 insertions(+), 163 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8893d5e010c..55e05709dd5 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -30,6 +30,7 @@ #define AST_H #include "kernel/rtlil.h" +#include "kernel/fmt.h" #include #include @@ -277,7 +278,7 @@ namespace AST bool replace_variables(std::map &variables, AstNode *fcall, bool must_succeed); AstNode *eval_const_function(AstNode *fcall, bool must_succeed); bool is_simple_const_expr(); - std::string process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint); + Fmt processFormat(int stage, bool sformat_like, int default_base = 10, size_t first_arg_at = 0); bool is_recursive_function() const; std::pair get_tern_choice(); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 64191cd7ebf..489ce255a0c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -43,141 +43,35 @@ using namespace AST_INTERNAL; // Process a format string and arguments for $display, $write, $sprintf, etc -std::string AstNode::process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint) { - // Other arguments are placeholders. Process the string as we go through it - std::string sout; - for (size_t i = 0; i < sformat.length(); i++) - { - // format specifier - if (sformat[i] == '%') - { - // If there's no next character, that's a problem - if (i+1 >= sformat.length()) - input_error("System task `%s' called with `%%' at end of string.\n", str.c_str()); - - char cformat = sformat[++i]; - - // %% is special, does not need a matching argument - if (cformat == '%') - { - sout += '%'; - continue; - } - - bool got_len = false; - bool got_zlen = false; - int len_value = 0; - - while ('0' <= cformat && cformat <= '9') - { - if (!got_len && cformat == '0') - got_zlen = true; - - got_len = true; - len_value = 10*len_value + (cformat - '0'); - - cformat = sformat[++i]; - } - - // Simplify the argument - AstNode *node_arg = nullptr; - - // Everything from here on depends on the format specifier - switch (cformat) - { - case 's': - case 'S': - case 'd': - case 'D': - if (got_len && len_value != 0) - goto unsupported_format; - YS_FALLTHROUGH - case 'x': - case 'X': - if (next_arg >= GetSize(children)) - input_error("Missing argument for %%%c format specifier in system task `%s'.\n", - cformat, str.c_str()); - - node_arg = children[next_arg++]; - while (node_arg->simplify(true, false, stage, width_hint, sign_hint, false)) { } - if (node_arg->type != AST_CONSTANT) - input_error("Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); - break; - - case 'm': - case 'M': - if (got_len) - goto unsupported_format; - break; - - case 'l': - case 'L': - if (got_len) - goto unsupported_format; - break; - - default: - unsupported_format: - input_error("System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); - break; - } - - switch (cformat) - { - case 's': - case 'S': - sout += node_arg->bitsAsConst().decode_string(); - break; - - case 'd': - case 'D': - sout += stringf("%d", node_arg->bitsAsConst().as_int()); - break; - - case 'x': - case 'X': - { - Const val = node_arg->bitsAsConst(); - - while (GetSize(val) % 4 != 0) - val.bits.push_back(State::S0); - - int len = GetSize(val) / 4; - for (int i = len; i < len_value; i++) - sout += got_zlen ? '0' : ' '; - - for (int i = len-1; i >= 0; i--) { - Const digit = val.extract(4*i, 4); - if (digit.is_fully_def()) - sout += stringf(cformat == 'x' ? "%x" : "%X", digit.as_int()); - else - sout += cformat == 'x' ? "x" : "X"; - } - } - break; - - case 'm': - case 'M': - sout += log_id(current_module->name); - break; - - case 'l': - case 'L': - sout += log_id(current_module->name); - break; - - default: - log_abort(); - } +Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_t first_arg_at) { + std::vector args; + for (size_t index = first_arg_at; index < children.size(); index++) { + AstNode *node_arg = children[index]; + while (node_arg->simplify(true, false, stage, -1, false, false)) { } + if (node_arg->type != AST_CONSTANT) + input_error("Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); + + VerilogFmtArg arg = {}; + arg.filename = filename; + arg.first_line = location.first_line; + if (node_arg->is_string) { + arg.type = VerilogFmtArg::STRING; + arg.str = node_arg->bitsAsConst().decode_string(); + // and in case this will be used as an argument... + arg.sig = node_arg->bitsAsConst(); + arg.signed_ = false; + } else { + arg.type = VerilogFmtArg::INTEGER; + arg.sig = node_arg->bitsAsConst(); + arg.signed_ = node_arg->is_signed; } - - // not a format specifier - else - sout += sformat[i]; + args.push_back(arg); } - return sout; -} + Fmt fmt = {}; + fmt.parse_verilog(args, sformat_like, default_base, /*task_name=*/str, current_module->name); + return fmt; +} void AstNode::annotateTypedEnums(AstNode *template_node) { @@ -1057,33 +951,30 @@ bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hin str = std::string(); } - if ((type == AST_TCALL) && (str == "$display" || str == "$write") && (!current_always || current_always->type != AST_INITIAL)) { + if ((type == AST_TCALL) && (str.substr(0, 8) == "$display" || str.substr(0, 6) == "$write") && (!current_always || current_always->type != AST_INITIAL)) { log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); delete_children(); str = std::string(); } - // print messages if this a call to $display() or $write() - // This code implements only a small subset of Verilog-2005 $display() format specifiers, - // but should be good enough for most uses - if ((type == AST_TCALL) && ((str == "$display") || (str == "$write"))) + // print messages if this a call to $display() or $write() family of functions + if ((type == AST_TCALL) && + (str == "$display" || str == "$displayb" || str == "$displayh" || str == "$displayo" || + str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo")) { - int nargs = GetSize(children); - if (nargs < 1) - input_error("System task `%s' got %d arguments, expected >= 1.\n", - str.c_str(), int(children.size())); - - // First argument is the format string - AstNode *node_string = children[0]; - while (node_string->simplify(true, false, stage, width_hint, sign_hint, false)) { } - if (node_string->type != AST_CONSTANT) - input_error("Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); - std::string sformat = node_string->bitsAsConst().decode_string(); - std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); - // Finally, print the message (only include a \n for $display, not for $write) - log("%s", sout.c_str()); - if (str == "$display") - log("\n"); + int default_base = 10; + if (str.back() == 'b') + default_base = 2; + else if (str.back() == 'o') + default_base = 8; + else if (str.back() == 'h') + default_base = 16; + + Fmt fmt = processFormat(stage, /*sformat_like=*/false, default_base); + if (str.substr(0, 8) == "$display") + fmt.append_string("\n"); + log("%s", fmt.render().c_str()); + delete_children(); str = std::string(); } @@ -3735,13 +3626,8 @@ skip_dynamic_range_lvalue_expansion:; } if (str == "\\$sformatf") { - AstNode *node_string = children[0]; - while (node_string->simplify(true, false, stage, width_hint, sign_hint, false)) { } - if (node_string->type != AST_CONSTANT) - input_error("Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); - std::string sformat = node_string->bitsAsConst().decode_string(); - std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); - newNode = AstNode::mkconst_str(sout); + Fmt fmt = processFormat(stage, /*sformat_like=*/true); + newNode = AstNode::mkconst_str(fmt.render()); goto apply_newNode; } diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 24998666828..89ccee788c9 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -386,7 +386,7 @@ and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 { supply0 { return TOK_SUPPLY0; } supply1 { return TOK_SUPPLY1; } -"$"(display|write|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { +"$"(display[bho]?|write[bho]?|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { yylval->string = new std::string(yytext); return TOK_ID; } diff --git a/tests/various/sformatf.ys b/tests/various/sformatf.ys index 66d6b0dbe9e..f281a9cd530 100644 --- a/tests/various/sformatf.ys +++ b/tests/various/sformatf.ys @@ -5,7 +5,7 @@ module top; localparam b = $sformatf("%d", 4'b011); generate if (a != "0x5a") $error("a incorrect!"); - if (b != "3") $error("b incorrect!"); + if (b != " 3") $error("b incorrect!"); endgenerate endmodule From d5c9953c09f5430ccc299d214c77f48e98cdc908 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 14:34:17 +0000 Subject: [PATCH 012/119] ast: translate $display/$write tasks in always blocks to new $print cell. --- frontends/ast/ast.h | 2 ++ frontends/ast/genrtlil.cc | 74 ++++++++++++++++++++++++++++++++++++++- frontends/ast/simplify.cc | 42 ++++++++++++---------- kernel/constids.inc | 7 ++++ kernel/rtlil.cc | 11 ++++++ 5 files changed, 116 insertions(+), 20 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 55e05709dd5..e357579add2 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -278,6 +278,8 @@ namespace AST bool replace_variables(std::map &variables, AstNode *fcall, bool must_succeed); AstNode *eval_const_function(AstNode *fcall, bool must_succeed); bool is_simple_const_expr(); + + // helper for parsing format strings Fmt processFormat(int stage, bool sformat_like, int default_base = 10, size_t first_arg_at = 0); bool is_recursive_function() const; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3aa19b70687..40e71e8bd20 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -693,8 +693,80 @@ struct AST_INTERNAL::ProcessGenerator ast->input_error("Found parameter declaration in block without label!\n"); break; - case AST_NONE: case AST_TCALL: + if (ast->str == "$display" || ast->str == "$displayb" || ast->str == "$displayh" || ast->str == "$displayo" || + ast->str == "$write" || ast->str == "$writeb" || ast->str == "$writeh" || ast->str == "$writeo") { + std::stringstream sstr; + sstr << ast->str << "$" << ast->filename << ":" << ast->location.first_line << "$" << (autoidx++); + + RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($print)); + cell->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); + + RTLIL::SigSpec triggers; + RTLIL::Const polarity; + for (auto sync : proc->syncs) { + if (sync->type == RTLIL::STp) { + triggers.append(sync->signal); + polarity.bits.push_back(RTLIL::S1); + } else if (sync->type == RTLIL::STn) { + triggers.append(sync->signal); + polarity.bits.push_back(RTLIL::S0); + } + } + cell->parameters[ID::TRG_WIDTH] = triggers.size(); + cell->parameters[ID::TRG_ENABLE] = !triggers.empty(); + cell->parameters[ID::TRG_POLARITY] = polarity; + cell->setPort(ID::TRG, triggers); + + Wire *wire = current_module->addWire(sstr.str() + "_EN", 1); + wire->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); + cell->setPort(ID::EN, wire); + + proc->root_case.actions.push_back(SigSig(wire, false)); + current_case->actions.push_back(SigSig(wire, true)); + + int default_base = 10; + if (ast->str.back() == 'b') + default_base = 2; + else if (ast->str.back() == 'o') + default_base = 8; + else if (ast->str.back() == 'h') + default_base = 16; + + std::vector args; + for (auto node : ast->children) { + int width; + bool is_signed; + node->detectSignWidth(width, is_signed, nullptr); + + VerilogFmtArg arg = {}; + arg.filename = node->filename; + arg.first_line = node->location.first_line; + if (node->type == AST_CONSTANT && node->is_string) { + arg.type = VerilogFmtArg::STRING; + arg.str = node->bitsAsConst().decode_string(); + // and in case this will be used as an argument... + arg.sig = node->bitsAsConst(); + arg.signed_ = false; + } else { + arg.type = VerilogFmtArg::INTEGER; + arg.sig = node->genRTLIL(); + arg.signed_ = is_signed; + } + args.push_back(arg); + } + + Fmt fmt = {}; + fmt.parse_verilog(args, /*sformat_like=*/false, default_base, /*task_name=*/ast->str, current_module->name); + if (ast->str.substr(0, 8) == "$display") + fmt.append_string("\n"); + fmt.emit_rtlil(cell); + } else if (!ast->str.empty()) { + log_file_error(ast->filename, ast->location.first_line, "Found unsupported invocation of system task `%s'!\n", ast->str.c_str()); + } + break; + + case AST_NONE: case AST_FOR: break; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 489ce255a0c..19e62668b9e 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -951,29 +951,33 @@ bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hin str = std::string(); } - if ((type == AST_TCALL) && (str.substr(0, 8) == "$display" || str.substr(0, 6) == "$write") && (!current_always || current_always->type != AST_INITIAL)) { - log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); - delete_children(); - str = std::string(); - } - - // print messages if this a call to $display() or $write() family of functions if ((type == AST_TCALL) && (str == "$display" || str == "$displayb" || str == "$displayh" || str == "$displayo" || str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo")) { - int default_base = 10; - if (str.back() == 'b') - default_base = 2; - else if (str.back() == 'o') - default_base = 8; - else if (str.back() == 'h') - default_base = 16; - - Fmt fmt = processFormat(stage, /*sformat_like=*/false, default_base); - if (str.substr(0, 8) == "$display") - fmt.append_string("\n"); - log("%s", fmt.render().c_str()); + if (!current_always) { + log_file_warning(filename, location.first_line, "System task `%s' outside initial or always block is unsupported.\n", str.c_str()); + } else if (current_always->type == AST_INITIAL) { + int default_base = 10; + if (str.back() == 'b') + default_base = 2; + else if (str.back() == 'o') + default_base = 8; + else if (str.back() == 'h') + default_base = 16; + + // when $display()/$write() functions are used in an initial block, print them during synthesis + Fmt fmt = processFormat(stage, /*sformat_like=*/false, default_base); + if (str.substr(0, 8) == "$display") + fmt.append_string("\n"); + log("%s", fmt.render().c_str()); + } else { + // when $display()/$write() functions are used in an always block, simplify the expressions and + // convert them to a special cell later in genrtlil + for (auto node : children) + while (node->simplify(true, false, stage, -1, false, false)) {} + return false; + } delete_children(); str = std::string(); diff --git a/kernel/constids.inc b/kernel/constids.inc index 39211d0c753..08b0ecdc2b4 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -22,6 +22,8 @@ X(always_ff) X(always_latch) X(anyconst) X(anyseq) +X(ARGS) +X(ARGS_WIDTH) X(ARST) X(ARST_POLARITY) X(ARST_VALUE) @@ -86,6 +88,7 @@ X(equiv_merged) X(equiv_region) X(extract_order) X(F) +X(FORMAT) X(force_downto) X(force_upto) X(fsm_encoding) @@ -233,6 +236,10 @@ X(TRANS_NUM) X(TRANSPARENCY_MASK) X(TRANSPARENT) X(TRANS_TABLE) +X(TRG) +X(TRG_ENABLE) +X(TRG_POLARITY) +X(TRG_WIDTH) X(T_RISE_MAX) X(T_RISE_MIN) X(T_RISE_TYP) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7011429ff5a..09fe0800078 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1720,6 +1720,17 @@ namespace { return; } + if (cell->type == ID($print)) { + param(ID(FORMAT)); + param_bool(ID::TRG_ENABLE); + param(ID::TRG_POLARITY); + port(ID::EN, 1); + port(ID::TRG, param(ID::TRG_WIDTH)); + port(ID::ARGS, param(ID::ARGS_WIDTH)); + check_expected(); + 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; } From d51ecde8c2e488fc299d6033bbc18202ee5058de Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 16:33:45 +0000 Subject: [PATCH 013/119] clean: keep $print cells, since they have unmodelled side effects. --- passes/opt/opt_clean.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index cb2490dc72e..4da67cf630f 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -79,6 +79,9 @@ struct keep_cache_t if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule))) return true; + if (cell->type == ID($print)) + return true; + if (cell->has_keep_attr()) return true; From 3f8eab15bb7677e32aac1980e361a566be8d68de Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 17:31:04 +0000 Subject: [PATCH 014/119] write_verilog: translate $print cells to $write tasks in always blocks. --- backends/verilog/verilog_backend.cc | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 5ff191a9c16..a6fd859a396 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -27,6 +27,7 @@ #include "kernel/sigtools.h" #include "kernel/ff.h" #include "kernel/mem.h" +#include "kernel/fmt.h" #include #include #include @@ -1753,6 +1754,57 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } + if (cell->type == ID($print)) + { + Fmt fmt = {}; + fmt.parse_rtlil(cell); + std::vector args = fmt.emit_verilog(); + + if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + f << stringf("%s" "always @(", indent.c_str()); + for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { + if (i != 0) + f << " or "; + if (cell->getParam(ID::TRG_POLARITY)[i]) + f << "posedge "; + else + f << "negedge "; + dump_sigspec(f, cell->getPort(ID::TRG)[i]); + } + f << ")\n"; + } else { + f << stringf("%s" "always @*\n", indent.c_str()); + } + + f << stringf("%s" " if (", indent.c_str()); + dump_sigspec(f, cell->getPort(ID::EN)); + f << stringf(")\n"); + + f << stringf("%s" " $write(", indent.c_str()); + bool first = true; + for (auto &arg : args) { + if (first) { + first = false; + } else { + f << ", "; + } + switch (arg.type) { + case VerilogFmtArg::STRING: + dump_const(f, RTLIL::Const(arg.str)); + break; + case VerilogFmtArg::INTEGER: + f << (arg.signed_ ? "$signed(" : "$unsigned("); + dump_sigspec(f, arg.sig); + f << ")"; + break; + default: log_abort(); + } + } + f << stringf(");\n"); + + return true; + } + // FIXME: $fsm return false; From 67052f62ec888fef2055ecca3da1c88123c6a1ed Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 5 Dec 2020 22:26:25 +0000 Subject: [PATCH 015/119] fmt: add tests for Yosys evaluation of format expressions. --- Makefile | 1 + tests/fmt/.gitignore | 2 + tests/fmt/initial_display.v | 245 ++++++++++++++++++++++++++++++++++++ tests/fmt/run-test.sh | 6 + 4 files changed, 254 insertions(+) create mode 100644 tests/fmt/.gitignore create mode 100644 tests/fmt/initial_display.v create mode 100644 tests/fmt/run-test.sh diff --git a/Makefile b/Makefile index dab83bcbe56..7883cf2b9b8 100644 --- a/Makefile +++ b/Makefile @@ -882,6 +882,7 @@ endif +cd tests/memfile && bash run-test.sh +cd tests/verilog && bash run-test.sh +cd tests/xprop && bash run-test.sh $(SEEDOPT) + +cd tests/fmt && bash run-test.sh @echo "" @echo " Passed \"make test\"." @echo "" diff --git a/tests/fmt/.gitignore b/tests/fmt/.gitignore new file mode 100644 index 00000000000..07043e54799 --- /dev/null +++ b/tests/fmt/.gitignore @@ -0,0 +1,2 @@ +*.log +iverilog-initial_display* diff --git a/tests/fmt/initial_display.v b/tests/fmt/initial_display.v new file mode 100644 index 00000000000..26a39d0ec88 --- /dev/null +++ b/tests/fmt/initial_display.v @@ -0,0 +1,245 @@ +module m; + initial $display("<<>>"); + + initial $display("==> small unsigned %%d"); + initial $display(":%d:", 16'haa); + initial $display(":%-d:", 16'haa); + initial $display(":%+d:", 16'haa); + initial $display(":%+-d:", 16'haa); + initial $display(":%0d:", 16'haa); + initial $display(":%-0d:", 16'haa); + initial $display(":%+0d:", 16'haa); + initial $display(":%+-0d:", 16'haa); + initial $display(":%20d:", 16'haa); + initial $display(":%-20d:", 16'haa); + initial $display(":%+20d:", 16'haa); + initial $display(":%+-20d:", 16'haa); + initial $display(":%020d:", 16'haa); + initial $display(":%-020d:", 16'haa); + initial $display(":%+020d:", 16'haa); + initial $display(":%+-020d:", 16'haa); + + initial $display("==> big unsigned %%d"); + initial $display(":%d:", 16'haaaa); + initial $display(":%-d:", 16'haaaa); + initial $display(":%+d:", 16'haaaa); + initial $display(":%+-d:", 16'haaaa); + initial $display(":%0d:", 16'haaaa); + initial $display(":%-0d:", 16'haaaa); + initial $display(":%+0d:", 16'haaaa); + initial $display(":%+-0d:", 16'haaaa); + initial $display(":%20d:", 16'haaaa); + initial $display(":%-20d:", 16'haaaa); + initial $display(":%+20d:", 16'haaaa); + initial $display(":%+-20d:", 16'haaaa); + initial $display(":%020d:", 16'haaaa); + initial $display(":%-020d:", 16'haaaa); + initial $display(":%+020d:", 16'haaaa); + initial $display(":%+-020d:", 16'haaaa); + + initial $display("==> small signed %%d"); + initial $display(":%d:", 16'shaa); + initial $display(":%-d:", 16'shaa); + initial $display(":%+d:", 16'shaa); + initial $display(":%+-d:", 16'shaa); + initial $display(":%0d:", 16'shaa); + initial $display(":%-0d:", 16'shaa); + initial $display(":%+0d:", 16'shaa); + initial $display(":%+-0d:", 16'shaa); + initial $display(":%20d:", 16'shaa); + initial $display(":%-20d:", 16'shaa); + initial $display(":%+20d:", 16'shaa); + initial $display(":%+-20d:", 16'shaa); + initial $display(":%020d:", 16'shaa); + initial $display(":%-020d:", 16'shaa); + initial $display(":%+020d:", 16'shaa); + initial $display(":%+-020d:", 16'shaa); + + initial $display("==> big signed %%d"); + initial $display(":%d:", 16'shaaaa); + initial $display(":%-d:", 16'shaaaa); + initial $display(":%+d:", 16'shaaaa); + initial $display(":%+-d:", 16'shaaaa); + initial $display(":%0d:", 16'shaaaa); + initial $display(":%-0d:", 16'shaaaa); + initial $display(":%+0d:", 16'shaaaa); + initial $display(":%+-0d:", 16'shaaaa); + initial $display(":%20d:", 16'shaaaa); + initial $display(":%-20d:", 16'shaaaa); + initial $display(":%+20d:", 16'shaaaa); + initial $display(":%+-20d:", 16'shaaaa); + initial $display(":%020d:", 16'shaaaa); + initial $display(":%-020d:", 16'shaaaa); + initial $display(":%+020d:", 16'shaaaa); + initial $display(":%+-020d:", 16'shaaaa); + + initial $display("==> small unsigned %%h"); + initial $display(":%h:", 16'haa); + initial $display(":%-h:", 16'haa); + initial $display(":%0h:", 16'haa); + initial $display(":%-0h:", 16'haa); + initial $display(":%20h:", 16'haa); + initial $display(":%-20h:", 16'haa); + initial $display(":%020h:", 16'haa); + initial $display(":%-020h:", 16'haa); + + initial $display("==> big unsigned %%h"); + initial $display(":%h:", 16'haaaa); + initial $display(":%-h:", 16'haaaa); + initial $display(":%0h:", 16'haaaa); + initial $display(":%-0h:", 16'haaaa); + initial $display(":%20h:", 16'haaaa); + initial $display(":%-20h:", 16'haaaa); + initial $display(":%020h:", 16'haaaa); + initial $display(":%-020h:", 16'haaaa); + + initial $display("==> small signed %%h"); + initial $display(":%h:", 16'shaa); + initial $display(":%-h:", 16'shaa); + initial $display(":%0h:", 16'shaa); + initial $display(":%-0h:", 16'shaa); + initial $display(":%20h:", 16'shaa); + initial $display(":%-20h:", 16'shaa); + initial $display(":%020h:", 16'shaa); + initial $display(":%-020h:", 16'shaa); + + initial $display("==> big signed %%h"); + initial $display(":%h:", 16'shaaaa); + initial $display(":%-h:", 16'shaaaa); + initial $display(":%0h:", 16'shaaaa); + initial $display(":%-0h:", 16'shaaaa); + initial $display(":%20h:", 16'shaaaa); + initial $display(":%-20h:", 16'shaaaa); + initial $display(":%020h:", 16'shaaaa); + initial $display(":%-020h:", 16'shaaaa); + + initial $display("==> small unsigned %%o"); + initial $display(":%o:", 16'haa); + initial $display(":%-o:", 16'haa); + initial $display(":%0o:", 16'haa); + initial $display(":%-0o:", 16'haa); + initial $display(":%20o:", 16'haa); + initial $display(":%-20o:", 16'haa); + initial $display(":%020o:", 16'haa); + initial $display(":%-020o:", 16'haa); + + initial $display("==> big unsigned %%o"); + initial $display(":%o:", 16'haaaa); + initial $display(":%-o:", 16'haaaa); + initial $display(":%0o:", 16'haaaa); + initial $display(":%-0o:", 16'haaaa); + initial $display(":%20o:", 16'haaaa); + initial $display(":%-20o:", 16'haaaa); + initial $display(":%020o:", 16'haaaa); + initial $display(":%-020o:", 16'haaaa); + + initial $display("==> small signed %%o"); + initial $display(":%o:", 16'shaa); + initial $display(":%-o:", 16'shaa); + initial $display(":%0o:", 16'shaa); + initial $display(":%-0o:", 16'shaa); + initial $display(":%20o:", 16'shaa); + initial $display(":%-20o:", 16'shaa); + initial $display(":%020o:", 16'shaa); + initial $display(":%-020o:", 16'shaa); + + initial $display("==> big signed %%o"); + initial $display(":%o:", 16'shaaaa); + initial $display(":%-o:", 16'shaaaa); + initial $display(":%0o:", 16'shaaaa); + initial $display(":%-0o:", 16'shaaaa); + initial $display(":%20o:", 16'shaaaa); + initial $display(":%-20o:", 16'shaaaa); + initial $display(":%020o:", 16'shaaaa); + initial $display(":%-020o:", 16'shaaaa); + + initial $display("==> small unsigned %%b"); + initial $display(":%b:", 16'haa); + initial $display(":%-b:", 16'haa); + initial $display(":%0b:", 16'haa); + initial $display(":%-0b:", 16'haa); + initial $display(":%20b:", 16'haa); + initial $display(":%-20b:", 16'haa); + initial $display(":%020b:", 16'haa); + initial $display(":%-020b:", 16'haa); + + initial $display("==> big unsigned %%b"); + initial $display(":%b:", 16'haaaa); + initial $display(":%-b:", 16'haaaa); + initial $display(":%0b:", 16'haaaa); + initial $display(":%-0b:", 16'haaaa); + initial $display(":%20b:", 16'haaaa); + initial $display(":%-20b:", 16'haaaa); + initial $display(":%020b:", 16'haaaa); + initial $display(":%-020b:", 16'haaaa); + + initial $display("==> small signed %%b"); + initial $display(":%b:", 16'shaa); + initial $display(":%-b:", 16'shaa); + initial $display(":%0b:", 16'shaa); + initial $display(":%-0b:", 16'shaa); + initial $display(":%20b:", 16'shaa); + initial $display(":%-20b:", 16'shaa); + initial $display(":%020b:", 16'shaa); + initial $display(":%-020b:", 16'shaa); + + initial $display("==> big signed %%b"); + initial $display(":%b:", 16'shaaaa); + initial $display(":%-b:", 16'shaaaa); + initial $display(":%0b:", 16'shaaaa); + initial $display(":%-0b:", 16'shaaaa); + initial $display(":%20b:", 16'shaaaa); + initial $display(":%-20b:", 16'shaaaa); + initial $display(":%020b:", 16'shaaaa); + initial $display(":%-020b:", 16'shaaaa); + + initial $display("===> %%s"); + initial $display(":%10s:", "foo"); + initial $display(":%010s:", "foo"); + initial $display(":%-10s:", "foo"); + initial $display(":%-010s:", "foo"); + + initial $display("===> %%c"); + initial $display(":%10c:", "foo"); + initial $display(":%010c:", "foo"); + initial $display(":%-10c:", "foo"); + initial $display(":%-010c:", "foo"); + + initial $display("==> aliases"); + initial $display(":%x:", 16'shaa); + initial $display(":%X:", 16'shaa); + initial $display(":%H:", 16'shaa); + initial $display(":%O:", 16'shaa); + initial $display(":%B:", 16'shaa); + + initial $display("==> x/z"); + initial $display(":%d:", 16'b1010101010101010); + initial $display(":%d:", 16'b101010101010101x); + initial $display(":%d:", 16'b101010101010101z); + initial $display(":%x:", 16'b1010101010101010); + initial $display(":%x:", 16'b101010101010101x); + initial $display(":%x:", 16'b101010101010101z); + initial $display(":%x:", 16'b101010101010xxxx); + initial $display(":%x:", 16'b101010101010zzzz); + initial $display(":%o:", 16'b1010101010101010); + initial $display(":%o:", 16'b101010101010101x); + initial $display(":%o:", 16'b101010101010101z); + initial $display(":%o:", 16'b1010101010101xxx); + initial $display(":%o:", 16'b1010101010101zzz); + initial $display(":%b:", 16'b1010101010101010); + initial $display(":%b:", 16'b101010101010101x); + initial $display(":%b:", 16'b101010101010101z); + + initial $display("==> default base"); + initial $displayh(16'haa); + initial $displayo(16'haa); + initial $displayb(16'haa); + + initial $display("==> write/format"); + initial $display("%d", 1, "%d", 1); + // this one hits a bug in iverilog: + // initial $display("%s", $sformatf("%d", 1, "%d", 1)); + + initial $display("<<>>"); + +endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh new file mode 100644 index 00000000000..c6bd111b2e2 --- /dev/null +++ b/tests/fmt/run-test.sh @@ -0,0 +1,6 @@ +#!/bin/bash -eu + +../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log +iverilog -o iverilog-initial_display initial_display.v +./iverilog-initial_display >iverilog-initial_display.log +diff yosys-initial_display.log iverilog-initial_display.log From c28588068407b4e5eec33c6fd5c6f5c97b7ae9d4 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 6 Dec 2020 04:08:44 +0000 Subject: [PATCH 016/119] fmt: add tests for Verilog round trip of format expressions. --- tests/fmt/.gitignore | 3 ++- tests/fmt/always_display.v | 17 +++++++++++++++ tests/fmt/roundtrip.v | 22 ++++++++++++++++++++ tests/fmt/roundtrip_tb.v | 13 ++++++++++++ tests/fmt/run-test.sh | 42 +++++++++++++++++++++++++++++++++++++- 5 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/fmt/always_display.v create mode 100644 tests/fmt/roundtrip.v create mode 100644 tests/fmt/roundtrip_tb.v diff --git a/tests/fmt/.gitignore b/tests/fmt/.gitignore index 07043e54799..a36a15ec464 100644 --- a/tests/fmt/.gitignore +++ b/tests/fmt/.gitignore @@ -1,2 +1,3 @@ *.log -iverilog-initial_display* +iverilog-* +yosys-* diff --git a/tests/fmt/always_display.v b/tests/fmt/always_display.v new file mode 100644 index 00000000000..593c5afc08c --- /dev/null +++ b/tests/fmt/always_display.v @@ -0,0 +1,17 @@ +module m(input clk, rst, en, input [31:0] data); + +`ifdef EVENT_CLK + always @(posedge clk) +`endif +`ifdef EVENT_CLK_RST + always @(posedge clk or negedge rst) +`endif +`ifdef EVENT_STAR + always @(*) +`endif +`ifdef COND_EN + if (en) +`endif + $display("data=%d", data); + +endmodule diff --git a/tests/fmt/roundtrip.v b/tests/fmt/roundtrip.v new file mode 100644 index 00000000000..7b50039cd26 --- /dev/null +++ b/tests/fmt/roundtrip.v @@ -0,0 +1,22 @@ +module m(input clk, input `SIGN [31:0] data); + + always @(posedge clk) + // All on a single line to avoid order effects. +`ifdef BASE_DEC + $display(":%d:%-d:%+d:%+-d:%0d:%-0d:%+0d:%+-0d:%20d:%-20d:%+20d:%+-20d:%020d:%-020d:%+020d:%+-020d:", + data, data, data, data, data, data, data, data, data, data, data, data, data, data, data, data); +`endif +`ifdef BASE_HEX + $display(":%h:%-h:%0h:%-0h:%20h:%-20h:%020h:%-020h:", + data, data, data, data, data, data, data, data); +`endif +`ifdef BASE_OCT + $display(":%o:%-o:%0o:%-0o:%20o:%-20o:%020o:%-020o:", + data, data, data, data, data, data, data, data); +`endif +`ifdef BASE_BIN + $display(":%b:%-b:%0b:%-0b:%20b:%-20b:%020b:%-020b:", + data, data, data, data, data, data, data, data); +`endif + +endmodule diff --git a/tests/fmt/roundtrip_tb.v b/tests/fmt/roundtrip_tb.v new file mode 100644 index 00000000000..988b8d8c2c0 --- /dev/null +++ b/tests/fmt/roundtrip_tb.v @@ -0,0 +1,13 @@ +module tb; + reg clk = 1'b0; + reg [31:0] data; + + m dut(.clk(clk), .data(data)); + + initial begin + data = 32'haa; + #10; clk = 1; #10; clk = 0; + data = 32'haaaa; + #10; clk = 1; #10; clk = 0; + end +endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index c6bd111b2e2..850dbd53eed 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -1,6 +1,46 @@ -#!/bin/bash -eu +#!/bin/bash -ex ../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log iverilog -o iverilog-initial_display initial_display.v ./iverilog-initial_display >iverilog-initial_display.log diff yosys-initial_display.log iverilog-initial_display.log + +test_always_display () { + local subtest=$1; shift + ../../yosys $* always_display.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-1.v + ../../yosys yosys-always_display-${subtest}-1.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-2.v + diff yosys-always_display-${subtest}-1.v yosys-always_display-${subtest}-2.v +} + +test_always_display clk -DEVENT_CLK +test_always_display clk_rst -DEVENT_CLK_RST +test_always_display star -DEVENT_STAR + +test_always_display clk_en -DEVENT_CLK -DCOND_EN +test_always_display clk_rst_en -DEVENT_CLK_RST -DCOND_EN +test_always_display star_en -DEVENT_STAR -DCOND_EN + +test_roundtrip () { + local subtest=$1; shift + ../../yosys $* roundtrip.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-1.v + ../../yosys yosys-roundtrip-${subtest}-1.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-2.v + diff yosys-roundtrip-${subtest}-1.v yosys-roundtrip-${subtest}-2.v + + iverilog $* -o iverilog-roundtrip-${subtest} roundtrip.v roundtrip_tb.v + ./iverilog-roundtrip-${subtest} >iverilog-roundtrip-${subtest}.log + iverilog $* -o iverilog-roundtrip-${subtest}-1 yosys-roundtrip-${subtest}-1.v roundtrip_tb.v + ./iverilog-roundtrip-${subtest}-1 >iverilog-roundtrip-${subtest}-1.log + iverilog $* -o iverilog-roundtrip-${subtest}-2 yosys-roundtrip-${subtest}-2.v roundtrip_tb.v + ./iverilog-roundtrip-${subtest}-1 >iverilog-roundtrip-${subtest}-2.log + diff iverilog-roundtrip-${subtest}.log iverilog-roundtrip-${subtest}-1.log + diff iverilog-roundtrip-${subtest}-1.log iverilog-roundtrip-${subtest}-2.log +} + +test_roundtrip dec_unsigned -DBASE_DEC -DSIGN="" +test_roundtrip dec_signed -DBASE_DEC -DSIGN="signed" +test_roundtrip hex_unsigned -DBASE_HEX -DSIGN="" +test_roundtrip hex_signed -DBASE_HEX -DSIGN="signed" +test_roundtrip oct_unsigned -DBASE_HEX -DSIGN="" +test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" +test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" +test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" From 1eff84cb926c7916b6127badf2b7cec37a7a7e7f Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:50:45 +1000 Subject: [PATCH 017/119] fmt: ensure test exits on fail shebang not honoured when directly called with "bash run-test.sh". --- tests/fmt/run-test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 850dbd53eed..e3e9972b1a6 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex +#!/bin/bash + +set -ex ../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log iverilog -o iverilog-initial_display initial_display.v From 9db73aa87282bacc710be05c8455fd09308bbdf7 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:09 +1000 Subject: [PATCH 018/119] celltypes: add `$print` Otherwise, the \TRG connection is pruned by CleanZeroWidthPass. --- kernel/celltypes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 63e7408c142..4a0621a7386 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -101,6 +101,7 @@ struct CellTypes setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool(), true); setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool(), true); setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool(), true); + setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool()); } void setup_internals_eval() From 51d9b73107254dccc5b8efd3924f5a2372deaa74 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:11 +1000 Subject: [PATCH 019/119] fmt: tests completing again We need to invoke "read_verilog" manually, since the default action on input files is to defer processing. Under such conditions, we never simplify the AST, and initial $prints never execute. --- tests/fmt/run-test.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index e3e9972b1a6..0757d7f2ae5 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -2,15 +2,15 @@ set -ex -../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log +../../yosys -p 'read_verilog initial_display.v' | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log iverilog -o iverilog-initial_display initial_display.v ./iverilog-initial_display >iverilog-initial_display.log diff yosys-initial_display.log iverilog-initial_display.log test_always_display () { local subtest=$1; shift - ../../yosys $* always_display.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-1.v - ../../yosys yosys-always_display-${subtest}-1.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-2.v + ../../yosys -p "read_verilog $* always_display.v; proc; opt_expr -mux_bool; clean" -o yosys-always_display-${subtest}-1.v + ../../yosys -p "read_verilog yosys-always_display-${subtest}-1.v; proc; opt_expr -mux_bool; clean" -o yosys-always_display-${subtest}-2.v diff yosys-always_display-${subtest}-1.v yosys-always_display-${subtest}-2.v } @@ -24,8 +24,8 @@ test_always_display star_en -DEVENT_STAR -DCOND_EN test_roundtrip () { local subtest=$1; shift - ../../yosys $* roundtrip.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-1.v - ../../yosys yosys-roundtrip-${subtest}-1.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-2.v + ../../yosys -p "read_verilog $* roundtrip.v; proc; clean" -o yosys-roundtrip-${subtest}-1.v + ../../yosys -p "read_verilog yosys-roundtrip-${subtest}-1.v; proc; clean" -o yosys-roundtrip-${subtest}-2.v diff yosys-roundtrip-${subtest}-1.v yosys-roundtrip-${subtest}-2.v iverilog $* -o iverilog-roundtrip-${subtest} roundtrip.v roundtrip_tb.v From 28bd3a4b5d24742567049875ef7456cf0633f64c Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:12 +1000 Subject: [PATCH 020/119] fmt: don't overrun fmt string buffer For input like "{", "{1", etc., we would exit the loop due to `i < fmt.size()` no longer being the case, and then check if `++i == fmt.size()`. That would increment i to `fmt.size() + 1`, and so execution continues. The intention is to move i beyond the ':', so we do it only in that case instead. --- kernel/fmt.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 924a23a0c1e..b24fe59b277 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -55,12 +55,13 @@ void Fmt::parse_rtlil(RTLIL::Cell *cell) { arg_size *= 10; arg_size += fmt[i] - '0'; } else if (fmt[i] == ':') { + ++i; break; } else { log_assert(false && "Unexpected character in format substitution"); } } - if (++i == fmt.size()) + if (i == fmt.size()) log_assert(false && "Unexpected end in format substitution"); if ((size_t)args.size() < arg_size) From 3c8f84b70bc94fe64ce3ca014031a16e68ced773 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:13 +1000 Subject: [PATCH 021/119] fmt: fix another overrun --- kernel/fmt.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index b24fe59b277..0f5ebd94e83 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -107,9 +107,10 @@ void Fmt::parse_rtlil(RTLIL::Cell *cell) { } else { log_assert(false && "Unexpected character in format substitution"); } + ++i; break; } - if (++i == fmt.size()) + if (i == fmt.size()) log_assert(false && "Unexpected end in format substitution"); if (part.type == FmtPart::INTEGER) { From 289f8d42cb7d8a0e5948c1bec73ea7a47ad2c370 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:13 +1000 Subject: [PATCH 022/119] fmt: correct parsing of {{ and }} for brace literals --- kernel/fmt.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 0f5ebd94e83..952511eeb15 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -36,11 +36,13 @@ void Fmt::parse_rtlil(RTLIL::Cell *cell) { FmtPart part; for (size_t i = 0; i < fmt.size(); i++) { - if (fmt.substr(i, 2) == "}}") + if (fmt.substr(i, 2) == "}}") { part.str += '}'; - else if (fmt.substr(i, 2) == "{{") + ++i; + } else if (fmt.substr(i, 2) == "{{") { part.str += '{'; - else if (fmt[i] == '}') + ++i; + } else if (fmt[i] == '}') log_assert(false && "Unexpected '}' in format string"); else if (fmt[i] == '{') { if (!part.str.empty()) { From 2d7b8f71ccdb651cb1e12db2700ae7ece4cdb1a3 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:14 +1000 Subject: [PATCH 023/119] docs: first pass $print documentation --- docs/source/CHAPTER_CellLib.rst | 68 +++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index c8904086879..31d114854eb 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -627,6 +627,74 @@ Add information about ``$assert``, ``$assume``, ``$live``, ``$fair``, Add information about ``$ff`` and ``$_FF_`` cells. +Debugging cells +~~~~~~~~~~~~~~~ + +The ``$print`` cell is used to log the values of signals, akin to (and +translatable to) the ``$display`` and ``$write`` tasks in Verilog. It +has parameters: + +``\FORMAT`` + The internal format string. + +``\ARGS_WIDTH`` + The number of args referenced by the format string/in ``\ARGS`` port. + XXX is this actually bitwidth? + +``\TRG_ENABLE`` + True if only triggered on ``\TRG``; false if always. + +If ``\TRG_ENABLE`` is true: + +``\TRG_WIDTH`` + The number of bits in the ``\TRG`` port. + +``\TRG_POLARITY`` + A bitfield for each signal in ``\TRG``, 1 if STp (posedge), 0 if + STn (negedge). + +Ports: + +``\TRG`` + The signals defining when to print. + +``\EN`` + Enable signal for the whole cell. + +``\ARGS`` + The values to be displayed, in format string order. + +The format string has format specifiers as following: + +``{`` size ``:`` justify padding width? base options ``}`` + +size + Signal size in bits. + +justify + ``>`` for right-justified, ``<`` for left-justified. + +width + The number of characters wide to pad to. + +base + ``b`` for base-2 integers (binary), ``o`` for base-8 integers + (octal), ``d`` for base-10 integers (decimal), ``h`` for base-16 + integers (hexadecimal), or ``c`` for ASCII characters/strings. + +options + Only valid for integers, and is an optional ``+`` if a + leading plus should be included for non-negatives (decimals only), + an optional ``0`` if the number should be zero-padded to its signal + size before any padding/justification (non-decimals only), and then + either ``u`` or ``s`` to specify if the value should be treated as + unsigned or signed respectively. This distinction is only respected + when rendering decimals. + +Literal ``{`` and ``}`` are written as ``{{`` and ``}}``. + +Everything else is passed through unchanged. + .. _sec:celllib_gates: Gates From 1a222cb163ac88f95848cc8fd843011207e6b4ff Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:15 +1000 Subject: [PATCH 024/119] fmt: function name typo --- kernel/fmt.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 952511eeb15..68725c136f5 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -214,7 +214,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { cell->setPort(ID(ARGS), args); } -static size_t compute_requried_decimal_places(size_t size, bool signed_) +static size_t compute_required_decimal_places(size_t size, bool signed_) { BigUnsigned max; if (!signed_) @@ -234,7 +234,7 @@ static size_t compute_requried_decimal_places(size_t size, bool signed_) static void apply_verilog_automatic_sizing(FmtPart &part) { if (part.base == 10) { - size_t places = compute_requried_decimal_places(part.sig.size(), part.signed_); + size_t places = compute_required_decimal_places(part.sig.size(), part.signed_); part.padding = ' '; part.width = std::max(part.width, places); } else { From d9e4582558b84f0cacb64b3e4a1e5d67854ddbd2 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:15 +1000 Subject: [PATCH 025/119] fmt: handle part with unspecified padding in `emit_rtlil` e.g. `$displayh(8'ha)` won't have a padding set, because it just gets `lzero` set instead by `compute_required_decimal_places`. It also doesn't have a width. In this case, we can just fill in a dummy (unused) padding. Either space or zero would work, but space is a bit more distinct given the width field follows. Also omit writing the width if it's zero. This makes the emitted ilang a little cleaner in places; `{8:> h0u}` is the output for this example, now. The other possible extreme would be `{8:>00h0u}`. --- kernel/fmt.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 68725c136f5..41de4939230 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -183,9 +183,10 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { else if (part.justify == FmtPart::LEFT) fmt += '<'; else log_abort(); - log_assert(part.padding == '0' || part.padding == ' '); - fmt += part.padding; - fmt += std::to_string(part.width); + log_assert(part.width == 0 || part.padding != '\0'); + fmt += part.padding != '\0' ? part.padding : ' '; + if (part.width > 0) + fmt += std::to_string(part.width); if (part.type == FmtPart::INTEGER) { switch (part.base) { case 2: fmt += 'b'; break; From 202c3776e240557e7e283cd7c14502ab0caab53b Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:16 +1000 Subject: [PATCH 026/119] docs: elaborate $print documentation --- docs/source/CHAPTER_CellLib.rst | 109 ++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index 31d114854eb..0fae4f44b6f 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -631,32 +631,32 @@ Debugging cells ~~~~~~~~~~~~~~~ The ``$print`` cell is used to log the values of signals, akin to (and -translatable to) the ``$display`` and ``$write`` tasks in Verilog. It -has parameters: +translatable to) the ``$display`` and ``$write`` family of tasks in Verilog. It +has the following parameters: ``\FORMAT`` - The internal format string. + The internal format string. The syntax is described below. ``\ARGS_WIDTH`` - The number of args referenced by the format string/in ``\ARGS`` port. - XXX is this actually bitwidth? + The width (in bits) of the signal on the ``\ARGS`` port. ``\TRG_ENABLE`` - True if only triggered on ``\TRG``; false if always. + True if only triggered on specific signals defined in ``\TRG``; false if + executed on every step. -If ``\TRG_ENABLE`` is true: +If ``\TRG_ENABLE`` is true, the following parameters are also set: ``\TRG_WIDTH`` The number of bits in the ``\TRG`` port. ``\TRG_POLARITY`` - A bitfield for each signal in ``\TRG``, 1 if STp (posedge), 0 if - STn (negedge). + For each bit in ``\TRG``, 1 if that signal is positive-edge triggered, 0 if + negative-edge triggered. Ports: ``\TRG`` - The signals defining when to print. + The signals that control when this ``$print`` cell is triggered. ``\EN`` Enable signal for the whole cell. @@ -664,36 +664,89 @@ Ports: ``\ARGS`` The values to be displayed, in format string order. -The format string has format specifiers as following: +Format string syntax +^^^^^^^^^^^^^^^^^^^^ -``{`` size ``:`` justify padding width? base options ``}`` +The format string syntax resembles Python f-strings. Regular text is passed +through unchanged until a format specifier is reached, starting with a ``{``. + +Format specifiers have the following syntax. Unless noted, all items are +required: + +``{`` + Denotes the start of the format specifier. size - Signal size in bits. + Signal size in bits; this many bits are consumed from the ``\ARGS`` port by + this specifier. + +``:`` + Separates the size from the remaining items. justify ``>`` for right-justified, ``<`` for left-justified. -width - The number of characters wide to pad to. +padding + ``0`` for zero-padding, or a space for space-padding. + +width\ *?* + (optional) The number of characters wide to pad to. base - ``b`` for base-2 integers (binary), ``o`` for base-8 integers - (octal), ``d`` for base-10 integers (decimal), ``h`` for base-16 - integers (hexadecimal), or ``c`` for ASCII characters/strings. - -options - Only valid for integers, and is an optional ``+`` if a - leading plus should be included for non-negatives (decimals only), - an optional ``0`` if the number should be zero-padded to its signal - size before any padding/justification (non-decimals only), and then - either ``u`` or ``s`` to specify if the value should be treated as - unsigned or signed respectively. This distinction is only respected + * ``b`` for base-2 integers (binary) + * ``o`` for base-8 integers (octal) + * ``d`` for base-10 integers (decimal) + * ``h`` for base-16 integers (hexadecimal) + * ``c`` for ASCII characters/strings + +For integers, these items follow: + +``+``\ *?* + (optional, decimals only) Include a leading plus for non-negative numbers. + This can assist with symmetry with negatives in tabulated output. + +``0``\ *?* + (optional, non-decimals only) Zero-pad the number to fit the signal's + largest value before any further padding/justification. + +signedness + ``u`` for unsigned, ``s`` for signed. This distinction is only respected when rendering decimals. -Literal ``{`` and ``}`` are written as ``{{`` and ``}}``. +ASCII characters/strings have no special options, but the signal size must be +divisible by 8. + +Finally: + +``}`` + Denotes the end of the format specifier. + +Some example format specifiers: + ++ ``{8:>02hu}`` - 8-bit unsigned integer rendered as hexadecimal, + right-justified, zero-padded to 2 characters wide. ++ ``{32:< 15d+s}`` - 32-bit signed integer rendered as decimal, left-justified, + space-padded to 15 characters wide, positive values prefixed with ``+``. ++ ``{16:< 10h0u}`` - 16-bit unsigned integer rendered as hexadecimal, + zero-padded to fit the largest signal value (4 characters for hex), + left-justified, space-padded to 10 characters wide. + +To include literal ``{`` and ``}`` characters in your format string, use ``{{`` +and ``}}`` respectively. + +It is an error for a format string to consume more or less bits from ``\ARGS`` +than the port width. + +Note that further restrictions on allowable combinations of options may apply +depending on the backend used. + +For example, Verilog does not have a format specifier that allows zero-padding a +string (i.e. more than 1 ASCII character), though zero-padding a single +character is permitted. -Everything else is passed through unchanged. +Thus, while the RTLIL format specifier ``{8:>02c}`` translates to ``%02c``, +``{16:>02c}`` cannot be represented in Verilog and will fail to emit. In this +case, ``{16:> 02c}`` must be used, which translates to ``%2s``. .. _sec:celllib_gates: From 095b093f4a58794becba06939a10a530c6758f70 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:17 +1000 Subject: [PATCH 027/119] cxxrtl: first pass of $print impl --- backends/cxxrtl/cxxrtl.h | 237 ++++++++++++++++++++++++++++++ backends/cxxrtl/cxxrtl_backend.cc | 52 ++++++- kernel/fmt.cc | 63 +++++++- kernel/fmt.h | 4 +- 4 files changed, 353 insertions(+), 3 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 5d0596f0d61..6d955fe9bfb 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -518,6 +518,14 @@ struct value : public expr_base> { return count; } + size_t chunks_used() const { + for (size_t n = chunks; n > 0; n--) { + if (data[n - 1] != 0) + return n; + } + return 0; + } + template std::pair, bool /*CarryOut*/> alu(const value &other) const { value result; @@ -575,6 +583,140 @@ struct value : public expr_base> { result.data[result.chunks - 1] &= result.msb_mask; return result; } + + // parallel to BigUnsigned::divideWithRemainder; quotient is stored in q, + // *this is left with the remainder. See that function for commentary describing + // how/why this works. + void divideWithRemainder(const value &b, value &q) { + assert(this != &q); + + if (this == &b || &q == &b) { + value tmpB(b); + divideWithRemainder(tmpB, q); + return; + } + + q = value {0u}; + + size_t blen = b.chunks_used(); + if (blen == 0) { + return; + } + + size_t len = chunks_used(); + if (len < blen) { + return; + } + + size_t i, j, k; + size_t i2; + chunk_t temp; + bool borrowIn, borrowOut; + + size_t origLen = len; + len++; + chunk::type blk[len]; + std::copy(data, data + origLen, blk); + blk[origLen] = 0; + chunk::type subtractBuf[len]; + std::fill(subtractBuf, subtractBuf + len, 0); + + size_t qlen = origLen - blen + 1; + + i = qlen; + while (i > 0) { + i--; + i2 = chunk::bits; + while (i2 > 0) { + i2--; + for (j = 0, k = i, borrowIn = false; j <= blen; j++, k++) { + temp = blk[k] - getShiftedBlock(b, j, i2); + borrowOut = (temp > blk[k]); + if (borrowIn) { + borrowOut |= (temp == 0); + temp--; + } + subtractBuf[k] = temp; + borrowIn = borrowOut; + } + for (; k < origLen && borrowIn; k++) { + borrowIn = (blk[k] == 0); + subtractBuf[k] = blk[k] - 1; + } + if (!borrowIn) { + q.data[i] |= (chunk::type(1) << i2); + while (k > i) { + k--; + blk[k] = subtractBuf[k]; + } + } + } + } + + std::copy(blk, blk + origLen, data); + std::fill(blk + origLen, blk + chunks, 0); + } + + static chunk::type getShiftedBlock(const value &num, size_t x, size_t y) { + chunk::type part1 = (x == 0 || y == 0) ? 0 : (num.data[x - 1] >> (chunk::bits - y)); + chunk::type part2 = (x == num.chunks) ? 0 : (num.data[x] << y); + return part1 | part2; + } + + // parallel to BigInteger::divideWithRemainder; quotient is stored in q, + // *this is left with the remainder. See that function for commentary describing + // how/why this works. + void signedDivideWithRemainder(const value &b, value &q) { + assert(this != &q); + + if (this == &b || &q == &b) { + value tmpB(b); + signedDivideWithRemainder(tmpB, q); + return; + } + + if (b.is_zero()) { + q = value{0u}; + return; + } + + if (is_zero()) { + q = value{0u}; + return; + } + + // BigInteger has a separate 'mag' to its sign. We don't, so the lazy + // approach is to improvise said. + auto mag = *this; + bool neg = mag.is_neg(); + if (neg) + mag = mag.neg(); + + auto bmag = b; + bool bneg = bmag.is_neg(); + if (bneg) + bmag = bmag.neg(); + + bool qneg = false; + if (neg != b.is_neg()) { + qneg = true; + mag = mag.sub(value{1u}); + } + + mag.divideWithRemainder(bmag, q); + + if (neg != bneg) { + q = q.add(value{1u}); + mag = bmag.sub(mag); + mag = mag.sub(value{1u}); + } + + neg = bneg; + + *this = neg ? mag.neg() : mag; + if (qneg) + q = q.neg(); + } }; // Expression template for a slice, usable as lvalue or rvalue, and composable with other expression templates here. @@ -707,6 +849,101 @@ std::ostream &operator<<(std::ostream &os, const value &val) { return os; } +template +struct value_formatted { + const value &val; + bool character; + bool justify_left; + char padding; + int width; + int base; + bool signed_; + bool lzero; + bool plus; + + value_formatted(const value &val, bool character, bool justify_left, char padding, int width, int base, bool signed_, bool lzero, bool plus) : + val(val), character(character), justify_left(justify_left), padding(padding), width(width), base(base), signed_(signed_), lzero(lzero), plus(plus) {} + value_formatted(const value_formatted &) = delete; + value_formatted &operator=(const value_formatted &rhs) = delete; +}; + +template +std::ostream &operator<<(std::ostream &os, const value_formatted &vf) +{ + value val = vf.val; + + std::string buf; + + // We might want to replace some of these bit() calls with direct + // chunk access if it turns out to be slow enough to matter. + + if (!vf.character) { + size_t width = Bits; + if (!vf.lzero && vf.base != 10) { + width = 0; + for (size_t index = 0; index < Bits; index++) + if (val.bit(index)) + width = index + 1; + } + + if (vf.base == 2) { + for (size_t i = width; i > 0; i--) + buf += (val.bit(i - 1) ? '1' : '0'); + } else if (vf.base == 8 || vf.base == 16) { + size_t step = (vf.base == 16) ? 4 : 3; + for (size_t index = 0; index < width; index += step) { + uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2); + if (step == 4) + value |= val.bit(index + 3) << 3; + buf += "0123456789abcdef"[value]; + } + std::reverse(buf.begin(), buf.end()); + } else if (vf.base == 10) { + bool negative = vf.signed_ && val.is_neg(); + if (negative) + val = val.neg(); + if (val.is_zero()) + buf += '0'; + // TODO: rigorously check our signed behaviour here + while (!val.is_zero()) { + value quotient; + val.signedDivideWithRemainder(value{10u}, quotient); + buf += '0' + val.template slice<3, 0>().val().template get(); + val = quotient; + } + if (negative || vf.plus) + buf += negative ? '-' : '+'; + std::reverse(buf.begin(), buf.end()); + } else assert(false); + } else { + buf.reserve(Bits/8); + for (int i = 0; i < Bits; i += 8) { + char ch = 0; + for (int j = 0; j < 8 && i + j < int(Bits); j++) + if (val.bit(i + j)) + ch |= 1 << j; + if (ch != 0) + buf.append({ch}); + } + std::reverse(buf.begin(), buf.end()); + } + + assert(vf.width == 0 || vf.padding != '\0'); + if (!vf.justify_left && buf.size() < vf.width) { + size_t pad_width = vf.width - buf.size(); + if (vf.padding == '0' && (buf.front() == '+' || buf.front() == '-')) { + os << buf.front(); + buf.erase(0, 1); + } + os << std::string(pad_width, vf.padding); + } + os << buf; + if (vf.justify_left && buf.size() < vf.width) + os << std::string(vf.width - buf.size(), vf.padding); + + return os; +} + template struct wire { static constexpr size_t bits = Bits; diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 1b13985ab4e..4986836b9f8 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -24,6 +24,7 @@ #include "kernel/celltypes.h" #include "kernel/mem.h" #include "kernel/log.h" +#include "kernel/fmt.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -217,7 +218,7 @@ bool is_internal_cell(RTLIL::IdString type) bool is_effectful_cell(RTLIL::IdString type) { - return type.isPublic(); + return type.isPublic() || type == ID($print); } bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell) @@ -1036,6 +1037,17 @@ struct CxxrtlWorker { f << ".val()"; } + void dump_print(const RTLIL::Cell *cell) + { + Fmt fmt = {}; + fmt.parse_rtlil(cell); + + // TODO: we may want to configure the output stream + f << indent << "std::cout"; + fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); + f << ";\n"; + } + void dump_inlined_cells(const std::vector &cells) { if (cells.empty()) { @@ -1202,6 +1214,34 @@ struct CxxrtlWorker { f << " = "; dump_cell_expr(cell, for_debug); f << ";\n"; + // $print cell + } else if (cell->type == ID($print)) { + log_assert(!for_debug); + f << indent << "if ("; + if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + f << '('; + for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { + RTLIL::SigBit trg_bit = cell->getPort(ID::TRG)[i]; + trg_bit = sigmaps[trg_bit.wire->module](trg_bit); + log_assert(trg_bit.wire); + + if (i != 0) + f << " || "; + + if (cell->getParam(ID::TRG_POLARITY)[i] == State::S1) + f << "posedge_"; + else + f << "negedge_"; + f << mangle(trg_bit); + } + f << ") && "; + } + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << " == value<1>{1u}) {\n"; + inc_indent(); + dump_print(cell); + dec_indent(); + f << indent << "}\n"; // Flip-flops } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); @@ -2601,6 +2641,16 @@ struct CxxrtlWorker { register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } + + // $print cells may be triggered on posedge/negedge events. + if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) { + for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { + RTLIL::SigBit trg = cell->getPort(ID::TRG).extract(i, 1); + if (is_valid_clock(trg)) + register_edge_signal(sigmap, trg, + cell->parameters[ID::TRG_POLARITY][i] == RTLIL::S1 ? RTLIL::STp : RTLIL::STn); + } + } } for (auto &mem : memories) { diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 41de4939230..074ec08ca09 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -29,7 +29,7 @@ void Fmt::append_string(const std::string &str) { parts.push_back(part); } -void Fmt::parse_rtlil(RTLIL::Cell *cell) { +void Fmt::parse_rtlil(const RTLIL::Cell *cell) { std::string fmt = cell->getParam(ID(FORMAT)).decode_string(); RTLIL::SigSpec args = cell->getPort(ID(ARGS)); parts.clear(); @@ -465,6 +465,67 @@ std::vector Fmt::emit_verilog() const return args; } +void Fmt::emit_cxxrtl(std::ostream &f, std::function emit_sig) const +{ + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + f << " << \""; + for (char c : part.str) { + switch (c) { + case '\\': + YS_FALLTHROUGH + case '"': + f << '\\' << c; + break; + case '\a': + f << "\\a"; + break; + case '\b': + f << "\\b"; + break; + case '\f': + f << "\\f"; + break; + case '\n': + f << "\\n"; + break; + case '\r': + f << "\\r"; + break; + case '\t': + f << "\\t"; + break; + case '\v': + f << "\\v"; + break; + default: + f << c; + break; + } + } + f << '"'; + break; + + case FmtPart::INTEGER: + case FmtPart::CHARACTER: { + f << " << value_formatted<" << part.sig.size() << ">("; + emit_sig(part.sig); + f << ", " << (part.type == FmtPart::CHARACTER); + f << ", " << (part.justify == FmtPart::LEFT); + f << ", (char)" << (int)part.padding; + f << ", " << part.width; + f << ", " << part.base; + f << ", " << part.signed_; + f << ", " << part.lzero; + f << ", " << part.plus; + f << ')'; + break; + } + } + } +} + std::string Fmt::render() const { std::string str; diff --git a/kernel/fmt.h b/kernel/fmt.h index c85da19c01b..00b8d9b594e 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -76,12 +76,14 @@ struct Fmt { void append_string(const std::string &str); - void parse_rtlil(RTLIL::Cell *cell); + void parse_rtlil(const RTLIL::Cell *cell); void emit_rtlil(RTLIL::Cell *cell) const; void parse_verilog(const std::vector &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name); std::vector emit_verilog() const; + void emit_cxxrtl(std::ostream &f, std::function emit_sig) const; + std::string render() const; }; From b0f69f2cd5fa37c8b6eaf7b30a3c9297af87bf58 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:18 +1000 Subject: [PATCH 028/119] tests: test cxxrtl against iverilog (and uncover bug!) --- kernel/fmt.h | 2 +- tests/fmt/always_full.v | 239 ++++++++++++++++++++++++++++++++++++ tests/fmt/always_full_tb.cc | 15 +++ tests/fmt/always_full_tb.v | 14 +++ tests/fmt/run-test.sh | 7 ++ 5 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 tests/fmt/always_full.v create mode 100644 tests/fmt/always_full_tb.cc create mode 100644 tests/fmt/always_full_tb.v diff --git a/kernel/fmt.h b/kernel/fmt.h index 00b8d9b594e..647fe3a8119 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -45,7 +45,7 @@ struct VerilogFmtArg { }; // RTLIL format part, such as the substitutions in: -// "foo {4: 4du} bar {2:01xs}" +// "foo {4:> 4du} bar {2:<01hs}" struct FmtPart { enum { STRING = 0, diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v new file mode 100644 index 00000000000..5e3b17e9c43 --- /dev/null +++ b/tests/fmt/always_full.v @@ -0,0 +1,239 @@ +module always_full(input clk, output reg fin); + + reg [7:0] counter = 0; + + always @(posedge clk) begin + + counter <= counter + 1; + + if (counter == 0) fin <= 0; + + if (counter == 1) $display("<<>>"); + + if (counter == 2) $display("==> small unsigned %%d"); + if (counter == 3) $display(":%d:", 16'haa); + if (counter == 4) $display(":%-d:", 16'haa); + if (counter == 5) $display(":%+d:", 16'haa); + if (counter == 6) $display(":%+-d:", 16'haa); + if (counter == 7) $display(":%0d:", 16'haa); + if (counter == 8) $display(":%-0d:", 16'haa); + if (counter == 9) $display(":%+0d:", 16'haa); + if (counter == 10) $display(":%+-0d:", 16'haa); + if (counter == 11) $display(":%20d:", 16'haa); + if (counter == 12) $display(":%-20d:", 16'haa); + if (counter == 13) $display(":%+20d:", 16'haa); + if (counter == 14) $display(":%+-20d:", 16'haa); + if (counter == 15) $display(":%020d:", 16'haa); + if (counter == 16) $display(":%-020d:", 16'haa); + if (counter == 17) $display(":%+020d:", 16'haa); + if (counter == 18) $display(":%+-020d:", 16'haa); + + if (counter == 19) $display("==> big unsigned %%d"); + if (counter == 20) $display(":%d:", 16'haaaa); + if (counter == 21) $display(":%-d:", 16'haaaa); + if (counter == 22) $display(":%+d:", 16'haaaa); + if (counter == 23) $display(":%+-d:", 16'haaaa); + if (counter == 24) $display(":%0d:", 16'haaaa); + if (counter == 25) $display(":%-0d:", 16'haaaa); + if (counter == 26) $display(":%+0d:", 16'haaaa); + if (counter == 27) $display(":%+-0d:", 16'haaaa); + if (counter == 28) $display(":%20d:", 16'haaaa); + if (counter == 29) $display(":%-20d:", 16'haaaa); + if (counter == 30) $display(":%+20d:", 16'haaaa); + if (counter == 31) $display(":%+-20d:", 16'haaaa); + if (counter == 32) $display(":%020d:", 16'haaaa); + if (counter == 33) $display(":%-020d:", 16'haaaa); + if (counter == 34) $display(":%+020d:", 16'haaaa); + if (counter == 35) $display(":%+-020d:", 16'haaaa); + + if (counter == 36) $display("==> small signed %%d"); + if (counter == 37) $display(":%d:", 16'shaa); + if (counter == 38) $display(":%-d:", 16'shaa); + if (counter == 39) $display(":%+d:", 16'shaa); + if (counter == 40) $display(":%+-d:", 16'shaa); + if (counter == 41) $display(":%0d:", 16'shaa); + if (counter == 42) $display(":%-0d:", 16'shaa); + if (counter == 43) $display(":%+0d:", 16'shaa); + if (counter == 44) $display(":%+-0d:", 16'shaa); + if (counter == 45) $display(":%20d:", 16'shaa); + if (counter == 46) $display(":%-20d:", 16'shaa); + if (counter == 47) $display(":%+20d:", 16'shaa); + if (counter == 48) $display(":%+-20d:", 16'shaa); + if (counter == 49) $display(":%020d:", 16'shaa); + if (counter == 50) $display(":%-020d:", 16'shaa); + if (counter == 51) $display(":%+020d:", 16'shaa); + if (counter == 52) $display(":%+-020d:", 16'shaa); + + if (counter == 53) $display("==> big signed %%d"); + if (counter == 54) $display(":%d:", 16'shaaaa); + if (counter == 55) $display(":%-d:", 16'shaaaa); + if (counter == 56) $display(":%+d:", 16'shaaaa); + if (counter == 57) $display(":%+-d:", 16'shaaaa); + if (counter == 58) $display(":%0d:", 16'shaaaa); + if (counter == 59) $display(":%-0d:", 16'shaaaa); + if (counter == 60) $display(":%+0d:", 16'shaaaa); + if (counter == 61) $display(":%+-0d:", 16'shaaaa); + if (counter == 62) $display(":%20d:", 16'shaaaa); + if (counter == 63) $display(":%-20d:", 16'shaaaa); + if (counter == 64) $display(":%+20d:", 16'shaaaa); + if (counter == 65) $display(":%+-20d:", 16'shaaaa); + if (counter == 66) $display(":%020d:", 16'shaaaa); + if (counter == 67) $display(":%-020d:", 16'shaaaa); + if (counter == 68) $display(":%+020d:", 16'shaaaa); + if (counter == 69) $display(":%+-020d:", 16'shaaaa); + + if (counter == 70) $display("==> small unsigned %%h"); + if (counter == 71) $display(":%h:", 16'haa); + if (counter == 72) $display(":%-h:", 16'haa); + if (counter == 73) $display(":%0h:", 16'haa); + if (counter == 74) $display(":%-0h:", 16'haa); + if (counter == 75) $display(":%20h:", 16'haa); + if (counter == 76) $display(":%-20h:", 16'haa); + if (counter == 77) $display(":%020h:", 16'haa); + if (counter == 78) $display(":%-020h:", 16'haa); + + if (counter == 79) $display("==> big unsigned %%h"); + if (counter == 80) $display(":%h:", 16'haaaa); + if (counter == 81) $display(":%-h:", 16'haaaa); + if (counter == 82) $display(":%0h:", 16'haaaa); + if (counter == 83) $display(":%-0h:", 16'haaaa); + if (counter == 84) $display(":%20h:", 16'haaaa); + if (counter == 85) $display(":%-20h:", 16'haaaa); + if (counter == 86) $display(":%020h:", 16'haaaa); + if (counter == 87) $display(":%-020h:", 16'haaaa); + + if (counter == 88) $display("==> small signed %%h"); + if (counter == 89) $display(":%h:", 16'shaa); + if (counter == 90) $display(":%-h:", 16'shaa); + if (counter == 91) $display(":%0h:", 16'shaa); + if (counter == 92) $display(":%-0h:", 16'shaa); + if (counter == 93) $display(":%20h:", 16'shaa); + if (counter == 94) $display(":%-20h:", 16'shaa); + if (counter == 95) $display(":%020h:", 16'shaa); + if (counter == 96) $display(":%-020h:", 16'shaa); + + if (counter == 97) $display("==> big signed %%h"); + if (counter == 98) $display(":%h:", 16'shaaaa); + if (counter == 99) $display(":%-h:", 16'shaaaa); + if (counter == 100) $display(":%0h:", 16'shaaaa); + if (counter == 101) $display(":%-0h:", 16'shaaaa); + if (counter == 102) $display(":%20h:", 16'shaaaa); + if (counter == 103) $display(":%-20h:", 16'shaaaa); + if (counter == 104) $display(":%020h:", 16'shaaaa); + if (counter == 105) $display(":%-020h:", 16'shaaaa); + + if (counter == 106) $display("==> small unsigned %%o"); + if (counter == 107) $display(":%o:", 16'haa); + if (counter == 108) $display(":%-o:", 16'haa); + if (counter == 109) $display(":%0o:", 16'haa); + if (counter == 110) $display(":%-0o:", 16'haa); + if (counter == 111) $display(":%20o:", 16'haa); + if (counter == 112) $display(":%-20o:", 16'haa); + if (counter == 113) $display(":%020o:", 16'haa); + if (counter == 114) $display(":%-020o:", 16'haa); + + if (counter == 115) $display("==> big unsigned %%o"); + if (counter == 116) $display(":%o:", 16'haaaa); + if (counter == 117) $display(":%-o:", 16'haaaa); + if (counter == 118) $display(":%0o:", 16'haaaa); + if (counter == 119) $display(":%-0o:", 16'haaaa); + if (counter == 120) $display(":%20o:", 16'haaaa); + if (counter == 121) $display(":%-20o:", 16'haaaa); + if (counter == 122) $display(":%020o:", 16'haaaa); + if (counter == 123) $display(":%-020o:", 16'haaaa); + + if (counter == 124) $display("==> small signed %%o"); + if (counter == 125) $display(":%o:", 16'shaa); + if (counter == 126) $display(":%-o:", 16'shaa); + if (counter == 127) $display(":%0o:", 16'shaa); + if (counter == 128) $display(":%-0o:", 16'shaa); + if (counter == 129) $display(":%20o:", 16'shaa); + if (counter == 130) $display(":%-20o:", 16'shaa); + if (counter == 131) $display(":%020o:", 16'shaa); + if (counter == 132) $display(":%-020o:", 16'shaa); + + if (counter == 133) $display("==> big signed %%o"); + if (counter == 134) $display(":%o:", 16'shaaaa); + if (counter == 135) $display(":%-o:", 16'shaaaa); + if (counter == 136) $display(":%0o:", 16'shaaaa); + if (counter == 137) $display(":%-0o:", 16'shaaaa); + if (counter == 138) $display(":%20o:", 16'shaaaa); + if (counter == 139) $display(":%-20o:", 16'shaaaa); + if (counter == 140) $display(":%020o:", 16'shaaaa); + if (counter == 141) $display(":%-020o:", 16'shaaaa); + + if (counter == 142) $display("==> small unsigned %%b"); + if (counter == 143) $display(":%b:", 16'haa); + if (counter == 144) $display(":%-b:", 16'haa); + if (counter == 145) $display(":%0b:", 16'haa); + if (counter == 146) $display(":%-0b:", 16'haa); + if (counter == 147) $display(":%20b:", 16'haa); + if (counter == 148) $display(":%-20b:", 16'haa); + if (counter == 149) $display(":%020b:", 16'haa); + if (counter == 150) $display(":%-020b:", 16'haa); + + if (counter == 151) $display("==> big unsigned %%b"); + if (counter == 152) $display(":%b:", 16'haaaa); + if (counter == 153) $display(":%-b:", 16'haaaa); + if (counter == 154) $display(":%0b:", 16'haaaa); + if (counter == 155) $display(":%-0b:", 16'haaaa); + if (counter == 156) $display(":%20b:", 16'haaaa); + if (counter == 157) $display(":%-20b:", 16'haaaa); + if (counter == 158) $display(":%020b:", 16'haaaa); + if (counter == 159) $display(":%-020b:", 16'haaaa); + + if (counter == 160) $display("==> small signed %%b"); + if (counter == 161) $display(":%b:", 16'shaa); + if (counter == 162) $display(":%-b:", 16'shaa); + if (counter == 163) $display(":%0b:", 16'shaa); + if (counter == 164) $display(":%-0b:", 16'shaa); + if (counter == 165) $display(":%20b:", 16'shaa); + if (counter == 166) $display(":%-20b:", 16'shaa); + if (counter == 167) $display(":%020b:", 16'shaa); + if (counter == 168) $display(":%-020b:", 16'shaa); + + if (counter == 169) $display("==> big signed %%b"); + if (counter == 170) $display(":%b:", 16'shaaaa); + if (counter == 171) $display(":%-b:", 16'shaaaa); + if (counter == 172) $display(":%0b:", 16'shaaaa); + if (counter == 173) $display(":%-0b:", 16'shaaaa); + if (counter == 174) $display(":%20b:", 16'shaaaa); + if (counter == 175) $display(":%-20b:", 16'shaaaa); + if (counter == 176) $display(":%020b:", 16'shaaaa); + if (counter == 177) $display(":%-020b:", 16'shaaaa); + + if (counter == 178) $display("===> %%s"); + if (counter == 179) $display(":%10s:", "foo"); + if (counter == 180) $display(":%010s:", "foo"); + if (counter == 181) $display(":%-10s:", "foo"); + if (counter == 182) $display(":%-010s:", "foo"); + + if (counter == 183) $display("===> %%c"); + if (counter == 184) $display(":%10c:", "foo"); + if (counter == 185) $display(":%010c:", "foo"); + if (counter == 186) $display(":%-10c:", "foo"); + if (counter == 187) $display(":%-010c:", "foo"); + + if (counter == 188) $display("==> aliases"); + if (counter == 189) $display(":%x:", 16'shaa); + if (counter == 190) $display(":%X:", 16'shaa); + if (counter == 191) $display(":%H:", 16'shaa); + if (counter == 192) $display(":%O:", 16'shaa); + if (counter == 193) $display(":%B:", 16'shaa); + + if (counter == 194) $display("==> default base"); + if (counter == 195) $displayh(16'haa); + if (counter == 196) $displayo(16'haa); + if (counter == 197) $displayb(16'haa); + + if (counter == 198) $display("==> write/format"); + if (counter == 199) $display("%d", 1, "%d", 1); + + if (counter == 200) begin + $display("<<>>"); + fin <= 1; + end + + end + +endmodule diff --git a/tests/fmt/always_full_tb.cc b/tests/fmt/always_full_tb.cc new file mode 100644 index 00000000000..8bf1022d330 --- /dev/null +++ b/tests/fmt/always_full_tb.cc @@ -0,0 +1,15 @@ +#include +#include "yosys-always_full.cc" + +int main() +{ + cxxrtl_design::p_always__full uut; + + while (true) { + uut.p_clk.set(!uut.p_clk); + uut.step(); + + if (uut.p_fin.get()) + return 0; + } +} diff --git a/tests/fmt/always_full_tb.v b/tests/fmt/always_full_tb.v new file mode 100644 index 00000000000..1edd35b67d9 --- /dev/null +++ b/tests/fmt/always_full_tb.v @@ -0,0 +1,14 @@ +module always_full_tb; + + reg clk = 0; + wire fin; + + always_full uut (.clk(clk), .fin(fin)); + + always begin + #1 clk <= ~clk; + + if (fin) $finish; + end + +endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 0757d7f2ae5..aa9c8fe7b8c 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -46,3 +46,10 @@ test_roundtrip oct_unsigned -DBASE_HEX -DSIGN="" test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" + +../../yosys -p "read_verilog always_full.v; write_cxxrtl yosys-always_full.cc" +${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc +./yosys-always_full >yosys-always_full.log +iverilog -o iverilog-always_full always_full.v always_full_tb.v +./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log +diff iverilog-always_full.log yosys-always_full.log From 52dc397a5085c360b6ac2e9538f96ba3e7956113 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:19 +1000 Subject: [PATCH 029/119] cxxrtl: don't use signed divide with unsigned/pos values Incorrect for unsigned, wasted effort for positive signed. --- backends/cxxrtl/cxxrtl.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 6d955fe9bfb..c7a6321056c 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -904,10 +904,12 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) val = val.neg(); if (val.is_zero()) buf += '0'; - // TODO: rigorously check our signed behaviour here while (!val.is_zero()) { value quotient; - val.signedDivideWithRemainder(value{10u}, quotient); + if (negative) + val.signedDivideWithRemainder(value{10u}, quotient); + else + val.divideWithRemainder(value{10u}, quotient); buf += '0' + val.template slice<3, 0>().val().template get(); val = quotient; } From c382d7d3ac2b713c5b3f55e81430e121520a1787 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:20 +1000 Subject: [PATCH 030/119] fmt: %t/$time support --- backends/cxxrtl/cxxrtl.h | 3 ++ backends/verilog/verilog_backend.cc | 6 +++ frontends/ast/genrtlil.cc | 5 ++ frontends/verilog/verilog_lexer.l | 2 +- kernel/fmt.cc | 74 ++++++++++++++++++++++++++++- kernel/fmt.h | 13 ++++- tests/fmt/always_full.v | 66 ++++++++++++++----------- 7 files changed, 138 insertions(+), 31 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index c7a6321056c..8ea800ed93f 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -1330,7 +1330,10 @@ struct module { virtual bool eval() = 0; virtual bool commit() = 0; + unsigned int steps = 0; + size_t step() { + ++steps; size_t deltas = 0; bool converged = false; do { diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a6fd859a396..573fa6d5b84 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1797,6 +1797,12 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) dump_sigspec(f, arg.sig); f << ")"; break; + case VerilogFmtArg::TIME: + if (arg.realtime) + f << "$realtime"; + else + f << "$time"; + break; default: log_abort(); } } diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 40e71e8bd20..2e2d0de74bf 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -748,6 +748,11 @@ struct AST_INTERNAL::ProcessGenerator // and in case this will be used as an argument... arg.sig = node->bitsAsConst(); arg.signed_ = false; + } else if (node->type == AST_IDENTIFIER && node->str == "$time") { + arg.type = VerilogFmtArg::TIME; + } else if (node->type == AST_IDENTIFIER && node->str == "$realtime") { + arg.type = VerilogFmtArg::TIME; + arg.realtime = true; } else { arg.type = VerilogFmtArg::INTEGER; arg.sig = node->genRTLIL(); diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 89ccee788c9..8a37343022f 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -386,7 +386,7 @@ and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 { supply0 { return TOK_SUPPLY0; } supply1 { return TOK_SUPPLY1; } -"$"(display[bho]?|write[bho]?|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { +"$"(display[bho]?|write[bho]?|strobe|monitor|time|realtime|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { yylval->string = new std::string(yytext); return TOK_ID; } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 074ec08ca09..d72d60ba8b2 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -51,8 +51,11 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part = {}; } + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + size_t arg_size = 0; - for (++i; i < fmt.size(); i++) { + for (; i < fmt.size(); i++) { if (fmt[i] >= '0' && fmt[i] <= '9') { arg_size *= 10; arg_size += fmt[i] - '0'; @@ -106,6 +109,11 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part.base = 16; } else if (fmt[i] == 'c') { part.type = FmtPart::CHARACTER; + } else if (fmt[i] == 't') { + part.type = FmtPart::TIME; + } else if (fmt[i] == 'r') { + part.type = FmtPart::TIME; + part.realtime = true; } else { log_assert(false && "Unexpected character in format substitution"); } @@ -170,6 +178,9 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { } break; + case FmtPart::TIME: + log_assert(part.sig.size() == 0); + YS_FALLTHROUGH case FmtPart::CHARACTER: log_assert(part.sig.size() % 8 == 0); YS_FALLTHROUGH @@ -202,6 +213,11 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { fmt += part.signed_ ? 's' : 'u'; } else if (part.type == FmtPart::CHARACTER) { fmt += 'c'; + } else if (part.type == FmtPart::TIME) { + if (part.realtime) + fmt += 'r'; + else + fmt += 't'; } else log_abort(); fmt += '}'; break; @@ -339,6 +355,15 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part.sig.extend_u0((part.sig.size() + 7) / 8 * 8); // %10s and %010s not fully defined in IEEE 1800-2017 and do the same thing in iverilog part.padding = ' '; + } else if (fmt[i] == 't' || fmt[i] == 'T') { + if (arg->type == VerilogFmtArg::TIME) { + part.type = FmtPart::TIME; + part.realtime = arg->realtime; + if (!has_width && !has_leading_zero) + part.width = 20; + } else { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); + } } else { log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); } @@ -458,6 +483,28 @@ std::vector Fmt::emit_verilog() const } break; } + + case FmtPart::TIME: { + VerilogFmtArg arg; + arg.type = VerilogFmtArg::TIME; + if (part.realtime) + arg.realtime = true; + args.push_back(arg); + + fmt.str += '%'; + if (part.plus) + fmt.str += '+'; + if (part.justify == FmtPart::LEFT) + fmt.str += '-'; + log_assert(part.padding == ' ' || part.padding == '0'); + if (part.padding == '0' && part.width > 0) + fmt.str += '0'; + fmt.str += std::to_string(part.width); + fmt.str += 't'; + break; + } + + default: log_abort(); } } @@ -522,6 +569,25 @@ void Fmt::emit_cxxrtl(std::ostream &f, std::function("; + f << "value<64>{steps}"; + f << ", " << (part.type == FmtPart::CHARACTER); + f << ", " << (part.justify == FmtPart::LEFT); + f << ", (char)" << (int)part.padding; + f << ", " << part.width; + f << ", " << part.base; + f << ", " << part.signed_; + f << ", " << part.lzero; + f << ", " << part.plus; + f << ')'; + break; + } + + default: log_abort(); } } } @@ -636,6 +702,12 @@ std::string Fmt::render() const str += std::string(part.width - buf.size(), part.padding); break; } + + case FmtPart::TIME: { + // We only render() during initial, so time is always zero. + str += "0"; + break; + } } } diff --git a/kernel/fmt.h b/kernel/fmt.h index 647fe3a8119..0d730074399 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -30,6 +30,7 @@ struct VerilogFmtArg { enum { STRING = 0, INTEGER = 1, + TIME = 2, } type; // All types @@ -42,6 +43,9 @@ struct VerilogFmtArg { // INTEGER type RTLIL::SigSpec sig; bool signed_ = false; + + // TIME type + bool realtime = false; }; // RTLIL format part, such as the substitutions in: @@ -51,24 +55,31 @@ struct FmtPart { STRING = 0, INTEGER = 1, CHARACTER = 2, + TIME = 3, } type; // STRING type std::string str; - // INTEGER/CHARACTER type + // INTEGER/CHARACTER types RTLIL::SigSpec sig; + + // INTEGER/CHARACTER/TIME types enum { RIGHT = 0, LEFT = 1, } justify = RIGHT; char padding = '\0'; size_t width = 0; + // INTEGER type unsigned base = 10; bool signed_ = false; bool lzero = false; bool plus = false; + + // TIME type + bool realtime = false; }; struct Fmt { diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v index 5e3b17e9c43..3727813543c 100644 --- a/tests/fmt/always_full.v +++ b/tests/fmt/always_full.v @@ -202,34 +202,44 @@ module always_full(input clk, output reg fin); if (counter == 176) $display(":%020b:", 16'shaaaa); if (counter == 177) $display(":%-020b:", 16'shaaaa); - if (counter == 178) $display("===> %%s"); - if (counter == 179) $display(":%10s:", "foo"); - if (counter == 180) $display(":%010s:", "foo"); - if (counter == 181) $display(":%-10s:", "foo"); - if (counter == 182) $display(":%-010s:", "foo"); - - if (counter == 183) $display("===> %%c"); - if (counter == 184) $display(":%10c:", "foo"); - if (counter == 185) $display(":%010c:", "foo"); - if (counter == 186) $display(":%-10c:", "foo"); - if (counter == 187) $display(":%-010c:", "foo"); - - if (counter == 188) $display("==> aliases"); - if (counter == 189) $display(":%x:", 16'shaa); - if (counter == 190) $display(":%X:", 16'shaa); - if (counter == 191) $display(":%H:", 16'shaa); - if (counter == 192) $display(":%O:", 16'shaa); - if (counter == 193) $display(":%B:", 16'shaa); - - if (counter == 194) $display("==> default base"); - if (counter == 195) $displayh(16'haa); - if (counter == 196) $displayo(16'haa); - if (counter == 197) $displayb(16'haa); - - if (counter == 198) $display("==> write/format"); - if (counter == 199) $display("%d", 1, "%d", 1); - - if (counter == 200) begin + if (counter == 178) $display("==> time %%t"); + if (counter == 179) $display(":%t:", $time); + if (counter == 180) $display(":%-t:", $time); + if (counter == 181) $display(":%0t:", $time); + if (counter == 182) $display(":%-0t:", $time); + if (counter == 183) $display(":%10t:", $time); + if (counter == 184) $display(":%-10t:", $time); + if (counter == 185) $display(":%015t:", $time); + if (counter == 186) $display(":%-015t:", $time); + + if (counter == 187) $display("===> %%s"); + if (counter == 188) $display(":%10s:", "foo"); + if (counter == 189) $display(":%010s:", "foo"); + if (counter == 190) $display(":%-10s:", "foo"); + if (counter == 191) $display(":%-010s:", "foo"); + + if (counter == 192) $display("===> %%c"); + if (counter == 193) $display(":%10c:", "foo"); + if (counter == 194) $display(":%010c:", "foo"); + if (counter == 195) $display(":%-10c:", "foo"); + if (counter == 196) $display(":%-010c:", "foo"); + + if (counter == 197) $display("==> aliases"); + if (counter == 198) $display(":%x:", 16'shaa); + if (counter == 199) $display(":%X:", 16'shaa); + if (counter == 200) $display(":%H:", 16'shaa); + if (counter == 201) $display(":%O:", 16'shaa); + if (counter == 202) $display(":%B:", 16'shaa); + + if (counter == 203) $display("==> default base"); + if (counter == 204) $displayh(16'haa); + if (counter == 205) $displayo(16'haa); + if (counter == 206) $displayb(16'haa); + + if (counter == 207) $display("==> write/format"); + if (counter == 208) $display("%d", 1, "%d", 1); + + if (counter == 209) begin $display("<<>>"); fin <= 1; end From 75b44f21d1ff0c79f64e4ec3d2c10d4bb93fdefe Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:21 +1000 Subject: [PATCH 031/119] fmt: rudimentary %m support (= %l) --- kernel/fmt.cc | 3 +++ tests/fmt/display_lm.v | 12 ++++++++++++ tests/fmt/display_lm_tb.cc | 10 ++++++++++ tests/fmt/run-test.sh | 9 +++++++++ 4 files changed, 34 insertions(+) create mode 100644 tests/fmt/display_lm.v create mode 100644 tests/fmt/display_lm_tb.cc diff --git a/kernel/fmt.cc b/kernel/fmt.cc index d72d60ba8b2..9d9e95ac392 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -291,6 +291,9 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik } else if (fmt.substr(i, 2) == "%l" || fmt.substr(i, 2) == "%L") { i++; part.str += module_name.str(); + } else if (fmt.substr(i, 2) == "%m" || fmt.substr(i, 2) == "%M") { + i++; + part.str += module_name.str(); } else { if (!part.str.empty()) { part.type = FmtPart::STRING; diff --git a/tests/fmt/display_lm.v b/tests/fmt/display_lm.v new file mode 100644 index 00000000000..d96f233f064 --- /dev/null +++ b/tests/fmt/display_lm.v @@ -0,0 +1,12 @@ +module top; + mid mid_uut (); +endmodule + +module mid (); + bot bot_uut (); +endmodule + +module bot (); + initial $display("%%l: %l\n%%m: %m"); + always $display("%%l: %l\n%%m: %m"); +endmodule diff --git a/tests/fmt/display_lm_tb.cc b/tests/fmt/display_lm_tb.cc new file mode 100644 index 00000000000..ebc62f80fad --- /dev/null +++ b/tests/fmt/display_lm_tb.cc @@ -0,0 +1,10 @@ +#include +#include "yosys-display_lm.cc" + +int main() +{ + cxxrtl_design::p_top uut; + + uut.step(); + return 0; +} diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index aa9c8fe7b8c..2568e27764d 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -53,3 +53,12 @@ ${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log diff iverilog-always_full.log yosys-always_full.log + +../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log +../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" +${CXX:-g++} -o yosys-display_lm_cc -I../.. display_lm_tb.cc +./yosys-display_lm_cc >yosys-display_lm_cc.log +for log in yosys-display_lm.log yosys-display_lm_cc.log; do + grep "^%l: \\\\bot\$" "$log" + grep "^%m: \\\\bot\$" "$log" +done From c391ee7a0d5be7d1fba0da1cd02da14138afdb35 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:22 +1000 Subject: [PATCH 032/119] docs: document simulation time format specifiers --- docs/source/CHAPTER_CellLib.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index 0fae4f44b6f..a4f986f7590 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -698,6 +698,7 @@ base * ``d`` for base-10 integers (decimal) * ``h`` for base-16 integers (hexadecimal) * ``c`` for ASCII characters/strings + * ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and :verilog:`$realtime`) For integers, these items follow: @@ -716,6 +717,8 @@ signedness ASCII characters/strings have no special options, but the signal size must be divisible by 8. +For simulation time, the signal size must be zero. + Finally: ``}`` @@ -730,6 +733,8 @@ Some example format specifiers: + ``{16:< 10h0u}`` - 16-bit unsigned integer rendered as hexadecimal, zero-padded to fit the largest signal value (4 characters for hex), left-justified, space-padded to 10 characters wide. ++ ``{0:>010t}`` - simulation time, right-justified, zero-padded to 10 characters + wide. To include literal ``{`` and ``}`` characters in your format string, use ``{{`` and ``}}`` respectively. From 9f9561379b10776d2e4ad6fcc7ec821ec208ae4c Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:22 +1000 Subject: [PATCH 033/119] fmt: format %t consistently at initial --- frontends/ast/simplify.cc | 13 +++++++++---- kernel/fmt.cc | 10 ++++------ tests/fmt/initial_display.v | 10 ++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 19e62668b9e..ee1be3781c8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -48,22 +48,27 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_ for (size_t index = first_arg_at; index < children.size(); index++) { AstNode *node_arg = children[index]; while (node_arg->simplify(true, false, stage, -1, false, false)) { } - if (node_arg->type != AST_CONSTANT) - input_error("Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); VerilogFmtArg arg = {}; arg.filename = filename; arg.first_line = location.first_line; - if (node_arg->is_string) { + if (node_arg->type == AST_CONSTANT && node_arg->is_string) { arg.type = VerilogFmtArg::STRING; arg.str = node_arg->bitsAsConst().decode_string(); // and in case this will be used as an argument... arg.sig = node_arg->bitsAsConst(); arg.signed_ = false; - } else { + } else if (node_arg->type == AST_IDENTIFIER && node_arg->str == "$time") { + arg.type = VerilogFmtArg::TIME; + } else if (node_arg->type == AST_IDENTIFIER && node_arg->str == "$realtime") { + arg.type = VerilogFmtArg::TIME; + arg.realtime = true; + } else if (node_arg->type == AST_CONSTANT) { arg.type = VerilogFmtArg::INTEGER; arg.sig = node_arg->bitsAsConst(); arg.signed_ = node_arg->is_signed; + } else { + log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); } args.push_back(arg); } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 9d9e95ac392..0fac6417560 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -606,6 +606,7 @@ std::string Fmt::render() const break; case FmtPart::INTEGER: + case FmtPart::TIME: case FmtPart::CHARACTER: { std::string buf; if (part.type == FmtPart::INTEGER) { @@ -689,6 +690,9 @@ std::string Fmt::render() const } else log_abort(); } else if (part.type == FmtPart::CHARACTER) { buf = part.sig.as_const().decode_string(); + } else if (part.type == FmtPart::TIME) { + // We only render() during initial, so time is always zero. + buf = "0"; } log_assert(part.width == 0 || part.padding != '\0'); @@ -705,12 +709,6 @@ std::string Fmt::render() const str += std::string(part.width - buf.size(), part.padding); break; } - - case FmtPart::TIME: { - // We only render() during initial, so time is always zero. - str += "0"; - break; - } } } diff --git a/tests/fmt/initial_display.v b/tests/fmt/initial_display.v index 26a39d0ec88..d3ef9ed7691 100644 --- a/tests/fmt/initial_display.v +++ b/tests/fmt/initial_display.v @@ -193,6 +193,16 @@ module m; initial $display(":%020b:", 16'shaaaa); initial $display(":%-020b:", 16'shaaaa); + initial $display("==> time %%t"); + initial $display(":%t:", $time); + initial $display(":%-t:", $time); + initial $display(":%0t:", $time); + initial $display(":%-0t:", $time); + initial $display(":%10t:", $time); + initial $display(":%-10t:", $time); + initial $display(":%015t:", $time); + initial $display(":%-015t:", $time); + initial $display("===> %%s"); initial $display(":%10s:", "foo"); initial $display(":%010s:", "foo"); From 2ae551c0af26dd81e7e28bac4618ca3fc84019dc Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:23 +1000 Subject: [PATCH 034/119] fmt: fuzz, fix (remove extraneous + incorrect fill) "blk + chunks" is often an overrun, plus the fill is unnecessary; we throw blk away immediately. --- backends/cxxrtl/cxxrtl.h | 1 - tests/fmt/fuzz/.gitignore | 2 ++ tests/fmt/fuzz/CMakeLists.txt | 23 +++++++++++++++++++ tests/fmt/fuzz/x_test.cc | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/fmt/fuzz/.gitignore create mode 100644 tests/fmt/fuzz/CMakeLists.txt create mode 100644 tests/fmt/fuzz/x_test.cc diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 8ea800ed93f..d2f06d6bf30 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -654,7 +654,6 @@ struct value : public expr_base> { } std::copy(blk, blk + origLen, data); - std::fill(blk + origLen, blk + chunks, 0); } static chunk::type getShiftedBlock(const value &num, size_t x, size_t y) { diff --git a/tests/fmt/fuzz/.gitignore b/tests/fmt/fuzz/.gitignore new file mode 100644 index 00000000000..88ea7e2ef91 --- /dev/null +++ b/tests/fmt/fuzz/.gitignore @@ -0,0 +1,2 @@ +fuzztest +build diff --git a/tests/fmt/fuzz/CMakeLists.txt b/tests/fmt/fuzz/CMakeLists.txt new file mode 100644 index 00000000000..6f7c43da888 --- /dev/null +++ b/tests/fmt/fuzz/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.14) +project(cxxrtl_division_fuzz) + +set(CMAKE_CXX_STANDARD 17) + +add_subdirectory(fuzztest) + +enable_testing() + +include(GoogleTest) + +fuzztest_setup_fuzzing_flags() + +include_directories(../../..) + +add_executable( + x_test + x_test.cc + ../../../libs/bigint/BigUnsigned.cc +) + +link_fuzztest(x_test) +gtest_discover_tests(x_test) diff --git a/tests/fmt/fuzz/x_test.cc b/tests/fmt/fuzz/x_test.cc new file mode 100644 index 00000000000..ce4af54135b --- /dev/null +++ b/tests/fmt/fuzz/x_test.cc @@ -0,0 +1,42 @@ +#include "fuzztest/fuzztest.h" +#include "gtest/gtest.h" + +#include +#include "backends/cxxrtl/cxxrtl.h" +#include "libs/bigint/BigUnsigned.hh" + +using namespace cxxrtl_yosys; + +void Formats128BitUnsignedIntegers(uint64_t x, uint64_t y) { + // Compare output to actual BigUnsigned. + value<64> vs; + value<128> v; + vs.set(x); + v = v.blit<127, 64>(vs); + vs.set(y); + v = v.blit<63, 0>(vs); + + std::ostringstream oss; + oss << value_formatted<128>(v, false, false, ' ', 0, 10, false, false, false); + auto actual = oss.str(); + + BigUnsigned b(x); + b.bitShiftLeft(b, 64); + b.bitOr(b, y); + + std::string expected; + + if (b.isZero()) { + expected = "0"; + } else { + while (!b.isZero()) { + expected += '0' + (b % 10).toInt(); + b /= 10; + } + std::reverse(expected.begin(), expected.end()); + } + + EXPECT_EQ(actual, expected); +} +FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitUnsignedIntegers); + From 3571bf2c2d4b84940533500cfae6471dbf6b7258 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:24 +1000 Subject: [PATCH 035/119] fmt: fuzz, remove some unnecessary busywork Removing some signed checks and logic where we've already guaranteed the values to be positive. Indeed, in these cases, if a negative value got through (per my realisation in the signed fuzz harness), it would cause an infinite loop due to flooring division. --- backends/cxxrtl/cxxrtl.h | 5 +-- kernel/fmt.cc | 4 +-- tests/fmt/fuzz/CMakeLists.txt | 1 + tests/fmt/fuzz/x_test.cc | 65 +++++++++++++++++++++++++++-------- 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index d2f06d6bf30..d4e2fa7fc86 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -905,10 +905,7 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) buf += '0'; while (!val.is_zero()) { value quotient; - if (negative) - val.signedDivideWithRemainder(value{10u}, quotient); - else - val.divideWithRemainder(value{10u}, quotient); + val.divideWithRemainder(value{10u}, quotient); buf += '0' + val.template slice<3, 0>().val().template get(); val = quotient; } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 0fac6417560..0fdd996fb8a 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -680,8 +680,8 @@ std::string Fmt::render() const if (absvalue.is_fully_zero()) buf += '0'; while (!absvalue.is_fully_zero()) { - buf += '0' + RTLIL::const_mod(absvalue, 10, part.signed_, false, 4).as_int(); - absvalue = RTLIL::const_div(absvalue, 10, part.signed_, false, absvalue.size()); + buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int(); + absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size()); } if (negative || part.plus) buf += negative ? '-' : '+'; diff --git a/tests/fmt/fuzz/CMakeLists.txt b/tests/fmt/fuzz/CMakeLists.txt index 6f7c43da888..e436067725d 100644 --- a/tests/fmt/fuzz/CMakeLists.txt +++ b/tests/fmt/fuzz/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable( x_test x_test.cc ../../../libs/bigint/BigUnsigned.cc + ../../../libs/bigint/BigInteger.cc ) link_fuzztest(x_test) diff --git a/tests/fmt/fuzz/x_test.cc b/tests/fmt/fuzz/x_test.cc index ce4af54135b..07ff7885dae 100644 --- a/tests/fmt/fuzz/x_test.cc +++ b/tests/fmt/fuzz/x_test.cc @@ -4,34 +4,33 @@ #include #include "backends/cxxrtl/cxxrtl.h" #include "libs/bigint/BigUnsigned.hh" +#include "libs/bigint/BigInteger.hh" using namespace cxxrtl_yosys; -void Formats128BitUnsignedIntegers(uint64_t x, uint64_t y) { - // Compare output to actual BigUnsigned. - value<64> vs; +void Formats128BitUnsignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) +{ + // Compare output to BigUnsigned. value<128> v; - vs.set(x); - v = v.blit<127, 64>(vs); - vs.set(y); - v = v.blit<63, 0>(vs); + v = v.blit<127, 64>(value<64>{x1, x0}); + v = v.blit<63, 0>(value<64>{x3, x2}); std::ostringstream oss; oss << value_formatted<128>(v, false, false, ' ', 0, 10, false, false, false); auto actual = oss.str(); - BigUnsigned b(x); - b.bitShiftLeft(b, 64); - b.bitOr(b, y); + BigUnsigned u; + u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); + u.bitOr(u, v.slice<63, 0>().val().get()); std::string expected; - if (b.isZero()) { + if (u.isZero()) { expected = "0"; } else { - while (!b.isZero()) { - expected += '0' + (b % 10).toInt(); - b /= 10; + while (!u.isZero()) { + expected += '0' + (u % 10).toInt(); + u /= 10; } std::reverse(expected.begin(), expected.end()); } @@ -40,3 +39,41 @@ void Formats128BitUnsignedIntegers(uint64_t x, uint64_t y) { } FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitUnsignedIntegers); + +void Formats128BitSignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) { + // Compare output to BigInteger. + value<128> v; + v = v.blit<127, 64>(value<64>{x1, x0}); + v = v.blit<63, 0>(value<64>{x3, x2}); + + std::ostringstream oss; + oss << value_formatted<128>(v, false, false, ' ', 0, 10, true, false, false); + auto actual = oss.str(); + + BigUnsigned u; + bool negative = v.is_neg(); + if (negative) + v = v.neg(); + u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); + u.bitOr(u, v.slice<63, 0>().val().get()); + + std::string expected; + if (u.isZero()) { + expected = "0"; + } else { + // Note that we never actually do division of negative numbers: our division + // routines are flooring, not truncating, so dividing by 10 repeatedly won't + // necessarily ever get to zero. + while (!u.isZero()) { + expected += '0' + (u % 10).toInt(); + u /= 10; + } + if (negative) { + expected += '-'; + } + std::reverse(expected.begin(), expected.end()); + } + + EXPECT_EQ(actual, expected); +} +FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitSignedIntegers); From a1de898fcc96ef1546fc7c656685403ef1242378 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:24 +1000 Subject: [PATCH 036/119] fmt: merge fuzzers since we don't rely on BigInteger logic This is per fmt's (effective) use, as it turns out, so we're not losing any fidelity in the comparison. --- tests/fmt/fuzz/CMakeLists.txt | 1 - tests/fmt/fuzz/x_test.cc | 47 +++++------------------------------ 2 files changed, 6 insertions(+), 42 deletions(-) diff --git a/tests/fmt/fuzz/CMakeLists.txt b/tests/fmt/fuzz/CMakeLists.txt index e436067725d..6f7c43da888 100644 --- a/tests/fmt/fuzz/CMakeLists.txt +++ b/tests/fmt/fuzz/CMakeLists.txt @@ -17,7 +17,6 @@ add_executable( x_test x_test.cc ../../../libs/bigint/BigUnsigned.cc - ../../../libs/bigint/BigInteger.cc ) link_fuzztest(x_test) diff --git a/tests/fmt/fuzz/x_test.cc b/tests/fmt/fuzz/x_test.cc index 07ff7885dae..ee061861f90 100644 --- a/tests/fmt/fuzz/x_test.cc +++ b/tests/fmt/fuzz/x_test.cc @@ -4,11 +4,10 @@ #include #include "backends/cxxrtl/cxxrtl.h" #include "libs/bigint/BigUnsigned.hh" -#include "libs/bigint/BigInteger.hh" using namespace cxxrtl_yosys; -void Formats128BitUnsignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) +void Formats128BitIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3, bool signed_) { // Compare output to BigUnsigned. value<128> v; @@ -16,64 +15,30 @@ void Formats128BitUnsignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x v = v.blit<63, 0>(value<64>{x3, x2}); std::ostringstream oss; - oss << value_formatted<128>(v, false, false, ' ', 0, 10, false, false, false); + oss << value_formatted<128>(v, false, false, ' ', 0, 10, signed_, false, false); auto actual = oss.str(); BigUnsigned u; - u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); - u.bitOr(u, v.slice<63, 0>().val().get()); - - std::string expected; - - if (u.isZero()) { - expected = "0"; - } else { - while (!u.isZero()) { - expected += '0' + (u % 10).toInt(); - u /= 10; - } - std::reverse(expected.begin(), expected.end()); - } - - EXPECT_EQ(actual, expected); -} -FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitUnsignedIntegers); - - -void Formats128BitSignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) { - // Compare output to BigInteger. - value<128> v; - v = v.blit<127, 64>(value<64>{x1, x0}); - v = v.blit<63, 0>(value<64>{x3, x2}); - - std::ostringstream oss; - oss << value_formatted<128>(v, false, false, ' ', 0, 10, true, false, false); - auto actual = oss.str(); - - BigUnsigned u; - bool negative = v.is_neg(); + bool negative = signed_ && v.is_neg(); if (negative) v = v.neg(); u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); u.bitOr(u, v.slice<63, 0>().val().get()); std::string expected; + if (u.isZero()) { expected = "0"; } else { - // Note that we never actually do division of negative numbers: our division - // routines are flooring, not truncating, so dividing by 10 repeatedly won't - // necessarily ever get to zero. while (!u.isZero()) { expected += '0' + (u % 10).toInt(); u /= 10; } - if (negative) { + if (negative) expected += '-'; - } std::reverse(expected.begin(), expected.end()); } EXPECT_EQ(actual, expected); } -FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitSignedIntegers); +FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitIntegers); From bfa8b631bf59da3f41f594ba9e9d4ac3588d2af4 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:25 +1000 Subject: [PATCH 037/119] cxxrtl: remove unused signedDivideWithRemainder --- backends/cxxrtl/cxxrtl.h | 55 ---------------------------------------- 1 file changed, 55 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index d4e2fa7fc86..4abb27be5dc 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -661,61 +661,6 @@ struct value : public expr_base> { chunk::type part2 = (x == num.chunks) ? 0 : (num.data[x] << y); return part1 | part2; } - - // parallel to BigInteger::divideWithRemainder; quotient is stored in q, - // *this is left with the remainder. See that function for commentary describing - // how/why this works. - void signedDivideWithRemainder(const value &b, value &q) { - assert(this != &q); - - if (this == &b || &q == &b) { - value tmpB(b); - signedDivideWithRemainder(tmpB, q); - return; - } - - if (b.is_zero()) { - q = value{0u}; - return; - } - - if (is_zero()) { - q = value{0u}; - return; - } - - // BigInteger has a separate 'mag' to its sign. We don't, so the lazy - // approach is to improvise said. - auto mag = *this; - bool neg = mag.is_neg(); - if (neg) - mag = mag.neg(); - - auto bmag = b; - bool bneg = bmag.is_neg(); - if (bneg) - bmag = bmag.neg(); - - bool qneg = false; - if (neg != b.is_neg()) { - qneg = true; - mag = mag.sub(value{1u}); - } - - mag.divideWithRemainder(bmag, q); - - if (neg != bneg) { - q = q.add(value{1u}); - mag = bmag.sub(mag); - mag = mag.sub(value{1u}); - } - - neg = bneg; - - *this = neg ? mag.neg() : mag; - if (qneg) - q = q.neg(); - } }; // Expression template for a slice, usable as lvalue or rvalue, and composable with other expression templates here. From f9b149fa7b6fe5b51c548e564dafd99a3cd87d0b Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:26 +1000 Subject: [PATCH 038/119] cxxrtl: add "-print-output" option, test in fmt --- backends/cxxrtl/cxxrtl_backend.cc | 12 ++++++++++-- tests/fmt/run-test.sh | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 4986836b9f8..2c9dc412178 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -682,6 +682,7 @@ struct CxxrtlWorker { bool split_intf = false; std::string intf_filename; std::string design_ns = "cxxrtl_design"; + std::string print_output = "std::cout"; std::ostream *impl_f = nullptr; std::ostream *intf_f = nullptr; @@ -1042,8 +1043,7 @@ struct CxxrtlWorker { Fmt fmt = {}; fmt.parse_rtlil(cell); - // TODO: we may want to configure the output stream - f << indent << "std::cout"; + f << indent << print_output; fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); f << ";\n"; } @@ -3263,6 +3263,10 @@ struct CxxrtlBackend : public Backend { log(" place the generated code into namespace . if not specified,\n"); log(" \"cxxrtl_design\" is used.\n"); log("\n"); + log(" -print-output \n"); + log(" $print cells in the generated code direct their output to .\n"); + log(" if not specified, \"std::cout\" is used.\n"); + log("\n"); log(" -nohierarchy\n"); log(" use design hierarchy as-is. in most designs, a top module should be\n"); log(" present as it is exposed through the C API and has unbuffered outputs\n"); @@ -3401,6 +3405,10 @@ struct CxxrtlBackend : public Backend { worker.design_ns = args[++argidx]; continue; } + if (args[argidx] == "-print-output" && argidx+1 < args.size()) { + worker.print_output = args[++argidx]; + continue; + } break; } extra_args(f, filename, args, argidx); diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 2568e27764d..a5a0c0c7e59 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -47,9 +47,9 @@ test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" -../../yosys -p "read_verilog always_full.v; write_cxxrtl yosys-always_full.cc" +../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" ${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc -./yosys-always_full >yosys-always_full.log +./yosys-always_full 2>yosys-always_full.log iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log diff iverilog-always_full.log yosys-always_full.log From fc0acd0ad119de5a606355cd8d9da2548338e579 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:26 +1000 Subject: [PATCH 039/119] cxxrtl: restrict -print-output to cout, cerr --- backends/cxxrtl/cxxrtl_backend.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 2c9dc412178..8f06dda66a9 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -3265,7 +3265,8 @@ struct CxxrtlBackend : public Backend { log("\n"); log(" -print-output \n"); log(" $print cells in the generated code direct their output to .\n"); - log(" if not specified, \"std::cout\" is used.\n"); + log(" must be one of \"std::cout\", \"std::cerr\". if not specified,\n"); + log(" \"std::cout\" is used.\n"); log("\n"); log(" -nohierarchy\n"); log(" use design hierarchy as-is. in most designs, a top module should be\n"); @@ -3407,6 +3408,10 @@ struct CxxrtlBackend : public Backend { } if (args[argidx] == "-print-output" && argidx+1 < args.size()) { worker.print_output = args[++argidx]; + if (!(worker.print_output == "std::cout" || worker.print_output == "std::cerr")) { + log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output.c_str()); + worker.print_output = "std::cout"; + } continue; } break; From 4e94f62116cf4b9180a7a0ddb6ca4ad61a97bd53 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:27 +1000 Subject: [PATCH 040/119] simlib: blackbox `$print` cell It's possible to `generate` the appropriate always blocks per the triggers, but unlikely to be worth parsing the RTLIL \FORMAT parameter. --- techlibs/common/simlib.v | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 9cb68e7252f..32f2b693740 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1799,6 +1799,23 @@ end endmodule +// -------------------------------------------------------- + +module \$print (EN, TRG, ARGS); + +parameter FORMAT = ""; +parameter ARGS_WIDTH = 0; +parameter TRG_ENABLE = 1; + +parameter TRG_WIDTH = 0; +parameter TRG_POLARITY = 0; + +input EN; +input [TRG_WIDTH-1:0] TRG; +input [ARGS_WIDTH-1:0] ARGS; + +endmodule + // -------------------------------------------------------- `ifndef SIMLIB_NOSR From 992a728ec7ad5b7a19d58e544fd0901065bb2f71 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:28 +1000 Subject: [PATCH 041/119] tests: CXX may be e.g. gcc, so use CC and link stdc++ explicitly --- frontends/ast/genrtlil.cc | 4 ++-- tests/fmt/run-test.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 2e2d0de74bf..849b5ebad46 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -700,7 +700,7 @@ struct AST_INTERNAL::ProcessGenerator sstr << ast->str << "$" << ast->filename << ":" << ast->location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($print)); - cell->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); + set_src_attr(cell, ast); RTLIL::SigSpec triggers; RTLIL::Const polarity; @@ -719,7 +719,7 @@ struct AST_INTERNAL::ProcessGenerator cell->setPort(ID::TRG, triggers); Wire *wire = current_module->addWire(sstr.str() + "_EN", 1); - wire->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); + set_src_attr(wire, ast); cell->setPort(ID::EN, wire); proc->root_case.actions.push_back(SigSig(wire, false)); diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index a5a0c0c7e59..0e073a707fa 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -48,7 +48,7 @@ test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" ../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" -${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc +${CC:-gcc} -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ ./yosys-always_full 2>yosys-always_full.log iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log @@ -56,7 +56,7 @@ diff iverilog-always_full.log yosys-always_full.log ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" -${CXX:-g++} -o yosys-display_lm_cc -I../.. display_lm_tb.cc +${CC:-gcc} -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ ./yosys-display_lm_cc >yosys-display_lm_cc.log for log in yosys-display_lm.log yosys-display_lm_cc.log; do grep "^%l: \\\\bot\$" "$log" From eb0fb4d6629876de5027263f8e47cc48b7643d8a Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:29 +1000 Subject: [PATCH 042/119] tests: -std=c++11 not optional --- tests/fmt/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 0e073a707fa..d793c37dd08 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -48,7 +48,7 @@ test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" ../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" -${CC:-gcc} -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ +${CC:-gcc} -std=c++11 -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ ./yosys-always_full 2>yosys-always_full.log iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log @@ -56,7 +56,7 @@ diff iverilog-always_full.log yosys-always_full.log ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" -${CC:-gcc} -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ +${CC:-gcc} -std=c++11 -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ ./yosys-display_lm_cc >yosys-display_lm_cc.log for log in yosys-display_lm.log yosys-display_lm_cc.log; do grep "^%l: \\\\bot\$" "$log" From 7f7c61c9f018cd7ed24d8c7e570a80e565ca7c7b Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:29 +1000 Subject: [PATCH 043/119] fmt: remove lzero by lowering during Verilog parse See https://github.com/YosysHQ/yosys/pull/3721#issuecomment-1502037466 -- this reduces logic within the cell, and makes the rules that apply much more clear. --- backends/cxxrtl/cxxrtl.h | 7 +-- docs/source/CHAPTER_CellLib.rst | 11 ++-- kernel/fmt.cc | 100 +++++++++++++++++++++++--------- kernel/fmt.h | 5 +- 4 files changed, 82 insertions(+), 41 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 4abb27be5dc..45ec256af3c 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -802,11 +802,10 @@ struct value_formatted { int width; int base; bool signed_; - bool lzero; bool plus; - value_formatted(const value &val, bool character, bool justify_left, char padding, int width, int base, bool signed_, bool lzero, bool plus) : - val(val), character(character), justify_left(justify_left), padding(padding), width(width), base(base), signed_(signed_), lzero(lzero), plus(plus) {} + value_formatted(const value &val, bool character, bool justify_left, char padding, int width, int base, bool signed_, bool plus) : + val(val), character(character), justify_left(justify_left), padding(padding), width(width), base(base), signed_(signed_), plus(plus) {} value_formatted(const value_formatted &) = delete; value_formatted &operator=(const value_formatted &rhs) = delete; }; @@ -823,7 +822,7 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) if (!vf.character) { size_t width = Bits; - if (!vf.lzero && vf.base != 10) { + if (vf.base != 10) { width = 0; for (size_t index = 0; index < Bits; index++) if (val.bit(index)) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index a4f986f7590..dc2ad3e578a 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -700,16 +700,12 @@ base * ``c`` for ASCII characters/strings * ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and :verilog:`$realtime`) -For integers, these items follow: +For integers, this item may follow: ``+``\ *?* (optional, decimals only) Include a leading plus for non-negative numbers. This can assist with symmetry with negatives in tabulated output. -``0``\ *?* - (optional, non-decimals only) Zero-pad the number to fit the signal's - largest value before any further padding/justification. - signedness ``u`` for unsigned, ``s`` for signed. This distinction is only respected when rendering decimals. @@ -730,8 +726,7 @@ Some example format specifiers: right-justified, zero-padded to 2 characters wide. + ``{32:< 15d+s}`` - 32-bit signed integer rendered as decimal, left-justified, space-padded to 15 characters wide, positive values prefixed with ``+``. -+ ``{16:< 10h0u}`` - 16-bit unsigned integer rendered as hexadecimal, - zero-padded to fit the largest signal value (4 characters for hex), ++ ``{16:< 10hu}`` - 16-bit unsigned integer rendered as hexadecimal, left-justified, space-padded to 10 characters wide. + ``{0:>010t}`` - simulation time, right-justified, zero-padded to 10 characters wide. @@ -742,6 +737,8 @@ and ``}}`` respectively. It is an error for a format string to consume more or less bits from ``\ARGS`` than the port width. +Values are never truncated, regardless of the specified width. + Note that further restrictions on allowable combinations of options may apply depending on the backend used. diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 0fdd996fb8a..69bdbb013b0 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -130,12 +130,6 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { log_assert(false && "Unexpected end in format substitution"); } - if (fmt[i] == '0') { - part.lzero = true; - if (++i == fmt.size()) - log_assert(false && "Unexpected end in format substitution"); - } - if (fmt[i] == 'u') part.signed_ = false; else if (fmt[i] == 's') @@ -208,8 +202,6 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { } if (part.plus) fmt += '+'; - if (part.lzero) - fmt += '0'; fmt += part.signed_ ? 's' : 'u'; } else if (part.type == FmtPart::CHARACTER) { fmt += 'c'; @@ -248,14 +240,72 @@ static size_t compute_required_decimal_places(size_t size, bool signed_) return places; } -static void apply_verilog_automatic_sizing(FmtPart &part) +static size_t compute_required_nondecimal_places(size_t size, unsigned base) +{ + log_assert(base != 10); + BigUnsigned max; + max.setBit(size - 1, true); + size_t places = 0; + while (!max.isZero()) { + places++; + max /= base; + } + return places; +} + +// Only called for integers, either when: +// +// (a) passed without a format string (e.g. "$display(a);"), or +// +// (b) the corresponding format specifier has no leading zero, e.g. "%b", +// "%20h", "%-10d". +// +// In these cases, for binary/octal/hex, we always zero-pad to the size of the +// signal; i.e. whether "%h" or "%10h" or "%-20h" is used, if the corresponding +// signal is 32'h1234, "00001234" will always be a substring of the output. +// +// For case (a), we have no specified width, so there is nothing more to do. +// +// For case (b), because we are only called with no leading zero on the +// specifier, any specified width beyond the signal size is therefore space +// padding, whatever the justification. +// +// For decimal, we do no zero-padding, instead space-padding to the size +// required for the signal's largest value. This is per other Verilog +// implementations, and intuitively makes sense as decimal representations lack +// a discrete mapping of digits to bit groups. Decimals may also show sign and +// must accommodate this, whereas other representations do not. +void Fmt::apply_verilog_automatic_sizing_and_add(FmtPart &part) { if (part.base == 10) { size_t places = compute_required_decimal_places(part.sig.size(), part.signed_); part.padding = ' '; part.width = std::max(part.width, places); - } else { - part.lzero = true; + parts.push_back(part); + return; + } + + part.padding = '0'; + + size_t places = compute_required_nondecimal_places(part.sig.size(), part.base); + if (part.width < places) { + part.justify = FmtPart::RIGHT; + part.width = places; + parts.push_back(part); + } else if (part.width == places) { + parts.push_back(part); + } else if (part.width > places) { + auto gap = std::string(part.width - places, ' '); + part.width = places; + + if (part.justify == FmtPart::RIGHT) { + append_string(gap); + parts.push_back(part); + } else { + part.justify = FmtPart::RIGHT; + parts.push_back(part); + append_string(gap); + } } } @@ -272,8 +322,7 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part.sig = arg->sig; part.base = default_base; part.signed_ = arg->signed_; - apply_verilog_automatic_sizing(part); - parts.push_back(part); + apply_verilog_automatic_sizing_and_add(part); break; } @@ -379,15 +428,13 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik if (part.padding == '\0') part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' '; - if (part.type == FmtPart::INTEGER) { - if (part.base != 10 && part.plus) { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); - } - if (!has_leading_zero) - apply_verilog_automatic_sizing(part); - } + if (part.type == FmtPart::INTEGER && part.base != 10 && part.plus) + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); - parts.push_back(part); + if (part.type == FmtPart::INTEGER && !has_leading_zero) + apply_verilog_automatic_sizing_and_add(part); + else + parts.push_back(part); part = {}; } } @@ -439,13 +486,10 @@ std::vector Fmt::emit_verilog() const if (part.justify == FmtPart::LEFT) fmt.str += '-'; if (part.width == 0) { - if (!part.lzero) - fmt.str += '0'; + fmt.str += '0'; } else if (part.width > 0) { log_assert(part.padding == ' ' || part.padding == '0'); - if (!part.lzero && part.base != 10) - fmt.str += '0'; - else if (part.padding == '0') + if (part.base != 10 || part.padding == '0') fmt.str += '0'; fmt.str += std::to_string(part.width); } @@ -567,7 +611,6 @@ void Fmt::emit_cxxrtl(std::ostream &f, std::function parts; void append_string(const std::string &str); @@ -96,6 +96,9 @@ struct Fmt { void emit_cxxrtl(std::ostream &f, std::function emit_sig) const; std::string render() const; + +private: + void apply_verilog_automatic_sizing_and_add(FmtPart &part); }; YOSYS_NAMESPACE_END From 843ad9331b6eaefc772d59b52ac0a3e2c04930d7 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:30 +1000 Subject: [PATCH 044/119] cxxrtl: WIP: adjust comb display cells to only fire on change Naming and use of statics to be possibly revised. --- backends/cxxrtl/cxxrtl.h | 2 +- backends/cxxrtl/cxxrtl_backend.cc | 33 ++++++++++++++++++++++++++++++- docs/source/CHAPTER_CellLib.rst | 4 ++-- tests/fmt/always_comb.v | 24 ++++++++++++++++++++++ tests/fmt/always_comb_tb.cc | 14 +++++++++++++ tests/fmt/always_comb_tb.v | 8 ++++++++ tests/fmt/always_full.v | 7 +------ tests/fmt/run-test.sh | 19 ++++++++++++------ 8 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 tests/fmt/always_comb.v create mode 100644 tests/fmt/always_comb_tb.cc create mode 100644 tests/fmt/always_comb_tb.v diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 45ec256af3c..8f5e4035a34 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -850,7 +850,7 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) while (!val.is_zero()) { value quotient; val.divideWithRemainder(value{10u}, quotient); - buf += '0' + val.template slice<3, 0>().val().template get(); + buf += '0' + val.template trunc<(Bits > 4 ? 4 : Bits)>().val().template get(); val = quotient; } if (negative || vf.plus) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 8f06dda66a9..82babe72b4f 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1217,8 +1217,18 @@ struct CxxrtlWorker { // $print cell } else if (cell->type == ID($print)) { log_assert(!for_debug); + + auto trg_enable = cell->getParam(ID::TRG_ENABLE).as_bool(); + static int cell_counter = 0; + if (!trg_enable) { + ++cell_counter; + f << indent << "static bool last_print_" << cell_counter << "_known = false;\n"; + f << indent << "static value<1> last_print_" << cell_counter << "_en;\n"; + f << indent << "static value<" << cell->getPort(ID::ARGS).size() << "> last_print_" << cell_counter << "_args;\n"; + } + f << indent << "if ("; - if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + if (trg_enable) { f << '('; for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { RTLIL::SigBit trg_bit = cell->getPort(ID::TRG)[i]; @@ -1235,6 +1245,17 @@ struct CxxrtlWorker { f << mangle(trg_bit); } f << ") && "; + } else { + f << '('; + f << "!last_print_" << cell_counter << "_known || "; + f << '('; + f << "last_print_" << cell_counter << "_en != "; + dump_sigspec_rhs(cell->getPort(ID::EN)); + + f << " || last_print_" << cell_counter << "_args != "; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ')'; + f << ") && "; } dump_sigspec_rhs(cell->getPort(ID::EN)); f << " == value<1>{1u}) {\n"; @@ -1242,6 +1263,16 @@ struct CxxrtlWorker { dump_print(cell); dec_indent(); f << indent << "}\n"; + + if (!trg_enable) { + f << indent << "last_print_" << cell_counter << "_known = true;\n"; + f << indent << "last_print_" << cell_counter << "_en = "; + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << ";\n"; + f << indent << "last_print_" << cell_counter << "_args = "; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ";\n"; + } // Flip-flops } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index dc2ad3e578a..4bbbe0ea85b 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -641,8 +641,8 @@ has the following parameters: The width (in bits) of the signal on the ``\ARGS`` port. ``\TRG_ENABLE`` - True if only triggered on specific signals defined in ``\TRG``; false if - executed on every step. + True if triggered on specific signals defined in ``\TRG``; false if + triggered whenever ``\ARGS`` or ``\EN`` change and ``\EN`` is 1. If ``\TRG_ENABLE`` is true, the following parameters are also set: diff --git a/tests/fmt/always_comb.v b/tests/fmt/always_comb.v new file mode 100644 index 00000000000..7147786bebf --- /dev/null +++ b/tests/fmt/always_comb.v @@ -0,0 +1,24 @@ +module top(input clk); + reg a = 0; + reg b = 0; + wire y; + + sub s (.a(a), .b(b), .y(y)); + + always @(posedge clk) begin + a <= (!a && !b) || (a && !b); + b <= (a && !b) || (a && b); + end +endmodule + +module sub(input a, input b, output wire y); + assign y = a & b; + + // Not fit for our purposes: always @* if (a) $display(a, b, y); + // + // We compare output against iverilog, but async iverilog $display fires + // even before values have propagated -- i.e. combinations of a/b/y will be + // shown where a & b are both 1, but y has not yet taken the value 1. We + // don't, so we specify it in the conditional. + always @* if (y & (y == (a & b))) $display(a, b, y); +endmodule diff --git a/tests/fmt/always_comb_tb.cc b/tests/fmt/always_comb_tb.cc new file mode 100644 index 00000000000..c949af4e330 --- /dev/null +++ b/tests/fmt/always_comb_tb.cc @@ -0,0 +1,14 @@ +#include +#include "yosys-always_comb.cc" + +int main() +{ + cxxrtl_design::p_top uut; + + for (int i = 0; i < 20; ++i) { + uut.p_clk.set(!uut.p_clk); + uut.step(); + } + + return 0; +} diff --git a/tests/fmt/always_comb_tb.v b/tests/fmt/always_comb_tb.v new file mode 100644 index 00000000000..44789743317 --- /dev/null +++ b/tests/fmt/always_comb_tb.v @@ -0,0 +1,8 @@ +module tb; + reg clk = 0; + + top uut (.clk(clk)); + + always #1 clk <= ~clk; + initial #20 $finish; +endmodule diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v index 3727813543c..d573bed317d 100644 --- a/tests/fmt/always_full.v +++ b/tests/fmt/always_full.v @@ -8,8 +8,6 @@ module always_full(input clk, output reg fin); if (counter == 0) fin <= 0; - if (counter == 1) $display("<<>>"); - if (counter == 2) $display("==> small unsigned %%d"); if (counter == 3) $display(":%d:", 16'haa); if (counter == 4) $display(":%-d:", 16'haa); @@ -239,10 +237,7 @@ module always_full(input clk, output reg fin); if (counter == 207) $display("==> write/format"); if (counter == 208) $display("%d", 1, "%d", 1); - if (counter == 209) begin - $display("<<>>"); - fin <= 1; - end + if (counter == 209) fin <= 1; end diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index d793c37dd08..44759dbc140 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -47,12 +47,19 @@ test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" -../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" -${CC:-gcc} -std=c++11 -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ -./yosys-always_full 2>yosys-always_full.log -iverilog -o iverilog-always_full always_full.v always_full_tb.v -./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log -diff iverilog-always_full.log yosys-always_full.log +test_cxxrtl () { + local subtest=$1; shift + + ../../yosys -p "read_verilog ${subtest}.v; write_cxxrtl -print-output std::cerr yosys-${subtest}.cc" + ${CC:-gcc} -std=c++11 -o yosys-${subtest} -I../.. ${subtest}_tb.cc -lstdc++ + ./yosys-${subtest} 2>yosys-${subtest}.log + iverilog -o iverilog-${subtest} ${subtest}.v ${subtest}_tb.v + ./iverilog-${subtest} |grep -v '\$finish called' >iverilog-${subtest}.log + diff iverilog-${subtest}.log yosys-${subtest}.log +} + +test_cxxrtl always_full +test_cxxrtl always_comb ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" From 4ffdee65e034493cf1eafd9f94d770c88d2f35e0 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:31 +1000 Subject: [PATCH 045/119] cxxrtl: store comb $print cell last EN/ARGS in module statics were obviously wrong -- may be multiple instantiations of any given module. Extend test to cover this. --- backends/cxxrtl/cxxrtl_backend.cc | 35 ++++++++++++------------------- tests/fmt/always_comb_tb.cc | 9 +++++--- tests/fmt/always_comb_tb.v | 3 ++- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 82babe72b4f..17080ef2ec6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1219,12 +1219,13 @@ struct CxxrtlWorker { log_assert(!for_debug); auto trg_enable = cell->getParam(ID::TRG_ENABLE).as_bool(); - static int cell_counter = 0; + if (!trg_enable) { - ++cell_counter; - f << indent << "static bool last_print_" << cell_counter << "_known = false;\n"; - f << indent << "static value<1> last_print_" << cell_counter << "_en;\n"; - f << indent << "static value<" << cell->getPort(ID::ARGS).size() << "> last_print_" << cell_counter << "_args;\n"; + f << indent << "auto " << mangle(cell) << "_curr = "; + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << ".concat("; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ").val();\n"; } f << indent << "if ("; @@ -1246,16 +1247,7 @@ struct CxxrtlWorker { } f << ") && "; } else { - f << '('; - f << "!last_print_" << cell_counter << "_known || "; - f << '('; - f << "last_print_" << cell_counter << "_en != "; - dump_sigspec_rhs(cell->getPort(ID::EN)); - - f << " || last_print_" << cell_counter << "_args != "; - dump_sigspec_rhs(cell->getPort(ID::ARGS)); - f << ')'; - f << ") && "; + f << mangle(cell) << " != " << mangle(cell) << "_curr && "; } dump_sigspec_rhs(cell->getPort(ID::EN)); f << " == value<1>{1u}) {\n"; @@ -1265,13 +1257,7 @@ struct CxxrtlWorker { f << indent << "}\n"; if (!trg_enable) { - f << indent << "last_print_" << cell_counter << "_known = true;\n"; - f << indent << "last_print_" << cell_counter << "_en = "; - dump_sigspec_rhs(cell->getPort(ID::EN)); - f << ";\n"; - f << indent << "last_print_" << cell_counter << "_args = "; - dump_sigspec_rhs(cell->getPort(ID::ARGS)); - f << ";\n"; + f << indent << mangle(cell) << " = " << mangle(cell) << "_curr;\n"; } // Flip-flops } else if (is_ff_cell(cell->type)) { @@ -2362,6 +2348,11 @@ struct CxxrtlWorker { f << "\n"; bool has_cells = false; for (auto cell : module->cells()) { + if (cell->type == ID($print) && !cell->getParam(ID::TRG_ENABLE).as_bool()) { + // comb $print cell -- store the last EN/ARGS values to know when they change. + dump_attrs(cell); + f << indent << "value<" << (1 + cell->getParam(ID::ARGS_WIDTH).as_int()) << "> " << mangle(cell) << ";\n"; + } if (is_internal_cell(cell->type)) continue; dump_attrs(cell); diff --git a/tests/fmt/always_comb_tb.cc b/tests/fmt/always_comb_tb.cc index c949af4e330..f2a8c6b2695 100644 --- a/tests/fmt/always_comb_tb.cc +++ b/tests/fmt/always_comb_tb.cc @@ -3,11 +3,14 @@ int main() { - cxxrtl_design::p_top uut; + cxxrtl_design::p_top uut1, uut2; for (int i = 0; i < 20; ++i) { - uut.p_clk.set(!uut.p_clk); - uut.step(); + uut1.p_clk.set(!uut1.p_clk); + uut1.step(); + + uut2.p_clk.set(!uut2.p_clk); + uut2.step(); } return 0; diff --git a/tests/fmt/always_comb_tb.v b/tests/fmt/always_comb_tb.v index 44789743317..3cc4496a04f 100644 --- a/tests/fmt/always_comb_tb.v +++ b/tests/fmt/always_comb_tb.v @@ -1,7 +1,8 @@ module tb; reg clk = 0; - top uut (.clk(clk)); + top uut1 (.clk(clk)); + top uut2 (.clk(clk)); always #1 clk <= ~clk; initial #20 $finish; From f9d38253c56cddf941e7969bb391dd57e78b8a5d Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:31 +1000 Subject: [PATCH 046/119] ast: add `PRIORITY` to `$print` cells --- docs/source/CHAPTER_CellLib.rst | 6 +++++- frontends/ast/genrtlil.cc | 6 +++++- kernel/rtlil.cc | 1 + techlibs/common/simlib.v | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index 4bbbe0ea85b..494c0651c6a 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -644,7 +644,7 @@ has the following parameters: True if triggered on specific signals defined in ``\TRG``; false if triggered whenever ``\ARGS`` or ``\EN`` change and ``\EN`` is 1. -If ``\TRG_ENABLE`` is true, the following parameters are also set: +If ``\TRG_ENABLE`` is true, the following parameters also apply: ``\TRG_WIDTH`` The number of bits in the ``\TRG`` port. @@ -653,6 +653,10 @@ If ``\TRG_ENABLE`` is true, the following parameters are also set: For each bit in ``\TRG``, 1 if that signal is positive-edge triggered, 0 if negative-edge triggered. +``\PRIORITY`` + When multiple ``$print`` cells fire on the same trigger, they execute in + descending priority order. + Ports: ``\TRG`` diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 849b5ebad46..81fb3189d94 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -315,7 +315,10 @@ struct AST_INTERNAL::ProcessGenerator // Buffer for generating the init action RTLIL::SigSpec init_lvalue, init_rvalue; - ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg) + // The most recently assigned $print cell \PRIORITY. + int last_print_priority; + + ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), last_print_priority(0) { // rewrite lookahead references LookaheadRewriter la_rewriter(always); @@ -716,6 +719,7 @@ struct AST_INTERNAL::ProcessGenerator cell->parameters[ID::TRG_WIDTH] = triggers.size(); cell->parameters[ID::TRG_ENABLE] = !triggers.empty(); cell->parameters[ID::TRG_POLARITY] = polarity; + cell->parameters[ID::PRIORITY] = --last_print_priority; cell->setPort(ID::TRG, triggers); Wire *wire = current_module->addWire(sstr.str() + "_EN", 1); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 09fe0800078..7a59c526275 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1724,6 +1724,7 @@ namespace { param(ID(FORMAT)); param_bool(ID::TRG_ENABLE); param(ID::TRG_POLARITY); + param(ID::PRIORITY); port(ID::EN, 1); port(ID::TRG, param(ID::TRG_WIDTH)); port(ID::ARGS, param(ID::ARGS_WIDTH)); diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 32f2b693740..cdb6e02e762 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1805,6 +1805,7 @@ module \$print (EN, TRG, ARGS); parameter FORMAT = ""; parameter ARGS_WIDTH = 0; +parameter PRIORITY = 0; parameter TRG_ENABLE = 1; parameter TRG_WIDTH = 0; From 04582f2fb79e08a4a8264add98b2080d329379db Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:32 +1000 Subject: [PATCH 047/119] verilog_backend: emit sync `$print` cells with same triggers together Sort by PRIORITY, ensuring output order. --- backends/verilog/verilog_backend.cc | 126 +++++--- tests/fmt/always_full.v | 466 ++++++++++++++-------------- tests/fmt/always_full_tb.cc | 11 +- tests/fmt/always_full_tb.v | 6 +- tests/fmt/run-test.sh | 6 + 5 files changed, 319 insertions(+), 296 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 573fa6d5b84..ca119427f6d 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1006,6 +1006,41 @@ void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell f << stringf(";\n"); } +void dump_cell_expr_print(std::ostream &f, std::string indent, RTLIL::Cell *cell) +{ + Fmt fmt = {}; + fmt.parse_rtlil(cell); + std::vector args = fmt.emit_verilog(); + + f << stringf("%s" "$write(", indent.c_str()); + bool first = true; + for (auto &arg : args) { + if (first) { + first = false; + } else { + f << ", "; + } + switch (arg.type) { + case VerilogFmtArg::STRING: + dump_const(f, RTLIL::Const(arg.str)); + break; + case VerilogFmtArg::INTEGER: + f << (arg.signed_ ? "$signed(" : "$unsigned("); + dump_sigspec(f, arg.sig); + f << ")"; + break; + case VerilogFmtArg::TIME: + if (arg.realtime) + f << "$realtime"; + else + f << "$time"; + break; + default: log_abort(); + } + } + f << stringf(");\n"); +} + bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) { if (cell->type == ID($_NOT_)) { @@ -1756,58 +1791,17 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) if (cell->type == ID($print)) { - Fmt fmt = {}; - fmt.parse_rtlil(cell); - std::vector args = fmt.emit_verilog(); - - if (cell->getParam(ID::TRG_ENABLE).as_bool()) { - f << stringf("%s" "always @(", indent.c_str()); - for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { - if (i != 0) - f << " or "; - if (cell->getParam(ID::TRG_POLARITY)[i]) - f << "posedge "; - else - f << "negedge "; - dump_sigspec(f, cell->getPort(ID::TRG)[i]); - } - f << ")\n"; - } else { - f << stringf("%s" "always @*\n", indent.c_str()); - } + // Sync $print cells are accumulated and handled in dump_module. + if (cell->getParam(ID::TRG_ENABLE).as_bool()) + return true; + + f << stringf("%s" "always @*\n", indent.c_str()); f << stringf("%s" " if (", indent.c_str()); dump_sigspec(f, cell->getPort(ID::EN)); f << stringf(")\n"); - f << stringf("%s" " $write(", indent.c_str()); - bool first = true; - for (auto &arg : args) { - if (first) { - first = false; - } else { - f << ", "; - } - switch (arg.type) { - case VerilogFmtArg::STRING: - dump_const(f, RTLIL::Const(arg.str)); - break; - case VerilogFmtArg::INTEGER: - f << (arg.signed_ ? "$signed(" : "$unsigned("); - dump_sigspec(f, arg.sig); - f << ")"; - break; - case VerilogFmtArg::TIME: - if (arg.realtime) - f << "$realtime"; - else - f << "$time"; - break; - default: log_abort(); - } - } - f << stringf(");\n"); - + dump_cell_expr_print(f, indent + " ", cell); return true; } @@ -1899,6 +1893,34 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) } } +void dump_sync_print(std::ostream &f, std::string indent, const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) +{ + f << stringf("%s" "always @(", indent.c_str()); + for (int i = 0; i < trg.size(); i++) { + if (i != 0) + f << " or "; + if (polarity[i]) + f << "posedge "; + else + f << "negedge "; + dump_sigspec(f, trg[i]); + } + f << ") begin\n"; + + std::sort(cells.begin(), 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 cell : cells) { + f << stringf("%s" " if (", indent.c_str()); + dump_sigspec(f, cell->getPort(ID::EN)); + f << stringf(")\n"); + + dump_cell_expr_print(f, indent + " ", cell); + } + + f << stringf("%s" "end\n", indent.c_str()); +} + void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { if (simple_lhs) { @@ -2080,6 +2102,8 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) { + std::map, std::vector> sync_print_cells; + reg_wires.clear(); reset_auto_counter(module); active_module = module; @@ -2110,6 +2134,11 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) std::set> reg_bits; for (auto cell : module->cells()) { + if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) { + sync_print_cells[make_pair(cell->getPort(ID::TRG), cell->getParam(ID::TRG_POLARITY))].push_back(cell); + continue; + } + if (!RTLIL::builtin_ff_cell_types().count(cell->type) || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_))) continue; @@ -2165,6 +2194,9 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) for (auto cell : module->cells()) dump_cell(f, indent + " ", cell); + for (auto &it : sync_print_cells) + dump_sync_print(f, indent + " ", it.first.first, it.first.second, it.second); + for (auto it = module->processes.begin(); it != module->processes.end(); ++it) dump_process(f, indent + " ", it->second); diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v index d573bed317d..4d3df7a615c 100644 --- a/tests/fmt/always_full.v +++ b/tests/fmt/always_full.v @@ -1,243 +1,235 @@ -module always_full(input clk, output reg fin); - - reg [7:0] counter = 0; +module always_full(input clk); always @(posedge clk) begin - counter <= counter + 1; - - if (counter == 0) fin <= 0; - - if (counter == 2) $display("==> small unsigned %%d"); - if (counter == 3) $display(":%d:", 16'haa); - if (counter == 4) $display(":%-d:", 16'haa); - if (counter == 5) $display(":%+d:", 16'haa); - if (counter == 6) $display(":%+-d:", 16'haa); - if (counter == 7) $display(":%0d:", 16'haa); - if (counter == 8) $display(":%-0d:", 16'haa); - if (counter == 9) $display(":%+0d:", 16'haa); - if (counter == 10) $display(":%+-0d:", 16'haa); - if (counter == 11) $display(":%20d:", 16'haa); - if (counter == 12) $display(":%-20d:", 16'haa); - if (counter == 13) $display(":%+20d:", 16'haa); - if (counter == 14) $display(":%+-20d:", 16'haa); - if (counter == 15) $display(":%020d:", 16'haa); - if (counter == 16) $display(":%-020d:", 16'haa); - if (counter == 17) $display(":%+020d:", 16'haa); - if (counter == 18) $display(":%+-020d:", 16'haa); - - if (counter == 19) $display("==> big unsigned %%d"); - if (counter == 20) $display(":%d:", 16'haaaa); - if (counter == 21) $display(":%-d:", 16'haaaa); - if (counter == 22) $display(":%+d:", 16'haaaa); - if (counter == 23) $display(":%+-d:", 16'haaaa); - if (counter == 24) $display(":%0d:", 16'haaaa); - if (counter == 25) $display(":%-0d:", 16'haaaa); - if (counter == 26) $display(":%+0d:", 16'haaaa); - if (counter == 27) $display(":%+-0d:", 16'haaaa); - if (counter == 28) $display(":%20d:", 16'haaaa); - if (counter == 29) $display(":%-20d:", 16'haaaa); - if (counter == 30) $display(":%+20d:", 16'haaaa); - if (counter == 31) $display(":%+-20d:", 16'haaaa); - if (counter == 32) $display(":%020d:", 16'haaaa); - if (counter == 33) $display(":%-020d:", 16'haaaa); - if (counter == 34) $display(":%+020d:", 16'haaaa); - if (counter == 35) $display(":%+-020d:", 16'haaaa); - - if (counter == 36) $display("==> small signed %%d"); - if (counter == 37) $display(":%d:", 16'shaa); - if (counter == 38) $display(":%-d:", 16'shaa); - if (counter == 39) $display(":%+d:", 16'shaa); - if (counter == 40) $display(":%+-d:", 16'shaa); - if (counter == 41) $display(":%0d:", 16'shaa); - if (counter == 42) $display(":%-0d:", 16'shaa); - if (counter == 43) $display(":%+0d:", 16'shaa); - if (counter == 44) $display(":%+-0d:", 16'shaa); - if (counter == 45) $display(":%20d:", 16'shaa); - if (counter == 46) $display(":%-20d:", 16'shaa); - if (counter == 47) $display(":%+20d:", 16'shaa); - if (counter == 48) $display(":%+-20d:", 16'shaa); - if (counter == 49) $display(":%020d:", 16'shaa); - if (counter == 50) $display(":%-020d:", 16'shaa); - if (counter == 51) $display(":%+020d:", 16'shaa); - if (counter == 52) $display(":%+-020d:", 16'shaa); - - if (counter == 53) $display("==> big signed %%d"); - if (counter == 54) $display(":%d:", 16'shaaaa); - if (counter == 55) $display(":%-d:", 16'shaaaa); - if (counter == 56) $display(":%+d:", 16'shaaaa); - if (counter == 57) $display(":%+-d:", 16'shaaaa); - if (counter == 58) $display(":%0d:", 16'shaaaa); - if (counter == 59) $display(":%-0d:", 16'shaaaa); - if (counter == 60) $display(":%+0d:", 16'shaaaa); - if (counter == 61) $display(":%+-0d:", 16'shaaaa); - if (counter == 62) $display(":%20d:", 16'shaaaa); - if (counter == 63) $display(":%-20d:", 16'shaaaa); - if (counter == 64) $display(":%+20d:", 16'shaaaa); - if (counter == 65) $display(":%+-20d:", 16'shaaaa); - if (counter == 66) $display(":%020d:", 16'shaaaa); - if (counter == 67) $display(":%-020d:", 16'shaaaa); - if (counter == 68) $display(":%+020d:", 16'shaaaa); - if (counter == 69) $display(":%+-020d:", 16'shaaaa); - - if (counter == 70) $display("==> small unsigned %%h"); - if (counter == 71) $display(":%h:", 16'haa); - if (counter == 72) $display(":%-h:", 16'haa); - if (counter == 73) $display(":%0h:", 16'haa); - if (counter == 74) $display(":%-0h:", 16'haa); - if (counter == 75) $display(":%20h:", 16'haa); - if (counter == 76) $display(":%-20h:", 16'haa); - if (counter == 77) $display(":%020h:", 16'haa); - if (counter == 78) $display(":%-020h:", 16'haa); - - if (counter == 79) $display("==> big unsigned %%h"); - if (counter == 80) $display(":%h:", 16'haaaa); - if (counter == 81) $display(":%-h:", 16'haaaa); - if (counter == 82) $display(":%0h:", 16'haaaa); - if (counter == 83) $display(":%-0h:", 16'haaaa); - if (counter == 84) $display(":%20h:", 16'haaaa); - if (counter == 85) $display(":%-20h:", 16'haaaa); - if (counter == 86) $display(":%020h:", 16'haaaa); - if (counter == 87) $display(":%-020h:", 16'haaaa); - - if (counter == 88) $display("==> small signed %%h"); - if (counter == 89) $display(":%h:", 16'shaa); - if (counter == 90) $display(":%-h:", 16'shaa); - if (counter == 91) $display(":%0h:", 16'shaa); - if (counter == 92) $display(":%-0h:", 16'shaa); - if (counter == 93) $display(":%20h:", 16'shaa); - if (counter == 94) $display(":%-20h:", 16'shaa); - if (counter == 95) $display(":%020h:", 16'shaa); - if (counter == 96) $display(":%-020h:", 16'shaa); - - if (counter == 97) $display("==> big signed %%h"); - if (counter == 98) $display(":%h:", 16'shaaaa); - if (counter == 99) $display(":%-h:", 16'shaaaa); - if (counter == 100) $display(":%0h:", 16'shaaaa); - if (counter == 101) $display(":%-0h:", 16'shaaaa); - if (counter == 102) $display(":%20h:", 16'shaaaa); - if (counter == 103) $display(":%-20h:", 16'shaaaa); - if (counter == 104) $display(":%020h:", 16'shaaaa); - if (counter == 105) $display(":%-020h:", 16'shaaaa); - - if (counter == 106) $display("==> small unsigned %%o"); - if (counter == 107) $display(":%o:", 16'haa); - if (counter == 108) $display(":%-o:", 16'haa); - if (counter == 109) $display(":%0o:", 16'haa); - if (counter == 110) $display(":%-0o:", 16'haa); - if (counter == 111) $display(":%20o:", 16'haa); - if (counter == 112) $display(":%-20o:", 16'haa); - if (counter == 113) $display(":%020o:", 16'haa); - if (counter == 114) $display(":%-020o:", 16'haa); - - if (counter == 115) $display("==> big unsigned %%o"); - if (counter == 116) $display(":%o:", 16'haaaa); - if (counter == 117) $display(":%-o:", 16'haaaa); - if (counter == 118) $display(":%0o:", 16'haaaa); - if (counter == 119) $display(":%-0o:", 16'haaaa); - if (counter == 120) $display(":%20o:", 16'haaaa); - if (counter == 121) $display(":%-20o:", 16'haaaa); - if (counter == 122) $display(":%020o:", 16'haaaa); - if (counter == 123) $display(":%-020o:", 16'haaaa); - - if (counter == 124) $display("==> small signed %%o"); - if (counter == 125) $display(":%o:", 16'shaa); - if (counter == 126) $display(":%-o:", 16'shaa); - if (counter == 127) $display(":%0o:", 16'shaa); - if (counter == 128) $display(":%-0o:", 16'shaa); - if (counter == 129) $display(":%20o:", 16'shaa); - if (counter == 130) $display(":%-20o:", 16'shaa); - if (counter == 131) $display(":%020o:", 16'shaa); - if (counter == 132) $display(":%-020o:", 16'shaa); - - if (counter == 133) $display("==> big signed %%o"); - if (counter == 134) $display(":%o:", 16'shaaaa); - if (counter == 135) $display(":%-o:", 16'shaaaa); - if (counter == 136) $display(":%0o:", 16'shaaaa); - if (counter == 137) $display(":%-0o:", 16'shaaaa); - if (counter == 138) $display(":%20o:", 16'shaaaa); - if (counter == 139) $display(":%-20o:", 16'shaaaa); - if (counter == 140) $display(":%020o:", 16'shaaaa); - if (counter == 141) $display(":%-020o:", 16'shaaaa); - - if (counter == 142) $display("==> small unsigned %%b"); - if (counter == 143) $display(":%b:", 16'haa); - if (counter == 144) $display(":%-b:", 16'haa); - if (counter == 145) $display(":%0b:", 16'haa); - if (counter == 146) $display(":%-0b:", 16'haa); - if (counter == 147) $display(":%20b:", 16'haa); - if (counter == 148) $display(":%-20b:", 16'haa); - if (counter == 149) $display(":%020b:", 16'haa); - if (counter == 150) $display(":%-020b:", 16'haa); - - if (counter == 151) $display("==> big unsigned %%b"); - if (counter == 152) $display(":%b:", 16'haaaa); - if (counter == 153) $display(":%-b:", 16'haaaa); - if (counter == 154) $display(":%0b:", 16'haaaa); - if (counter == 155) $display(":%-0b:", 16'haaaa); - if (counter == 156) $display(":%20b:", 16'haaaa); - if (counter == 157) $display(":%-20b:", 16'haaaa); - if (counter == 158) $display(":%020b:", 16'haaaa); - if (counter == 159) $display(":%-020b:", 16'haaaa); - - if (counter == 160) $display("==> small signed %%b"); - if (counter == 161) $display(":%b:", 16'shaa); - if (counter == 162) $display(":%-b:", 16'shaa); - if (counter == 163) $display(":%0b:", 16'shaa); - if (counter == 164) $display(":%-0b:", 16'shaa); - if (counter == 165) $display(":%20b:", 16'shaa); - if (counter == 166) $display(":%-20b:", 16'shaa); - if (counter == 167) $display(":%020b:", 16'shaa); - if (counter == 168) $display(":%-020b:", 16'shaa); - - if (counter == 169) $display("==> big signed %%b"); - if (counter == 170) $display(":%b:", 16'shaaaa); - if (counter == 171) $display(":%-b:", 16'shaaaa); - if (counter == 172) $display(":%0b:", 16'shaaaa); - if (counter == 173) $display(":%-0b:", 16'shaaaa); - if (counter == 174) $display(":%20b:", 16'shaaaa); - if (counter == 175) $display(":%-20b:", 16'shaaaa); - if (counter == 176) $display(":%020b:", 16'shaaaa); - if (counter == 177) $display(":%-020b:", 16'shaaaa); - - if (counter == 178) $display("==> time %%t"); - if (counter == 179) $display(":%t:", $time); - if (counter == 180) $display(":%-t:", $time); - if (counter == 181) $display(":%0t:", $time); - if (counter == 182) $display(":%-0t:", $time); - if (counter == 183) $display(":%10t:", $time); - if (counter == 184) $display(":%-10t:", $time); - if (counter == 185) $display(":%015t:", $time); - if (counter == 186) $display(":%-015t:", $time); - - if (counter == 187) $display("===> %%s"); - if (counter == 188) $display(":%10s:", "foo"); - if (counter == 189) $display(":%010s:", "foo"); - if (counter == 190) $display(":%-10s:", "foo"); - if (counter == 191) $display(":%-010s:", "foo"); - - if (counter == 192) $display("===> %%c"); - if (counter == 193) $display(":%10c:", "foo"); - if (counter == 194) $display(":%010c:", "foo"); - if (counter == 195) $display(":%-10c:", "foo"); - if (counter == 196) $display(":%-010c:", "foo"); - - if (counter == 197) $display("==> aliases"); - if (counter == 198) $display(":%x:", 16'shaa); - if (counter == 199) $display(":%X:", 16'shaa); - if (counter == 200) $display(":%H:", 16'shaa); - if (counter == 201) $display(":%O:", 16'shaa); - if (counter == 202) $display(":%B:", 16'shaa); - - if (counter == 203) $display("==> default base"); - if (counter == 204) $displayh(16'haa); - if (counter == 205) $displayo(16'haa); - if (counter == 206) $displayb(16'haa); - - if (counter == 207) $display("==> write/format"); - if (counter == 208) $display("%d", 1, "%d", 1); - - if (counter == 209) fin <= 1; + $display("==> small unsigned %%d"); + $display(":%d:", 16'haa); + $display(":%-d:", 16'haa); + $display(":%+d:", 16'haa); + $display(":%+-d:", 16'haa); + $display(":%0d:", 16'haa); + $display(":%-0d:", 16'haa); + $display(":%+0d:", 16'haa); + $display(":%+-0d:", 16'haa); + $display(":%20d:", 16'haa); + $display(":%-20d:", 16'haa); + $display(":%+20d:", 16'haa); + $display(":%+-20d:", 16'haa); + $display(":%020d:", 16'haa); + $display(":%-020d:", 16'haa); + $display(":%+020d:", 16'haa); + $display(":%+-020d:", 16'haa); + + $display("==> big unsigned %%d"); + $display(":%d:", 16'haaaa); + $display(":%-d:", 16'haaaa); + $display(":%+d:", 16'haaaa); + $display(":%+-d:", 16'haaaa); + $display(":%0d:", 16'haaaa); + $display(":%-0d:", 16'haaaa); + $display(":%+0d:", 16'haaaa); + $display(":%+-0d:", 16'haaaa); + $display(":%20d:", 16'haaaa); + $display(":%-20d:", 16'haaaa); + $display(":%+20d:", 16'haaaa); + $display(":%+-20d:", 16'haaaa); + $display(":%020d:", 16'haaaa); + $display(":%-020d:", 16'haaaa); + $display(":%+020d:", 16'haaaa); + $display(":%+-020d:", 16'haaaa); + + $display("==> small signed %%d"); + $display(":%d:", 16'shaa); + $display(":%-d:", 16'shaa); + $display(":%+d:", 16'shaa); + $display(":%+-d:", 16'shaa); + $display(":%0d:", 16'shaa); + $display(":%-0d:", 16'shaa); + $display(":%+0d:", 16'shaa); + $display(":%+-0d:", 16'shaa); + $display(":%20d:", 16'shaa); + $display(":%-20d:", 16'shaa); + $display(":%+20d:", 16'shaa); + $display(":%+-20d:", 16'shaa); + $display(":%020d:", 16'shaa); + $display(":%-020d:", 16'shaa); + $display(":%+020d:", 16'shaa); + $display(":%+-020d:", 16'shaa); + + $display("==> big signed %%d"); + $display(":%d:", 16'shaaaa); + $display(":%-d:", 16'shaaaa); + $display(":%+d:", 16'shaaaa); + $display(":%+-d:", 16'shaaaa); + $display(":%0d:", 16'shaaaa); + $display(":%-0d:", 16'shaaaa); + $display(":%+0d:", 16'shaaaa); + $display(":%+-0d:", 16'shaaaa); + $display(":%20d:", 16'shaaaa); + $display(":%-20d:", 16'shaaaa); + $display(":%+20d:", 16'shaaaa); + $display(":%+-20d:", 16'shaaaa); + $display(":%020d:", 16'shaaaa); + $display(":%-020d:", 16'shaaaa); + $display(":%+020d:", 16'shaaaa); + $display(":%+-020d:", 16'shaaaa); + + $display("==> small unsigned %%h"); + $display(":%h:", 16'haa); + $display(":%-h:", 16'haa); + $display(":%0h:", 16'haa); + $display(":%-0h:", 16'haa); + $display(":%20h:", 16'haa); + $display(":%-20h:", 16'haa); + $display(":%020h:", 16'haa); + $display(":%-020h:", 16'haa); + + $display("==> big unsigned %%h"); + $display(":%h:", 16'haaaa); + $display(":%-h:", 16'haaaa); + $display(":%0h:", 16'haaaa); + $display(":%-0h:", 16'haaaa); + $display(":%20h:", 16'haaaa); + $display(":%-20h:", 16'haaaa); + $display(":%020h:", 16'haaaa); + $display(":%-020h:", 16'haaaa); + + $display("==> small signed %%h"); + $display(":%h:", 16'shaa); + $display(":%-h:", 16'shaa); + $display(":%0h:", 16'shaa); + $display(":%-0h:", 16'shaa); + $display(":%20h:", 16'shaa); + $display(":%-20h:", 16'shaa); + $display(":%020h:", 16'shaa); + $display(":%-020h:", 16'shaa); + + $display("==> big signed %%h"); + $display(":%h:", 16'shaaaa); + $display(":%-h:", 16'shaaaa); + $display(":%0h:", 16'shaaaa); + $display(":%-0h:", 16'shaaaa); + $display(":%20h:", 16'shaaaa); + $display(":%-20h:", 16'shaaaa); + $display(":%020h:", 16'shaaaa); + $display(":%-020h:", 16'shaaaa); + + $display("==> small unsigned %%o"); + $display(":%o:", 16'haa); + $display(":%-o:", 16'haa); + $display(":%0o:", 16'haa); + $display(":%-0o:", 16'haa); + $display(":%20o:", 16'haa); + $display(":%-20o:", 16'haa); + $display(":%020o:", 16'haa); + $display(":%-020o:", 16'haa); + + $display("==> big unsigned %%o"); + $display(":%o:", 16'haaaa); + $display(":%-o:", 16'haaaa); + $display(":%0o:", 16'haaaa); + $display(":%-0o:", 16'haaaa); + $display(":%20o:", 16'haaaa); + $display(":%-20o:", 16'haaaa); + $display(":%020o:", 16'haaaa); + $display(":%-020o:", 16'haaaa); + + $display("==> small signed %%o"); + $display(":%o:", 16'shaa); + $display(":%-o:", 16'shaa); + $display(":%0o:", 16'shaa); + $display(":%-0o:", 16'shaa); + $display(":%20o:", 16'shaa); + $display(":%-20o:", 16'shaa); + $display(":%020o:", 16'shaa); + $display(":%-020o:", 16'shaa); + + $display("==> big signed %%o"); + $display(":%o:", 16'shaaaa); + $display(":%-o:", 16'shaaaa); + $display(":%0o:", 16'shaaaa); + $display(":%-0o:", 16'shaaaa); + $display(":%20o:", 16'shaaaa); + $display(":%-20o:", 16'shaaaa); + $display(":%020o:", 16'shaaaa); + $display(":%-020o:", 16'shaaaa); + + $display("==> small unsigned %%b"); + $display(":%b:", 16'haa); + $display(":%-b:", 16'haa); + $display(":%0b:", 16'haa); + $display(":%-0b:", 16'haa); + $display(":%20b:", 16'haa); + $display(":%-20b:", 16'haa); + $display(":%020b:", 16'haa); + $display(":%-020b:", 16'haa); + + $display("==> big unsigned %%b"); + $display(":%b:", 16'haaaa); + $display(":%-b:", 16'haaaa); + $display(":%0b:", 16'haaaa); + $display(":%-0b:", 16'haaaa); + $display(":%20b:", 16'haaaa); + $display(":%-20b:", 16'haaaa); + $display(":%020b:", 16'haaaa); + $display(":%-020b:", 16'haaaa); + + $display("==> small signed %%b"); + $display(":%b:", 16'shaa); + $display(":%-b:", 16'shaa); + $display(":%0b:", 16'shaa); + $display(":%-0b:", 16'shaa); + $display(":%20b:", 16'shaa); + $display(":%-20b:", 16'shaa); + $display(":%020b:", 16'shaa); + $display(":%-020b:", 16'shaa); + + $display("==> big signed %%b"); + $display(":%b:", 16'shaaaa); + $display(":%-b:", 16'shaaaa); + $display(":%0b:", 16'shaaaa); + $display(":%-0b:", 16'shaaaa); + $display(":%20b:", 16'shaaaa); + $display(":%-20b:", 16'shaaaa); + $display(":%020b:", 16'shaaaa); + $display(":%-020b:", 16'shaaaa); + + $display("==> time %%t"); + $display(":%t:", $time); + $display(":%-t:", $time); + $display(":%0t:", $time); + $display(":%-0t:", $time); + $display(":%10t:", $time); + $display(":%-10t:", $time); + $display(":%015t:", $time); + $display(":%-015t:", $time); + + $display("===> %%s"); + $display(":%10s:", "foo"); + $display(":%010s:", "foo"); + $display(":%-10s:", "foo"); + $display(":%-010s:", "foo"); + + $display("===> %%c"); + $display(":%10c:", "foo"); + $display(":%010c:", "foo"); + $display(":%-10c:", "foo"); + $display(":%-010c:", "foo"); + + $display("==> aliases"); + $display(":%x:", 16'shaa); + $display(":%X:", 16'shaa); + $display(":%H:", 16'shaa); + $display(":%O:", 16'shaa); + $display(":%B:", 16'shaa); + + $display("==> default base"); + $displayh(16'haa); + $displayo(16'haa); + $displayb(16'haa); + + $display("==> write/format"); + $display("%d", 1, "%d", 1); end diff --git a/tests/fmt/always_full_tb.cc b/tests/fmt/always_full_tb.cc index 8bf1022d330..bd98020dec1 100644 --- a/tests/fmt/always_full_tb.cc +++ b/tests/fmt/always_full_tb.cc @@ -4,12 +4,7 @@ int main() { cxxrtl_design::p_always__full uut; - - while (true) { - uut.p_clk.set(!uut.p_clk); - uut.step(); - - if (uut.p_fin.get()) - return 0; - } + uut.p_clk.set(!uut.p_clk); + uut.step(); + return 0; } diff --git a/tests/fmt/always_full_tb.v b/tests/fmt/always_full_tb.v index 1edd35b67d9..0c2599cc263 100644 --- a/tests/fmt/always_full_tb.v +++ b/tests/fmt/always_full_tb.v @@ -1,14 +1,12 @@ module always_full_tb; reg clk = 0; - wire fin; - always_full uut (.clk(clk), .fin(fin)); + always_full uut (.clk(clk)); always begin #1 clk <= ~clk; - - if (fin) $finish; + #1 $finish; end endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 44759dbc140..ba5aea9f627 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -61,6 +61,12 @@ test_cxxrtl () { test_cxxrtl always_full test_cxxrtl always_comb +# Ensure Verilog backend preserves behaviour of always block with multiple $displays. +../../yosys -p "read_verilog always_full.v; prep; clean" -o yosys-always_full-1.v +iverilog -o iverilog-always_full-1 yosys-always_full-1.v always_full_tb.v +./iverilog-always_full-1 |grep -v '\$finish called' >iverilog-always_full-1.log +diff iverilog-always_full.log iverilog-always_full-1.log + ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" ${CC:-gcc} -std=c++11 -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ From ce245b51054a316d3f4c3476335a4b42221af21f Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:33 +1000 Subject: [PATCH 048/119] cxxrtl_backend: respect sync `$print` priority We add a new flow graph node type, PRINT_SYNC, as they don't get handled with regular CELL_EVALs. We could probably move this grouping out of the dump method. --- backends/cxxrtl/cxxrtl_backend.cc | 102 +++++++++++++++++----------- backends/verilog/verilog_backend.cc | 6 +- tests/fmt/run-test.sh | 2 +- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 17080ef2ec6..8f9cd941ecb 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -282,6 +282,7 @@ struct FlowGraph { CONNECT, CELL_SYNC, CELL_EVAL, + PRINT_SYNC, PROCESS_SYNC, PROCESS_CASE, MEM_RDPORT, @@ -472,6 +473,8 @@ struct FlowGraph { Node *node = new Node; node->type = Node::Type::CELL_EVAL; + if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) + node->type = Node::Type::PRINT_SYNC; node->cell = cell; nodes.push_back(node); add_cell_eval_defs_uses(node, cell); @@ -1043,9 +1046,49 @@ struct CxxrtlWorker { Fmt fmt = {}; fmt.parse_rtlil(cell); - f << indent << print_output; - fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); - f << ";\n"; + f << indent << "if ("; + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << " == value<1>{1u}) {\n"; + inc_indent(); + f << indent << print_output; + fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); + f << ";\n"; + dec_indent(); + f << indent << "}\n"; + } + + void dump_sync_print(const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) + { + f << indent << "if ("; + for (int i = 0; i < trg.size(); i++) { + RTLIL::SigBit trg_bit = trg[i]; + trg_bit = sigmaps[trg_bit.wire->module](trg_bit); + log_assert(trg_bit.wire); + + if (i != 0) + f << " || "; + + if (polarity[i] == State::S1) + f << "posedge_"; + else + f << "negedge_"; + f << mangle(trg_bit); + } + f << ") {\n"; + inc_indent(); + std::sort(cells.begin(), 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 cell : cells) { + log_assert(cell->getParam(ID::TRG_ENABLE).as_bool()); + std::vector inlined_cells; + collect_cell_eval(cell, /*for_debug=*/false, inlined_cells); + dump_inlined_cells(inlined_cells); + dump_print(cell); + } + dec_indent(); + + f << indent << "}\n"; } void dump_inlined_cells(const std::vector &cells) @@ -1218,47 +1261,21 @@ struct CxxrtlWorker { } else if (cell->type == ID($print)) { log_assert(!for_debug); - auto trg_enable = cell->getParam(ID::TRG_ENABLE).as_bool(); + // Sync $print cells become PRINT_SYNC in the FlowGraph, not CELL_EVAL. + log_assert(!cell->getParam(ID::TRG_ENABLE).as_bool()); - if (!trg_enable) { - f << indent << "auto " << mangle(cell) << "_curr = "; - dump_sigspec_rhs(cell->getPort(ID::EN)); - f << ".concat("; - dump_sigspec_rhs(cell->getPort(ID::ARGS)); - f << ").val();\n"; - } - - f << indent << "if ("; - if (trg_enable) { - f << '('; - for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { - RTLIL::SigBit trg_bit = cell->getPort(ID::TRG)[i]; - trg_bit = sigmaps[trg_bit.wire->module](trg_bit); - log_assert(trg_bit.wire); - - if (i != 0) - f << " || "; - - if (cell->getParam(ID::TRG_POLARITY)[i] == State::S1) - f << "posedge_"; - else - f << "negedge_"; - f << mangle(trg_bit); - } - f << ") && "; - } else { - f << mangle(cell) << " != " << mangle(cell) << "_curr && "; - } + f << indent << "auto " << mangle(cell) << "_curr = "; dump_sigspec_rhs(cell->getPort(ID::EN)); - f << " == value<1>{1u}) {\n"; + f << ".concat("; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ").val();\n"; + + f << indent << "if (" << mangle(cell) << " != " << mangle(cell) << "_curr) {\n"; inc_indent(); dump_print(cell); + f << indent << mangle(cell) << " = " << mangle(cell) << "_curr;\n"; dec_indent(); f << indent << "}\n"; - - if (!trg_enable) { - f << indent << mangle(cell) << " = " << mangle(cell) << "_curr;\n"; - } // Flip-flops } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); @@ -1971,6 +1988,8 @@ struct CxxrtlWorker { void dump_eval_method(RTLIL::Module *module) { + std::map, std::vector> sync_print_cells; + inc_indent(); f << indent << "bool converged = " << (eval_converges.at(module) ? "true" : "false") << ";\n"; if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { @@ -2003,6 +2022,9 @@ struct CxxrtlWorker { case FlowGraph::Node::Type::CELL_EVAL: dump_cell_eval(node.cell); break; + case FlowGraph::Node::Type::PRINT_SYNC: + sync_print_cells[make_pair(node.cell->getPort(ID::TRG), node.cell->getParam(ID::TRG_POLARITY))].push_back(node.cell); + break; case FlowGraph::Node::Type::PROCESS_CASE: dump_process_case(node.process); break; @@ -2017,6 +2039,8 @@ struct CxxrtlWorker { break; } } + for (auto &it : sync_print_cells) + dump_sync_print(it.first.first, it.first.second, it.second); } f << indent << "return converged;\n"; dec_indent(); @@ -2808,6 +2832,8 @@ struct CxxrtlWorker { for (auto node : flow.nodes) { if (node->type == FlowGraph::Node::Type::CELL_EVAL && is_effectful_cell(node->cell->type)) worklist.insert(node); // node has effects + else if (node->type == FlowGraph::Node::Type::PRINT_SYNC) + worklist.insert(node); // node is sync $print else if (node->type == FlowGraph::Node::Type::MEM_WRPORTS) worklist.insert(node); // node is memory write else if (node->type == FlowGraph::Node::Type::PROCESS_SYNC && is_memwr_process(node->process)) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index ca119427f6d..7099c18c349 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1006,7 +1006,7 @@ void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell f << stringf(";\n"); } -void dump_cell_expr_print(std::ostream &f, std::string indent, RTLIL::Cell *cell) +void dump_cell_expr_print(std::ostream &f, std::string indent, const RTLIL::Cell *cell) { Fmt fmt = {}; fmt.parse_rtlil(cell); @@ -1893,7 +1893,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) } } -void dump_sync_print(std::ostream &f, std::string indent, const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) +void dump_sync_print(std::ostream &f, std::string indent, const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) { f << stringf("%s" "always @(", indent.c_str()); for (int i = 0; i < trg.size(); i++) { @@ -2102,7 +2102,7 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) { - std::map, std::vector> sync_print_cells; + std::map, std::vector> sync_print_cells; reg_wires.clear(); reset_auto_counter(module); diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index ba5aea9f627..914a7234747 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -50,7 +50,7 @@ test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" test_cxxrtl () { local subtest=$1; shift - ../../yosys -p "read_verilog ${subtest}.v; write_cxxrtl -print-output std::cerr yosys-${subtest}.cc" + ../../yosys -p "read_verilog ${subtest}.v; proc; clean; write_cxxrtl -print-output std::cerr yosys-${subtest}.cc" ${CC:-gcc} -std=c++11 -o yosys-${subtest} -I../.. ${subtest}_tb.cc -lstdc++ ./yosys-${subtest} 2>yosys-${subtest}.log iverilog -o iverilog-${subtest} ${subtest}.v ${subtest}_tb.v From 2829cd9caa5729b3b7e2393d3428e265cd038ea6 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:34 +1000 Subject: [PATCH 049/119] cxxrtl_backend: move sync $print grouping out of dump into analyze --- backends/cxxrtl/cxxrtl_backend.cc | 48 +++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 8f9cd941ecb..3a3bc39bcd6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -292,6 +292,7 @@ struct FlowGraph { Type type; RTLIL::SigSig connect = {}; const RTLIL::Cell *cell = nullptr; + std::vector print_sync_cells; const RTLIL::Process *process = nullptr; const Mem *mem = nullptr; int portidx; @@ -473,14 +474,21 @@ struct FlowGraph { Node *node = new Node; node->type = Node::Type::CELL_EVAL; - if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) - node->type = Node::Type::PRINT_SYNC; node->cell = cell; nodes.push_back(node); add_cell_eval_defs_uses(node, cell); return node; } + Node *add_print_sync_node(std::vector cells) + { + Node *node = new Node; + node->type = Node::Type::PRINT_SYNC; + node->print_sync_cells = cells; + nodes.push_back(node); + return node; + } + // Processes void add_case_rule_defs_uses(Node *node, const RTLIL::CaseRule *case_) { @@ -1057,8 +1065,12 @@ struct CxxrtlWorker { f << indent << "}\n"; } - void dump_sync_print(const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) + void dump_sync_print(std::vector &cells) { + log_assert(!cells.empty()); + const auto &trg = cells[0]->getPort(ID::TRG); + const auto &trg_polarity = cells[0]->getParam(ID::TRG_POLARITY); + f << indent << "if ("; for (int i = 0; i < trg.size(); i++) { RTLIL::SigBit trg_bit = trg[i]; @@ -1068,7 +1080,7 @@ struct CxxrtlWorker { if (i != 0) f << " || "; - if (polarity[i] == State::S1) + if (trg_polarity[i] == State::S1) f << "posedge_"; else f << "negedge_"; @@ -1081,6 +1093,9 @@ struct CxxrtlWorker { }); for (auto cell : cells) { log_assert(cell->getParam(ID::TRG_ENABLE).as_bool()); + log_assert(cell->getPort(ID::TRG) == trg); + log_assert(cell->getParam(ID::TRG_POLARITY) == trg_polarity); + std::vector inlined_cells; collect_cell_eval(cell, /*for_debug=*/false, inlined_cells); dump_inlined_cells(inlined_cells); @@ -1261,7 +1276,7 @@ struct CxxrtlWorker { } else if (cell->type == ID($print)) { log_assert(!for_debug); - // Sync $print cells become PRINT_SYNC in the FlowGraph, not CELL_EVAL. + // Sync $print cells are grouped into PRINT_SYNC nodes in the FlowGraph. log_assert(!cell->getParam(ID::TRG_ENABLE).as_bool()); f << indent << "auto " << mangle(cell) << "_curr = "; @@ -1988,8 +2003,6 @@ struct CxxrtlWorker { void dump_eval_method(RTLIL::Module *module) { - std::map, std::vector> sync_print_cells; - inc_indent(); f << indent << "bool converged = " << (eval_converges.at(module) ? "true" : "false") << ";\n"; if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { @@ -2023,7 +2036,7 @@ struct CxxrtlWorker { dump_cell_eval(node.cell); break; case FlowGraph::Node::Type::PRINT_SYNC: - sync_print_cells[make_pair(node.cell->getPort(ID::TRG), node.cell->getParam(ID::TRG_POLARITY))].push_back(node.cell); + dump_sync_print(node.print_sync_cells); break; case FlowGraph::Node::Type::PROCESS_CASE: dump_process_case(node.process); @@ -2039,8 +2052,6 @@ struct CxxrtlWorker { break; } } - for (auto &it : sync_print_cells) - dump_sync_print(it.first.first, it.first.second, it.second); } f << indent << "return converged;\n"; dec_indent(); @@ -2890,9 +2901,22 @@ struct CxxrtlWorker { } // Emit reachable nodes in eval(). + // Accumulate sync $print cells per trigger condition. + dict, std::vector> sync_print_cells; for (auto node : node_order) - if (live_nodes[node]) - schedule[module].push_back(*node); + if (live_nodes[node]) { + if (node->type == FlowGraph::Node::Type::CELL_EVAL && + node->cell->type == ID($print) && + node->cell->getParam(ID::TRG_ENABLE).as_bool()) + sync_print_cells[make_pair(node->cell->getPort(ID::TRG), node->cell->getParam(ID::TRG_POLARITY))].push_back(node->cell); + else + schedule[module].push_back(*node); + } + + for (auto &it : sync_print_cells) { + auto node = flow.add_print_sync_node(it.second); + schedule[module].push_back(*node); + } // For maximum performance, the state of the simulation (which is the same as the set of its double buffered // wires, since using a singly buffered wire for any kind of state introduces a race condition) should contain From 40978971f4fe8ad4d089b70526313bf0c6d1ec65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Aug 2023 00:13:32 +0000 Subject: [PATCH 050/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7883cf2b9b8..8beae8a355e 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+1 +YOSYS_VER := 0.32+43 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From bf84861fc2abeb877b770b33206ff2ee61d11552 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Fri, 11 Aug 2023 15:52:05 +1000 Subject: [PATCH 051/119] proc_clean: only consider fully-defined case operands. --- passes/proc/proc_clean.cc | 2 +- tests/proc/clean_undef_case.ys | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/proc/clean_undef_case.ys diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 45872907bd8..6ce2f8cb031 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -41,7 +41,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did break; for (int j = 0; j < int(cs->compare.size()); j++) { RTLIL::SigSpec &val = cs->compare[j]; - if (!val.is_fully_const()) + if (!val.is_fully_def()) continue; if (val == sw->signal) { cs->compare.clear(); diff --git a/tests/proc/clean_undef_case.ys b/tests/proc/clean_undef_case.ys new file mode 100644 index 00000000000..3c29c93bcab --- /dev/null +++ b/tests/proc/clean_undef_case.ys @@ -0,0 +1,22 @@ +read_rtlil < Date: Fri, 11 Aug 2023 16:34:00 +1000 Subject: [PATCH 052/119] proc_clean: only consider fully-defined switch operands too. --- passes/proc/proc_clean.cc | 2 +- tests/proc/clean_undef_case.ys | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 6ce2f8cb031..95cb0e88ca9 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -31,7 +31,7 @@ PRIVATE_NAMESPACE_BEGIN void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth) { - if (sw->signal.size() > 0 && sw->signal.is_fully_const()) + if (sw->signal.size() > 0 && sw->signal.is_fully_def()) { int found_matching_case_idx = -1; for (int i = 0; i < int(sw->cases.size()) && found_matching_case_idx < 0; i++) diff --git a/tests/proc/clean_undef_case.ys b/tests/proc/clean_undef_case.ys index 3c29c93bcab..c874b08c017 100644 --- a/tests/proc/clean_undef_case.ys +++ b/tests/proc/clean_undef_case.ys @@ -1,6 +1,6 @@ read_rtlil < Date: Sun, 13 Aug 2023 00:15:02 +0000 Subject: [PATCH 053/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8beae8a355e..657b2c245df 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+43 +YOSYS_VER := 0.32+46 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 6d9cd16fadfab64201a07ae9e84e4596a4497fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 14 Aug 2023 11:42:19 +0200 Subject: [PATCH 054/119] cellaigs: Drop initializer list in call to `IdString::in` Remove superfluous curly braces in call to IdString::in to address a compilation error (reproduced below) under GCC 9 and earlier. kernel/cellaigs.cc:395:18: error: call to member function 'in' is ambiguous if (cell->type.in({ID($gt), ID($ge)})) ~~~~~~~~~~~^~ ./kernel/rtlil.h:383:8: note: candidate function bool in(const std::string &rhs) const { return *this == rhs; } ^ ./kernel/rtlil.h:384:8: note: candidate function bool in(const pool &rhs) const { return rhs.co... ^ --- kernel/cellaigs.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 332f821b76c..5dda4503fdd 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -385,17 +385,17 @@ Aig::Aig(Cell *cell) goto optimize; } - if (cell->type.in({ID($lt), ID($gt), ID($le), ID($ge)})) + if (cell->type.in(ID($lt), ID($gt), ID($le), ID($ge))) { int width = std::max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B))) + 1; vector A = mk.inport_vec(ID::A, width); vector B = mk.inport_vec(ID::B, width); - if (cell->type.in({ID($gt), ID($ge)})) + if (cell->type.in(ID($gt), ID($ge))) std::swap(A, B); - int carry = mk.bool_node(!cell->type.in({ID($le), ID($ge)})); + int carry = mk.bool_node(!cell->type.in(ID($le), ID($ge))); for (auto &n : B) n = mk.not_gate(n); vector Y = mk.adder(A, B, carry); From cbd3ff2d3a8d29fda2d796e4db5feb384990812c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 00:14:23 +0000 Subject: [PATCH 055/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 657b2c245df..33fe11c5207 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+46 +YOSYS_VER := 0.32+49 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From d525a414978236682e067180a8a5d94189f67335 Mon Sep 17 00:00:00 2001 From: Ethan Mahintorabi Date: Tue, 15 Aug 2023 20:03:46 +0000 Subject: [PATCH 056/119] abc: Exposes dont_use flag in ABC ABC's read_lib command has a dont_use cell list that is configurable by the user. This PR exposes that option to Yosys. See https://github.com/berkeley-abc/abc/blob/5405d4787a86615de76afccf1356676fb5c56c1c/src/map/scl/scl.c#L285 for documentation on this option. Signed-off-by: Ethan Mahintorabi --- passes/techmap/abc.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 364a8e54458..f36cadc8882 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 std::vector &liberty_files, std::vector &genlib_files, std::string constr_file, bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, bool keepff, std::string delay_target, std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode, - const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress) + const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector &dont_use_cells) { module = current_module; map_autoidx = autoidx++; @@ -795,8 +795,13 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin std::string abc_script = stringf("read_blif \"%s/input.blif\"; ", tempdir_name.c_str()); if (!liberty_files.empty() || !genlib_files.empty()) { - for (std::string liberty_file : liberty_files) - abc_script += stringf("read_lib -w \"%s\"; ", liberty_file.c_str()); + std::string dont_use_args; + for (std::string dont_use_cell : dont_use_cells) { + dont_use_args += stringf("-X \"%s\" ", dont_use_cell.c_str()); + } + for (std::string liberty_file : liberty_files) { + abc_script += stringf("read_lib %s -w \"%s\" ; ", dont_use_args.c_str(), liberty_file.c_str()); + } for (std::string liberty_file : genlib_files) abc_script += stringf("read_library \"%s\"; ", liberty_file.c_str()); if (!constr_file.empty()) @@ -1503,6 +1508,10 @@ struct AbcPass : public Pass { log(" generate netlists for the specified cell library (using the liberty\n"); log(" file format).\n"); log("\n"); + log(" -dont_use \n"); + log(" generate netlists for the specified cell library (using the liberty\n"); + log(" file format).\n"); + log("\n"); log(" -genlib \n"); log(" generate netlists for the specified cell library (using the SIS Genlib\n"); log(" file format).\n"); @@ -1639,7 +1648,7 @@ struct AbcPass : public Pass { std::string exe_file = yosys_abc_executable; std::string script_file, default_liberty_file, constr_file, clk_str; - std::vector liberty_files, genlib_files; + std::vector liberty_files, genlib_files, dont_use_cells; std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1"; bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; bool show_tempdir = false, sop_mode = false; @@ -1722,6 +1731,10 @@ struct AbcPass : public Pass { liberty_files.push_back(args[++argidx]); continue; } + if (arg == "-dont_use" && argidx+1 < args.size()) { + dont_use_cells.push_back(args[++argidx]); + continue; + } if (arg == "-genlib" && argidx+1 < args.size()) { genlib_files.push_back(args[++argidx]); continue; @@ -2028,7 +2041,7 @@ struct AbcPass : public Pass { if (!dff_mode || !clk_str.empty()) { abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, - delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress); + delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress, dont_use_cells); continue; } @@ -2190,7 +2203,7 @@ struct AbcPass : public Pass { srst_polarity = std::get<6>(it.first); srst_sig = assign_map(std::get<7>(it.first)); abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", - keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress); + keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress, dont_use_cells); assign_map.set(mod); } } From 4a475fa7a2788679b4c575dc3c1231a065d35271 Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Wed, 19 Apr 2023 19:54:09 +1000 Subject: [PATCH 057/119] cxxrtl: include iostream when prints are used --- backends/cxxrtl/cxxrtl_backend.cc | 5 +++++ tests/fmt/always_comb_tb.cc | 1 - tests/fmt/always_full_tb.cc | 1 - tests/fmt/display_lm_tb.cc | 5 ++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 3a3bc39bcd6..7696ae5747c 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2474,6 +2474,7 @@ struct CxxrtlWorker { RTLIL::Module *top_module = nullptr; std::vector modules; TopoSort topo_design; + bool has_prints = false; for (auto module : design->modules()) { if (!design->selected_module(module)) continue; @@ -2486,6 +2487,8 @@ struct CxxrtlWorker { topo_design.node(module); for (auto cell : module->cells()) { + if (cell->type == ID($print)) + has_prints = true; if (is_internal_cell(cell->type) || is_cxxrtl_blackbox_cell(cell)) continue; RTLIL::Module *cell_module = design->module(cell->type); @@ -2544,6 +2547,8 @@ struct CxxrtlWorker { f << "#include \"" << intf_filename << "\"\n"; else f << "#include \n"; + if (has_prints) + f << "#include \n"; f << "\n"; f << "#if defined(CXXRTL_INCLUDE_CAPI_IMPL) || \\\n"; f << " defined(CXXRTL_INCLUDE_VCD_CAPI_IMPL)\n"; diff --git a/tests/fmt/always_comb_tb.cc b/tests/fmt/always_comb_tb.cc index f2a8c6b2695..5812500535a 100644 --- a/tests/fmt/always_comb_tb.cc +++ b/tests/fmt/always_comb_tb.cc @@ -1,4 +1,3 @@ -#include #include "yosys-always_comb.cc" int main() diff --git a/tests/fmt/always_full_tb.cc b/tests/fmt/always_full_tb.cc index bd98020dec1..229f78aebe1 100644 --- a/tests/fmt/always_full_tb.cc +++ b/tests/fmt/always_full_tb.cc @@ -1,4 +1,3 @@ -#include #include "yosys-always_full.cc" int main() diff --git a/tests/fmt/display_lm_tb.cc b/tests/fmt/display_lm_tb.cc index ebc62f80fad..7a593d72919 100644 --- a/tests/fmt/display_lm_tb.cc +++ b/tests/fmt/display_lm_tb.cc @@ -1,10 +1,9 @@ -#include #include "yosys-display_lm.cc" int main() { cxxrtl_design::p_top uut; - uut.step(); - return 0; + uut.step(); + return 0; } From 6405bbab1e8afc587febf41339aaf8b514c8f202 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 00:14:07 +0000 Subject: [PATCH 058/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 33fe11c5207..09cf4992dab 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+49 +YOSYS_VER := 0.32+51 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a8809989c4f31e284a2bed593d71e9a11deec771 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 22 Aug 2023 10:50:11 +0200 Subject: [PATCH 059/119] ecp5_gsr -> lattice_gsr, change opt_lut_ins to accept lattice as tech --- passes/opt/opt_lut_ins.cc | 14 +++++++------- techlibs/ecp5/Makefile.inc | 2 +- techlibs/ecp5/synth_ecp5.cc | 4 ++-- techlibs/lattice/Makefile.inc | 1 + .../{ecp5/ecp5_gsr.cc => lattice/lattice_gsr.cc} | 10 +++++----- techlibs/machxo2/synth_machxo2.cc | 2 +- 6 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 techlibs/lattice/Makefile.inc rename techlibs/{ecp5/ecp5_gsr.cc => lattice/lattice_gsr.cc} (93%) diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index 2f7c392b29a..652fce1e2d5 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -39,7 +39,7 @@ struct OptLutInsPass : public Pass { log("\n"); log(" -tech \n"); log(" Instead of generic $lut cells, operate on LUT cells specific\n"); - log(" to the given technology. Valid values are: xilinx, ecp5, gowin.\n"); + log(" to the given technology. Valid values are: xilinx, lattice, gowin.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -58,7 +58,7 @@ struct OptLutInsPass : public Pass { } extra_args(args, argidx, design); - if (techname != "" && techname != "xilinx" && techname != "ecp5" && techname != "gowin") + if (techname != "" && techname != "xilinx" && techname != "lattice" && techname != "ecp5" && techname != "gowin") log_cmd_error("Unsupported technology: '%s'\n", techname.c_str()); for (auto module : design->selected_modules()) @@ -130,7 +130,7 @@ struct OptLutInsPass : public Pass { output = cell->getPort(ID::O); else output = cell->getPort(ID::F); - } else if (techname == "ecp5") { + } else if (techname == "lattice" || techname == "ecp5") { if (cell->type == ID(LUT4)) { inputs = { cell->getPort(ID::A), @@ -181,7 +181,7 @@ struct OptLutInsPass : public Pass { if (!doit) continue; log(" Optimizing lut %s (%d -> %d)\n", log_id(cell), GetSize(inputs), GetSize(new_inputs)); - if (techname == "ecp5") { + if (techname == "lattice" || techname == "ecp5") { // Pad the LUT to 4 inputs, adding consts from the front. int extra = 4 - GetSize(new_inputs); log_assert(extra >= 0); @@ -215,9 +215,9 @@ struct OptLutInsPass : public Pass { } new_lut[i] = lut[lidx]; } - // For ecp5, and gowin do not replace with a const driver — the nextpnr + // For lattice, and gowin do not replace with a const driver — the nextpnr // packer requires a complete set of LUTs for wide LUT muxes. - if (new_inputs.empty() && techname != "ecp5" && techname != "gowin") { + if (new_inputs.empty() && techname != "lattice" && techname != "ecp5" && techname != "gowin") { // const driver. remove_cells.push_back(cell); module->connect(output, new_lut[0]); @@ -226,7 +226,7 @@ struct OptLutInsPass : public Pass { cell->setParam(ID::LUT, new_lut); cell->setParam(ID::WIDTH, GetSize(new_inputs)); cell->setPort(ID::A, new_inputs); - } else if (techname == "ecp5") { + } else if (techname == "lattice" || techname == "ecp5") { log_assert(GetSize(new_inputs) == 4); cell->setParam(ID::INIT, new_lut); cell->setPort(ID::A, new_inputs[0]); diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index f9fa79ab9ad..a1c9bfc5233 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -1,5 +1,5 @@ -OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o +OBJS += techlibs/ecp5/synth_ecp5.o $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_ff.vh)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_io.vh)) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 82e23486844..fdc36e55267 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -359,7 +359,7 @@ struct SynthEcp5Pass : public ScriptPass run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); run("opt_expr -undriven -mux_undef"); run("simplemap"); - run("ecp5_gsr"); + run("lattice_gsr"); run("attrmvcp -copy -attr syn_useioff"); run("opt_clean"); } @@ -404,7 +404,7 @@ struct SynthEcp5Pass : public ScriptPass run("techmap -map +/ecp5/cells_map.v", "(skip if -vpr)"); else if (!vpr) run("techmap -map +/ecp5/cells_map.v"); - run("opt_lut_ins -tech ecp5"); + run("opt_lut_ins -tech lattice"); run("clean"); } diff --git a/techlibs/lattice/Makefile.inc b/techlibs/lattice/Makefile.inc new file mode 100644 index 00000000000..b198de0cc11 --- /dev/null +++ b/techlibs/lattice/Makefile.inc @@ -0,0 +1 @@ +OBJS += techlibs/lattice/lattice_gsr.o diff --git a/techlibs/ecp5/ecp5_gsr.cc b/techlibs/lattice/lattice_gsr.cc similarity index 93% rename from techlibs/ecp5/ecp5_gsr.cc rename to techlibs/lattice/lattice_gsr.cc index 62b231aab3b..d7d41eca519 100644 --- a/techlibs/ecp5/ecp5_gsr.cc +++ b/techlibs/lattice/lattice_gsr.cc @@ -24,13 +24,13 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct Ecp5GsrPass : public Pass { - Ecp5GsrPass() : Pass("ecp5_gsr", "ECP5: handle GSR") { } +struct LatticeGsrPass : public Pass { + LatticeGsrPass() : Pass("lattice_gsr", "Lattice: handle GSR") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" ecp5_gsr [options] [selection]\n"); + log(" lattice_gsr [options] [selection]\n"); log("\n"); log("Trim active low async resets connected to GSR and resolve GSR parameter,\n"); log("if a GSR or SGSR primitive is used in the design.\n"); @@ -42,7 +42,7 @@ struct Ecp5GsrPass : public Pass { } void execute(std::vector args, RTLIL::Design *design) override { - log_header(design, "Executing ECP5_GSR pass (implement FF init values).\n"); + log_header(design, "Executing LATTICE_GSR pass (implement FF init values).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -130,6 +130,6 @@ struct Ecp5GsrPass : public Pass { } } -} Ecp5GsrPass; +} LatticeGsrPass; PRIVATE_NAMESPACE_END diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index 2b684a7d8fd..907c6659ed8 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -239,7 +239,7 @@ struct SynthMachXO2Pass : public ScriptPass run("techmap -D NO_LUT -map +/machxo2/cells_map.v"); run("opt_expr -undriven -mux_undef"); run("simplemap"); - run("ecp5_gsr"); + run("lattice_gsr"); run("attrmvcp -copy -attr syn_useioff"); run("opt_clean"); } From e3c15f003e1d976c4d27c2ffc08196b50576bd26 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 10:53:21 +0200 Subject: [PATCH 060/119] Create synth_lattice --- techlibs/lattice/Makefile.inc | 26 + techlibs/lattice/arith_map_ccu2c.v | 90 +++ techlibs/lattice/arith_map_ccu2d.v | 90 +++ techlibs/lattice/brams_16kd.txt | 52 ++ techlibs/lattice/brams_8kc.txt | 50 ++ techlibs/lattice/brams_map_16kd.v | 489 +++++++++++++ techlibs/lattice/brams_map_8kc.v | 337 +++++++++ techlibs/lattice/ccu2c_sim.vh | 61 ++ techlibs/lattice/ccu2d_sim.vh | 33 + techlibs/lattice/cells_bb_ecp5.v | 1067 ++++++++++++++++++++++++++++ techlibs/lattice/cells_bb_xo2.v | 293 ++++++++ techlibs/lattice/cells_bb_xo3.v | 293 ++++++++ techlibs/lattice/cells_bb_xo3d.v | 293 ++++++++ techlibs/lattice/cells_ff.vh | 40 ++ techlibs/lattice/cells_io.vh | 14 + techlibs/lattice/cells_map.v | 191 +++++ techlibs/lattice/cells_sim_ecp5.v | 9 + techlibs/lattice/cells_sim_xo2.v | 9 + techlibs/lattice/cells_sim_xo3.v | 9 + techlibs/lattice/cells_sim_xo3d.v | 9 + techlibs/lattice/common_sim.vh | 402 +++++++++++ techlibs/lattice/dsp_map_18x18.v | 17 + techlibs/lattice/latches_map.v | 11 + techlibs/lattice/lutrams.txt | 12 + techlibs/lattice/lutrams_map.v | 30 + techlibs/lattice/synth_lattice.cc | 574 +++++++++++++++ 26 files changed, 4501 insertions(+) create mode 100644 techlibs/lattice/arith_map_ccu2c.v create mode 100644 techlibs/lattice/arith_map_ccu2d.v create mode 100644 techlibs/lattice/brams_16kd.txt create mode 100644 techlibs/lattice/brams_8kc.txt create mode 100644 techlibs/lattice/brams_map_16kd.v create mode 100644 techlibs/lattice/brams_map_8kc.v create mode 100644 techlibs/lattice/ccu2c_sim.vh create mode 100644 techlibs/lattice/ccu2d_sim.vh create mode 100644 techlibs/lattice/cells_bb_ecp5.v create mode 100644 techlibs/lattice/cells_bb_xo2.v create mode 100644 techlibs/lattice/cells_bb_xo3.v create mode 100644 techlibs/lattice/cells_bb_xo3d.v create mode 100644 techlibs/lattice/cells_ff.vh create mode 100644 techlibs/lattice/cells_io.vh create mode 100644 techlibs/lattice/cells_map.v create mode 100644 techlibs/lattice/cells_sim_ecp5.v create mode 100644 techlibs/lattice/cells_sim_xo2.v create mode 100644 techlibs/lattice/cells_sim_xo3.v create mode 100644 techlibs/lattice/cells_sim_xo3d.v create mode 100644 techlibs/lattice/common_sim.vh create mode 100644 techlibs/lattice/dsp_map_18x18.v create mode 100644 techlibs/lattice/latches_map.v create mode 100644 techlibs/lattice/lutrams.txt create mode 100644 techlibs/lattice/lutrams_map.v create mode 100644 techlibs/lattice/synth_lattice.cc diff --git a/techlibs/lattice/Makefile.inc b/techlibs/lattice/Makefile.inc index b198de0cc11..4a908fa3ead 100644 --- a/techlibs/lattice/Makefile.inc +++ b/techlibs/lattice/Makefile.inc @@ -1 +1,27 @@ + +OBJS += techlibs/lattice/synth_lattice.o OBJS += techlibs/lattice/lattice_gsr.o + +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_ff.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_io.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_map.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/common_sim.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/ccu2d_sim.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/ccu2c_sim.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_ecp5.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo2.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3d.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_ecp5.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo2.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_map.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams.txt)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_16kd.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_16kd.txt)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_8kc.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_8kc.txt)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/arith_map_ccu2c.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/arith_map_ccu2d.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/latches_map.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/dsp_map_18x18.v)) diff --git a/techlibs/lattice/arith_map_ccu2c.v b/techlibs/lattice/arith_map_ccu2c.v new file mode 100644 index 00000000000..a5efc35613a --- /dev/null +++ b/techlibs/lattice/arith_map_ccu2c.v @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2018 gatecat + * + * 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. + * + */ + +(* techmap_celltype = "$alu" *) +module _80_ccu2c_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; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; + + (* force_downto *) + 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)); + + function integer round_up2; + input integer N; + begin + round_up2 = ((N + 1) / 2) * 2; + end + endfunction + + localparam Y_WIDTH2 = round_up2(Y_WIDTH); + + (* force_downto *) + wire [Y_WIDTH2-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BX = B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] C = {CO, CI}; + (* force_downto *) + wire [Y_WIDTH2-1:0] FCO, Y1; + + genvar i; + generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice + CCU2C #( + .INIT0(16'b1001011010101010), + .INIT1(16'b1001011010101010), + .INJECT1_0("NO"), + .INJECT1_1("NO") + ) ccu2c_i ( + .CIN(C[i]), + .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b1), + .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b1), + .S0(Y[i]), .S1(Y1[i]), + .COUT(FCO[i]) + ); + + assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); + if (i+1 < Y_WIDTH) begin + assign CO[i+1] = FCO[i]; + assign Y[i+1] = Y1[i]; + end + end endgenerate + + assign X = AA ^ BB; +endmodule diff --git a/techlibs/lattice/arith_map_ccu2d.v b/techlibs/lattice/arith_map_ccu2d.v new file mode 100644 index 00000000000..31e4afe09a1 --- /dev/null +++ b/techlibs/lattice/arith_map_ccu2d.v @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2018 gatecat + * + * 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. + * + */ + +(* techmap_celltype = "$alu" *) +module _80_ccu2d_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; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; + + (* force_downto *) + 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)); + + function integer round_up2; + input integer N; + begin + round_up2 = ((N + 1) / 2) * 2; + end + endfunction + + localparam Y_WIDTH2 = round_up2(Y_WIDTH); + + (* force_downto *) + wire [Y_WIDTH2-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BX = B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] C = {CO, CI}; + (* force_downto *) + wire [Y_WIDTH2-1:0] FCO, Y1; + + genvar i; + generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice + CCU2D #( + .INIT0(16'b0101_1010_1001_0110), + .INIT1(16'b0101_1010_1001_0110), + .INJECT1_0("NO"), + .INJECT1_1("NO") + ) ccu2d_i ( + .CIN(C[i]), + .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b0), + .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b0), + .S0(Y[i]), .S1(Y1[i]), + .COUT(FCO[i]) + ); + + assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); + if (i+1 < Y_WIDTH) begin + assign CO[i+1] = FCO[i]; + assign Y[i+1] = Y1[i]; + end + end endgenerate + + assign X = AA ^ BB; +endmodule diff --git a/techlibs/lattice/brams_16kd.txt b/techlibs/lattice/brams_16kd.txt new file mode 100644 index 00000000000..ccdf490501f --- /dev/null +++ b/techlibs/lattice/brams_16kd.txt @@ -0,0 +1,52 @@ +ram block $__DP16KD_ { + abits 14; + widths 1 2 4 9 18 per_port; + byte 9; + cost 128; + init no_undef; + port srsw "A" "B" { + clock anyedge; + clken; + wrbe_separate; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + portoption "WRITEMODE" "READBEFOREWRITE" { + rdwr old; + } + option "RESETMODE" "SYNC" { + rdsrst zero ungated block_wr; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} + +ram block $__PDPW16KD_ { + abits 14; + widths 1 2 4 9 18 36 per_port; + byte 9; + cost 128; + init no_undef; + port sr "R" { + clock anyedge; + clken; + option "RESETMODE" "SYNC" { + rdsrst zero ungated; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + width 36; + clock anyedge; + clken; + } +} diff --git a/techlibs/lattice/brams_8kc.txt b/techlibs/lattice/brams_8kc.txt new file mode 100644 index 00000000000..3afbeda07e6 --- /dev/null +++ b/techlibs/lattice/brams_8kc.txt @@ -0,0 +1,50 @@ +ram block $__DP8KC_ { + abits 13; + widths 1 2 4 9 per_port; + cost 64; + init no_undef; + port srsw "A" "B" { + clock posedge; + clken; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + portoption "WRITEMODE" "READBEFOREWRITE" { + rdwr old; + } + option "RESETMODE" "SYNC" { + rdsrst zero ungated block_wr; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} + +ram block $__PDPW8KC_ { + abits 13; + widths 1 2 4 9 18 per_port; + byte 9; + cost 64; + init no_undef; + port sr "R" { + clock posedge; + clken; + option "RESETMODE" "SYNC" { + rdsrst zero ungated; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + width 18; + clock posedge; + clken; + } +} diff --git a/techlibs/lattice/brams_map_16kd.v b/techlibs/lattice/brams_map_16kd.v new file mode 100644 index 00000000000..da4d8041770 --- /dev/null +++ b/techlibs/lattice/brams_map_16kd.v @@ -0,0 +1,489 @@ +module $__DP16KD_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_WR_BE_WIDTH = 2; +parameter PORT_A_CLK_POL = 1; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_WR_BE_WIDTH = 2; +parameter PORT_B_CLK_POL = 1; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [13:0] PORT_B_ADDR; +input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [17:0] DOA; +wire [17:0] DOB; +wire [17:0] DIA = PORT_A_WR_DATA; +wire [17:0] DIB = PORT_B_WR_DATA; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +DP16KD #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .INITVAL_20(init_slice('h20)), + .INITVAL_21(init_slice('h21)), + .INITVAL_22(init_slice('h22)), + .INITVAL_23(init_slice('h23)), + .INITVAL_24(init_slice('h24)), + .INITVAL_25(init_slice('h25)), + .INITVAL_26(init_slice('h26)), + .INITVAL_27(init_slice('h27)), + .INITVAL_28(init_slice('h28)), + .INITVAL_29(init_slice('h29)), + .INITVAL_2A(init_slice('h2a)), + .INITVAL_2B(init_slice('h2b)), + .INITVAL_2C(init_slice('h2c)), + .INITVAL_2D(init_slice('h2d)), + .INITVAL_2E(init_slice('h2e)), + .INITVAL_2F(init_slice('h2f)), + .INITVAL_30(init_slice('h30)), + .INITVAL_31(init_slice('h31)), + .INITVAL_32(init_slice('h32)), + .INITVAL_33(init_slice('h33)), + .INITVAL_34(init_slice('h34)), + .INITVAL_35(init_slice('h35)), + .INITVAL_36(init_slice('h36)), + .INITVAL_37(init_slice('h37)), + .INITVAL_38(init_slice('h38)), + .INITVAL_39(init_slice('h39)), + .INITVAL_3A(init_slice('h3a)), + .INITVAL_3B(init_slice('h3b)), + .INITVAL_3C(init_slice('h3c)), + .INITVAL_3D(init_slice('h3d)), + .INITVAL_3E(init_slice('h3e)), + .INITVAL_3F(init_slice('h3f)), + .DATA_WIDTH_A(PORT_A_WIDTH), + .DATA_WIDTH_B(PORT_B_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .CLKAMUX(PORT_A_CLK_POL ? "CLKA" : "INV"), + .CLKBMUX(PORT_B_CLK_POL ? "CLKB" : "INV"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_A_CLK), + .WEA(PORT_A_WIDTH == 18 ? PORT_A_WR_EN : (PORT_A_WR_EN | PORT_A_WR_BE[0])), + .CEA(PORT_A_CLK_EN), + .OCEA(1'b1), + .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[0] : PORT_A_ADDR[0]), + .ADA1(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[1] : PORT_A_ADDR[1]), + .ADA2(PORT_A_ADDR[2]), + .ADA3(PORT_A_ADDR[3]), + .ADA4(PORT_A_ADDR[4]), + .ADA5(PORT_A_ADDR[5]), + .ADA6(PORT_A_ADDR[6]), + .ADA7(PORT_A_ADDR[7]), + .ADA8(PORT_A_ADDR[8]), + .ADA9(PORT_A_ADDR[9]), + .ADA10(PORT_A_ADDR[10]), + .ADA11(PORT_A_ADDR[11]), + .ADA12(PORT_A_ADDR[12]), + .ADA13(PORT_A_ADDR[13]), + .DIA0(DIA[0]), + .DIA1(DIA[1]), + .DIA2(DIA[2]), + .DIA3(DIA[3]), + .DIA4(DIA[4]), + .DIA5(DIA[5]), + .DIA6(DIA[6]), + .DIA7(DIA[7]), + .DIA8(DIA[8]), + .DIA9(DIA[9]), + .DIA10(DIA[10]), + .DIA11(DIA[11]), + .DIA12(DIA[12]), + .DIA13(DIA[13]), + .DIA14(DIA[14]), + .DIA15(DIA[15]), + .DIA16(DIA[16]), + .DIA17(DIA[17]), + .DOA0(DOA[0]), + .DOA1(DOA[1]), + .DOA2(DOA[2]), + .DOA3(DOA[3]), + .DOA4(DOA[4]), + .DOA5(DOA[5]), + .DOA6(DOA[6]), + .DOA7(DOA[7]), + .DOA8(DOA[8]), + .DOA9(DOA[9]), + .DOA10(DOA[10]), + .DOA11(DOA[11]), + .DOA12(DOA[12]), + .DOA13(DOA[13]), + .DOA14(DOA[14]), + .DOA15(DOA[15]), + .DOA16(DOA[16]), + .DOA17(DOA[17]), + + .CLKB(PORT_B_CLK), + .WEB(PORT_B_WIDTH == 18 ? PORT_B_WR_EN : (PORT_B_WR_EN | PORT_B_WR_BE[0])), + .CEB(PORT_B_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[0] : PORT_B_ADDR[0]), + .ADB1(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[1] : PORT_B_ADDR[1]), + .ADB2(PORT_B_ADDR[2]), + .ADB3(PORT_B_ADDR[3]), + .ADB4(PORT_B_ADDR[4]), + .ADB5(PORT_B_ADDR[5]), + .ADB6(PORT_B_ADDR[6]), + .ADB7(PORT_B_ADDR[7]), + .ADB8(PORT_B_ADDR[8]), + .ADB9(PORT_B_ADDR[9]), + .ADB10(PORT_B_ADDR[10]), + .ADB11(PORT_B_ADDR[11]), + .ADB12(PORT_B_ADDR[12]), + .ADB13(PORT_B_ADDR[13]), + .DIB0(DIB[0]), + .DIB1(DIB[1]), + .DIB2(DIB[2]), + .DIB3(DIB[3]), + .DIB4(DIB[4]), + .DIB5(DIB[5]), + .DIB6(DIB[6]), + .DIB7(DIB[7]), + .DIB8(DIB[8]), + .DIB9(DIB[9]), + .DIB10(DIB[10]), + .DIB11(DIB[11]), + .DIB12(DIB[12]), + .DIB13(DIB[13]), + .DIB14(DIB[14]), + .DIB15(DIB[15]), + .DIB16(DIB[16]), + .DIB17(DIB[17]), + .DOB0(DOB[0]), + .DOB1(DOB[1]), + .DOB2(DOB[2]), + .DOB3(DOB[3]), + .DOB4(DOB[4]), + .DOB5(DOB[5]), + .DOB6(DOB[6]), + .DOB7(DOB[7]), + .DOB8(DOB[8]), + .DOB9(DOB[9]), + .DOB10(DOB[10]), + .DOB11(DOB[11]), + .DOB12(DOB[12]), + .DOB13(DOB[13]), + .DOB14(DOB[14]), + .DOB15(DOB[15]), + .DOB16(DOB[16]), + .DOB17(DOB[17]), +); + +endmodule + + +module $__PDPW16KD_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_R_WIDTH = 36; +parameter PORT_R_CLK_POL = 1; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [13:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 36; +parameter PORT_W_WR_EN_WIDTH = 4; +parameter PORT_W_CLK_POL = 1; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [13:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [35:0] DI = PORT_W_WR_DATA; +wire [35:0] DO; + +assign PORT_R_RD_DATA = PORT_R_WIDTH == 36 ? DO : DO[35:18]; + +DP16KD #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .INITVAL_20(init_slice('h20)), + .INITVAL_21(init_slice('h21)), + .INITVAL_22(init_slice('h22)), + .INITVAL_23(init_slice('h23)), + .INITVAL_24(init_slice('h24)), + .INITVAL_25(init_slice('h25)), + .INITVAL_26(init_slice('h26)), + .INITVAL_27(init_slice('h27)), + .INITVAL_28(init_slice('h28)), + .INITVAL_29(init_slice('h29)), + .INITVAL_2A(init_slice('h2a)), + .INITVAL_2B(init_slice('h2b)), + .INITVAL_2C(init_slice('h2c)), + .INITVAL_2D(init_slice('h2d)), + .INITVAL_2E(init_slice('h2e)), + .INITVAL_2F(init_slice('h2f)), + .INITVAL_30(init_slice('h30)), + .INITVAL_31(init_slice('h31)), + .INITVAL_32(init_slice('h32)), + .INITVAL_33(init_slice('h33)), + .INITVAL_34(init_slice('h34)), + .INITVAL_35(init_slice('h35)), + .INITVAL_36(init_slice('h36)), + .INITVAL_37(init_slice('h37)), + .INITVAL_38(init_slice('h38)), + .INITVAL_39(init_slice('h39)), + .INITVAL_3A(init_slice('h3a)), + .INITVAL_3B(init_slice('h3b)), + .INITVAL_3C(init_slice('h3c)), + .INITVAL_3D(init_slice('h3d)), + .INITVAL_3E(init_slice('h3e)), + .INITVAL_3F(init_slice('h3f)), + .DATA_WIDTH_A(PORT_W_WIDTH), + .DATA_WIDTH_B(PORT_R_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .CLKAMUX(PORT_W_CLK_POL ? "CLKA" : "INV"), + .CLKBMUX(PORT_R_CLK_POL ? "CLKB" : "INV"), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_W_CLK), + .WEA(PORT_W_WIDTH >= 18 ? 1'b1 : PORT_W_WR_EN[0]), + .CEA(PORT_W_CLK_EN), + .OCEA(1'b0), + .RSTA(1'b0), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), + .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), + .ADA2(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[2] : PORT_W_ADDR[2]), + .ADA3(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[3] : PORT_W_ADDR[3]), + .ADA4(PORT_W_ADDR[4]), + .ADA5(PORT_W_ADDR[5]), + .ADA6(PORT_W_ADDR[6]), + .ADA7(PORT_W_ADDR[7]), + .ADA8(PORT_W_ADDR[8]), + .ADA9(PORT_W_ADDR[9]), + .ADA10(PORT_W_ADDR[10]), + .ADA11(PORT_W_ADDR[11]), + .ADA12(PORT_W_ADDR[12]), + .ADA13(PORT_W_ADDR[13]), + .DIA0(DI[0]), + .DIA1(DI[1]), + .DIA2(DI[2]), + .DIA3(DI[3]), + .DIA4(DI[4]), + .DIA5(DI[5]), + .DIA6(DI[6]), + .DIA7(DI[7]), + .DIA8(DI[8]), + .DIA9(DI[9]), + .DIA10(DI[10]), + .DIA11(DI[11]), + .DIA12(DI[12]), + .DIA13(DI[13]), + .DIA14(DI[14]), + .DIA15(DI[15]), + .DIA16(DI[16]), + .DIA17(DI[17]), + .DIB0(DI[18]), + .DIB1(DI[19]), + .DIB2(DI[20]), + .DIB3(DI[21]), + .DIB4(DI[22]), + .DIB5(DI[23]), + .DIB6(DI[24]), + .DIB7(DI[25]), + .DIB8(DI[26]), + .DIB9(DI[27]), + .DIB10(DI[28]), + .DIB11(DI[29]), + .DIB12(DI[30]), + .DIB13(DI[31]), + .DIB14(DI[32]), + .DIB15(DI[33]), + .DIB16(DI[34]), + .DIB17(DI[35]), + + .CLKB(PORT_R_CLK), + .WEB(1'b0), + .CEB(PORT_R_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_R_ADDR[0]), + .ADB1(PORT_R_ADDR[1]), + .ADB2(PORT_R_ADDR[2]), + .ADB3(PORT_R_ADDR[3]), + .ADB4(PORT_R_ADDR[4]), + .ADB5(PORT_R_ADDR[5]), + .ADB6(PORT_R_ADDR[6]), + .ADB7(PORT_R_ADDR[7]), + .ADB8(PORT_R_ADDR[8]), + .ADB9(PORT_R_ADDR[9]), + .ADB10(PORT_R_ADDR[10]), + .ADB11(PORT_R_ADDR[11]), + .ADB12(PORT_R_ADDR[12]), + .ADB13(PORT_R_ADDR[13]), + .DOA0(DO[0]), + .DOA1(DO[1]), + .DOA2(DO[2]), + .DOA3(DO[3]), + .DOA4(DO[4]), + .DOA5(DO[5]), + .DOA6(DO[6]), + .DOA7(DO[7]), + .DOA8(DO[8]), + .DOA9(DO[9]), + .DOA10(DO[10]), + .DOA11(DO[11]), + .DOA12(DO[12]), + .DOA13(DO[13]), + .DOA14(DO[14]), + .DOA15(DO[15]), + .DOA16(DO[16]), + .DOA17(DO[17]), + .DOB0(DO[18]), + .DOB1(DO[19]), + .DOB2(DO[20]), + .DOB3(DO[21]), + .DOB4(DO[22]), + .DOB5(DO[23]), + .DOB6(DO[24]), + .DOB7(DO[25]), + .DOB8(DO[26]), + .DOB9(DO[27]), + .DOB10(DO[28]), + .DOB11(DO[29]), + .DOB12(DO[30]), + .DOB13(DO[31]), + .DOB14(DO[32]), + .DOB15(DO[33]), + .DOB16(DO[34]), + .DOB17(DO[35]), +); + +endmodule diff --git a/techlibs/lattice/brams_map_8kc.v b/techlibs/lattice/brams_map_8kc.v new file mode 100644 index 00000000000..6783e5b2902 --- /dev/null +++ b/techlibs/lattice/brams_map_8kc.v @@ -0,0 +1,337 @@ +module $__DP8KC_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [12:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [12:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [8:0] DOA; +wire [8:0] DOB; +wire [8:0] DIA = PORT_A_WR_DATA; +wire [8:0] DIB = PORT_B_WR_DATA; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +DP8KC #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .DATA_WIDTH_A(PORT_A_WIDTH), + .DATA_WIDTH_B(PORT_B_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_A_CLK), + .WEA(PORT_A_WR_EN), + .CEA(PORT_A_CLK_EN), + .OCEA(1'b1), + .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_A_WIDTH == 9 ? 1'b1 : PORT_A_ADDR[0]), + .ADA1(PORT_A_ADDR[1]), + .ADA2(PORT_A_ADDR[2]), + .ADA3(PORT_A_ADDR[3]), + .ADA4(PORT_A_ADDR[4]), + .ADA5(PORT_A_ADDR[5]), + .ADA6(PORT_A_ADDR[6]), + .ADA7(PORT_A_ADDR[7]), + .ADA8(PORT_A_ADDR[8]), + .ADA9(PORT_A_ADDR[9]), + .ADA10(PORT_A_ADDR[10]), + .ADA11(PORT_A_ADDR[11]), + .ADA12(PORT_A_ADDR[12]), + .DIA0(DIA[0]), + .DIA1(DIA[1]), + .DIA2(DIA[2]), + .DIA3(DIA[3]), + .DIA4(DIA[4]), + .DIA5(DIA[5]), + .DIA6(DIA[6]), + .DIA7(DIA[7]), + .DIA8(DIA[8]), + .DOA0(DOA[0]), + .DOA1(DOA[1]), + .DOA2(DOA[2]), + .DOA3(DOA[3]), + .DOA4(DOA[4]), + .DOA5(DOA[5]), + .DOA6(DOA[6]), + .DOA7(DOA[7]), + .DOA8(DOA[8]), + + .CLKB(PORT_B_CLK), + .WEB(PORT_B_WR_EN), + .CEB(PORT_B_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_B_WIDTH == 9 ? 1'b1 : PORT_B_ADDR[0]), + .ADB1(PORT_B_ADDR[1]), + .ADB2(PORT_B_ADDR[2]), + .ADB3(PORT_B_ADDR[3]), + .ADB4(PORT_B_ADDR[4]), + .ADB5(PORT_B_ADDR[5]), + .ADB6(PORT_B_ADDR[6]), + .ADB7(PORT_B_ADDR[7]), + .ADB8(PORT_B_ADDR[8]), + .ADB9(PORT_B_ADDR[9]), + .ADB10(PORT_B_ADDR[10]), + .ADB11(PORT_B_ADDR[11]), + .ADB12(PORT_B_ADDR[12]), + .DIB0(DIB[0]), + .DIB1(DIB[1]), + .DIB2(DIB[2]), + .DIB3(DIB[3]), + .DIB4(DIB[4]), + .DIB5(DIB[5]), + .DIB6(DIB[6]), + .DIB7(DIB[7]), + .DIB8(DIB[8]), + .DOB0(DOB[0]), + .DOB1(DOB[1]), + .DOB2(DOB[2]), + .DOB3(DOB[3]), + .DOB4(DOB[4]), + .DOB5(DOB[5]), + .DOB6(DOB[6]), + .DOB7(DOB[7]), + .DOB8(DOB[8]), +); + +endmodule + + +module $__PDPW8KC_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_R_WIDTH = 18; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [12:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 18; +parameter PORT_W_WR_EN_WIDTH = 2; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [12:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [17:0] DI = PORT_W_WR_DATA; +wire [17:0] DO; + +assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9]; + +DP8KC #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .DATA_WIDTH_A(PORT_W_WIDTH), + .DATA_WIDTH_B(PORT_R_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_W_CLK), + .WEA(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]), + .CEA(PORT_W_CLK_EN), + .OCEA(1'b0), + .RSTA(1'b0), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_W_WIDTH >= 9 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), + .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), + .ADA2(PORT_W_ADDR[2]), + .ADA3(PORT_W_ADDR[3]), + .ADA4(PORT_W_ADDR[4]), + .ADA5(PORT_W_ADDR[5]), + .ADA6(PORT_W_ADDR[6]), + .ADA7(PORT_W_ADDR[7]), + .ADA8(PORT_W_ADDR[8]), + .ADA9(PORT_W_ADDR[9]), + .ADA10(PORT_W_ADDR[10]), + .ADA11(PORT_W_ADDR[11]), + .ADA12(PORT_W_ADDR[12]), + .DIA0(DI[0]), + .DIA1(DI[1]), + .DIA2(DI[2]), + .DIA3(DI[3]), + .DIA4(DI[4]), + .DIA5(DI[5]), + .DIA6(DI[6]), + .DIA7(DI[7]), + .DIA8(DI[8]), + .DIB0(DI[9]), + .DIB1(DI[10]), + .DIB2(DI[11]), + .DIB3(DI[12]), + .DIB4(DI[13]), + .DIB5(DI[14]), + .DIB6(DI[15]), + .DIB7(DI[16]), + .DIB8(DI[17]), + + .CLKB(PORT_R_CLK), + .WEB(1'b0), + .CEB(PORT_R_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_R_ADDR[0]), + .ADB1(PORT_R_ADDR[1]), + .ADB2(PORT_R_ADDR[2]), + .ADB3(PORT_R_ADDR[3]), + .ADB4(PORT_R_ADDR[4]), + .ADB5(PORT_R_ADDR[5]), + .ADB6(PORT_R_ADDR[6]), + .ADB7(PORT_R_ADDR[7]), + .ADB8(PORT_R_ADDR[8]), + .ADB9(PORT_R_ADDR[9]), + .ADB10(PORT_R_ADDR[10]), + .ADB11(PORT_R_ADDR[11]), + .ADB12(PORT_R_ADDR[12]), + .DOA0(DO[0]), + .DOA1(DO[1]), + .DOA2(DO[2]), + .DOA3(DO[3]), + .DOA4(DO[4]), + .DOA5(DO[5]), + .DOA6(DO[6]), + .DOA7(DO[7]), + .DOA8(DO[8]), + .DOB0(DO[9]), + .DOB1(DO[10]), + .DOB2(DO[11]), + .DOB3(DO[12]), + .DOB4(DO[13]), + .DOB5(DO[14]), + .DOB6(DO[15]), + .DOB7(DO[16]), + .DOB8(DO[17]), +); + +endmodule diff --git a/techlibs/lattice/ccu2c_sim.vh b/techlibs/lattice/ccu2c_sim.vh new file mode 100644 index 00000000000..d9eb69ab455 --- /dev/null +++ b/techlibs/lattice/ccu2c_sim.vh @@ -0,0 +1,61 @@ +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module CCU2C( + (* abc9_carry *) + input CIN, + input A0, B0, C0, D0, A1, B1, C1, D1, + output S0, S1, + (* abc9_carry *) + output COUT +); + parameter [15:0] INIT0 = 16'h0000; + parameter [15:0] INIT1 = 16'h0000; + parameter INJECT1_0 = "YES"; + parameter INJECT1_1 = "YES"; + + // First half + wire LUT4_0, LUT2_0; + LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); + LUT2 #(.INIT(INIT0[3:0])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); + wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; + assign S0 = LUT4_0 ^ gated_cin_0; + + wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0; + wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN); + + // Second half + wire LUT4_1, LUT2_1; + LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); + LUT2 #(.INIT(INIT1[3:0])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); + wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; + assign S1 = LUT4_1 ^ gated_cin_1; + + wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1; + assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0); + + specify + (A0 => S0) = 379; + (B0 => S0) = 379; + (C0 => S0) = 275; + (D0 => S0) = 141; + (CIN => S0) = 257; + (A0 => S1) = 630; + (B0 => S1) = 630; + (C0 => S1) = 526; + (D0 => S1) = 392; + (A1 => S1) = 379; + (B1 => S1) = 379; + (C1 => S1) = 275; + (D1 => S1) = 141; + (CIN => S1) = 273; + (A0 => COUT) = 516; + (B0 => COUT) = 516; + (C0 => COUT) = 412; + (D0 => COUT) = 278; + (A1 => COUT) = 516; + (B1 => COUT) = 516; + (C1 => COUT) = 412; + (D1 => COUT) = 278; + (CIN => COUT) = 43; + endspecify +endmodule diff --git a/techlibs/lattice/ccu2d_sim.vh b/techlibs/lattice/ccu2d_sim.vh new file mode 100644 index 00000000000..5b9c95cc9ef --- /dev/null +++ b/techlibs/lattice/ccu2d_sim.vh @@ -0,0 +1,33 @@ +// --------------------------------------- +(* lib_whitebox *) +module CCU2D ( + input CIN, + input A0, B0, C0, D0, A1, B1, C1, D1, + output S0, S1, + output COUT +); + parameter [15:0] INIT0 = 16'h0000; + parameter [15:0] INIT1 = 16'h0000; + parameter INJECT1_0 = "YES"; + parameter INJECT1_1 = "YES"; + + // First half + wire LUT4_0, LUT2_0; + LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); + LUT2 #(.INIT(~INIT0[15:12])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); + wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; + assign S0 = LUT4_0 ^ gated_cin_0; + + wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0; + wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN); + + // Second half + wire LUT4_1, LUT2_1; + LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); + LUT2 #(.INIT(~INIT1[15:12])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); + wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; + assign S1 = LUT4_1 ^ gated_cin_1; + + wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1; + assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0); +endmodule diff --git a/techlibs/lattice/cells_bb_ecp5.v b/techlibs/lattice/cells_bb_ecp5.v new file mode 100644 index 00000000000..5cb90b97efc --- /dev/null +++ b/techlibs/lattice/cells_bb_ecp5.v @@ -0,0 +1,1067 @@ +// ECP5 Blackbox cells +// FIXME: Create sim models + +(* blackbox *) +module DP16KD( + input DIA17, DIA16, DIA15, DIA14, DIA13, DIA12, DIA11, DIA10, DIA9, DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA13, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA17, DOA16, DOA15, DOA14, DOA13, DOA12, DOA11, DOA10, DOA9, DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB17, DIB16, DIB15, DIB14, DIB13, DIB12, DIB11, DIB10, DIB9, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB13, ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 18; + parameter DATA_WIDTH_B = 18; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter DIA17MUX = "DIA17"; + parameter DIA16MUX = "DIA16"; + parameter DIA15MUX = "DIA15"; + parameter DIA14MUX = "DIA14"; + parameter DIA13MUX = "DIA13"; + parameter DIA12MUX = "DIA12"; + parameter DIA11MUX = "DIA11"; + parameter DIA10MUX = "DIA10"; + parameter DIA9MUX = "DIA9"; + parameter DIA8MUX = "DIA8"; + parameter DIA7MUX = "DIA7"; + parameter DIA6MUX = "DIA6"; + parameter DIA5MUX = "DIA5"; + parameter DIA4MUX = "DIA4"; + parameter DIA3MUX = "DIA3"; + parameter DIA2MUX = "DIA2"; + parameter DIA1MUX = "DIA1"; + parameter DIA0MUX = "DIA0"; + parameter ADA13MUX = "ADA13"; + parameter ADA12MUX = "ADA12"; + parameter ADA11MUX = "ADA11"; + parameter ADA10MUX = "ADA10"; + parameter ADA9MUX = "ADA9"; + parameter ADA8MUX = "ADA8"; + parameter ADA7MUX = "ADA7"; + parameter ADA6MUX = "ADA6"; + parameter ADA5MUX = "ADA5"; + parameter ADA4MUX = "ADA4"; + parameter ADA3MUX = "ADA3"; + parameter ADA2MUX = "ADA2"; + parameter ADA1MUX = "ADA1"; + parameter ADA0MUX = "ADA0"; + parameter CEAMUX = "CEA"; + parameter OCEAMUX = "OCEA"; + parameter CLKAMUX = "CLKA"; + parameter WEAMUX = "WEA"; + parameter RSTAMUX = "RSTA"; + parameter CSA2MUX = "CSA2"; + parameter CSA1MUX = "CSA1"; + parameter CSA0MUX = "CSA0"; + parameter DOA17MUX = "DOA17"; + parameter DOA16MUX = "DOA16"; + parameter DOA15MUX = "DOA15"; + parameter DOA14MUX = "DOA14"; + parameter DOA13MUX = "DOA13"; + parameter DOA12MUX = "DOA12"; + parameter DOA11MUX = "DOA11"; + parameter DOA10MUX = "DOA10"; + parameter DOA9MUX = "DOA9"; + parameter DOA8MUX = "DOA8"; + parameter DOA7MUX = "DOA7"; + parameter DOA6MUX = "DOA6"; + parameter DOA5MUX = "DOA5"; + parameter DOA4MUX = "DOA4"; + parameter DOA3MUX = "DOA3"; + parameter DOA2MUX = "DOA2"; + parameter DOA1MUX = "DOA1"; + parameter DOA0MUX = "DOA0"; + parameter DIB17MUX = "DIB17"; + parameter DIB16MUX = "DIB16"; + parameter DIB15MUX = "DIB15"; + parameter DIB14MUX = "DIB14"; + parameter DIB13MUX = "DIB13"; + parameter DIB12MUX = "DIB12"; + parameter DIB11MUX = "DIB11"; + parameter DIB10MUX = "DIB10"; + parameter DIB9MUX = "DIB9"; + parameter DIB8MUX = "DIB8"; + parameter DIB7MUX = "DIB7"; + parameter DIB6MUX = "DIB6"; + parameter DIB5MUX = "DIB5"; + parameter DIB4MUX = "DIB4"; + parameter DIB3MUX = "DIB3"; + parameter DIB2MUX = "DIB2"; + parameter DIB1MUX = "DIB1"; + parameter DIB0MUX = "DIB0"; + parameter ADB13MUX = "ADB13"; + parameter ADB12MUX = "ADB12"; + parameter ADB11MUX = "ADB11"; + parameter ADB10MUX = "ADB10"; + parameter ADB9MUX = "ADB9"; + parameter ADB8MUX = "ADB8"; + parameter ADB7MUX = "ADB7"; + parameter ADB6MUX = "ADB6"; + parameter ADB5MUX = "ADB5"; + parameter ADB4MUX = "ADB4"; + parameter ADB3MUX = "ADB3"; + parameter ADB2MUX = "ADB2"; + parameter ADB1MUX = "ADB1"; + parameter ADB0MUX = "ADB0"; + parameter CEBMUX = "CEB"; + parameter OCEBMUX = "OCEB"; + parameter CLKBMUX = "CLKB"; + parameter WEBMUX = "WEB"; + parameter RSTBMUX = "RSTB"; + parameter CSB2MUX = "CSB2"; + parameter CSB1MUX = "CSB1"; + parameter CSB0MUX = "CSB0"; + parameter DOB17MUX = "DOB17"; + parameter DOB16MUX = "DOB16"; + parameter DOB15MUX = "DOB15"; + parameter DOB14MUX = "DOB14"; + parameter DOB13MUX = "DOB13"; + parameter DOB12MUX = "DOB12"; + parameter DOB11MUX = "DOB11"; + parameter DOB10MUX = "DOB10"; + parameter DOB9MUX = "DOB9"; + parameter DOB8MUX = "DOB8"; + parameter DOB7MUX = "DOB7"; + parameter DOB6MUX = "DOB6"; + parameter DOB5MUX = "DOB5"; + parameter DOB4MUX = "DOB4"; + parameter DOB3MUX = "DOB3"; + parameter DOB2MUX = "DOB2"; + parameter DOB1MUX = "DOB1"; + parameter DOB0MUX = "DOB0"; + + parameter WID = 0; + + parameter GSR = "ENABLED"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module MULT18X18D( + input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, + input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, + input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, + input SIGNEDA, SIGNEDB, SOURCEA, SOURCEB, + input CLK0, CLK1, CLK2, CLK3, + input CE0, CE1, CE2, CE3, + input RST0, RST1, RST2, RST3, + input SRIA0, SRIA1, SRIA2, SRIA3, SRIA4, SRIA5, SRIA6, SRIA7, SRIA8, SRIA9, SRIA10, SRIA11, SRIA12, SRIA13, SRIA14, SRIA15, SRIA16, SRIA17, + input SRIB0, SRIB1, SRIB2, SRIB3, SRIB4, SRIB5, SRIB6, SRIB7, SRIB8, SRIB9, SRIB10, SRIB11, SRIB12, SRIB13, SRIB14, SRIB15, SRIB16, SRIB17, + output SROA0, SROA1, SROA2, SROA3, SROA4, SROA5, SROA6, SROA7, SROA8, SROA9, SROA10, SROA11, SROA12, SROA13, SROA14, SROA15, SROA16, SROA17, + output SROB0, SROB1, SROB2, SROB3, SROB4, SROB5, SROB6, SROB7, SROB8, SROB9, SROB10, SROB11, SROB12, SROB13, SROB14, SROB15, SROB16, SROB17, + output ROA0, ROA1, ROA2, ROA3, ROA4, ROA5, ROA6, ROA7, ROA8, ROA9, ROA10, ROA11, ROA12, ROA13, ROA14, ROA15, ROA16, ROA17, + output ROB0, ROB1, ROB2, ROB3, ROB4, ROB5, ROB6, ROB7, ROB8, ROB9, ROB10, ROB11, ROB12, ROB13, ROB14, ROB15, ROB16, ROB17, + output ROC0, ROC1, ROC2, ROC3, ROC4, ROC5, ROC6, ROC7, ROC8, ROC9, ROC10, ROC11, ROC12, ROC13, ROC14, ROC15, ROC16, ROC17, + output P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, + output SIGNEDP +); + parameter REG_INPUTA_CLK = "NONE"; + parameter REG_INPUTA_CE = "CE0"; + parameter REG_INPUTA_RST = "RST0"; + parameter REG_INPUTB_CLK = "NONE"; + parameter REG_INPUTB_CE = "CE0"; + parameter REG_INPUTB_RST = "RST0"; + parameter REG_INPUTC_CLK = "NONE"; + parameter REG_INPUTC_CE = "CE0"; + parameter REG_INPUTC_RST = "RST0"; + parameter REG_PIPELINE_CLK = "NONE"; + parameter REG_PIPELINE_CE = "CE0"; + parameter REG_PIPELINE_RST = "RST0"; + parameter REG_OUTPUT_CLK = "NONE"; + parameter REG_OUTPUT_CE = "CE0"; + parameter REG_OUTPUT_RST = "RST0"; + parameter [127:0] CLK0_DIV = "ENABLED"; + parameter [127:0] CLK1_DIV = "ENABLED"; + parameter [127:0] CLK2_DIV = "ENABLED"; + parameter [127:0] CLK3_DIV = "ENABLED"; + parameter HIGHSPEED_CLK = "NONE"; + parameter [127:0] GSR = "ENABLED"; + parameter CAS_MATCH_REG = "FALSE"; + parameter [127:0] SOURCEB_MODE = "B_SHIFT"; + parameter [127:0] MULT_BYPASS = "DISABLED"; + parameter [127:0] RESETMODE = "SYNC"; +endmodule + +(* blackbox *) +module ALU54B( + input CLK0, CLK1, CLK2, CLK3, + input CE0, CE1, CE2, CE3, + input RST0, RST1, RST2, RST3, + input SIGNEDIA, SIGNEDIB, SIGNEDCIN, + input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, + input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B20, B21, B22, B23, B24, B25, B26, B27, B28, B29, B30, B31, B32, B33, B34, B35, + input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26, C27, C28, C29, C30, C31, C32, C33, C34, C35, C36, C37, C38, C39, C40, C41, C42, C43, C44, C45, C46, C47, C48, C49, C50, C51, C52, C53, + input CFB0, CFB1, CFB2, CFB3, CFB4, CFB5, CFB6, CFB7, CFB8, CFB9, CFB10, CFB11, CFB12, CFB13, CFB14, CFB15, CFB16, CFB17, CFB18, CFB19, CFB20, CFB21, CFB22, CFB23, CFB24, CFB25, CFB26, CFB27, CFB28, CFB29, CFB30, CFB31, CFB32, CFB33, CFB34, CFB35, CFB36, CFB37, CFB38, CFB39, CFB40, CFB41, CFB42, CFB43, CFB44, CFB45, CFB46, CFB47, CFB48, CFB49, CFB50, CFB51, CFB52, CFB53, + input MA0, MA1, MA2, MA3, MA4, MA5, MA6, MA7, MA8, MA9, MA10, MA11, MA12, MA13, MA14, MA15, MA16, MA17, MA18, MA19, MA20, MA21, MA22, MA23, MA24, MA25, MA26, MA27, MA28, MA29, MA30, MA31, MA32, MA33, MA34, MA35, + input MB0, MB1, MB2, MB3, MB4, MB5, MB6, MB7, MB8, MB9, MB10, MB11, MB12, MB13, MB14, MB15, MB16, MB17, MB18, MB19, MB20, MB21, MB22, MB23, MB24, MB25, MB26, MB27, MB28, MB29, MB30, MB31, MB32, MB33, MB34, MB35, + input CIN0, CIN1, CIN2, CIN3, CIN4, CIN5, CIN6, CIN7, CIN8, CIN9, CIN10, CIN11, CIN12, CIN13, CIN14, CIN15, CIN16, CIN17, CIN18, CIN19, CIN20, CIN21, CIN22, CIN23, CIN24, CIN25, CIN26, CIN27, CIN28, CIN29, CIN30, CIN31, CIN32, CIN33, CIN34, CIN35, CIN36, CIN37, CIN38, CIN39, CIN40, CIN41, CIN42, CIN43, CIN44, CIN45, CIN46, CIN47, CIN48, CIN49, CIN50, CIN51, CIN52, CIN53, + input OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7, OP8, OP9, OP10, + output R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, R47, R48, R49, R50, R51, R52, R53, + output CO0, CO1, CO2, CO3, CO4, CO5, CO6, CO7, CO8, CO9, CO10, CO11, CO12, CO13, CO14, CO15, CO16, CO17, CO18, CO19, CO20, CO21, CO22, CO23, CO24, CO25, CO26, CO27, CO28, CO29, CO30, CO31, CO32, CO33, CO34, CO35, CO36, CO37, CO38, CO39, CO40, CO41, CO42, CO43, CO44, CO45, CO46, CO47, CO48, CO49, CO50, CO51, CO52, CO53, + output EQZ, EQZM, EQOM, EQPAT, EQPATB, + output OVER, UNDER, OVERUNDER, + output SIGNEDR +); + parameter REG_INPUTC0_CLK = "NONE"; + parameter REG_INPUTC0_CE = "CE0"; + parameter REG_INPUTC0_RST = "RST0"; + parameter REG_INPUTC1_CLK = "NONE"; + parameter REG_INPUTC1_CE = "CE0"; + parameter REG_INPUTC1_RST = "RST0"; + parameter REG_OPCODEOP0_0_CLK = "NONE"; + parameter REG_OPCODEOP0_0_CE = "CE0"; + parameter REG_OPCODEOP0_0_RST = "RST0"; + parameter REG_OPCODEOP1_0_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CE = "CE0"; + parameter REG_OPCODEOP0_1_RST = "RST0"; + parameter REG_OPCODEOP1_1_CLK = "NONE"; + parameter REG_OPCODEIN_0_CLK = "NONE"; + parameter REG_OPCODEIN_0_CE = "CE0"; + parameter REG_OPCODEIN_0_RST = "RST0"; + parameter REG_OPCODEIN_1_CLK = "NONE"; + parameter REG_OPCODEIN_1_CE = "CE0"; + parameter REG_OPCODEIN_1_RST = "RST0"; + parameter REG_OUTPUT0_CLK = "NONE"; + parameter REG_OUTPUT0_CE = "CE0"; + parameter REG_OUTPUT0_RST = "RST0"; + parameter REG_OUTPUT1_CLK = "NONE"; + parameter REG_OUTPUT1_CE = "CE0"; + parameter REG_OUTPUT1_RST = "RST0"; + parameter REG_FLAG_CLK = "NONE"; + parameter REG_FLAG_CE = "CE0"; + parameter REG_FLAG_RST = "RST0"; + parameter REG_INPUTCFB_CLK = "NONE"; + parameter REG_INPUTCFB_CE = "CE0"; + parameter REG_INPUTCFB_RST = "RST0"; + parameter [127:0] MCPAT_SOURCE = "STATIC"; + parameter [127:0] MASKPAT_SOURCE = "STATIC"; + parameter MASK01 = "0x00000000000000"; + parameter [127:0] CLK0_DIV = "ENABLED"; + parameter [127:0] CLK1_DIV = "ENABLED"; + parameter [127:0] CLK2_DIV = "ENABLED"; + parameter [127:0] CLK3_DIV = "ENABLED"; + parameter MCPAT = "0x00000000000000"; + parameter MASKPAT = "0x00000000000000"; + parameter RNDPAT = "0x00000000000000"; + parameter [127:0] GSR = "ENABLED"; + parameter [127:0] RESETMODE = "SYNC"; + parameter MULT9_MODE = "DISABLED"; + parameter FORCE_ZERO_BARREL_SHIFT = "DISABLED"; + parameter LEGACY = "DISABLED"; +endmodule + +(* blackbox *) +module EHXPLLL ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, PHASELOADREG, + input STDBY, PLLWAKESYNC, + input RST, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, + output CLKOP, CLKOS, CLKOS2, CLKOS3, + output LOCK, INTLOCK, + output REFCLK, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "DISABLED"; + parameter CLKOS2_ENABLE = "DISABLED"; + parameter CLKOS3_ENABLE = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter OUTDIVIDER_MUXA = "DIVA"; + parameter OUTDIVIDER_MUXB = "DIVB"; + parameter OUTDIVIDER_MUXC = "DIVC"; + parameter OUTDIVIDER_MUXD = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter PLL_LOCK_DELAY = 200; + parameter STDBY_ENABLE = "DISABLED"; + parameter REFIN_RESET = "DISABLED"; + parameter SYNC_ENABLE = "DISABLED"; + parameter INT_LOCK_STICKY = "ENABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module DTR( + input STARTPULSE, + output DTROUT7, DTROUT6, DTROUT5, DTROUT4, DTROUT3, DTROUT2, DTROUT1, DTROUT0 +); +endmodule + +(* blackbox *) +module OSCG( + output OSC +); +parameter DIV = 128; +endmodule + +(* blackbox *) (* keep *) +module USRMCLK( + input USRMCLKI, USRMCLKTS, + output USRMCLKO +); +endmodule + +(* blackbox *) (* keep *) +module JTAGG( + (* iopad_external_pin *) + input TCK, + (* iopad_external_pin *) + input TMS, + (* iopad_external_pin *) + input TDI, + input JTDO2, JTDO1, + (* iopad_external_pin *) + output TDO, + output JTDI, JTCK, JRTI2, JRTI1, + output JSHIFT, JUPDATE, JRSTN, JCE2, JCE1 +); +parameter ER1 = "ENABLED"; +parameter ER2 = "ENABLED"; +endmodule + +(* blackbox *) +module DELAYF( + input A, LOADN, MOVE, DIRECTION, + output Z, CFLAG +); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; +endmodule + +(* blackbox *) +module DELAYG( + input A, + output Z +); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; +endmodule + +(* blackbox *) +module IDDRX1F( + input D, SCLK, RST, + output Q0, Q1 +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module IDDRX2F( + input D, SCLK, ECLK, RST, ALIGNWD, + output Q0, Q1, Q2, Q3 +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module IDDR71B( + input D, SCLK, ECLK, RST, ALIGNWD, + output Q0, Q1, Q2, Q3, Q4, Q5, Q6 +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module IDDRX2DQA( + input D, DQSR90, ECLK, SCLK, RST, + input RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, + output Q0, Q1, Q2, Q3, QWL +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX1F( + input SCLK, RST, D0, D1, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX2F( + input SCLK, ECLK, RST, D0, D1, D2, D3, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDR71B( + input SCLK, ECLK, RST, D0, D1, D2, D3, D4, D5, D6, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module OSHX2A( + input D0, D1, RST, ECLK, SCLK, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX2DQA( + input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW270, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX2DQSB( + input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module TSHX2DQA( + input T0, T1, SCLK, ECLK, DQSW270, RST, + output Q +); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; +endmodule + +(* blackbox *) +module TSHX2DQSA( + input T0, T1, SCLK, ECLK, DQSW, RST, + output Q +); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; +endmodule + +(* blackbox *) +module DQSBUFM( + input DQSI, READ1, READ0, READCLKSEL2, READCLKSEL1, READCLKSEL0, DDRDEL, + input ECLK, SCLK, + input DYNDELAY7, DYNDELAY6, DYNDELAY5, DYNDELAY4, + input DYNDELAY3, DYNDELAY2, DYNDELAY1, DYNDELAY0, + input RST, RDLOADN, RDMOVE, RDDIRECTION, WRLOADN, WRMOVE, WRDIRECTION, PAUSE, + output DQSR90, DQSW, DQSW270, + output RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, + output DATAVALID, BURSTDET, RDCFLAG, WRCFLAG +); + parameter DQS_LI_DEL_ADJ = "FACTORYONLY"; + parameter DQS_LI_DEL_VAL = 0; + parameter DQS_LO_DEL_ADJ = "FACTORYONLY"; + parameter DQS_LO_DEL_VAL = 0; + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module DDRDLLA( + input CLK, RST, UDDCNTLN, FREEZE, + output LOCK, DDRDEL, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1, DCNTL0 +); + parameter FORCE_MAX_DELAY = "NO"; + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module DLLDELD( + input A, DDRDEL, LOADN, MOVE, DIRECTION, + output Z, CFLAG +); + parameter DEL_ADJ = "PLUS"; + parameter DEL_VAL = 0; +endmodule + +(* blackbox *) +module CLKDIVF( + input CLKI, RST, ALIGNWD, + output CDIVX +); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; +endmodule + +(* blackbox *) +module ECLKSYNCB( + input ECLKI, STOP, + output ECLKO +); +endmodule + +(* blackbox *) +module ECLKBRIDGECS( + input CLK0, CLK1, SEL, + output ECSOUT +); +endmodule + +(* blackbox *) +module DCCA( + input CLKI, CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCSC( + input CLK1, CLK0, + input SEL1, SEL0, + input MODESEL, + output DCSOUT +); + parameter DCSMODE = "POS"; +endmodule + +(* blackbox *) (* keep *) +module DCUA( + (* iopad_external_pin *) + input CH0_HDINP, + (* iopad_external_pin *) + input CH1_HDINP, + (* iopad_external_pin *) + input CH0_HDINN, + (* iopad_external_pin *) + input CH1_HDINN, + input D_TXBIT_CLKP_FROM_ND, D_TXBIT_CLKN_FROM_ND, D_SYNC_ND, D_TXPLL_LOL_FROM_ND, + input CH0_RX_REFCLK, CH1_RX_REFCLK, CH0_FF_RXI_CLK, CH1_FF_RXI_CLK, CH0_FF_TXI_CLK, CH1_FF_TXI_CLK, CH0_FF_EBRD_CLK, CH1_FF_EBRD_CLK, + input CH0_FF_TX_D_0, CH1_FF_TX_D_0, CH0_FF_TX_D_1, CH1_FF_TX_D_1, CH0_FF_TX_D_2, CH1_FF_TX_D_2, CH0_FF_TX_D_3, CH1_FF_TX_D_3, + input CH0_FF_TX_D_4, CH1_FF_TX_D_4, CH0_FF_TX_D_5, CH1_FF_TX_D_5, CH0_FF_TX_D_6, CH1_FF_TX_D_6, CH0_FF_TX_D_7, CH1_FF_TX_D_7, + input CH0_FF_TX_D_8, CH1_FF_TX_D_8, CH0_FF_TX_D_9, CH1_FF_TX_D_9, CH0_FF_TX_D_10, CH1_FF_TX_D_10, CH0_FF_TX_D_11, CH1_FF_TX_D_11, + input CH0_FF_TX_D_12, CH1_FF_TX_D_12, CH0_FF_TX_D_13, CH1_FF_TX_D_13, CH0_FF_TX_D_14, CH1_FF_TX_D_14, CH0_FF_TX_D_15, CH1_FF_TX_D_15, + input CH0_FF_TX_D_16, CH1_FF_TX_D_16, CH0_FF_TX_D_17, CH1_FF_TX_D_17, CH0_FF_TX_D_18, CH1_FF_TX_D_18, CH0_FF_TX_D_19, CH1_FF_TX_D_19, + input CH0_FF_TX_D_20, CH1_FF_TX_D_20, CH0_FF_TX_D_21, CH1_FF_TX_D_21, CH0_FF_TX_D_22, CH1_FF_TX_D_22, CH0_FF_TX_D_23, CH1_FF_TX_D_23, + input CH0_FFC_EI_EN, CH1_FFC_EI_EN, CH0_FFC_PCIE_DET_EN, CH1_FFC_PCIE_DET_EN, CH0_FFC_PCIE_CT, CH1_FFC_PCIE_CT, CH0_FFC_SB_INV_RX, CH1_FFC_SB_INV_RX, + input CH0_FFC_ENABLE_CGALIGN, CH1_FFC_ENABLE_CGALIGN, CH0_FFC_SIGNAL_DETECT, CH1_FFC_SIGNAL_DETECT, CH0_FFC_FB_LOOPBACK, CH1_FFC_FB_LOOPBACK, CH0_FFC_SB_PFIFO_LP, CH1_FFC_SB_PFIFO_LP, + input CH0_FFC_PFIFO_CLR, CH1_FFC_PFIFO_CLR, CH0_FFC_RATE_MODE_RX, CH1_FFC_RATE_MODE_RX, CH0_FFC_RATE_MODE_TX, CH1_FFC_RATE_MODE_TX, CH0_FFC_DIV11_MODE_RX, CH1_FFC_DIV11_MODE_RX, CH0_FFC_RX_GEAR_MODE, CH1_FFC_RX_GEAR_MODE, CH0_FFC_TX_GEAR_MODE, CH1_FFC_TX_GEAR_MODE, + input CH0_FFC_DIV11_MODE_TX, CH1_FFC_DIV11_MODE_TX, CH0_FFC_LDR_CORE2TX_EN, CH1_FFC_LDR_CORE2TX_EN, CH0_FFC_LANE_TX_RST, CH1_FFC_LANE_TX_RST, CH0_FFC_LANE_RX_RST, CH1_FFC_LANE_RX_RST, + input CH0_FFC_RRST, CH1_FFC_RRST, CH0_FFC_TXPWDNB, CH1_FFC_TXPWDNB, CH0_FFC_RXPWDNB, CH1_FFC_RXPWDNB, CH0_LDR_CORE2TX, CH1_LDR_CORE2TX, + input D_SCIWDATA0, D_SCIWDATA1, D_SCIWDATA2, D_SCIWDATA3, D_SCIWDATA4, D_SCIWDATA5, D_SCIWDATA6, D_SCIWDATA7, + input D_SCIADDR0, D_SCIADDR1, D_SCIADDR2, D_SCIADDR3, D_SCIADDR4, D_SCIADDR5, D_SCIENAUX, D_SCISELAUX, + input CH0_SCIEN, CH1_SCIEN, CH0_SCISEL, CH1_SCISEL, D_SCIRD, D_SCIWSTN, D_CYAWSTN, D_FFC_SYNC_TOGGLE, + input D_FFC_DUAL_RST, D_FFC_MACRO_RST, D_FFC_MACROPDB, D_FFC_TRST, CH0_FFC_CDR_EN_BITSLIP, CH1_FFC_CDR_EN_BITSLIP, D_SCAN_ENABLE, D_SCAN_IN_0, + input D_SCAN_IN_1, D_SCAN_IN_2, D_SCAN_IN_3, D_SCAN_IN_4, D_SCAN_IN_5, D_SCAN_IN_6, D_SCAN_IN_7, D_SCAN_MODE, + input D_SCAN_RESET, D_CIN0, D_CIN1, D_CIN2, D_CIN3, D_CIN4, D_CIN5, D_CIN6,D_CIN7, D_CIN8, D_CIN9, D_CIN10, D_CIN11, + output CH0_HDOUTP, CH1_HDOUTP, CH0_HDOUTN, CH1_HDOUTN, D_TXBIT_CLKP_TO_ND, D_TXBIT_CLKN_TO_ND, D_SYNC_PULSE2ND, D_TXPLL_LOL_TO_ND, + output CH0_FF_RX_F_CLK, CH1_FF_RX_F_CLK, CH0_FF_RX_H_CLK, CH1_FF_RX_H_CLK, CH0_FF_TX_F_CLK, CH1_FF_TX_F_CLK, CH0_FF_TX_H_CLK, CH1_FF_TX_H_CLK, + output CH0_FF_RX_PCLK, CH1_FF_RX_PCLK, CH0_FF_TX_PCLK, CH1_FF_TX_PCLK, CH0_FF_RX_D_0, CH1_FF_RX_D_0, CH0_FF_RX_D_1, CH1_FF_RX_D_1, + output CH0_FF_RX_D_2, CH1_FF_RX_D_2, CH0_FF_RX_D_3, CH1_FF_RX_D_3, CH0_FF_RX_D_4, CH1_FF_RX_D_4, CH0_FF_RX_D_5, CH1_FF_RX_D_5, + output CH0_FF_RX_D_6, CH1_FF_RX_D_6, CH0_FF_RX_D_7, CH1_FF_RX_D_7, CH0_FF_RX_D_8, CH1_FF_RX_D_8, CH0_FF_RX_D_9, CH1_FF_RX_D_9, + output CH0_FF_RX_D_10, CH1_FF_RX_D_10, CH0_FF_RX_D_11, CH1_FF_RX_D_11, CH0_FF_RX_D_12, CH1_FF_RX_D_12, CH0_FF_RX_D_13, CH1_FF_RX_D_13, + output CH0_FF_RX_D_14, CH1_FF_RX_D_14, CH0_FF_RX_D_15, CH1_FF_RX_D_15, CH0_FF_RX_D_16, CH1_FF_RX_D_16, CH0_FF_RX_D_17, CH1_FF_RX_D_17, + output CH0_FF_RX_D_18, CH1_FF_RX_D_18, CH0_FF_RX_D_19, CH1_FF_RX_D_19, CH0_FF_RX_D_20, CH1_FF_RX_D_20, CH0_FF_RX_D_21, CH1_FF_RX_D_21, + output CH0_FF_RX_D_22, CH1_FF_RX_D_22, CH0_FF_RX_D_23, CH1_FF_RX_D_23, CH0_FFS_PCIE_DONE, CH1_FFS_PCIE_DONE, CH0_FFS_PCIE_CON, CH1_FFS_PCIE_CON, + output CH0_FFS_RLOS, CH1_FFS_RLOS, CH0_FFS_LS_SYNC_STATUS, CH1_FFS_LS_SYNC_STATUS, CH0_FFS_CC_UNDERRUN, CH1_FFS_CC_UNDERRUN, CH0_FFS_CC_OVERRUN, CH1_FFS_CC_OVERRUN, + output CH0_FFS_RXFBFIFO_ERROR, CH1_FFS_RXFBFIFO_ERROR, CH0_FFS_TXFBFIFO_ERROR, CH1_FFS_TXFBFIFO_ERROR, CH0_FFS_RLOL, CH1_FFS_RLOL, CH0_FFS_SKP_ADDED, CH1_FFS_SKP_ADDED, + output CH0_FFS_SKP_DELETED, CH1_FFS_SKP_DELETED, CH0_LDR_RX2CORE, CH1_LDR_RX2CORE, D_SCIRDATA0, D_SCIRDATA1, D_SCIRDATA2, D_SCIRDATA3, + output D_SCIRDATA4, D_SCIRDATA5, D_SCIRDATA6, D_SCIRDATA7, D_SCIINT, D_SCAN_OUT_0, D_SCAN_OUT_1, D_SCAN_OUT_2, D_SCAN_OUT_3, D_SCAN_OUT_4, D_SCAN_OUT_5, D_SCAN_OUT_6, D_SCAN_OUT_7, + output D_COUT0, D_COUT1, D_COUT2, D_COUT3, D_COUT4, D_COUT5, D_COUT6, D_COUT7, D_COUT8, D_COUT9, D_COUT10, D_COUT11, D_COUT12, D_COUT13, D_COUT14, D_COUT15, D_COUT16, D_COUT17, D_COUT18, D_COUT19, + + input D_REFCLKI, + output D_FFS_PLOL +); + parameter CH0_AUTO_CALIB_EN = "0b0"; + parameter CH0_AUTO_FACQ_EN = "0b0"; + parameter CH0_BAND_THRESHOLD = "0b000000"; + parameter CH0_CALIB_CK_MODE = "0b0"; + parameter CH0_CC_MATCH_1 = "0b0000000000"; + parameter CH0_CC_MATCH_2 = "0b0000000000"; + parameter CH0_CC_MATCH_3 = "0b0000000000"; + parameter CH0_CC_MATCH_4 = "0b0000000000"; + parameter CH0_CDR_CNT4SEL = "0b00"; + parameter CH0_CDR_CNT8SEL = "0b00"; + parameter CH0_CTC_BYPASS = "0b0"; + parameter CH0_DCOATDCFG = "0b00"; + parameter CH0_DCOATDDLY = "0b00"; + parameter CH0_DCOBYPSATD = "0b0"; + parameter CH0_DCOCALDIV = "0b000"; + parameter CH0_DCOCTLGI = "0b000"; + parameter CH0_DCODISBDAVOID = "0b0"; + parameter CH0_DCOFLTDAC = "0b00"; + parameter CH0_DCOFTNRG = "0b000"; + parameter CH0_DCOIOSTUNE = "0b000"; + parameter CH0_DCOITUNE = "0b00"; + parameter CH0_DCOITUNE4LSB = "0b000"; + parameter CH0_DCOIUPDNX2 = "0b0"; + parameter CH0_DCONUOFLSB = "0b000"; + parameter CH0_DCOSCALEI = "0b00"; + parameter CH0_DCOSTARTVAL = "0b000"; + parameter CH0_DCOSTEP = "0b00"; + parameter CH0_DEC_BYPASS = "0b0"; + parameter CH0_ENABLE_CG_ALIGN = "0b0"; + parameter CH0_ENC_BYPASS = "0b0"; + parameter CH0_FF_RX_F_CLK_DIS = "0b0"; + parameter CH0_FF_RX_H_CLK_EN = "0b0"; + parameter CH0_FF_TX_F_CLK_DIS = "0b0"; + parameter CH0_FF_TX_H_CLK_EN = "0b0"; + parameter CH0_GE_AN_ENABLE = "0b0"; + parameter CH0_INVERT_RX = "0b0"; + parameter CH0_INVERT_TX = "0b0"; + parameter CH0_LDR_CORE2TX_SEL = "0b0"; + parameter CH0_LDR_RX2CORE_SEL = "0b0"; + parameter CH0_LEQ_OFFSET_SEL = "0b0"; + parameter CH0_LEQ_OFFSET_TRIM = "0b000"; + parameter CH0_LSM_DISABLE = "0b0"; + parameter CH0_MATCH_2_ENABLE = "0b0"; + parameter CH0_MATCH_4_ENABLE = "0b0"; + parameter CH0_MIN_IPG_CNT = "0b00"; + parameter CH0_PCIE_EI_EN = "0b0"; + parameter CH0_PCIE_MODE = "0b0"; + parameter CH0_PCS_DET_TIME_SEL = "0b00"; + parameter CH0_PDEN_SEL = "0b0"; + parameter CH0_PRBS_ENABLE = "0b0"; + parameter CH0_PRBS_LOCK = "0b0"; + parameter CH0_PRBS_SELECTION = "0b0"; + parameter CH0_RATE_MODE_RX = "0b0"; + parameter CH0_RATE_MODE_TX = "0b0"; + parameter CH0_RCV_DCC_EN = "0b0"; + parameter CH0_REG_BAND_OFFSET = "0b0000"; + parameter CH0_REG_BAND_SEL = "0b000000"; + parameter CH0_REG_IDAC_EN = "0b0"; + parameter CH0_REG_IDAC_SEL = "0b0000000000"; + parameter CH0_REQ_EN = "0b0"; + parameter CH0_REQ_LVL_SET = "0b00"; + parameter CH0_RIO_MODE = "0b0"; + parameter CH0_RLOS_SEL = "0b0"; + parameter CH0_RPWDNB = "0b0"; + parameter CH0_RTERM_RX = "0b00000"; + parameter CH0_RTERM_TX = "0b00000"; + parameter CH0_RXIN_CM = "0b00"; + parameter CH0_RXTERM_CM = "0b00"; + parameter CH0_RX_DCO_CK_DIV = "0b000"; + parameter CH0_RX_DIV11_SEL = "0b0"; + parameter CH0_RX_GEAR_BYPASS = "0b0"; + parameter CH0_RX_GEAR_MODE = "0b0"; + parameter CH0_RX_LOS_CEQ = "0b00"; + parameter CH0_RX_LOS_EN = "0b0"; + parameter CH0_RX_LOS_HYST_EN = "0b0"; + parameter CH0_RX_LOS_LVL = "0b000"; + parameter CH0_RX_RATE_SEL = "0b0000"; + parameter CH0_RX_SB_BYPASS = "0b0"; + parameter CH0_SB_BYPASS = "0b0"; + parameter CH0_SEL_SD_RX_CLK = "0b0"; + parameter CH0_TDRV_DAT_SEL = "0b00"; + parameter CH0_TDRV_POST_EN = "0b0"; + parameter CH0_TDRV_PRE_EN = "0b0"; + parameter CH0_TDRV_SLICE0_CUR = "0b000"; + parameter CH0_TDRV_SLICE0_SEL = "0b00"; + parameter CH0_TDRV_SLICE1_CUR = "0b000"; + parameter CH0_TDRV_SLICE1_SEL = "0b00"; + parameter CH0_TDRV_SLICE2_CUR = "0b00"; + parameter CH0_TDRV_SLICE2_SEL = "0b00"; + parameter CH0_TDRV_SLICE3_CUR = "0b00"; + parameter CH0_TDRV_SLICE3_SEL = "0b00"; + parameter CH0_TDRV_SLICE4_CUR = "0b00"; + parameter CH0_TDRV_SLICE4_SEL = "0b00"; + parameter CH0_TDRV_SLICE5_CUR = "0b00"; + parameter CH0_TDRV_SLICE5_SEL = "0b00"; + parameter CH0_TPWDNB = "0b0"; + parameter CH0_TX_CM_SEL = "0b00"; + parameter CH0_TX_DIV11_SEL = "0b0"; + parameter CH0_TX_GEAR_BYPASS = "0b0"; + parameter CH0_TX_GEAR_MODE = "0b0"; + parameter CH0_TX_POST_SIGN = "0b0"; + parameter CH0_TX_PRE_SIGN = "0b0"; + parameter CH0_UC_MODE = "0b0"; + parameter CH0_UDF_COMMA_A = "0b0000000000"; + parameter CH0_UDF_COMMA_B = "0b0000000000"; + parameter CH0_UDF_COMMA_MASK = "0b0000000000"; + parameter CH0_WA_BYPASS = "0b0"; + parameter CH0_WA_MODE = "0b0"; + parameter CH1_AUTO_CALIB_EN = "0b0"; + parameter CH1_AUTO_FACQ_EN = "0b0"; + parameter CH1_BAND_THRESHOLD = "0b000000"; + parameter CH1_CALIB_CK_MODE = "0b0"; + parameter CH1_CC_MATCH_1 = "0b0000000000"; + parameter CH1_CC_MATCH_2 = "0b0000000000"; + parameter CH1_CC_MATCH_3 = "0b0000000000"; + parameter CH1_CC_MATCH_4 = "0b0000000000"; + parameter CH1_CDR_CNT4SEL = "0b00"; + parameter CH1_CDR_CNT8SEL = "0b00"; + parameter CH1_CTC_BYPASS = "0b0"; + parameter CH1_DCOATDCFG = "0b00"; + parameter CH1_DCOATDDLY = "0b00"; + parameter CH1_DCOBYPSATD = "0b0"; + parameter CH1_DCOCALDIV = "0b000"; + parameter CH1_DCOCTLGI = "0b000"; + parameter CH1_DCODISBDAVOID = "0b0"; + parameter CH1_DCOFLTDAC = "0b00"; + parameter CH1_DCOFTNRG = "0b000"; + parameter CH1_DCOIOSTUNE = "0b000"; + parameter CH1_DCOITUNE = "0b00"; + parameter CH1_DCOITUNE4LSB = "0b000"; + parameter CH1_DCOIUPDNX2 = "0b0"; + parameter CH1_DCONUOFLSB = "0b000"; + parameter CH1_DCOSCALEI = "0b00"; + parameter CH1_DCOSTARTVAL = "0b000"; + parameter CH1_DCOSTEP = "0b00"; + parameter CH1_DEC_BYPASS = "0b0"; + parameter CH1_ENABLE_CG_ALIGN = "0b0"; + parameter CH1_ENC_BYPASS = "0b0"; + parameter CH1_FF_RX_F_CLK_DIS = "0b0"; + parameter CH1_FF_RX_H_CLK_EN = "0b0"; + parameter CH1_FF_TX_F_CLK_DIS = "0b0"; + parameter CH1_FF_TX_H_CLK_EN = "0b0"; + parameter CH1_GE_AN_ENABLE = "0b0"; + parameter CH1_INVERT_RX = "0b0"; + parameter CH1_INVERT_TX = "0b0"; + parameter CH1_LDR_CORE2TX_SEL = "0b0"; + parameter CH1_LDR_RX2CORE_SEL = "0b0"; + parameter CH1_LEQ_OFFSET_SEL = "0b0"; + parameter CH1_LEQ_OFFSET_TRIM = "0b000"; + parameter CH1_LSM_DISABLE = "0b0"; + parameter CH1_MATCH_2_ENABLE = "0b0"; + parameter CH1_MATCH_4_ENABLE = "0b0"; + parameter CH1_MIN_IPG_CNT = "0b00"; + parameter CH1_PCIE_EI_EN = "0b0"; + parameter CH1_PCIE_MODE = "0b0"; + parameter CH1_PCS_DET_TIME_SEL = "0b00"; + parameter CH1_PDEN_SEL = "0b0"; + parameter CH1_PRBS_ENABLE = "0b0"; + parameter CH1_PRBS_LOCK = "0b0"; + parameter CH1_PRBS_SELECTION = "0b0"; + parameter CH1_RATE_MODE_RX = "0b0"; + parameter CH1_RATE_MODE_TX = "0b0"; + parameter CH1_RCV_DCC_EN = "0b0"; + parameter CH1_REG_BAND_OFFSET = "0b0000"; + parameter CH1_REG_BAND_SEL = "0b000000"; + parameter CH1_REG_IDAC_EN = "0b0"; + parameter CH1_REG_IDAC_SEL = "0b0000000000"; + parameter CH1_REQ_EN = "0b0"; + parameter CH1_REQ_LVL_SET = "0b00"; + parameter CH1_RIO_MODE = "0b0"; + parameter CH1_RLOS_SEL = "0b0"; + parameter CH1_RPWDNB = "0b0"; + parameter CH1_RTERM_RX = "0b00000"; + parameter CH1_RTERM_TX = "0b00000"; + parameter CH1_RXIN_CM = "0b00"; + parameter CH1_RXTERM_CM = "0b00"; + parameter CH1_RX_DCO_CK_DIV = "0b000"; + parameter CH1_RX_DIV11_SEL = "0b0"; + parameter CH1_RX_GEAR_BYPASS = "0b0"; + parameter CH1_RX_GEAR_MODE = "0b0"; + parameter CH1_RX_LOS_CEQ = "0b00"; + parameter CH1_RX_LOS_EN = "0b0"; + parameter CH1_RX_LOS_HYST_EN = "0b0"; + parameter CH1_RX_LOS_LVL = "0b000"; + parameter CH1_RX_RATE_SEL = "0b0000"; + parameter CH1_RX_SB_BYPASS = "0b0"; + parameter CH1_SB_BYPASS = "0b0"; + parameter CH1_SEL_SD_RX_CLK = "0b0"; + parameter CH1_TDRV_DAT_SEL = "0b00"; + parameter CH1_TDRV_POST_EN = "0b0"; + parameter CH1_TDRV_PRE_EN = "0b0"; + parameter CH1_TDRV_SLICE0_CUR = "0b000"; + parameter CH1_TDRV_SLICE0_SEL = "0b00"; + parameter CH1_TDRV_SLICE1_CUR = "0b000"; + parameter CH1_TDRV_SLICE1_SEL = "0b00"; + parameter CH1_TDRV_SLICE2_CUR = "0b00"; + parameter CH1_TDRV_SLICE2_SEL = "0b00"; + parameter CH1_TDRV_SLICE3_CUR = "0b00"; + parameter CH1_TDRV_SLICE3_SEL = "0b00"; + parameter CH1_TDRV_SLICE4_CUR = "0b00"; + parameter CH1_TDRV_SLICE4_SEL = "0b00"; + parameter CH1_TDRV_SLICE5_CUR = "0b00"; + parameter CH1_TDRV_SLICE5_SEL = "0b00"; + parameter CH1_TPWDNB = "0b0"; + parameter CH1_TX_CM_SEL = "0b00"; + parameter CH1_TX_DIV11_SEL = "0b0"; + parameter CH1_TX_GEAR_BYPASS = "0b0"; + parameter CH1_TX_GEAR_MODE = "0b0"; + parameter CH1_TX_POST_SIGN = "0b0"; + parameter CH1_TX_PRE_SIGN = "0b0"; + parameter CH1_UC_MODE = "0b0"; + parameter CH1_UDF_COMMA_A = "0b0000000000"; + parameter CH1_UDF_COMMA_B = "0b0000000000"; + parameter CH1_UDF_COMMA_MASK = "0b0000000000"; + parameter CH1_WA_BYPASS = "0b0"; + parameter CH1_WA_MODE = "0b0"; + parameter D_BITCLK_FROM_ND_EN = "0b0"; + parameter D_BITCLK_LOCAL_EN = "0b0"; + parameter D_BITCLK_ND_EN = "0b0"; + parameter D_BUS8BIT_SEL = "0b0"; + parameter D_CDR_LOL_SET = "0b00"; + parameter D_CMUSETBIASI = "0b00"; + parameter D_CMUSETI4CPP = "0b0000"; + parameter D_CMUSETI4CPZ = "0b0000"; + parameter D_CMUSETI4VCO = "0b00"; + parameter D_CMUSETICP4P = "0b00"; + parameter D_CMUSETICP4Z = "0b000"; + parameter D_CMUSETINITVCT = "0b00"; + parameter D_CMUSETISCL4VCO = "0b000"; + parameter D_CMUSETP1GM = "0b000"; + parameter D_CMUSETP2AGM = "0b000"; + parameter D_CMUSETZGM = "0b000"; + parameter D_DCO_CALIB_TIME_SEL = "0b00"; + parameter D_HIGH_MARK = "0b0000"; + parameter D_IB_PWDNB = "0b0"; + parameter D_ISETLOS = "0b00000000"; + parameter D_LOW_MARK = "0b0000"; + parameter D_MACROPDB = "0b0"; + parameter D_PD_ISET = "0b00"; + parameter D_PLL_LOL_SET = "0b00"; + parameter D_REFCK_MODE = "0b000"; + parameter D_REQ_ISET = "0b000"; + parameter D_RG_EN = "0b0"; + parameter D_RG_SET = "0b00"; + parameter D_SETICONST_AUX = "0b00"; + parameter D_SETICONST_CH = "0b00"; + parameter D_SETIRPOLY_AUX = "0b00"; + parameter D_SETIRPOLY_CH = "0b00"; + parameter D_SETPLLRC = "0b000000"; + parameter D_SYNC_LOCAL_EN = "0b0"; + parameter D_SYNC_ND_EN = "0b0"; + parameter D_TXPLL_PWDNB = "0b0"; + parameter D_TX_VCO_CK_DIV = "0b000"; + parameter D_XGE_MODE = "0b0"; + +// These parameters don't do anything but are +// needed for compatibility with Diamond + parameter D_TX_MAX_RATE = "2.5"; + parameter D_RX_MAX_RATE = "2.5"; + parameter CH0_TXAMPLITUDE = "0d1300"; + parameter CH1_TXAMPLITUDE = "0d1300"; + parameter CH0_PROTOCOL = "8B10B"; + parameter CH1_PROTOCOL = "8B10B"; + parameter CH0_CDR_MAX_RATE = "2.5"; + parameter CH1_CDR_MAX_RATE = "2.5"; + parameter CH0_TXDEPRE = "DISABLED"; + parameter CH1_TXDEPRE = "DISABLED"; + parameter CH0_TXDEPOST = "DISABLED"; + parameter CH1_TXDEPOST = "DISABLED"; +endmodule + +(* blackbox *) +module EXTREFB ( + (* iopad_external_pin *) + input REFCLKP, + (* iopad_external_pin *) + input REFCLKN, + output REFCLKO +); + parameter REFCK_PWDNB = "0b0"; + parameter REFCK_RTERM = "0b0"; + parameter REFCK_DCBIAS_EN = "0b0"; +endmodule + +(* blackbox *) +module PCSCLKDIV ( + input CLKI, RST, SEL2, SEL1, SEL0, + output CDIV1, CDIVX +); + parameter GSR = "DISABLED"; +endmodule + +// Note: this module is not marked keep as we want it swept away in synth (sim use only) +(* blackbox *) +module PUR ( + input PUR +); + parameter RST_PULSE = 1; +endmodule + +(* blackbox, keep *) +module GSR ( + input GSR +); +endmodule + +(* blackbox, keep *) +module SGSR ( + input GSR, CLK +); +endmodule + + +(* blackbox *) +module PDPW16KD ( + input DI35, DI34, DI33, DI32, DI31, DI30, DI29, DI28, DI27, DI26, DI25, DI24, DI23, DI22, DI21, DI20, DI19, DI18, + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE3, BE2, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, + input ADR13, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO35, DO34, DO33, DO32, DO31, DO30, DO29, DO28, DO27, DO26, DO25, DO24, DO23, DO22, DO21, DO20, DO19, DO18, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 36; + parameter DATA_WIDTH_R = 36; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + parameter CLKWMUX = "CLKW"; + parameter CLKRMUX = "CLKR"; + +endmodule diff --git a/techlibs/lattice/cells_bb_xo2.v b/techlibs/lattice/cells_bb_xo2.v new file mode 100644 index 00000000000..3363ed5710d --- /dev/null +++ b/techlibs/lattice/cells_bb_xo2.v @@ -0,0 +1,293 @@ +(* blackbox *) +module DP8KC( + input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter GSR = "ENABLED"; + parameter INIT_DATA = "STATIC"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +endmodule + +(* blackbox *) +module EHXPLLJ ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, + input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, + input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, + input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, + input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, + output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, + output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, + output DPHSRC, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule + +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + +(* blackbox *) +module PDPW8KC ( + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE1, BE0, + input CEW, CLKW, CSW2, CSW1, CSW0, + input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 9; + + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + +endmodule + +(* blackbox *) +module SP8KC ( + input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, + input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, + output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH = 9; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE = "0b000"; + + parameter WRITEMODE = "NORMAL"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module FIFO8KB ( + input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, + input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, + output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, + input EF, AEF, AFF, FF +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 18; + + parameter GSR = "DISABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "ASYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b00"; + parameter CSDECODE_R = "0b00"; + + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; + parameter FULLPOINTER1 = "0b00000000000000"; +endmodule diff --git a/techlibs/lattice/cells_bb_xo3.v b/techlibs/lattice/cells_bb_xo3.v new file mode 100644 index 00000000000..3363ed5710d --- /dev/null +++ b/techlibs/lattice/cells_bb_xo3.v @@ -0,0 +1,293 @@ +(* blackbox *) +module DP8KC( + input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter GSR = "ENABLED"; + parameter INIT_DATA = "STATIC"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +endmodule + +(* blackbox *) +module EHXPLLJ ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, + input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, + input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, + input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, + input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, + output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, + output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, + output DPHSRC, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule + +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + +(* blackbox *) +module PDPW8KC ( + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE1, BE0, + input CEW, CLKW, CSW2, CSW1, CSW0, + input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 9; + + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + +endmodule + +(* blackbox *) +module SP8KC ( + input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, + input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, + output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH = 9; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE = "0b000"; + + parameter WRITEMODE = "NORMAL"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module FIFO8KB ( + input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, + input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, + output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, + input EF, AEF, AFF, FF +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 18; + + parameter GSR = "DISABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "ASYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b00"; + parameter CSDECODE_R = "0b00"; + + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; + parameter FULLPOINTER1 = "0b00000000000000"; +endmodule diff --git a/techlibs/lattice/cells_bb_xo3d.v b/techlibs/lattice/cells_bb_xo3d.v new file mode 100644 index 00000000000..3363ed5710d --- /dev/null +++ b/techlibs/lattice/cells_bb_xo3d.v @@ -0,0 +1,293 @@ +(* blackbox *) +module DP8KC( + input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter GSR = "ENABLED"; + parameter INIT_DATA = "STATIC"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +endmodule + +(* blackbox *) +module EHXPLLJ ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, + input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, + input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, + input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, + input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, + output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, + output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, + output DPHSRC, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule + +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + +(* blackbox *) +module PDPW8KC ( + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE1, BE0, + input CEW, CLKW, CSW2, CSW1, CSW0, + input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 9; + + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + +endmodule + +(* blackbox *) +module SP8KC ( + input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, + input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, + output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH = 9; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE = "0b000"; + + parameter WRITEMODE = "NORMAL"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module FIFO8KB ( + input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, + input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, + output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, + input EF, AEF, AFF, FF +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 18; + + parameter GSR = "DISABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "ASYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b00"; + parameter CSDECODE_R = "0b00"; + + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; + parameter FULLPOINTER1 = "0b00000000000000"; +endmodule diff --git a/techlibs/lattice/cells_ff.vh b/techlibs/lattice/cells_ff.vh new file mode 100644 index 00000000000..6b745f391ee --- /dev/null +++ b/techlibs/lattice/cells_ff.vh @@ -0,0 +1,40 @@ +// Diamond flip-flops +module FD1P3AX(input D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3AY(input D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3BX(input PD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3DX(input CD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3IX(input CD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3JX(input PD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1S3AX(input D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .DI(D), .Q(Q)); endmodule +module FD1S3AY(input D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .DI(D), .Q(Q)); endmodule +module FD1S3BX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule +module FD1S3DX(input CD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule +module FD1S3IX(input CD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule +module FD1S3JX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule + +// TODO: Diamond latches +// module FL1P3AY(); endmodule +// module FL1P3AZ(); endmodule +// module FL1P3BX(); endmodule +// module FL1P3DX(); endmodule +// module FL1P3IY(); endmodule +// module FL1P3JY(); endmodule +// module FL1S3AX(); endmodule +// module FL1S3AY(); endmodule + +// Diamond I/O registers +module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule + +module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule + +// TODO: Diamond I/O latches +// module IFS1S1B(input PD, D, SCLK, output Q); endmodule +// module IFS1S1D(input CD, D, SCLK, output Q); endmodule +// module IFS1S1I(input PD, D, SCLK, output Q); endmodule +// module IFS1S1J(input CD, D, SCLK, output Q); endmodule diff --git a/techlibs/lattice/cells_io.vh b/techlibs/lattice/cells_io.vh new file mode 100644 index 00000000000..220460c4467 --- /dev/null +++ b/techlibs/lattice/cells_io.vh @@ -0,0 +1,14 @@ +// Diamond I/O buffers +module IB ((* iopad_external_pin *) input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPU ((* iopad_external_pin *) input I, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPD ((* iopad_external_pin *) input I, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module OB (input I, (* iopad_external_pin *) output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I)); endmodule +module OBZ (input I, T, (* iopad_external_pin *) output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPU(input I, T, (* iopad_external_pin *) output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPD(input I, T, (* iopad_external_pin *) output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBCO (input I, output OT, OC); OLVDS olvds (.A(I), .Z(OT), .ZN(OC)); endmodule +module BB (input I, T, output O, (* iopad_external_pin *) inout B); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module BBPU (input I, T, output O, (* iopad_external_pin *) inout B); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module BBPD (input I, T, output O, (* iopad_external_pin *) inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module ILVDS(input A, AN, (* iopad_external_pin *) output Z ); TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(A), .O(Z)); endmodule +module OLVDS(input A, (* iopad_external_pin *) output Z, output ZN); TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(Z), .I(A)); endmodule diff --git a/techlibs/lattice/cells_map.v b/techlibs/lattice/cells_map.v new file mode 100644 index 00000000000..4944ece4569 --- /dev/null +++ b/techlibs/lattice/cells_map.v @@ -0,0 +1,191 @@ +module \$_DFF_N_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_P_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_ALDFF_NP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFF_PP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule + +module \$_ALDFFE_NPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_NPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule + +`include "cells_ff.vh" +`include "cells_io.vh" + +`ifndef NO_LUT +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + (* force_downto *) + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(1'b0), .C(1'b0), .D(A[0])); + end else + if (WIDTH == 2) begin + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(1'b0), .C(A[0]), .D(A[1])); + end else + if (WIDTH == 3) begin + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(A[0]), .C(A[1]), .D(A[2])); + end else + if (WIDTH == 4) begin + LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + `ifndef NO_PFUMUX + end else + if (WIDTH == 5) begin + wire f0, f1; + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(Y)); + end else + if (WIDTH == 6) begin + wire f0, f1, f2, f3, g0, g1; + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); + L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[5]), .Z(Y)); + end else + if (WIDTH == 7) begin + wire f0, f1, f2, f3, f4, f5, f6, f7, g0, g1, g2, g3, h0, h1; + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[79:64])) lut4 (.Z(f4), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[95:80])) lut5 (.Z(f5), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[111: 96])) lut6 (.Z(f6), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[127:112])) lut7 (.Z(f7), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); + PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[4]), .Z(g2)); + PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[4]), .Z(g3)); + L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[5]), .Z(h0)); + L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[5]), .Z(h1)); + L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[6]), .Z(Y)); + `endif + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule +`endif diff --git a/techlibs/lattice/cells_sim_ecp5.v b/techlibs/lattice/cells_sim_ecp5.v new file mode 100644 index 00000000000..9439e3a5b31 --- /dev/null +++ b/techlibs/lattice/cells_sim_ecp5.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2c_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/cells_sim_xo2.v b/techlibs/lattice/cells_sim_xo2.v new file mode 100644 index 00000000000..54414287572 --- /dev/null +++ b/techlibs/lattice/cells_sim_xo2.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2d_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/cells_sim_xo3.v b/techlibs/lattice/cells_sim_xo3.v new file mode 100644 index 00000000000..54414287572 --- /dev/null +++ b/techlibs/lattice/cells_sim_xo3.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2d_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/cells_sim_xo3d.v b/techlibs/lattice/cells_sim_xo3d.v new file mode 100644 index 00000000000..54414287572 --- /dev/null +++ b/techlibs/lattice/cells_sim_xo3d.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2d_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/common_sim.vh b/techlibs/lattice/common_sim.vh new file mode 100644 index 00000000000..e6c2e57b507 --- /dev/null +++ b/techlibs/lattice/common_sim.vh @@ -0,0 +1,402 @@ +// --------------------------------------- + +(* abc9_lut=1, lib_whitebox *) +module LUT4(input A, B, C, D, output Z); + parameter [15:0] INIT = 16'h0000; + wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0]; + wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; + wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; + assign Z = A ? s1[1] : s1[0]; + specify + (A => Z) = 141; + (B => Z) = 275; + (C => Z) = 379; + (D => Z) = 379; + endspecify +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// cost of 5-input LUTs and is not intended to be instantiated +// LUT5 = 2x LUT4 + PFUMX +(* abc9_lut=2 *) +module \$__ABC9_LUT5 (input M0, D, C, B, A, output Z); + specify + (M0 => Z) = 151; + (D => Z) = 239; + (C => Z) = 373; + (B => Z) = 477; + (A => Z) = 477; + endspecify +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// of 6-input LUTs and is not intended to be instantiated +// LUT6 = 2x LUT5 + MUX2 +(* abc9_lut=4 *) +module \$__ABC9_LUT6 (input M1, M0, D, C, B, A, output Z); + specify + (M1 => Z) = 148; + (M0 => Z) = 292; + (D => Z) = 380; + (C => Z) = 514; + (B => Z) = 618; + (A => Z) = 618; + endspecify +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// of 7-input LUTs and is not intended to be instantiated +// LUT7 = 2x LUT6 + MUX2 +(* abc9_lut=8 *) +module \$__ABC9_LUT7 (input M2, M1, M0, D, C, B, A, output Z); + specify + (M2 => Z) = 148; + (M1 => Z) = 289; + (M0 => Z) = 433; + (D => Z) = 521; + (C => Z) = 655; + (B => Z) = 759; + (A => Z) = 759; + endspecify +endmodule + +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module L6MUX21 (input D0, D1, SD, output Z); + assign Z = SD ? D1 : D0; + specify + (D0 => Z) = 140; + (D1 => Z) = 141; + (SD => Z) = 148; + endspecify +endmodule + +// --------------------------------------- + +module TRELLIS_RAM16X2 ( + input DI0, DI1, + input WAD0, WAD1, WAD2, WAD3, + input WRE, WCK, + input RAD0, RAD1, RAD2, RAD3, + output DO0, DO1 +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter INITVAL_0 = 16'h0000; + parameter INITVAL_1 = 16'h0000; + + reg [1:0] mem[15:0]; + + integer i; + initial begin + for (i = 0; i < 16; i = i + 1) + mem[i] <= {INITVAL_1[i], INITVAL_0[i]}; + end + + wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; + + reg muxwre; + always @(*) + case (WREMUX) + "1": muxwre = 1'b1; + "0": muxwre = 1'b0; + "INV": muxwre = ~WRE; + default: muxwre = WRE; + endcase + + + always @(posedge muxwck) + if (muxwre) + mem[{WAD3, WAD2, WAD1, WAD0}] <= {DI1, DI0}; + + assign {DO1, DO0} = mem[{RAD3, RAD2, RAD1, RAD0}]; +endmodule + +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module PFUMX (input ALUT, BLUT, C0, output Z); + assign Z = C0 ? ALUT : BLUT; + specify + (ALUT => Z) = 98; + (BLUT => Z) = 98; + (C0 => Z) = 151; + endspecify +endmodule + +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module TRELLIS_DPR16X4 ( + input [3:0] DI, + input [3:0] WAD, + input WRE, + input WCK, + input [3:0] RAD, + output [3:0] DO +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter [63:0] INITVAL = 64'h0000000000000000; + + reg [3:0] mem[15:0]; + + integer i; + initial begin + for (i = 0; i < 16; i = i + 1) + mem[i] <= INITVAL[4*i +: 4]; + end + + wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; + + reg muxwre; + always @(*) + case (WREMUX) + "1": muxwre = 1'b1; + "0": muxwre = 1'b0; + "INV": muxwre = ~WRE; + default: muxwre = WRE; + endcase + + always @(posedge muxwck) + if (muxwre) + mem[WAD] <= DI; + + assign DO = mem[RAD]; + + specify + // TODO + (RAD *> DO) = 0; + endspecify +endmodule + +// --------------------------------------- + +(* abc9_box, lib_whitebox *) +module DPR16X4C ( + input [3:0] DI, + input WCK, WRE, + input [3:0] RAD, + input [3:0] WAD, + output [3:0] DO +); + // For legacy Lattice compatibility, INITIVAL is a hex + // string rather than a numeric parameter + parameter INITVAL = "0x0000000000000000"; + + function [63:0] convert_initval; + input [143:0] hex_initval; + reg done; + reg [63:0] temp; + reg [7:0] char; + integer i; + begin + done = 1'b0; + temp = 0; + for (i = 0; i < 16; i = i + 1) begin + if (!done) begin + char = hex_initval[8*i +: 8]; + if (char == "x") begin + done = 1'b1; + end else begin + if (char >= "0" && char <= "9") + temp[4*i +: 4] = char - "0"; + else if (char >= "A" && char <= "F") + temp[4*i +: 4] = 10 + char - "A"; + else if (char >= "a" && char <= "f") + temp[4*i +: 4] = 10 + char - "a"; + end + end + end + convert_initval = temp; + end + endfunction + + localparam conv_initval = convert_initval(INITVAL); + + reg [3:0] ram[0:15]; + integer i; + initial begin + for (i = 0; i < 15; i = i + 1) begin + ram[i] <= conv_initval[4*i +: 4]; + end + end + + always @(posedge WCK) + if (WRE) + ram[WAD] <= DI; + + assign DO = ram[RAD]; + + specify + // TODO + (RAD *> DO) = 0; + endspecify +endmodule + +// --------------------------------------- + +(* lib_whitebox *) +module LUT2(input A, B, output Z); + parameter [3:0] INIT = 4'h0; + wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0]; + assign Z = A ? s1[1] : s1[0]; +endmodule + +// --------------------------------------- + +`ifdef YOSYS +(* abc9_flop=(SRMODE != "ASYNC"), abc9_box=(SRMODE == "ASYNC"), lib_whitebox *) +`endif +module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); + parameter GSR = "ENABLED"; + parameter [127:0] CEMUX = "1"; + parameter CLKMUX = "CLK"; + parameter LSRMUX = "LSR"; + parameter SRMODE = "LSR_OVER_CE"; + parameter REGSET = "RESET"; + parameter [127:0] LSRMODE = "LSR"; + + wire muxce; + generate + case (CEMUX) + "1": assign muxce = 1'b1; + "0": assign muxce = 1'b0; + "INV": assign muxce = ~CE; + default: assign muxce = CE; + endcase + endgenerate + + wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; + wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; + wire srval; + generate + if (LSRMODE == "PRLD") + assign srval = M; + else + assign srval = (REGSET == "SET") ? 1'b1 : 1'b0; + endgenerate + + initial Q = srval; + + generate + if (SRMODE == "ASYNC") begin + always @(posedge muxclk, posedge muxlsr) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end else begin + always @(posedge muxclk) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end + endgenerate + + specify + $setup(DI, negedge CLK &&& CLKMUX == "INV", 0); + $setup(CE, negedge CLK &&& CLKMUX == "INV", 0); + $setup(LSR, negedge CLK &&& CLKMUX == "INV", 0); + $setup(DI, posedge CLK &&& CLKMUX != "INV", 0); + $setup(CE, posedge CLK &&& CLKMUX != "INV", 0); + $setup(LSR, posedge CLK &&& CLKMUX != "INV", 0); +`ifndef YOSYS + if (SRMODE == "ASYNC" && muxlsr && CLKMUX == "INV") (negedge CLK => (Q : srval)) = 0; + if (SRMODE == "ASYNC" && muxlsr && CLKMUX != "INV") (posedge CLK => (Q : srval)) = 0; +`else + if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path +`endif + if (!muxlsr && muxce && CLKMUX == "INV") (negedge CLK => (Q : DI)) = 0; + if (!muxlsr && muxce && CLKMUX != "INV") (posedge CLK => (Q : DI)) = 0; + endspecify +endmodule + +// --------------------------------------- +(* keep *) +module TRELLIS_IO( + (* iopad_external_pin *) + inout B, + input I, + input T, + output O +); + parameter DIR = "INPUT"; + reg T_pd; + always @(*) if (T === 1'bz) T_pd <= 1'b0; else T_pd <= T; + + generate + if (DIR == "INPUT") begin + assign B = 1'bz; + assign O = B; + end else if (DIR == "OUTPUT") begin + assign B = T_pd ? 1'bz : I; + assign O = 1'bx; + end else if (DIR == "BIDIR") begin + assign B = T_pd ? 1'bz : I; + assign O = B; + end else begin + ERROR_UNKNOWN_IO_MODE error(); + end + endgenerate + +endmodule + +// --------------------------------------- + +module INV(input A, output Z); + assign Z = !A; +endmodule + +// --------------------------------------- + +module TRELLIS_COMB( + input A, B, C, D, M, + input FCI, F1, FXA, FXB, + input WD, + input WAD0, WAD1, WAD2, WAD3, + input WRE, WCK, + output F, FCO, OFX +); + parameter MODE = "LOGIC"; + parameter INITVAL = 16'h0; + parameter CCU2_INJECT1 = "NO"; + parameter WREMUX = "WRE"; + parameter IS_Z1 = 1'b0; + + generate + if (MODE == "LOGIC") begin: mode_logic + LUT4 #(.INIT(INITVAL)) lut4 (.A(A), .B(B), .C(C), .D(D), .Z(F)); + end else if (MODE == "CCU2") begin: mode_ccu2 + wire l4o, l2o; + LUT4 #(.INIT(INITVAL)) lut4_0(.A(A), .B(B), .C(C), .D(D), .Z(l4o)); + LUT2 #(.INIT(INITVAL[3:0])) lut2_0(.A(A), .B(B), .Z(l2o)); + wire gated_cin_0 = (CCU2_INJECT1 == "YES") ? 1'b0 : FCI; + assign F = l4o ^ gated_cin_0; + wire gated_lut2_0 = (CCU2_INJECT1 == "YES") ? 1'b0 : l2o; + wire FCO = (~l4o & gated_lut2_0) | (l4o & FCI); + end else if (MODE == "DPRAM") begin: mode_dpram + reg [15:0] ram = INITVAL; + always @(posedge WCK) + if (WRE) + ram[{WAD3, WAD2, WAD1, WAD0}] <= WD; + assign F = ram[{A, C, B, D}]; + end else begin + $error("unsupported COMB mode %s", MODE); + end + + if (IS_Z1) + L6MUX21 lutx_mux (.D0(FXA), .D1(FXB), .SD(M), .Z(OFX)); + else + PFUMX lut5_mux (.ALUT(F1), .BLUT(F), .C0(M), .Z(OFX)); + endgenerate + +endmodule + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/dsp_map_18x18.v b/techlibs/lattice/dsp_map_18x18.v new file mode 100644 index 00000000000..df54d1d9f9f --- /dev/null +++ b/techlibs/lattice/dsp_map_18x18.v @@ -0,0 +1,17 @@ +module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y); + + parameter A_WIDTH = 18; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 36; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT18X18D _TECHMAP_REPLACE_ ( + .A0(A[0]), .A1(A[1]), .A2(A[2]), .A3(A[3]), .A4(A[4]), .A5(A[5]), .A6(A[6]), .A7(A[7]), .A8(A[8]), .A9(A[9]), .A10(A[10]), .A11(A[11]), .A12(A[12]), .A13(A[13]), .A14(A[14]), .A15(A[15]), .A16(A[16]), .A17(A[17]), + .B0(B[0]), .B1(B[1]), .B2(B[2]), .B3(B[3]), .B4(B[4]), .B5(B[5]), .B6(B[6]), .B7(B[7]), .B8(B[8]), .B9(B[9]), .B10(B[10]), .B11(B[11]), .B12(B[12]), .B13(B[13]), .B14(B[14]), .B15(B[15]), .B16(B[16]), .B17(B[17]), + .C17(1'b0), .C16(1'b0), .C15(1'b0), .C14(1'b0), .C13(1'b0), .C12(1'b0), .C11(1'b0), .C10(1'b0), .C9(1'b0), .C8(1'b0), .C7(1'b0), .C6(1'b0), .C5(1'b0), .C4(1'b0), .C3(1'b0), .C2(1'b0), .C1(1'b0), .C0(1'b0), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), .SOURCEA(1'b0), .SOURCEB(1'b0), + + .P0(Y[0]), .P1(Y[1]), .P2(Y[2]), .P3(Y[3]), .P4(Y[4]), .P5(Y[5]), .P6(Y[6]), .P7(Y[7]), .P8(Y[8]), .P9(Y[9]), .P10(Y[10]), .P11(Y[11]), .P12(Y[12]), .P13(Y[13]), .P14(Y[14]), .P15(Y[15]), .P16(Y[16]), .P17(Y[17]), .P18(Y[18]), .P19(Y[19]), .P20(Y[20]), .P21(Y[21]), .P22(Y[22]), .P23(Y[23]), .P24(Y[24]), .P25(Y[25]), .P26(Y[26]), .P27(Y[27]), .P28(Y[28]), .P29(Y[29]), .P30(Y[30]), .P31(Y[31]), .P32(Y[32]), .P33(Y[33]), .P34(Y[34]), .P35(Y[35]) + ); +endmodule diff --git a/techlibs/lattice/latches_map.v b/techlibs/lattice/latches_map.v new file mode 100644 index 00000000000..c28f88cf767 --- /dev/null +++ b/techlibs/lattice/latches_map.v @@ -0,0 +1,11 @@ +module \$_DLATCH_N_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = !E ? D : Q; +endmodule + +module \$_DLATCH_P_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = E ? D : Q; +endmodule diff --git a/techlibs/lattice/lutrams.txt b/techlibs/lattice/lutrams.txt new file mode 100644 index 00000000000..ea42d4fcb5e --- /dev/null +++ b/techlibs/lattice/lutrams.txt @@ -0,0 +1,12 @@ +ram distributed $__TRELLIS_DPR16X4_ { + abits 4; + width 4; + cost 4; + init any; + prune_rom; + port sw "W" { + clock anyedge; + } + port ar "R" { + } +} diff --git a/techlibs/lattice/lutrams_map.v b/techlibs/lattice/lutrams_map.v new file mode 100644 index 00000000000..3cb325f041e --- /dev/null +++ b/techlibs/lattice/lutrams_map.v @@ -0,0 +1,30 @@ +module $__TRELLIS_DPR16X4_(...); + +parameter INIT = 64'bx; +parameter PORT_W_CLK_POL = 1; + +input PORT_W_CLK; +input [3:0] PORT_W_ADDR; +input [3:0] PORT_W_WR_DATA; +input PORT_W_WR_EN; + +input [3:0] PORT_R_ADDR; +output [3:0] PORT_R_RD_DATA; + +localparam WCKMUX = PORT_W_CLK_POL ? "WCK" : "INV"; + +TRELLIS_DPR16X4 #( + .INITVAL(INIT), + .WCKMUX(WCKMUX), + .WREMUX("WRE") +) _TECHMAP_REPLACE_ ( + .RAD(PORT_R_ADDR), + .DO(PORT_R_RD_DATA), + + .WAD(PORT_W_ADDR), + .DI(PORT_W_WR_DATA), + .WCK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) +); + +endmodule diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc new file mode 100644 index 00000000000..edca6855e08 --- /dev/null +++ b/techlibs/lattice/synth_lattice.cc @@ -0,0 +1,574 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2018 gatecat + * + * 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/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthLatticePass : public ScriptPass +{ + SynthLatticePass() : ScriptPass("synth_lattice", "synthesis for Lattice FPGAs") { } + + void on_register() override + { + RTLIL::constpad["synth_lattice.abc9.W"] = "300"; + } + + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_lattice [options]\n"); + log("\n"); + log("This command runs synthesis for Lattice FPGAs.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -family \n"); + log(" run synthesis for the specified Lattice architecture\n"); + log(" generate the synthesis netlist for the specified family.\n"); + log(" supported values:\n"); + log(" - ecp5: ECP5\n"); + log(" - xo2: MachXO2\n"); + log(" - xo3: MachXO3L/LF\n"); + log(" - xo3d: MachXO3D\n"); + //log(" - xo: MachXO (EXPERIMENTAL)\n"); + //log(" - pm: Platform Manager (EXPERIMENTAL)\n"); + //log(" - pm2: Platform Manager 2 (EXPERIMENTAL)\n"); + //log(" - xp: LatticeXP (EXPERIMENTAL)\n"); + //log(" - xp2: LatticeXP2 (EXPERIMENTAL)\n"); + //log(" - ecp: LatticeECP/EC (EXPERIMENTAL)\n"); + //log(" - sm: LatticeSC/M (EXPERIMENTAL)\n"); + //log(" - ecp2: LatticeECP2/M (EXPERIMENTAL)\n"); + //log(" - ecp3: LatticeECP3 (EXPERIMENTAL)\n"); + //log(" - lifmd: LIFMD (EXPERIMENTAL)\n"); + //log(" - lifmdf: LIFMDF (EXPERIMENTAL)\n"); + log("\n"); + log(" -blif \n"); + log(" write the design to the specified BLIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -edif \n"); + log(" write the design to the specified EDIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -json \n"); + log(" write the design to the specified JSON file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -run :\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(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); + log("\n"); + log(" -dff\n"); + log(" run 'abc'/'abc9' with -dff option\n"); + log("\n"); + log(" -retime\n"); + log(" run 'abc' with '-dff -D 1' options\n"); + log("\n"); + log(" -noccu2\n"); + log(" do not use CCU2 cells in output netlist\n"); + log("\n"); + log(" -nodffe\n"); + log(" do not use flipflops with CE in output netlist\n"); + log("\n"); + log(" -nobram\n"); + log(" do not use block RAM cells in output netlist\n"); + log("\n"); + log(" -nolutram\n"); + log(" do not use LUT RAM cells in output netlist\n"); + log("\n"); + log(" -nowidelut\n"); + log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); + log("\n"); + log(" -asyncprld\n"); + log(" use async PRLD mode to implement ALDFF (EXPERIMENTAL)\n"); + log("\n"); + log(" -abc2\n"); + log(" run two passes of 'abc' for slightly improved logic density\n"); + log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\n"); + log("\n"); + log(" -vpr\n"); + log(" generate an output netlist (and BLIF file) suitable for VPR\n"); + log(" (this feature is experimental and incomplete)\n"); + log("\n"); + log(" -iopad\n"); + log(" insert IO buffers\n"); + log("\n"); + log(" -nodsp\n"); + log(" do not map multipliers to MULT18X18D\n"); + log("\n"); + log(" -no-rw-check\n"); + log(" marks all recognized read ports as \"return don't-care value on\n"); + log(" read/write collision\" (same result as setting the no_rw_check\n"); + log(" attribute on all memories).\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + string top_opt, blif_file, edif_file, json_file, family; + bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, vpr, no_rw_check, have_dsp; + string postfix, arith_map, brams_map, dsp_map; + + void clear_flags() override + { + top_opt = "-auto-top"; + blif_file = ""; + edif_file = ""; + json_file = ""; + family = ""; + noccu2 = false; + nodffe = false; + nobram = false; + nolutram = false; + nowidelut = false; + asyncprld = false; + flatten = true; + dff = false; + retime = false; + abc2 = false; + vpr = false; + abc9 = false; + iopad = false; + nodsp = false; + no_rw_check = false; + postfix = ""; + arith_map = ""; + brams_map = ""; + dsp_map = ""; + have_dsp = false; + } + + void execute(std::vector args, RTLIL::Design *design) override + { + string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) { + family = args[++argidx]; + continue; + } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-json" && argidx+1 < args.size()) { + json_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] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-dff") { + dff = true; + continue; + } + if (args[argidx] == "-retime") { + retime = true; + continue; + } + if (args[argidx] == "-noccu2") { + noccu2 = true; + continue; + } + if (args[argidx] == "-nodffe") { + nodffe = true; + continue; + } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } + if (args[argidx] == "-asyncprld") { + asyncprld = true; + continue; + } + if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") { + nolutram = true; + continue; + } + if (args[argidx] == "-nowidelut" || /*deprecated alias*/ args[argidx] == "-nomux") { + nowidelut = true; + continue; + } + if (args[argidx] == "-abc2") { + abc2 = true; + continue; + } + if (args[argidx] == "-vpr") { + vpr = true; + continue; + } + if (args[argidx] == "-abc9") { + abc9 = true; + continue; + } + if (args[argidx] == "-iopad") { + iopad = true; + continue; + } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } + if (args[argidx] == "-no-rw-check") { + no_rw_check = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (family.empty()) + log_cmd_error("Lattice family parameter must be set.\n"); + + if (family == "ecp5") { + postfix = "_ecp5"; + arith_map = "_ccu2c"; + brams_map = "_16kd"; + dsp_map = "_18x18"; + have_dsp = true; + } else if (family == "xo2" || + family == "xo3" || + family == "xo3d" /* || + family == "pm2"*/) { + postfix = "_" + family; + arith_map = "_ccu2d"; + brams_map = "_8kc"; + have_dsp = false; +/* } else if (family == "xo" || + family == "pm") { + } else if (family == "xp" || + family == "xp2" || + family == "ecp" || + family == "sm" || + family == "ecp2" || + family == "ecp3" || + family == "lifmd" || + family == "lifmdf") {*/ + } else + log_cmd_error("Invalid Lattice -family setting: '%s'.\n", family.c_str()); + + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + + if (abc9 && retime) + log_cmd_error("-retime option not currently compatible with -abc9!\n"); + + log_header(design, "Executing SYNTH_LATTICE pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() override + { + std::string no_rw_check_opt = ""; + if (no_rw_check) + no_rw_check_opt = " -no-rw-check"; + if (help_mode) + no_rw_check_opt = " [-no-rw-check]"; + + if (check_label("begin")) + { + run("read_verilog -lib -specify +/lattice/cells_sim" + postfix + ".v +/lattice/cells_bb" + postfix + ".v"); + run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); + } + + if (check_label("coarse")) + { + run("proc"); + if (flatten || help_mode) + run("flatten"); + run("tribuf -logic"); + run("deminout"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); + run("opt"); + run("wreduce"); + run("peepopt"); + run("opt_clean"); + run("share"); + run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4"); + run("opt_expr"); + run("opt_clean"); + if (have_dsp && !nodsp) { + run("techmap -map +/mul2dsp.v -map +/lattice/dsp_map" + 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)"); + run("chtype -set $mul t:$__soft_mul", "(unless -nodsp)"); + } + run("alumacc"); + run("opt"); + run("memory -nomap" + no_rw_check_opt); + run("opt_clean"); + } + + if (check_label("map_ram")) + { + std::string args = ""; + if (nobram) + args += " -no-auto-block"; + if (nolutram) + args += " -no-auto-distributed"; + if (help_mode) + args += " [-no-auto-block] [-no-auto-distributed]"; + run("memory_libmap -lib +/lattice/lutrams.txt -lib +/lattice/brams" + brams_map + ".txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run("techmap -map +/lattice/lutrams_map.v -map +/lattice/brams_map" + brams_map + ".v"); + } + + if (check_label("map_ffram")) + { + run("opt -fast -mux_undef -undriven -fine"); + run("memory_map"); + run("opt -undriven -fine"); + } + + if (check_label("map_gates")) + { + if (noccu2) + run("techmap"); + else + run("techmap -map +/techmap.v -map +/lattice/arith_map" + arith_map + ".v"); + if (help_mode || iopad) { + run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(only if '-iopad')"); + run("attrmvcp -attr src -attr LOC t:OB %x:+[O] t:OBZ %x:+[O] t:BB %x:+[B]"); + run("attrmvcp -attr src -attr LOC -driven t:IB %x:+[I]"); + } + run("opt -fast"); + if (retime || help_mode) + run("abc -dff -D 1", "(only if -retime)"); + } + + if (check_label("map_ffs")) + { + run("opt_clean"); + std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r"; + if (help_mode) { + dfflegalize_args += " [-cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r]"; + } else if (!nodffe) { + dfflegalize_args += " -cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r"; + } + if (help_mode) { + dfflegalize_args += " [-cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x] [-cell $_DLATCH_?_ x]"; + } else if (asyncprld) { + dfflegalize_args += " -cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x"; + } else { + dfflegalize_args += " -cell $_DLATCH_?_ x"; + } + run("dfflegalize" + dfflegalize_args, "($_ALDFF_*_ only if -asyncprld, $_DLATCH_* only if not -asyncprld, $_*DFFE_* only if not -nodffe)"); + if ((abc9 && dff) || help_mode) + run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff)"); + run("techmap -D NO_LUT -map +/lattice/cells_map.v"); + run("opt_expr -undriven -mux_undef"); + run("simplemap"); + run("lattice_gsr"); + run("attrmvcp -copy -attr syn_useioff"); + run("opt_clean"); + } + + if (check_label("map_luts")) + { + if (abc2 || help_mode) + run("abc", " (only if -abc2)"); + if (!asyncprld || help_mode) + run("techmap -map +/lattice/latches_map.v", "(skip if -asyncprld)"); + + if (abc9) { + std::string abc9_opts; + if (nowidelut) + abc9_opts += " -maxlut 4"; + std::string k = "synth_lattice.abc9.W"; + if (active_design && active_design->scratchpad.count(k)) + abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); + else + abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); + if (nowidelut) + abc9_opts += " -maxlut 4"; + if (dff) + abc9_opts += " -dff"; + run("abc9" + abc9_opts); + } else { + std::string abc_args = " -dress"; + if (nowidelut) + abc_args += " -lut 4"; + else + abc_args += " -lut 4:7"; + if (dff) + abc_args += " -dff"; + run("abc" + abc_args); + } + run("clean"); + } + + if (check_label("map_cells")) + { + if (help_mode) + run("techmap -map +/lattice/cells_map.v", "(skip if -vpr)"); + else if (!vpr) + run("techmap -map +/lattice/cells_map.v"); + run("opt_lut_ins -tech lattice"); + run("clean"); + } + + if (check_label("check")) + { + run("autoname"); + run("hierarchy -check"); + run("stat"); + run("check -noinit"); + run("blackbox =A:whitebox"); + } + + if (check_label("blif")) + { + if (!blif_file.empty() || help_mode) { + if (vpr || help_mode) { + run(stringf("opt_clean -purge"), + " (vpr mode)"); + run(stringf("write_blif -attr -cname -conn -param %s", + help_mode ? "" : blif_file.c_str()), + " (vpr mode)"); + } + if (!vpr) + run(stringf("write_blif -gates -attr -param %s", + help_mode ? "" : blif_file.c_str()), + " (non-vpr mode)"); + } + } + + if (check_label("edif")) + { + if (!edif_file.empty() || help_mode) + run(stringf("write_edif %s", help_mode ? "" : edif_file.c_str())); + } + + if (check_label("json")) + { + if (!json_file.empty() || help_mode) + run(stringf("write_json %s", help_mode ? "" : json_file.c_str())); + } + } +} SynthLatticePass; + +/* +struct SynthEcp5Pass : public Pass +{ + SynthEcp5Pass() : Pass("synth_ecp5", "synthesis for ECP5 FPGAs") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "ecp5"; + Pass::call(design, args); + } +} SynthEcp5Pass; +*/ + +struct SynthMachXO2Pass : public Pass +{ + SynthMachXO2Pass() : Pass("synth_machxo2", "synthesis for MachXO2 FPGAs.") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "xo2"; + Pass::call(design, args); + } +} SynthMachXO2Pass; + +struct SynthMachXO3Pass : public Pass +{ + SynthMachXO3Pass() : Pass("synth_machxo3", "synthesis for MachXO3 FPGAs.") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "xo3"; + Pass::call(design, args); + } +} SynthMachXO3Pass; + +struct SynthMachXO3DPass : public Pass +{ + SynthMachXO3DPass() : Pass("synth_machxo3d", "synthesis for MachXO3D FPGAs.") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "xo3d"; + Pass::call(design, args); + } +} SynthMachXO3DPass; + +PRIVATE_NAMESPACE_END From 75fd706487d16c3d4cbd48665c86cef1c1f70959 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 10:54:17 +0200 Subject: [PATCH 061/119] delete machxo2 since it is now supported in lattice --- techlibs/machxo2/Makefile.inc | 14 -- techlibs/machxo2/arith_map.v | 90 ------- techlibs/machxo2/brams.txt | 50 ---- techlibs/machxo2/brams_map.v | 337 -------------------------- techlibs/machxo2/cells_bb.v | 227 ------------------ techlibs/machxo2/cells_map.v | 117 --------- techlibs/machxo2/cells_sim.v | 385 ------------------------------ techlibs/machxo2/synth_machxo2.cc | 297 ----------------------- 8 files changed, 1517 deletions(-) delete mode 100644 techlibs/machxo2/Makefile.inc delete mode 100644 techlibs/machxo2/arith_map.v delete mode 100644 techlibs/machxo2/brams.txt delete mode 100644 techlibs/machxo2/brams_map.v delete mode 100644 techlibs/machxo2/cells_bb.v delete mode 100644 techlibs/machxo2/cells_map.v delete mode 100644 techlibs/machxo2/cells_sim.v delete mode 100644 techlibs/machxo2/synth_machxo2.cc diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc deleted file mode 100644 index cd4e27884fc..00000000000 --- a/techlibs/machxo2/Makefile.inc +++ /dev/null @@ -1,14 +0,0 @@ - -OBJS += techlibs/machxo2/synth_machxo2.o - -$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/cells_io.vh)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_bb.v)) - -$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams.txt)) -$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams_map.v)) - -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams.txt)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams_map.v)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/arith_map.v)) diff --git a/techlibs/machxo2/arith_map.v b/techlibs/machxo2/arith_map.v deleted file mode 100644 index ab4a6b1da6c..00000000000 --- a/techlibs/machxo2/arith_map.v +++ /dev/null @@ -1,90 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2018 gatecat - * - * 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. - * - */ - -(* techmap_celltype = "$alu" *) -module _80_ecp5_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; - - (* force_downto *) - input [A_WIDTH-1:0] A; - (* force_downto *) - input [B_WIDTH-1:0] B; - (* force_downto *) - output [Y_WIDTH-1:0] X, Y; - - input CI, BI; - (* force_downto *) - output [Y_WIDTH-1:0] CO; - - wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; - - (* force_downto *) - 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)); - - function integer round_up2; - input integer N; - begin - round_up2 = ((N + 1) / 2) * 2; - end - endfunction - - localparam Y_WIDTH2 = round_up2(Y_WIDTH); - - (* force_downto *) - wire [Y_WIDTH2-1:0] AA = A_buf; - (* force_downto *) - wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; - (* force_downto *) - wire [Y_WIDTH2-1:0] BX = B_buf; - (* force_downto *) - wire [Y_WIDTH2-1:0] C = {CO, CI}; - (* force_downto *) - wire [Y_WIDTH2-1:0] FCO, Y1; - - genvar i; - generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice - CCU2D #( - .INIT0(16'b0101_1010_1001_0110), - .INIT1(16'b0101_1010_1001_0110), - .INJECT1_0("NO"), - .INJECT1_1("NO") - ) ccu2d_i ( - .CIN(C[i]), - .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b0), - .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b0), - .S0(Y[i]), .S1(Y1[i]), - .COUT(FCO[i]) - ); - - assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); - if (i+1 < Y_WIDTH) begin - assign CO[i+1] = FCO[i]; - assign Y[i+1] = Y1[i]; - end - end endgenerate - - assign X = AA ^ BB; -endmodule diff --git a/techlibs/machxo2/brams.txt b/techlibs/machxo2/brams.txt deleted file mode 100644 index 3afbeda07e6..00000000000 --- a/techlibs/machxo2/brams.txt +++ /dev/null @@ -1,50 +0,0 @@ -ram block $__DP8KC_ { - abits 13; - widths 1 2 4 9 per_port; - cost 64; - init no_undef; - port srsw "A" "B" { - clock posedge; - clken; - portoption "WRITEMODE" "NORMAL" { - rdwr no_change; - } - portoption "WRITEMODE" "WRITETHROUGH" { - rdwr new; - } - portoption "WRITEMODE" "READBEFOREWRITE" { - rdwr old; - } - option "RESETMODE" "SYNC" { - rdsrst zero ungated block_wr; - } - option "RESETMODE" "ASYNC" { - rdarst zero; - } - rdinit zero; - } -} - -ram block $__PDPW8KC_ { - abits 13; - widths 1 2 4 9 18 per_port; - byte 9; - cost 64; - init no_undef; - port sr "R" { - clock posedge; - clken; - option "RESETMODE" "SYNC" { - rdsrst zero ungated; - } - option "RESETMODE" "ASYNC" { - rdarst zero; - } - rdinit zero; - } - port sw "W" { - width 18; - clock posedge; - clken; - } -} diff --git a/techlibs/machxo2/brams_map.v b/techlibs/machxo2/brams_map.v deleted file mode 100644 index 6783e5b2902..00000000000 --- a/techlibs/machxo2/brams_map.v +++ /dev/null @@ -1,337 +0,0 @@ -module $__DP8KC_ (...); - -parameter INIT = 0; -parameter OPTION_RESETMODE = "SYNC"; - -parameter PORT_A_WIDTH = 18; -parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; - -input PORT_A_CLK; -input PORT_A_CLK_EN; -input PORT_A_WR_EN; -input PORT_A_RD_SRST; -input PORT_A_RD_ARST; -input [12:0] PORT_A_ADDR; -input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; -output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; - -parameter PORT_B_WIDTH = 18; -parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; - -input PORT_B_CLK; -input PORT_B_CLK_EN; -input PORT_B_WR_EN; -input PORT_B_RD_SRST; -input PORT_B_RD_ARST; -input [12:0] PORT_B_ADDR; -input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; -output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; - -function [319:0] init_slice; - input integer idx; - integer i, j; - init_slice = 0; - for (i = 0; i < 16; i = i + 1) begin - init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; - end -endfunction - -wire [8:0] DOA; -wire [8:0] DOB; -wire [8:0] DIA = PORT_A_WR_DATA; -wire [8:0] DIB = PORT_B_WR_DATA; - -assign PORT_A_RD_DATA = DOA; -assign PORT_B_RD_DATA = DOB; - -DP8KC #( - .INITVAL_00(init_slice('h00)), - .INITVAL_01(init_slice('h01)), - .INITVAL_02(init_slice('h02)), - .INITVAL_03(init_slice('h03)), - .INITVAL_04(init_slice('h04)), - .INITVAL_05(init_slice('h05)), - .INITVAL_06(init_slice('h06)), - .INITVAL_07(init_slice('h07)), - .INITVAL_08(init_slice('h08)), - .INITVAL_09(init_slice('h09)), - .INITVAL_0A(init_slice('h0a)), - .INITVAL_0B(init_slice('h0b)), - .INITVAL_0C(init_slice('h0c)), - .INITVAL_0D(init_slice('h0d)), - .INITVAL_0E(init_slice('h0e)), - .INITVAL_0F(init_slice('h0f)), - .INITVAL_10(init_slice('h10)), - .INITVAL_11(init_slice('h11)), - .INITVAL_12(init_slice('h12)), - .INITVAL_13(init_slice('h13)), - .INITVAL_14(init_slice('h14)), - .INITVAL_15(init_slice('h15)), - .INITVAL_16(init_slice('h16)), - .INITVAL_17(init_slice('h17)), - .INITVAL_18(init_slice('h18)), - .INITVAL_19(init_slice('h19)), - .INITVAL_1A(init_slice('h1a)), - .INITVAL_1B(init_slice('h1b)), - .INITVAL_1C(init_slice('h1c)), - .INITVAL_1D(init_slice('h1d)), - .INITVAL_1E(init_slice('h1e)), - .INITVAL_1F(init_slice('h1f)), - .DATA_WIDTH_A(PORT_A_WIDTH), - .DATA_WIDTH_B(PORT_B_WIDTH), - .REGMODE_A("NOREG"), - .REGMODE_B("NOREG"), - .RESETMODE(OPTION_RESETMODE), - .ASYNC_RESET_RELEASE(OPTION_RESETMODE), - .CSDECODE_A("0b000"), - .CSDECODE_B("0b000"), - .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), - .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), - .GSR("AUTO") -) _TECHMAP_REPLACE_ ( - .CLKA(PORT_A_CLK), - .WEA(PORT_A_WR_EN), - .CEA(PORT_A_CLK_EN), - .OCEA(1'b1), - .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), - .CSA0(1'b0), - .CSA1(1'b0), - .CSA2(1'b0), - .ADA0(PORT_A_WIDTH == 9 ? 1'b1 : PORT_A_ADDR[0]), - .ADA1(PORT_A_ADDR[1]), - .ADA2(PORT_A_ADDR[2]), - .ADA3(PORT_A_ADDR[3]), - .ADA4(PORT_A_ADDR[4]), - .ADA5(PORT_A_ADDR[5]), - .ADA6(PORT_A_ADDR[6]), - .ADA7(PORT_A_ADDR[7]), - .ADA8(PORT_A_ADDR[8]), - .ADA9(PORT_A_ADDR[9]), - .ADA10(PORT_A_ADDR[10]), - .ADA11(PORT_A_ADDR[11]), - .ADA12(PORT_A_ADDR[12]), - .DIA0(DIA[0]), - .DIA1(DIA[1]), - .DIA2(DIA[2]), - .DIA3(DIA[3]), - .DIA4(DIA[4]), - .DIA5(DIA[5]), - .DIA6(DIA[6]), - .DIA7(DIA[7]), - .DIA8(DIA[8]), - .DOA0(DOA[0]), - .DOA1(DOA[1]), - .DOA2(DOA[2]), - .DOA3(DOA[3]), - .DOA4(DOA[4]), - .DOA5(DOA[5]), - .DOA6(DOA[6]), - .DOA7(DOA[7]), - .DOA8(DOA[8]), - - .CLKB(PORT_B_CLK), - .WEB(PORT_B_WR_EN), - .CEB(PORT_B_CLK_EN), - .OCEB(1'b1), - .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), - .CSB0(1'b0), - .CSB1(1'b0), - .CSB2(1'b0), - .ADB0(PORT_B_WIDTH == 9 ? 1'b1 : PORT_B_ADDR[0]), - .ADB1(PORT_B_ADDR[1]), - .ADB2(PORT_B_ADDR[2]), - .ADB3(PORT_B_ADDR[3]), - .ADB4(PORT_B_ADDR[4]), - .ADB5(PORT_B_ADDR[5]), - .ADB6(PORT_B_ADDR[6]), - .ADB7(PORT_B_ADDR[7]), - .ADB8(PORT_B_ADDR[8]), - .ADB9(PORT_B_ADDR[9]), - .ADB10(PORT_B_ADDR[10]), - .ADB11(PORT_B_ADDR[11]), - .ADB12(PORT_B_ADDR[12]), - .DIB0(DIB[0]), - .DIB1(DIB[1]), - .DIB2(DIB[2]), - .DIB3(DIB[3]), - .DIB4(DIB[4]), - .DIB5(DIB[5]), - .DIB6(DIB[6]), - .DIB7(DIB[7]), - .DIB8(DIB[8]), - .DOB0(DOB[0]), - .DOB1(DOB[1]), - .DOB2(DOB[2]), - .DOB3(DOB[3]), - .DOB4(DOB[4]), - .DOB5(DOB[5]), - .DOB6(DOB[6]), - .DOB7(DOB[7]), - .DOB8(DOB[8]), -); - -endmodule - - -module $__PDPW8KC_ (...); - -parameter INIT = 0; -parameter OPTION_RESETMODE = "SYNC"; - -parameter PORT_R_WIDTH = 18; - -input PORT_R_CLK; -input PORT_R_CLK_EN; -input PORT_R_RD_SRST; -input PORT_R_RD_ARST; -input [12:0] PORT_R_ADDR; -output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; - -parameter PORT_W_WIDTH = 18; -parameter PORT_W_WR_EN_WIDTH = 2; - -input PORT_W_CLK; -input PORT_W_CLK_EN; -input [12:0] PORT_W_ADDR; -input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; -input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; - -function [319:0] init_slice; - input integer idx; - integer i, j; - init_slice = 0; - for (i = 0; i < 16; i = i + 1) begin - init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; - end -endfunction - -wire [17:0] DI = PORT_W_WR_DATA; -wire [17:0] DO; - -assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9]; - -DP8KC #( - .INITVAL_00(init_slice('h00)), - .INITVAL_01(init_slice('h01)), - .INITVAL_02(init_slice('h02)), - .INITVAL_03(init_slice('h03)), - .INITVAL_04(init_slice('h04)), - .INITVAL_05(init_slice('h05)), - .INITVAL_06(init_slice('h06)), - .INITVAL_07(init_slice('h07)), - .INITVAL_08(init_slice('h08)), - .INITVAL_09(init_slice('h09)), - .INITVAL_0A(init_slice('h0a)), - .INITVAL_0B(init_slice('h0b)), - .INITVAL_0C(init_slice('h0c)), - .INITVAL_0D(init_slice('h0d)), - .INITVAL_0E(init_slice('h0e)), - .INITVAL_0F(init_slice('h0f)), - .INITVAL_10(init_slice('h10)), - .INITVAL_11(init_slice('h11)), - .INITVAL_12(init_slice('h12)), - .INITVAL_13(init_slice('h13)), - .INITVAL_14(init_slice('h14)), - .INITVAL_15(init_slice('h15)), - .INITVAL_16(init_slice('h16)), - .INITVAL_17(init_slice('h17)), - .INITVAL_18(init_slice('h18)), - .INITVAL_19(init_slice('h19)), - .INITVAL_1A(init_slice('h1a)), - .INITVAL_1B(init_slice('h1b)), - .INITVAL_1C(init_slice('h1c)), - .INITVAL_1D(init_slice('h1d)), - .INITVAL_1E(init_slice('h1e)), - .INITVAL_1F(init_slice('h1f)), - .DATA_WIDTH_A(PORT_W_WIDTH), - .DATA_WIDTH_B(PORT_R_WIDTH), - .REGMODE_A("NOREG"), - .REGMODE_B("NOREG"), - .RESETMODE(OPTION_RESETMODE), - .ASYNC_RESET_RELEASE(OPTION_RESETMODE), - .CSDECODE_A("0b000"), - .CSDECODE_B("0b000"), - .GSR("AUTO") -) _TECHMAP_REPLACE_ ( - .CLKA(PORT_W_CLK), - .WEA(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]), - .CEA(PORT_W_CLK_EN), - .OCEA(1'b0), - .RSTA(1'b0), - .CSA0(1'b0), - .CSA1(1'b0), - .CSA2(1'b0), - .ADA0(PORT_W_WIDTH >= 9 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), - .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), - .ADA2(PORT_W_ADDR[2]), - .ADA3(PORT_W_ADDR[3]), - .ADA4(PORT_W_ADDR[4]), - .ADA5(PORT_W_ADDR[5]), - .ADA6(PORT_W_ADDR[6]), - .ADA7(PORT_W_ADDR[7]), - .ADA8(PORT_W_ADDR[8]), - .ADA9(PORT_W_ADDR[9]), - .ADA10(PORT_W_ADDR[10]), - .ADA11(PORT_W_ADDR[11]), - .ADA12(PORT_W_ADDR[12]), - .DIA0(DI[0]), - .DIA1(DI[1]), - .DIA2(DI[2]), - .DIA3(DI[3]), - .DIA4(DI[4]), - .DIA5(DI[5]), - .DIA6(DI[6]), - .DIA7(DI[7]), - .DIA8(DI[8]), - .DIB0(DI[9]), - .DIB1(DI[10]), - .DIB2(DI[11]), - .DIB3(DI[12]), - .DIB4(DI[13]), - .DIB5(DI[14]), - .DIB6(DI[15]), - .DIB7(DI[16]), - .DIB8(DI[17]), - - .CLKB(PORT_R_CLK), - .WEB(1'b0), - .CEB(PORT_R_CLK_EN), - .OCEB(1'b1), - .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), - .CSB0(1'b0), - .CSB1(1'b0), - .CSB2(1'b0), - .ADB0(PORT_R_ADDR[0]), - .ADB1(PORT_R_ADDR[1]), - .ADB2(PORT_R_ADDR[2]), - .ADB3(PORT_R_ADDR[3]), - .ADB4(PORT_R_ADDR[4]), - .ADB5(PORT_R_ADDR[5]), - .ADB6(PORT_R_ADDR[6]), - .ADB7(PORT_R_ADDR[7]), - .ADB8(PORT_R_ADDR[8]), - .ADB9(PORT_R_ADDR[9]), - .ADB10(PORT_R_ADDR[10]), - .ADB11(PORT_R_ADDR[11]), - .ADB12(PORT_R_ADDR[12]), - .DOA0(DO[0]), - .DOA1(DO[1]), - .DOA2(DO[2]), - .DOA3(DO[3]), - .DOA4(DO[4]), - .DOA5(DO[5]), - .DOA6(DO[6]), - .DOA7(DO[7]), - .DOA8(DO[8]), - .DOB0(DO[9]), - .DOB1(DO[10]), - .DOB2(DO[11]), - .DOB3(DO[12]), - .DOB4(DO[13]), - .DOB5(DO[14]), - .DOB6(DO[15]), - .DOB7(DO[16]), - .DOB8(DO[17]), -); - -endmodule diff --git a/techlibs/machxo2/cells_bb.v b/techlibs/machxo2/cells_bb.v deleted file mode 100644 index 3d047b1692a..00000000000 --- a/techlibs/machxo2/cells_bb.v +++ /dev/null @@ -1,227 +0,0 @@ -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); -endmodule - -(* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); -endmodule - -(* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); - parameter DATA_WIDTH_W = 18; - parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_W = "0b000"; - parameter CSDECODE_R = "0b000"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - -endmodule - -(* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); - parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE = "0b000"; - - parameter WRITEMODE = "NORMAL"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; -endmodule - -(* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); - parameter DATA_WIDTH_W = 18; - parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "ASYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_W = "0b00"; - parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; - parameter FULLPOINTER1 = "0b00000000000000"; -endmodule diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v deleted file mode 100644 index 22994a634df..00000000000 --- a/techlibs/machxo2/cells_map.v +++ /dev/null @@ -1,117 +0,0 @@ -module \$_DFF_N_ (input D, C, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFF_P_ (input D, C, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_NN_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_PN_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_NP_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_PP_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_DFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_SDFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$lut (A, Y); - parameter WIDTH = 0; - parameter LUT = 0; - input [WIDTH-1:0] A; - output Y; - - localparam rep = 1<<(4-WIDTH); - wire [3:0] I; - - generate - if(WIDTH == 1) begin - assign I = {1'b0, 1'b0, 1'b0, A[0]}; - end else if(WIDTH == 2) begin - assign I = {1'b0, 1'b0, A[1], A[0]}; - end else if(WIDTH == 3) begin - assign I = {1'b0, A[2], A[1], A[0]}; - end else if(WIDTH == 4) begin - assign I = {A[3], A[2], A[1], A[0]}; - end else begin - wire _TECHMAP_FAIL_ = 1; - end - endgenerate - - LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .Z(Y)); -endmodule - -`include "cells_io.vh" diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v deleted file mode 100644 index 8e0e411791c..00000000000 --- a/techlibs/machxo2/cells_sim.v +++ /dev/null @@ -1,385 +0,0 @@ -module LUT2(input A, B, output Z); - parameter [3:0] INIT = 4'h0; - wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0]; - assign Z = A ? s1[1] : s1[0]; -endmodule - -module LUT4 #( - parameter [15:0] INIT = 0 -) ( - input A, B, C, D, - output Z -); - // This form of LUT propagates as few x's as possible. - wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0]; - wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; - wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; - assign Z = A ? s1[1] : s1[0]; -endmodule - -module TRELLIS_FF #( - parameter GSR = "ENABLED", - parameter CEMUX = "1", - parameter CLKMUX = "0", - parameter LSRMUX = "LSR", - parameter LSRONMUX = "LSRMUX", - parameter SRMODE = "LSR_OVER_CE", - parameter REGSET = "SET", - parameter REGMODE = "FF" -) ( - input CLK, DI, LSR, CE, - output reg Q -); - - wire muxce; - generate - case (CEMUX) - "1": assign muxce = 1'b1; - "0": assign muxce = 1'b0; - "INV": assign muxce = ~CE; - default: assign muxce = CE; - endcase - endgenerate - - wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; - wire muxlsron = (LSRONMUX == "LSRMUX") ? muxlsr : 1'b0; - wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; - wire srval = (REGSET == "SET") ? 1'b1 : 1'b0; - - initial Q = srval; - - generate - if (REGMODE == "FF") begin - if (SRMODE == "ASYNC") begin - always @(posedge muxclk, posedge muxlsron) - if (muxlsron) - Q <= srval; - else if (muxce) - Q <= DI; - end else begin - always @(posedge muxclk) - if (muxlsron) - Q <= srval; - else if (muxce) - Q <= DI; - end - end else if (REGMODE == "LATCH") begin - ERROR_UNSUPPORTED_FF_MODE error(); - end else begin - ERROR_UNKNOWN_FF_MODE error(); - end - endgenerate -endmodule - -/* For consistency with ECP5; represents F0/F1 => OFX0 mux in a slice. */ -module PFUMX (input ALUT, BLUT, C0, output Z); - assign Z = C0 ? ALUT : BLUT; -endmodule - -/* For consistency with ECP5; represents FXA/FXB => OFX1 mux in a slice. */ -module L6MUX21 (input D0, D1, SD, output Z); - assign Z = SD ? D1 : D0; -endmodule - -/* For consistency, input order matches TRELLIS_SLICE even though the BELs in -prjtrellis were filled in clockwise order from bottom left. */ -module TRELLIS_SLICE #( - parameter MODE = "LOGIC", - parameter GSR = "ENABLED", - parameter SRMODE = "LSR_OVER_CE", - parameter CEMUX = "1", - parameter CLKMUX = "0", - parameter LSRMUX = "LSR", - parameter LSRONMUX = "LSRMUX", - parameter LUT0_INITVAL = 16'hFFFF, - parameter LUT1_INITVAL = 16'hFFFF, - parameter REGMODE = "FF", - parameter REG0_SD = "1", - parameter REG1_SD = "1", - parameter REG0_REGSET = "SET", - parameter REG1_REGSET = "SET", - parameter CCU2_INJECT1_0 = "YES", - parameter CCU2_INJECT1_1 = "YES", - parameter WREMUX = "INV" -) ( - input A0, B0, C0, D0, - input A1, B1, C1, D1, - input M0, M1, - input FCI, FXA, FXB, - - input CLK, LSR, CE, - input DI0, DI1, - - input WD0, WD1, - input WAD0, WAD1, WAD2, WAD3, - input WRE, WCK, - - output F0, Q0, - output F1, Q1, - output FCO, OFX0, OFX1, - - output WDO0, WDO1, WDO2, WDO3, - output WADO0, WADO1, WADO2, WADO3 -); - - generate - if (MODE == "LOGIC") begin - L6MUX21 FXMUX (.D0(FXA), .D1(FXB), .SD(M1), .Z(OFX1)); - - wire k0; - wire k1; - PFUMX K0K1MUX (.ALUT(k1), .BLUT(k0), .C0(M0), .Z(OFX0)); - - LUT4 #(.INIT(LUT0_INITVAL)) LUT_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k0)); - LUT4 #(.INIT(LUT1_INITVAL)) LUT_1 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k1)); - - assign F0 = k0; - assign F1 = k1; - end else if (MODE == "CCU2") begin - ERROR_UNSUPPORTED_SLICE_MODE error(); - end else if (MODE == "DPRAM") begin - ERROR_UNSUPPORTED_SLICE_MODE error(); - end else begin - ERROR_UNKNOWN_SLICE_MODE error(); - end - endgenerate - - /* Reg can be fed either by M, or DI inputs; DI inputs muxes OFX and F - outputs (in other words, feeds back into TRELLIS_SLICE). */ - wire di0 = (REG0_SD == "1") ? DI0 : M0; - wire di1 = (REG1_SD == "1") ? DI1 : M1; - - TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), - .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG0_REGSET), - .REGMODE(REGMODE)) REG_0 (.CLK(CLK), .DI(di0), .LSR(LSR), .CE(CE), .Q(Q0)); - TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), - .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG1_REGSET), - .REGMODE(REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1)); -endmodule - -module TRELLIS_IO #( - parameter DIR = "INPUT" -) ( - (* iopad_external_pin *) - inout B, - input I, T, - output O -); - generate - if (DIR == "INPUT") begin - assign O = B; - end else if (DIR == "OUTPUT") begin - assign B = T ? 1'bz : I; - end else if (DIR == "BIDIR") begin - assign B = T ? 1'bz : I; - assign O = B; - end else begin - ERROR_UNKNOWN_IO_MODE error(); - end - endgenerate -endmodule - -(* abc9_box, lib_whitebox *) -module TRELLIS_DPR16X4 ( - input [3:0] DI, - input [3:0] WAD, - input WRE, - input WCK, - input [3:0] RAD, - output [3:0] DO -); - parameter WCKMUX = "WCK"; - parameter WREMUX = "WRE"; - parameter [63:0] INITVAL = 64'h0000000000000000; - - reg [3:0] mem[15:0]; - - integer i; - initial begin - for (i = 0; i < 16; i = i + 1) - mem[i] <= INITVAL[4*i +: 4]; - end - - wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; - - reg muxwre; - always @(*) - case (WREMUX) - "1": muxwre = 1'b1; - "0": muxwre = 1'b0; - "INV": muxwre = ~WRE; - default: muxwre = WRE; - endcase - - always @(posedge muxwck) - if (muxwre) - mem[WAD] <= DI; - - assign DO = mem[RAD]; - - specify - // TODO - (RAD *> DO) = 0; - endspecify -endmodule - -(* abc9_box, lib_whitebox *) -module DPR16X4C ( - input [3:0] DI, - input WCK, WRE, - input [3:0] RAD, - input [3:0] WAD, - output [3:0] DO -); - parameter INITVAL = "0x0000000000000000"; - - function [63:0] convert_initval; - input [143:0] hex_initval; - reg done; - reg [63:0] temp; - reg [7:0] char; - integer i; - begin - done = 1'b0; - temp = 0; - for (i = 0; i < 16; i = i + 1) begin - if (!done) begin - char = hex_initval[8*i +: 8]; - if (char == "x") begin - done = 1'b1; - end else begin - if (char >= "0" && char <= "9") - temp[4*i +: 4] = char - "0"; - else if (char >= "A" && char <= "F") - temp[4*i +: 4] = 10 + char - "A"; - else if (char >= "a" && char <= "f") - temp[4*i +: 4] = 10 + char - "a"; - end - end - end - convert_initval = temp; - end - endfunction - - localparam conv_initval = convert_initval(INITVAL); - - reg [3:0] ram[0:15]; - integer i; - initial begin - for (i = 0; i < 15; i = i + 1) begin - ram[i] <= conv_initval[4*i +: 4]; - end - end - - always @(posedge WCK) - if (WRE) - ram[WAD] <= DI; - - assign DO = ram[RAD]; -endmodule - -// --------------------------------------- -(* lib_whitebox *) -module CCU2D ( - input CIN, - input A0, B0, C0, D0, A1, B1, C1, D1, - output S0, S1, - output COUT -); - parameter [15:0] INIT0 = 16'h0000; - parameter [15:0] INIT1 = 16'h0000; - parameter INJECT1_0 = "YES"; - parameter INJECT1_1 = "YES"; - - // First half - wire LUT4_0, LUT2_0; - LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); - LUT2 #(.INIT(~INIT0[15:12])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); - wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; - assign S0 = LUT4_0 ^ gated_cin_0; - - wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0; - wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN); - - // Second half - wire LUT4_1, LUT2_1; - LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); - LUT2 #(.INIT(~INIT1[15:12])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); - wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; - assign S1 = LUT4_1 ^ gated_cin_1; - - wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1; - assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0); -endmodule - -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; - - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; -endmodule - -`ifndef NO_INCLUDES - -`include "cells_io.vh" - -`endif diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc deleted file mode 100644 index 907c6659ed8..00000000000 --- a/techlibs/machxo2/synth_machxo2.cc +++ /dev/null @@ -1,297 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2020 William D. Jones - * - * 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/register.h" -#include "kernel/celltypes.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct SynthMachXO2Pass : public ScriptPass -{ - SynthMachXO2Pass() : ScriptPass("synth_machxo2", "synthesis for MachXO2 FPGAs. This work is experimental.") { } - - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" synth_machxo2 [options]\n"); - log("\n"); - log("This command runs synthesis for MachXO2 FPGAs.\n"); - log("\n"); - log(" -top \n"); - log(" use the specified module as top module\n"); - log("\n"); - log(" -blif \n"); - log(" write the design to the specified BLIF file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); - log(" -edif \n"); - log(" write the design to the specified EDIF file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); - log(" -json \n"); - log(" write the design to the specified JSON file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); - log(" -run :\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(" -nobram\n"); - log(" do not use block RAM cells in output netlist\n"); - log("\n"); - log(" -nolutram\n"); - log(" do not use LUT RAM cells in output netlist\n"); - log("\n"); - log(" -noflatten\n"); - log(" do not flatten design before synthesis\n"); - log("\n"); - log(" -noiopad\n"); - log(" do not insert IO buffers\n"); - log("\n"); - log(" -ccu2\n"); - log(" use CCU2 cells in output netlist\n"); - log("\n"); - log(" -vpr\n"); - log(" generate an output netlist (and BLIF file) suitable for VPR\n"); - log(" (this feature is experimental and incomplete)\n"); - log("\n"); - log("\n"); - log("The following commands are executed by this synthesis command:\n"); - help_script(); - log("\n"); - } - - string top_opt, blif_file, edif_file, json_file; - bool ccu2, nobram, nolutram, flatten, vpr, noiopad; - - void clear_flags() override - { - top_opt = "-auto-top"; - blif_file = ""; - edif_file = ""; - json_file = ""; - ccu2 = false; - nobram = false; - nolutram = false; - flatten = true; - vpr = false; - noiopad = false; - } - - void execute(std::vector args, RTLIL::Design *design) override - { - string run_from, run_to; - clear_flags(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-top" && argidx+1 < args.size()) { - top_opt = "-top " + args[++argidx]; - continue; - } - if (args[argidx] == "-blif" && argidx+1 < args.size()) { - blif_file = args[++argidx]; - continue; - } - if (args[argidx] == "-edif" && argidx+1 < args.size()) { - edif_file = args[++argidx]; - continue; - } - if (args[argidx] == "-json" && argidx+1 < args.size()) { - json_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] == "-flatten") { - flatten = true; - continue; - } - if (args[argidx] == "-noflatten") { - flatten = false; - continue; - } - if (args[argidx] == "-nobram") { - nobram = true; - continue; - } - if (args[argidx] == "-nolutram") { - nolutram = true; - continue; - } - if (args[argidx] == "-noiopad") { - noiopad = true; - continue; - } - if (args[argidx] == "-ccu2") { - ccu2 = true; - continue; - } - if (args[argidx] == "-vpr") { - vpr = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - if (!design->full_selection()) - log_cmd_error("This command only operates on fully selected designs!\n"); - - log_header(design, "Executing SYNTH_MACHXO2 pass.\n"); - log_push(); - - run_script(design, run_from, run_to); - - log_pop(); - } - - void script() override - { - if (check_label("begin")) - { - run("read_verilog -lib -icells +/machxo2/cells_sim.v +/machxo2/cells_bb.v"); - run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); - } - - if (check_label("flatten", "(unless -noflatten)")) - { - if (flatten || help_mode) { - run("proc"); - run("flatten"); - run("tribuf -logic"); - run("deminout"); - } - } - - if (check_label("coarse")) - { - run("synth -run coarse"); - } - - if (check_label("map_ram")) - { - std::string args = ""; - if (nobram) - args += " -no-auto-block"; - if (nolutram) - args += " -no-auto-distributed"; - if (help_mode) - args += " [-no-auto-block] [-no-auto-distributed]"; - run("memory_libmap -lib +/machxo2/lutrams.txt -lib +/machxo2/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); - run("techmap -map +/machxo2/lutrams_map.v -map +/machxo2/brams_map.v"); - } - - if (check_label("fine")) - { - run("opt -fast -mux_undef -undriven -fine"); - run("memory_map"); - run("opt -undriven -fine"); - } - - if (check_label("map_gates", "(unless -noiopad)")) - { - if (!ccu2) - run("techmap"); - else - run("techmap -map +/techmap.v -map +/machxo2/arith_map.v"); - if (!noiopad || help_mode) - { - run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(only if '-iopad')"); - run("attrmvcp -attr src -attr LOC t:OB %x:+[O] t:OBZ %x:+[O] t:BB %x:+[B]"); - run("attrmvcp -attr src -attr LOC -driven t:IB %x:+[I]"); - } - } - - if (check_label("map_ffs")) - { - run("opt_clean"); - std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r"; - run("dfflegalize" + dfflegalize_args); - run("techmap -D NO_LUT -map +/machxo2/cells_map.v"); - run("opt_expr -undriven -mux_undef"); - run("simplemap"); - run("lattice_gsr"); - run("attrmvcp -copy -attr syn_useioff"); - run("opt_clean"); - } - - if (check_label("map_luts")) - { - run("abc -lut 4 -dress"); - run("clean"); - } - - if (check_label("map_cells")) - { - run("techmap -map +/machxo2/cells_map.v"); - run("clean"); - } - - if (check_label("check")) - { - run("hierarchy -check"); - run("stat"); - run("blackbox =A:whitebox"); - } - - if (check_label("blif")) - { - if (!blif_file.empty() || help_mode) { - if (vpr || help_mode) { - run(stringf("opt_clean -purge"), - " (vpr mode)"); - run(stringf("write_blif -attr -cname -conn -param %s", - help_mode ? "" : blif_file.c_str()), - " (vpr mode)"); - } - if (!vpr) - run(stringf("write_blif -gates -attr -param %s", - help_mode ? "" : blif_file.c_str()), - " (non-vpr mode)"); - } - } - - if (check_label("edif")) - { - if (!edif_file.empty() || help_mode) - run(stringf("write_edif %s", help_mode ? "" : edif_file.c_str())); - } - - if (check_label("json")) - { - if (!json_file.empty() || help_mode) - run(stringf("write_json %s", help_mode ? "" : json_file.c_str())); - } - } -} SynthMachXO2Pass; - -PRIVATE_NAMESPACE_END From ea50d96135ad5c337f41169c08383c460bf97e83 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 10:54:29 +0200 Subject: [PATCH 062/119] fixed tests --- tests/arch/machxo2/add_sub.ys | 2 +- tests/arch/machxo2/adffs.ys | 8 ++++---- tests/arch/machxo2/counter.ys | 2 +- tests/arch/machxo2/dffs.ys | 6 +++--- tests/arch/machxo2/fsm.ys | 2 +- tests/arch/machxo2/logic.ys | 2 +- tests/arch/machxo2/lutram.ys | 2 +- tests/arch/machxo2/mux.ys | 8 ++++---- tests/arch/machxo2/shifter.ys | 2 +- tests/arch/machxo2/tribuf.ys | 7 +++---- 10 files changed, 20 insertions(+), 21 deletions(-) diff --git a/tests/arch/machxo2/add_sub.ys b/tests/arch/machxo2/add_sub.ys index 97ee90fbbe2..6897363aaee 100644 --- a/tests/arch/machxo2/add_sub.ys +++ b/tests/arch/machxo2/add_sub.ys @@ -1,7 +1,7 @@ read_verilog ../common/add_sub.v hierarchy -top top proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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 10 t:LUT4 diff --git a/tests/arch/machxo2/adffs.ys b/tests/arch/machxo2/adffs.ys index a9f8980c6e4..f1134a6ac67 100644 --- a/tests/arch/machxo2/adffs.ys +++ b/tests/arch/machxo2/adffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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:TRELLIS_FF @@ -12,7 +12,7 @@ select -assert-none t:TRELLIS_FF %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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:TRELLIS_FF @@ -22,7 +22,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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:TRELLIS_FF @@ -32,7 +32,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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:TRELLIS_FF diff --git a/tests/arch/machxo2/counter.ys b/tests/arch/machxo2/counter.ys index 54ee80066ff..11560b551fc 100644 --- a/tests/arch/machxo2/counter.ys +++ b/tests/arch/machxo2/counter.ys @@ -2,7 +2,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -assert -multiclock -map +/machxo2/cells_sim.v synth_machxo2 -ccu2 -noiopad # equivalency check +equiv_opt -assert -multiclock -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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 4 t:CCU2D diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys index 29dcafe2383..663a64294bf 100644 --- a/tests/arch/machxo2/dffs.ys +++ b/tests/arch/machxo2/dffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top dff proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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:TRELLIS_FF @@ -12,8 +12,8 @@ select -assert-none t:TRELLIS_FF t:TRELLIS_IO %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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 2 t:TRELLIS_FF t:LUT4 +select -assert-count 1 t:TRELLIS_FF t:LUT4 select -assert-none t:TRELLIS_FF t:LUT4 t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys index a61357fcdd2..70e1a632bdf 100644 --- a/tests/arch/machxo2/fsm.ys +++ b/tests/arch/machxo2/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/machxo2/cells_sim.v synth_machxo2 +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut 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 diff --git a/tests/arch/machxo2/logic.ys b/tests/arch/machxo2/logic.ys index 0cf57310c81..5c799530519 100644 --- a/tests/arch/machxo2/logic.ys +++ b/tests/arch/machxo2/logic.ys @@ -1,7 +1,7 @@ read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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 9 t:LUT4 diff --git a/tests/arch/machxo2/lutram.ys b/tests/arch/machxo2/lutram.ys index dc6b86fd349..8f1918587c9 100644 --- a/tests/arch/machxo2/lutram.ys +++ b/tests/arch/machxo2/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/machxo2/cells_sim.v synth_machxo2 -noiopad +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut memory opt -full diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 27bffbe63aa..4fa1bd2fcc8 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # 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:LUT4 @@ -12,7 +12,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # 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 2 t:LUT4 @@ -22,7 +22,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # 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 5 t:LUT4 @@ -32,7 +32,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # 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-max 12 t:LUT4 diff --git a/tests/arch/machxo2/shifter.ys b/tests/arch/machxo2/shifter.ys index bff881fb734..f6440c025e8 100644 --- a/tests/arch/machxo2/shifter.ys +++ b/tests/arch/machxo2/shifter.ys @@ -2,7 +2,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # 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 diff --git a/tests/arch/machxo2/tribuf.ys b/tests/arch/machxo2/tribuf.ys index 840979439f8..08c86008da5 100644 --- a/tests/arch/machxo2/tribuf.ys +++ b/tests/arch/machxo2/tribuf.ys @@ -2,9 +2,8 @@ read_verilog ../common/tribuf.v hierarchy -top tristate proc flatten -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v -map +/simcells.v synth_machxo2 # 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 -select -assert-count 3 t:TRELLIS_IO -select -assert-count 1 t:LUT4 -select -assert-none t:TRELLIS_IO t:LUT4 %% t:* %D +select -assert-count 1 t:$_TBUF_ +select -assert-none t:$_TBUF_ %% t:* %D From 541c1ab567cb060cfc528b0143404e62efef126b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 11:51:00 +0200 Subject: [PATCH 063/119] add script for blackbox extraction --- techlibs/lattice/cells_bb_ecp5.v | 3040 ++++++++++++++++++++---------- techlibs/lattice/cells_bb_xo2.v | 634 +++++-- techlibs/lattice/cells_bb_xo3.v | 634 +++++-- techlibs/lattice/cells_bb_xo3d.v | 635 +++++-- techlibs/lattice/cells_xtra.py | 854 +++++++++ 5 files changed, 4244 insertions(+), 1553 deletions(-) create mode 100644 techlibs/lattice/cells_xtra.py diff --git a/techlibs/lattice/cells_bb_ecp5.v b/techlibs/lattice/cells_bb_ecp5.v index 5cb90b97efc..9c4d1fde4ef 100644 --- a/techlibs/lattice/cells_bb_ecp5.v +++ b/techlibs/lattice/cells_bb_ecp5.v @@ -1,1067 +1,2177 @@ -// ECP5 Blackbox cells -// FIXME: Create sim models +// Created by cells_xtra.py from Lattice models -(* blackbox *) -module DP16KD( - input DIA17, DIA16, DIA15, DIA14, DIA13, DIA12, DIA11, DIA10, DIA9, DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA13, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA17, DOA16, DOA15, DOA14, DOA13, DOA12, DOA11, DOA10, DOA9, DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB17, DIB16, DIB15, DIB14, DIB13, DIB12, DIB11, DIB10, DIB9, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB13, ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 18; - parameter DATA_WIDTH_B = 18; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; - - parameter DIA17MUX = "DIA17"; - parameter DIA16MUX = "DIA16"; - parameter DIA15MUX = "DIA15"; - parameter DIA14MUX = "DIA14"; - parameter DIA13MUX = "DIA13"; - parameter DIA12MUX = "DIA12"; - parameter DIA11MUX = "DIA11"; - parameter DIA10MUX = "DIA10"; - parameter DIA9MUX = "DIA9"; - parameter DIA8MUX = "DIA8"; - parameter DIA7MUX = "DIA7"; - parameter DIA6MUX = "DIA6"; - parameter DIA5MUX = "DIA5"; - parameter DIA4MUX = "DIA4"; - parameter DIA3MUX = "DIA3"; - parameter DIA2MUX = "DIA2"; - parameter DIA1MUX = "DIA1"; - parameter DIA0MUX = "DIA0"; - parameter ADA13MUX = "ADA13"; - parameter ADA12MUX = "ADA12"; - parameter ADA11MUX = "ADA11"; - parameter ADA10MUX = "ADA10"; - parameter ADA9MUX = "ADA9"; - parameter ADA8MUX = "ADA8"; - parameter ADA7MUX = "ADA7"; - parameter ADA6MUX = "ADA6"; - parameter ADA5MUX = "ADA5"; - parameter ADA4MUX = "ADA4"; - parameter ADA3MUX = "ADA3"; - parameter ADA2MUX = "ADA2"; - parameter ADA1MUX = "ADA1"; - parameter ADA0MUX = "ADA0"; - parameter CEAMUX = "CEA"; - parameter OCEAMUX = "OCEA"; - parameter CLKAMUX = "CLKA"; - parameter WEAMUX = "WEA"; - parameter RSTAMUX = "RSTA"; - parameter CSA2MUX = "CSA2"; - parameter CSA1MUX = "CSA1"; - parameter CSA0MUX = "CSA0"; - parameter DOA17MUX = "DOA17"; - parameter DOA16MUX = "DOA16"; - parameter DOA15MUX = "DOA15"; - parameter DOA14MUX = "DOA14"; - parameter DOA13MUX = "DOA13"; - parameter DOA12MUX = "DOA12"; - parameter DOA11MUX = "DOA11"; - parameter DOA10MUX = "DOA10"; - parameter DOA9MUX = "DOA9"; - parameter DOA8MUX = "DOA8"; - parameter DOA7MUX = "DOA7"; - parameter DOA6MUX = "DOA6"; - parameter DOA5MUX = "DOA5"; - parameter DOA4MUX = "DOA4"; - parameter DOA3MUX = "DOA3"; - parameter DOA2MUX = "DOA2"; - parameter DOA1MUX = "DOA1"; - parameter DOA0MUX = "DOA0"; - parameter DIB17MUX = "DIB17"; - parameter DIB16MUX = "DIB16"; - parameter DIB15MUX = "DIB15"; - parameter DIB14MUX = "DIB14"; - parameter DIB13MUX = "DIB13"; - parameter DIB12MUX = "DIB12"; - parameter DIB11MUX = "DIB11"; - parameter DIB10MUX = "DIB10"; - parameter DIB9MUX = "DIB9"; - parameter DIB8MUX = "DIB8"; - parameter DIB7MUX = "DIB7"; - parameter DIB6MUX = "DIB6"; - parameter DIB5MUX = "DIB5"; - parameter DIB4MUX = "DIB4"; - parameter DIB3MUX = "DIB3"; - parameter DIB2MUX = "DIB2"; - parameter DIB1MUX = "DIB1"; - parameter DIB0MUX = "DIB0"; - parameter ADB13MUX = "ADB13"; - parameter ADB12MUX = "ADB12"; - parameter ADB11MUX = "ADB11"; - parameter ADB10MUX = "ADB10"; - parameter ADB9MUX = "ADB9"; - parameter ADB8MUX = "ADB8"; - parameter ADB7MUX = "ADB7"; - parameter ADB6MUX = "ADB6"; - parameter ADB5MUX = "ADB5"; - parameter ADB4MUX = "ADB4"; - parameter ADB3MUX = "ADB3"; - parameter ADB2MUX = "ADB2"; - parameter ADB1MUX = "ADB1"; - parameter ADB0MUX = "ADB0"; - parameter CEBMUX = "CEB"; - parameter OCEBMUX = "OCEB"; - parameter CLKBMUX = "CLKB"; - parameter WEBMUX = "WEB"; - parameter RSTBMUX = "RSTB"; - parameter CSB2MUX = "CSB2"; - parameter CSB1MUX = "CSB1"; - parameter CSB0MUX = "CSB0"; - parameter DOB17MUX = "DOB17"; - parameter DOB16MUX = "DOB16"; - parameter DOB15MUX = "DOB15"; - parameter DOB14MUX = "DOB14"; - parameter DOB13MUX = "DOB13"; - parameter DOB12MUX = "DOB12"; - parameter DOB11MUX = "DOB11"; - parameter DOB10MUX = "DOB10"; - parameter DOB9MUX = "DOB9"; - parameter DOB8MUX = "DOB8"; - parameter DOB7MUX = "DOB7"; - parameter DOB6MUX = "DOB6"; - parameter DOB5MUX = "DOB5"; - parameter DOB4MUX = "DOB4"; - parameter DOB3MUX = "DOB3"; - parameter DOB2MUX = "DOB2"; - parameter DOB1MUX = "DOB1"; - parameter DOB0MUX = "DOB0"; - - parameter WID = 0; - - parameter GSR = "ENABLED"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule (* blackbox *) -module MULT18X18D( - input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, - input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, - input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, - input SIGNEDA, SIGNEDB, SOURCEA, SOURCEB, - input CLK0, CLK1, CLK2, CLK3, - input CE0, CE1, CE2, CE3, - input RST0, RST1, RST2, RST3, - input SRIA0, SRIA1, SRIA2, SRIA3, SRIA4, SRIA5, SRIA6, SRIA7, SRIA8, SRIA9, SRIA10, SRIA11, SRIA12, SRIA13, SRIA14, SRIA15, SRIA16, SRIA17, - input SRIB0, SRIB1, SRIB2, SRIB3, SRIB4, SRIB5, SRIB6, SRIB7, SRIB8, SRIB9, SRIB10, SRIB11, SRIB12, SRIB13, SRIB14, SRIB15, SRIB16, SRIB17, - output SROA0, SROA1, SROA2, SROA3, SROA4, SROA5, SROA6, SROA7, SROA8, SROA9, SROA10, SROA11, SROA12, SROA13, SROA14, SROA15, SROA16, SROA17, - output SROB0, SROB1, SROB2, SROB3, SROB4, SROB5, SROB6, SROB7, SROB8, SROB9, SROB10, SROB11, SROB12, SROB13, SROB14, SROB15, SROB16, SROB17, - output ROA0, ROA1, ROA2, ROA3, ROA4, ROA5, ROA6, ROA7, ROA8, ROA9, ROA10, ROA11, ROA12, ROA13, ROA14, ROA15, ROA16, ROA17, - output ROB0, ROB1, ROB2, ROB3, ROB4, ROB5, ROB6, ROB7, ROB8, ROB9, ROB10, ROB11, ROB12, ROB13, ROB14, ROB15, ROB16, ROB17, - output ROC0, ROC1, ROC2, ROC3, ROC4, ROC5, ROC6, ROC7, ROC8, ROC9, ROC10, ROC11, ROC12, ROC13, ROC14, ROC15, ROC16, ROC17, - output P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, - output SIGNEDP -); - parameter REG_INPUTA_CLK = "NONE"; - parameter REG_INPUTA_CE = "CE0"; - parameter REG_INPUTA_RST = "RST0"; - parameter REG_INPUTB_CLK = "NONE"; - parameter REG_INPUTB_CE = "CE0"; - parameter REG_INPUTB_RST = "RST0"; - parameter REG_INPUTC_CLK = "NONE"; - parameter REG_INPUTC_CE = "CE0"; - parameter REG_INPUTC_RST = "RST0"; - parameter REG_PIPELINE_CLK = "NONE"; - parameter REG_PIPELINE_CE = "CE0"; - parameter REG_PIPELINE_RST = "RST0"; - parameter REG_OUTPUT_CLK = "NONE"; - parameter REG_OUTPUT_CE = "CE0"; - parameter REG_OUTPUT_RST = "RST0"; - parameter [127:0] CLK0_DIV = "ENABLED"; - parameter [127:0] CLK1_DIV = "ENABLED"; - parameter [127:0] CLK2_DIV = "ENABLED"; - parameter [127:0] CLK3_DIV = "ENABLED"; - parameter HIGHSPEED_CLK = "NONE"; - parameter [127:0] GSR = "ENABLED"; - parameter CAS_MATCH_REG = "FALSE"; - parameter [127:0] SOURCEB_MODE = "B_SHIFT"; - parameter [127:0] MULT_BYPASS = "DISABLED"; - parameter [127:0] RESETMODE = "SYNC"; +module PUR (...); + parameter RST_PULSE = 1; + input PUR; endmodule -(* blackbox *) -module ALU54B( - input CLK0, CLK1, CLK2, CLK3, - input CE0, CE1, CE2, CE3, - input RST0, RST1, RST2, RST3, - input SIGNEDIA, SIGNEDIB, SIGNEDCIN, - input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, - input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B20, B21, B22, B23, B24, B25, B26, B27, B28, B29, B30, B31, B32, B33, B34, B35, - input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26, C27, C28, C29, C30, C31, C32, C33, C34, C35, C36, C37, C38, C39, C40, C41, C42, C43, C44, C45, C46, C47, C48, C49, C50, C51, C52, C53, - input CFB0, CFB1, CFB2, CFB3, CFB4, CFB5, CFB6, CFB7, CFB8, CFB9, CFB10, CFB11, CFB12, CFB13, CFB14, CFB15, CFB16, CFB17, CFB18, CFB19, CFB20, CFB21, CFB22, CFB23, CFB24, CFB25, CFB26, CFB27, CFB28, CFB29, CFB30, CFB31, CFB32, CFB33, CFB34, CFB35, CFB36, CFB37, CFB38, CFB39, CFB40, CFB41, CFB42, CFB43, CFB44, CFB45, CFB46, CFB47, CFB48, CFB49, CFB50, CFB51, CFB52, CFB53, - input MA0, MA1, MA2, MA3, MA4, MA5, MA6, MA7, MA8, MA9, MA10, MA11, MA12, MA13, MA14, MA15, MA16, MA17, MA18, MA19, MA20, MA21, MA22, MA23, MA24, MA25, MA26, MA27, MA28, MA29, MA30, MA31, MA32, MA33, MA34, MA35, - input MB0, MB1, MB2, MB3, MB4, MB5, MB6, MB7, MB8, MB9, MB10, MB11, MB12, MB13, MB14, MB15, MB16, MB17, MB18, MB19, MB20, MB21, MB22, MB23, MB24, MB25, MB26, MB27, MB28, MB29, MB30, MB31, MB32, MB33, MB34, MB35, - input CIN0, CIN1, CIN2, CIN3, CIN4, CIN5, CIN6, CIN7, CIN8, CIN9, CIN10, CIN11, CIN12, CIN13, CIN14, CIN15, CIN16, CIN17, CIN18, CIN19, CIN20, CIN21, CIN22, CIN23, CIN24, CIN25, CIN26, CIN27, CIN28, CIN29, CIN30, CIN31, CIN32, CIN33, CIN34, CIN35, CIN36, CIN37, CIN38, CIN39, CIN40, CIN41, CIN42, CIN43, CIN44, CIN45, CIN46, CIN47, CIN48, CIN49, CIN50, CIN51, CIN52, CIN53, - input OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7, OP8, OP9, OP10, - output R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, R47, R48, R49, R50, R51, R52, R53, - output CO0, CO1, CO2, CO3, CO4, CO5, CO6, CO7, CO8, CO9, CO10, CO11, CO12, CO13, CO14, CO15, CO16, CO17, CO18, CO19, CO20, CO21, CO22, CO23, CO24, CO25, CO26, CO27, CO28, CO29, CO30, CO31, CO32, CO33, CO34, CO35, CO36, CO37, CO38, CO39, CO40, CO41, CO42, CO43, CO44, CO45, CO46, CO47, CO48, CO49, CO50, CO51, CO52, CO53, - output EQZ, EQZM, EQOM, EQPAT, EQPATB, - output OVER, UNDER, OVERUNDER, - output SIGNEDR -); - parameter REG_INPUTC0_CLK = "NONE"; - parameter REG_INPUTC0_CE = "CE0"; - parameter REG_INPUTC0_RST = "RST0"; - parameter REG_INPUTC1_CLK = "NONE"; - parameter REG_INPUTC1_CE = "CE0"; - parameter REG_INPUTC1_RST = "RST0"; - parameter REG_OPCODEOP0_0_CLK = "NONE"; - parameter REG_OPCODEOP0_0_CE = "CE0"; - parameter REG_OPCODEOP0_0_RST = "RST0"; - parameter REG_OPCODEOP1_0_CLK = "NONE"; - parameter REG_OPCODEOP0_1_CLK = "NONE"; - parameter REG_OPCODEOP0_1_CE = "CE0"; - parameter REG_OPCODEOP0_1_RST = "RST0"; - parameter REG_OPCODEOP1_1_CLK = "NONE"; - parameter REG_OPCODEIN_0_CLK = "NONE"; - parameter REG_OPCODEIN_0_CE = "CE0"; - parameter REG_OPCODEIN_0_RST = "RST0"; - parameter REG_OPCODEIN_1_CLK = "NONE"; - parameter REG_OPCODEIN_1_CE = "CE0"; - parameter REG_OPCODEIN_1_RST = "RST0"; - parameter REG_OUTPUT0_CLK = "NONE"; - parameter REG_OUTPUT0_CE = "CE0"; - parameter REG_OUTPUT0_RST = "RST0"; - parameter REG_OUTPUT1_CLK = "NONE"; - parameter REG_OUTPUT1_CE = "CE0"; - parameter REG_OUTPUT1_RST = "RST0"; - parameter REG_FLAG_CLK = "NONE"; - parameter REG_FLAG_CE = "CE0"; - parameter REG_FLAG_RST = "RST0"; - parameter REG_INPUTCFB_CLK = "NONE"; - parameter REG_INPUTCFB_CE = "CE0"; - parameter REG_INPUTCFB_RST = "RST0"; - parameter [127:0] MCPAT_SOURCE = "STATIC"; - parameter [127:0] MASKPAT_SOURCE = "STATIC"; - parameter MASK01 = "0x00000000000000"; - parameter [127:0] CLK0_DIV = "ENABLED"; - parameter [127:0] CLK1_DIV = "ENABLED"; - parameter [127:0] CLK2_DIV = "ENABLED"; - parameter [127:0] CLK3_DIV = "ENABLED"; - parameter MCPAT = "0x00000000000000"; - parameter MASKPAT = "0x00000000000000"; - parameter RNDPAT = "0x00000000000000"; - parameter [127:0] GSR = "ENABLED"; - parameter [127:0] RESETMODE = "SYNC"; - parameter MULT9_MODE = "DISABLED"; - parameter FORCE_ZERO_BARREL_SHIFT = "DISABLED"; - parameter LEGACY = "DISABLED"; +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module EHXPLLL ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, PHASELOADREG, - input STDBY, PLLWAKESYNC, - input RST, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, - output CLKOP, CLKOS, CLKOS2, CLKOS3, - output LOCK, INTLOCK, - output REFCLK, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "DISABLED"; - parameter CLKOS2_ENABLE = "DISABLED"; - parameter CLKOS3_ENABLE = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter OUTDIVIDER_MUXA = "DIVA"; - parameter OUTDIVIDER_MUXB = "DIVB"; - parameter OUTDIVIDER_MUXC = "DIVC"; - parameter OUTDIVIDER_MUXD = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter PLL_LOCK_DELAY = 200; - parameter STDBY_ENABLE = "DISABLED"; - parameter REFIN_RESET = "DISABLED"; - parameter SYNC_ENABLE = "DISABLED"; - parameter INT_LOCK_STICKY = "ENABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; +module DP16KD (...); + parameter DATA_WIDTH_A = 18; + parameter DATA_WIDTH_B = 18; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter GSR = "ENABLED"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + input DIA17; + input DIA16; + input DIA15; + input DIA14; + input DIA13; + input DIA12; + input DIA11; + input DIA10; + input DIA9; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA13; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB17; + input DIB16; + input DIB15; + input DIB14; + input DIB13; + input DIB12; + input DIB11; + input DIB10; + input DIB9; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB13; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA17; + output DOA16; + output DOA15; + output DOA14; + output DOA13; + output DOA12; + output DOA11; + output DOA10; + output DOA9; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB17; + output DOB16; + output DOB15; + output DOB14; + output DOB13; + output DOB12; + output DOB11; + output DOB10; + output DOB9; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module DTR( - input STARTPULSE, - output DTROUT7, DTROUT6, DTROUT5, DTROUT4, DTROUT3, DTROUT2, DTROUT1, DTROUT0 -); +module PDPW16KD (...); + parameter DATA_WIDTH_W = 36; + parameter DATA_WIDTH_R = 36; + parameter GSR = "ENABLED"; + parameter REGMODE = "NOREG"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + input DI35; + input DI34; + input DI33; + input DI32; + input DI31; + input DI30; + input DI29; + input DI28; + input DI27; + input DI26; + input DI25; + input DI24; + input DI23; + input DI22; + input DI21; + input DI20; + input DI19; + input DI18; + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE3; + input BE2; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR13; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO35; + output DO34; + output DO33; + output DO32; + output DO31; + output DO30; + output DO29; + output DO28; + output DO27; + output DO26; + output DO25; + output DO24; + output DO23; + output DO22; + output DO21; + output DO20; + output DO19; + output DO18; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module OSCG( - output OSC -); -parameter DIV = 128; +module MULT18X18D (...); + parameter REG_INPUTA_CLK = "NONE"; + parameter REG_INPUTA_CE = "CE0"; + parameter REG_INPUTA_RST = "RST0"; + parameter REG_INPUTB_CLK = "NONE"; + parameter REG_INPUTB_CE = "CE0"; + parameter REG_INPUTB_RST = "RST0"; + parameter REG_INPUTC_CLK = "NONE"; + parameter REG_INPUTC_CE = "CE0"; + parameter REG_INPUTC_RST = "RST0"; + parameter REG_PIPELINE_CLK = "NONE"; + parameter REG_PIPELINE_CE = "CE0"; + parameter REG_PIPELINE_RST = "RST0"; + parameter REG_OUTPUT_CLK = "NONE"; + parameter REG_OUTPUT_CE = "CE0"; + parameter REG_OUTPUT_RST = "RST0"; + parameter CLK0_DIV = "ENABLED"; + parameter CLK1_DIV = "ENABLED"; + parameter CLK2_DIV = "ENABLED"; + parameter CLK3_DIV = "ENABLED"; + parameter HIGHSPEED_CLK = "NONE"; + parameter GSR = "ENABLED"; + parameter CAS_MATCH_REG = "FALSE"; + parameter SOURCEB_MODE = "B_SHIFT"; + parameter MULT_BYPASS = "DISABLED"; + parameter RESETMODE = "SYNC"; + input A17; + input A16; + input A15; + input A14; + input A13; + input A12; + input A11; + input A10; + input A9; + input A8; + input A7; + input A6; + input A5; + input A4; + input A3; + input A2; + input A1; + input A0; + input B17; + input B16; + input B15; + input B14; + input B13; + input B12; + input B11; + input B10; + input B9; + input B8; + input B7; + input B6; + input B5; + input B4; + input B3; + input B2; + input B1; + input B0; + input C17; + input C16; + input C15; + input C14; + input C13; + input C12; + input C11; + input C10; + input C9; + input C8; + input C7; + input C6; + input C5; + input C4; + input C3; + input C2; + input C1; + input C0; + input SIGNEDA; + input SIGNEDB; + input SOURCEA; + input SOURCEB; + input CLK3; + input CLK2; + input CLK1; + input CLK0; + input CE3; + input CE2; + input CE1; + input CE0; + input RST3; + input RST2; + input RST1; + input RST0; + input SRIA17; + input SRIA16; + input SRIA15; + input SRIA14; + input SRIA13; + input SRIA12; + input SRIA11; + input SRIA10; + input SRIA9; + input SRIA8; + input SRIA7; + input SRIA6; + input SRIA5; + input SRIA4; + input SRIA3; + input SRIA2; + input SRIA1; + input SRIA0; + input SRIB17; + input SRIB16; + input SRIB15; + input SRIB14; + input SRIB13; + input SRIB12; + input SRIB11; + input SRIB10; + input SRIB9; + input SRIB8; + input SRIB7; + input SRIB6; + input SRIB5; + input SRIB4; + input SRIB3; + input SRIB2; + input SRIB1; + input SRIB0; + output SROA17; + output SROA16; + output SROA15; + output SROA14; + output SROA13; + output SROA12; + output SROA11; + output SROA10; + output SROA9; + output SROA8; + output SROA7; + output SROA6; + output SROA5; + output SROA4; + output SROA3; + output SROA2; + output SROA1; + output SROA0; + output SROB17; + output SROB16; + output SROB15; + output SROB14; + output SROB13; + output SROB12; + output SROB11; + output SROB10; + output SROB9; + output SROB8; + output SROB7; + output SROB6; + output SROB5; + output SROB4; + output SROB3; + output SROB2; + output SROB1; + output SROB0; + output ROA17; + output ROA16; + output ROA15; + output ROA14; + output ROA13; + output ROA12; + output ROA11; + output ROA10; + output ROA9; + output ROA8; + output ROA7; + output ROA6; + output ROA5; + output ROA4; + output ROA3; + output ROA2; + output ROA1; + output ROA0; + output ROB17; + output ROB16; + output ROB15; + output ROB14; + output ROB13; + output ROB12; + output ROB11; + output ROB10; + output ROB9; + output ROB8; + output ROB7; + output ROB6; + output ROB5; + output ROB4; + output ROB3; + output ROB2; + output ROB1; + output ROB0; + output ROC17; + output ROC16; + output ROC15; + output ROC14; + output ROC13; + output ROC12; + output ROC11; + output ROC10; + output ROC9; + output ROC8; + output ROC7; + output ROC6; + output ROC5; + output ROC4; + output ROC3; + output ROC2; + output ROC1; + output ROC0; + output P35; + output P34; + output P33; + output P32; + output P31; + output P30; + output P29; + output P28; + output P27; + output P26; + output P25; + output P24; + output P23; + output P22; + output P21; + output P20; + output P19; + output P18; + output P17; + output P16; + output P15; + output P14; + output P13; + output P12; + output P11; + output P10; + output P9; + output P8; + output P7; + output P6; + output P5; + output P4; + output P3; + output P2; + output P1; + output P0; + output SIGNEDP; endmodule -(* blackbox *) (* keep *) -module USRMCLK( - input USRMCLKI, USRMCLKTS, - output USRMCLKO -); +(* blackbox *) +module ALU54B (...); + parameter REG_INPUTC0_CLK = "NONE"; + parameter REG_INPUTC0_CE = "CE0"; + parameter REG_INPUTC0_RST = "RST0"; + parameter REG_INPUTC1_CLK = "NONE"; + parameter REG_INPUTC1_CE = "CE0"; + parameter REG_INPUTC1_RST = "RST0"; + parameter REG_OPCODEOP0_0_CLK = "NONE"; + parameter REG_OPCODEOP0_0_CE = "CE0"; + parameter REG_OPCODEOP0_0_RST = "RST0"; + parameter REG_OPCODEOP1_0_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CE = "CE0"; + parameter REG_OPCODEOP0_1_RST = "RST0"; + parameter REG_OPCODEOP1_1_CLK = "NONE"; + parameter REG_OPCODEIN_0_CLK = "NONE"; + parameter REG_OPCODEIN_0_CE = "CE0"; + parameter REG_OPCODEIN_0_RST = "RST0"; + parameter REG_OPCODEIN_1_CLK = "NONE"; + parameter REG_OPCODEIN_1_CE = "CE0"; + parameter REG_OPCODEIN_1_RST = "RST0"; + parameter REG_OUTPUT0_CLK = "NONE"; + parameter REG_OUTPUT0_CE = "CE0"; + parameter REG_OUTPUT0_RST = "RST0"; + parameter REG_OUTPUT1_CLK = "NONE"; + parameter REG_OUTPUT1_CE = "CE0"; + parameter REG_OUTPUT1_RST = "RST0"; + parameter REG_FLAG_CLK = "NONE"; + parameter REG_FLAG_CE = "CE0"; + parameter REG_FLAG_RST = "RST0"; + parameter MCPAT_SOURCE = "STATIC"; + parameter MASKPAT_SOURCE = "STATIC"; + parameter MASK01 = "0x00000000000000"; + parameter REG_INPUTCFB_CLK = "NONE"; + parameter REG_INPUTCFB_CE = "CE0"; + parameter REG_INPUTCFB_RST = "RST0"; + parameter CLK0_DIV = "ENABLED"; + parameter CLK1_DIV = "ENABLED"; + parameter CLK2_DIV = "ENABLED"; + parameter CLK3_DIV = "ENABLED"; + parameter MCPAT = "0x00000000000000"; + parameter MASKPAT = "0x00000000000000"; + parameter RNDPAT = "0x00000000000000"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter MULT9_MODE = "DISABLED"; + parameter FORCE_ZERO_BARREL_SHIFT = "DISABLED"; + parameter LEGACY = "DISABLED"; + input CE3; + input CE2; + input CE1; + input CE0; + input CLK3; + input CLK2; + input CLK1; + input CLK0; + input RST3; + input RST2; + input RST1; + input RST0; + input SIGNEDIA; + input SIGNEDIB; + input SIGNEDCIN; + input A35; + input A34; + input A33; + input A32; + input A31; + input A30; + input A29; + input A28; + input A27; + input A26; + input A25; + input A24; + input A23; + input A22; + input A21; + input A20; + input A19; + input A18; + input A17; + input A16; + input A15; + input A14; + input A13; + input A12; + input A11; + input A10; + input A9; + input A8; + input A7; + input A6; + input A5; + input A4; + input A3; + input A2; + input A1; + input A0; + input B35; + input B34; + input B33; + input B32; + input B31; + input B30; + input B29; + input B28; + input B27; + input B26; + input B25; + input B24; + input B23; + input B22; + input B21; + input B20; + input B19; + input B18; + input B17; + input B16; + input B15; + input B14; + input B13; + input B12; + input B11; + input B10; + input B9; + input B8; + input B7; + input B6; + input B5; + input B4; + input B3; + input B2; + input B1; + input B0; + input C53; + input C52; + input C51; + input C50; + input C49; + input C48; + input C47; + input C46; + input C45; + input C44; + input C43; + input C42; + input C41; + input C40; + input C39; + input C38; + input C37; + input C36; + input C35; + input C34; + input C33; + input C32; + input C31; + input C30; + input C29; + input C28; + input C27; + input C26; + input C25; + input C24; + input C23; + input C22; + input C21; + input C20; + input C19; + input C18; + input C17; + input C16; + input C15; + input C14; + input C13; + input C12; + input C11; + input C10; + input C9; + input C8; + input C7; + input C6; + input C5; + input C4; + input C3; + input C2; + input C1; + input C0; + input CFB53; + input CFB52; + input CFB51; + input CFB50; + input CFB49; + input CFB48; + input CFB47; + input CFB46; + input CFB45; + input CFB44; + input CFB43; + input CFB42; + input CFB41; + input CFB40; + input CFB39; + input CFB38; + input CFB37; + input CFB36; + input CFB35; + input CFB34; + input CFB33; + input CFB32; + input CFB31; + input CFB30; + input CFB29; + input CFB28; + input CFB27; + input CFB26; + input CFB25; + input CFB24; + input CFB23; + input CFB22; + input CFB21; + input CFB20; + input CFB19; + input CFB18; + input CFB17; + input CFB16; + input CFB15; + input CFB14; + input CFB13; + input CFB12; + input CFB11; + input CFB10; + input CFB9; + input CFB8; + input CFB7; + input CFB6; + input CFB5; + input CFB4; + input CFB3; + input CFB2; + input CFB1; + input CFB0; + input MA35; + input MA34; + input MA33; + input MA32; + input MA31; + input MA30; + input MA29; + input MA28; + input MA27; + input MA26; + input MA25; + input MA24; + input MA23; + input MA22; + input MA21; + input MA20; + input MA19; + input MA18; + input MA17; + input MA16; + input MA15; + input MA14; + input MA13; + input MA12; + input MA11; + input MA10; + input MA9; + input MA8; + input MA7; + input MA6; + input MA5; + input MA4; + input MA3; + input MA2; + input MA1; + input MA0; + input MB35; + input MB34; + input MB33; + input MB32; + input MB31; + input MB30; + input MB29; + input MB28; + input MB27; + input MB26; + input MB25; + input MB24; + input MB23; + input MB22; + input MB21; + input MB20; + input MB19; + input MB18; + input MB17; + input MB16; + input MB15; + input MB14; + input MB13; + input MB12; + input MB11; + input MB10; + input MB9; + input MB8; + input MB7; + input MB6; + input MB5; + input MB4; + input MB3; + input MB2; + input MB1; + input MB0; + input CIN53; + input CIN52; + input CIN51; + input CIN50; + input CIN49; + input CIN48; + input CIN47; + input CIN46; + input CIN45; + input CIN44; + input CIN43; + input CIN42; + input CIN41; + input CIN40; + input CIN39; + input CIN38; + input CIN37; + input CIN36; + input CIN35; + input CIN34; + input CIN33; + input CIN32; + input CIN31; + input CIN30; + input CIN29; + input CIN28; + input CIN27; + input CIN26; + input CIN25; + input CIN24; + input CIN23; + input CIN22; + input CIN21; + input CIN20; + input CIN19; + input CIN18; + input CIN17; + input CIN16; + input CIN15; + input CIN14; + input CIN13; + input CIN12; + input CIN11; + input CIN10; + input CIN9; + input CIN8; + input CIN7; + input CIN6; + input CIN5; + input CIN4; + input CIN3; + input CIN2; + input CIN1; + input CIN0; + input OP10; + input OP9; + input OP8; + input OP7; + input OP6; + input OP5; + input OP4; + input OP3; + input OP2; + input OP1; + input OP0; + output R53; + output R52; + output R51; + output R50; + output R49; + output R48; + output R47; + output R46; + output R45; + output R44; + output R43; + output R42; + output R41; + output R40; + output R39; + output R38; + output R37; + output R36; + output R35; + output R34; + output R33; + output R32; + output R31; + output R30; + output R29; + output R28; + output R27; + output R26; + output R25; + output R24; + output R23; + output R22; + output R21; + output R20; + output R19; + output R18; + output R17; + output R16; + output R15; + output R14; + output R13; + output R12; + output R11; + output R10; + output R9; + output R8; + output R7; + output R6; + output R5; + output R4; + output R3; + output R2; + output R1; + output R0; + output CO53; + output CO52; + output CO51; + output CO50; + output CO49; + output CO48; + output CO47; + output CO46; + output CO45; + output CO44; + output CO43; + output CO42; + output CO41; + output CO40; + output CO39; + output CO38; + output CO37; + output CO36; + output CO35; + output CO34; + output CO33; + output CO32; + output CO31; + output CO30; + output CO29; + output CO28; + output CO27; + output CO26; + output CO25; + output CO24; + output CO23; + output CO22; + output CO21; + output CO20; + output CO19; + output CO18; + output CO17; + output CO16; + output CO15; + output CO14; + output CO13; + output CO12; + output CO11; + output CO10; + output CO9; + output CO8; + output CO7; + output CO6; + output CO5; + output CO4; + output CO3; + output CO2; + output CO1; + output CO0; + output EQZ; + output EQZM; + output EQOM; + output EQPAT; + output EQPATB; + output OVER; + output UNDER; + output OVERUNDER; + output SIGNEDR; endmodule -(* blackbox *) (* keep *) -module JTAGG( - (* iopad_external_pin *) - input TCK, - (* iopad_external_pin *) - input TMS, - (* iopad_external_pin *) - input TDI, - input JTDO2, JTDO1, - (* iopad_external_pin *) - output TDO, - output JTDI, JTCK, JRTI2, JRTI1, - output JSHIFT, JUPDATE, JRSTN, JCE2, JCE1 -); -parameter ER1 = "ENABLED"; -parameter ER2 = "ENABLED"; +(* blackbox *) +module CLKDIVF (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input CLKI; + input RST; + input ALIGNWD; + output CDIVX; endmodule (* blackbox *) -module DELAYF( - input A, LOADN, MOVE, DIRECTION, - output Z, CFLAG -); - parameter DEL_MODE = "USER_DEFINED"; - parameter DEL_VALUE = 0; +module PCSCLKDIV (...); + parameter GSR = "DISABLED"; + input CLKI; + input RST; + input SEL2; + input SEL1; + input SEL0; + output CDIV1; + output CDIVX; endmodule (* blackbox *) -module DELAYG( - input A, - output Z -); - parameter DEL_MODE = "USER_DEFINED"; - parameter DEL_VALUE = 0; +module DCSC (...); + parameter DCSMODE = "POS"; + input CLK1; + input CLK0; + input SEL1; + input SEL0; + input MODESEL; + output DCSOUT; endmodule (* blackbox *) -module IDDRX1F( - input D, SCLK, RST, - output Q0, Q1 -); - parameter GSR = "ENABLED"; +module DCCA (...); + input CLKI; + input CE; + output CLKO; endmodule (* blackbox *) -module IDDRX2F( - input D, SCLK, ECLK, RST, ALIGNWD, - output Q0, Q1, Q2, Q3 -); - parameter GSR = "ENABLED"; +module ECLKSYNCB (...); + input ECLKI; + input STOP; + output ECLKO; endmodule (* blackbox *) -module IDDR71B( - input D, SCLK, ECLK, RST, ALIGNWD, - output Q0, Q1, Q2, Q3, Q4, Q5, Q6 -); - parameter GSR = "ENABLED"; +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; endmodule (* blackbox *) -module IDDRX2DQA( - input D, DQSR90, ECLK, SCLK, RST, - input RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, - output Q0, Q1, Q2, Q3, QWL -); - parameter GSR = "ENABLED"; +module DELAYF (...); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; + input A; + input LOADN; + input MOVE; + input DIRECTION; + output Z; + output CFLAG; endmodule (* blackbox *) -module ODDRX1F( - input SCLK, RST, D0, D1, - output Q -); - parameter GSR = "ENABLED"; +module DELAYG (...); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; + input A; + output Z; endmodule -(* blackbox *) -module ODDRX2F( - input SCLK, ECLK, RST, D0, D1, D2, D3, - output Q -); - parameter GSR = "ENABLED"; +(* blackbox *) (* keep *) +module USRMCLK (...); + input USRMCLKI; + input USRMCLKTS; endmodule (* blackbox *) -module ODDR71B( - input SCLK, ECLK, RST, D0, D1, D2, D3, D4, D5, D6, - output Q -); - parameter GSR = "ENABLED"; +module DQSBUFM (...); + parameter DQS_LI_DEL_VAL = 4; + parameter DQS_LI_DEL_ADJ = "FACTORYONLY"; + parameter DQS_LO_DEL_VAL = 0; + parameter DQS_LO_DEL_ADJ = "FACTORYONLY"; + parameter GSR = "ENABLED"; + input DQSI; + input READ1; + input READ0; + input READCLKSEL2; + input READCLKSEL1; + input READCLKSEL0; + input DDRDEL; + input ECLK; + input SCLK; + input RST; + input DYNDELAY7; + input DYNDELAY6; + input DYNDELAY5; + input DYNDELAY4; + input DYNDELAY3; + input DYNDELAY2; + input DYNDELAY1; + input DYNDELAY0; + input PAUSE; + input RDLOADN; + input RDMOVE; + input RDDIRECTION; + input WRLOADN; + input WRMOVE; + input WRDIRECTION; + output DQSR90; + output DQSW; + output DQSW270; + output RDPNTR2; + output RDPNTR1; + output RDPNTR0; + output WRPNTR2; + output WRPNTR1; + output WRPNTR0; + output DATAVALID; + output BURSTDET; + output RDCFLAG; + output WRCFLAG; endmodule (* blackbox *) -module OSHX2A( - input D0, D1, RST, ECLK, SCLK, - output Q -); - parameter GSR = "ENABLED"; +module DDRDLLA (...); + parameter FORCE_MAX_DELAY = "NO"; + parameter GSR = "ENABLED"; + input CLK; + input RST; + input UDDCNTLN; + input FREEZE; + output DDRDEL; + output LOCK; + output DCNTL7; + output DCNTL6; + output DCNTL5; + output DCNTL4; + output DCNTL3; + output DCNTL2; + output DCNTL1; + output DCNTL0; endmodule (* blackbox *) -module ODDRX2DQA( - input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW270, - output Q -); - parameter GSR = "ENABLED"; +module DLLDELD (...); + input A; + input DDRDEL; + input LOADN; + input MOVE; + input DIRECTION; + output Z; + output CFLAG; endmodule (* blackbox *) -module ODDRX2DQSB( - input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW, - output Q -); - parameter GSR = "ENABLED"; +module IDDRX1F (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input RST; + output Q0; + output Q1; endmodule (* blackbox *) -module TSHX2DQA( - input T0, T1, SCLK, ECLK, DQSW270, RST, - output Q -); - parameter GSR = "ENABLED"; - parameter REGSET = "SET"; +module IDDRX2F (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input ECLK; + input RST; + input ALIGNWD; + output Q3; + output Q2; + output Q1; + output Q0; endmodule (* blackbox *) -module TSHX2DQSA( - input T0, T1, SCLK, ECLK, DQSW, RST, - output Q -); - parameter GSR = "ENABLED"; - parameter REGSET = "SET"; +module IDDR71B (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input ECLK; + input RST; + input ALIGNWD; + output Q6; + output Q5; + output Q4; + output Q3; + output Q2; + output Q1; + output Q0; endmodule (* blackbox *) -module DQSBUFM( - input DQSI, READ1, READ0, READCLKSEL2, READCLKSEL1, READCLKSEL0, DDRDEL, - input ECLK, SCLK, - input DYNDELAY7, DYNDELAY6, DYNDELAY5, DYNDELAY4, - input DYNDELAY3, DYNDELAY2, DYNDELAY1, DYNDELAY0, - input RST, RDLOADN, RDMOVE, RDDIRECTION, WRLOADN, WRMOVE, WRDIRECTION, PAUSE, - output DQSR90, DQSW, DQSW270, - output RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, - output DATAVALID, BURSTDET, RDCFLAG, WRCFLAG -); - parameter DQS_LI_DEL_ADJ = "FACTORYONLY"; - parameter DQS_LI_DEL_VAL = 0; - parameter DQS_LO_DEL_ADJ = "FACTORYONLY"; - parameter DQS_LO_DEL_VAL = 0; - parameter GSR = "ENABLED"; +module IDDRX2DQA (...); + parameter GSR = "ENABLED"; + input SCLK; + input ECLK; + input DQSR90; + input D; + input RST; + input RDPNTR2; + input RDPNTR1; + input RDPNTR0; + input WRPNTR2; + input WRPNTR1; + input WRPNTR0; + output Q3; + output Q2; + output Q1; + output Q0; + output QWL; endmodule (* blackbox *) -module DDRDLLA( - input CLK, RST, UDDCNTLN, FREEZE, - output LOCK, DDRDEL, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1, DCNTL0 -); - parameter FORCE_MAX_DELAY = "NO"; - parameter GSR = "ENABLED"; +module ODDRX1F (...); + parameter GSR = "ENABLED"; + input SCLK; + input RST; + input D0; + input D1; + output Q; endmodule (* blackbox *) -module DLLDELD( - input A, DDRDEL, LOADN, MOVE, DIRECTION, - output Z, CFLAG -); - parameter DEL_ADJ = "PLUS"; - parameter DEL_VAL = 0; +module ODDRX2F (...); + parameter GSR = "ENABLED"; + input SCLK; + input ECLK; + input RST; + input D3; + input D2; + input D1; + input D0; + output Q; endmodule (* blackbox *) -module CLKDIVF( - input CLKI, RST, ALIGNWD, - output CDIVX -); - parameter GSR = "DISABLED"; - parameter DIV = "2.0"; +module ODDR71B (...); + parameter GSR = "ENABLED"; + input SCLK; + input ECLK; + input RST; + input D6; + input D5; + input D4; + input D3; + input D2; + input D1; + input D0; + output Q; endmodule (* blackbox *) -module ECLKSYNCB( - input ECLKI, STOP, - output ECLKO -); +module OSHX2A (...); + parameter GSR = "ENABLED"; + input D1; + input D0; + input SCLK; + input ECLK; + input RST; + output Q; endmodule (* blackbox *) -module ECLKBRIDGECS( - input CLK0, CLK1, SEL, - output ECSOUT -); +module TSHX2DQA (...); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; + input T1; + input T0; + input SCLK; + input ECLK; + input DQSW270; + input RST; + output Q; endmodule (* blackbox *) -module DCCA( - input CLKI, CE, - output CLKO -); +module TSHX2DQSA (...); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; + input T1; + input T0; + input SCLK; + input ECLK; + input DQSW; + input RST; + output Q; endmodule (* blackbox *) -module DCSC( - input CLK1, CLK0, - input SEL1, SEL0, - input MODESEL, - output DCSOUT -); - parameter DCSMODE = "POS"; +module ODDRX2DQA (...); + parameter GSR = "ENABLED"; + input D3; + input D2; + input D1; + input D0; + input DQSW270; + input SCLK; + input ECLK; + input RST; + output Q; endmodule -(* blackbox *) (* keep *) -module DCUA( - (* iopad_external_pin *) - input CH0_HDINP, - (* iopad_external_pin *) - input CH1_HDINP, - (* iopad_external_pin *) - input CH0_HDINN, - (* iopad_external_pin *) - input CH1_HDINN, - input D_TXBIT_CLKP_FROM_ND, D_TXBIT_CLKN_FROM_ND, D_SYNC_ND, D_TXPLL_LOL_FROM_ND, - input CH0_RX_REFCLK, CH1_RX_REFCLK, CH0_FF_RXI_CLK, CH1_FF_RXI_CLK, CH0_FF_TXI_CLK, CH1_FF_TXI_CLK, CH0_FF_EBRD_CLK, CH1_FF_EBRD_CLK, - input CH0_FF_TX_D_0, CH1_FF_TX_D_0, CH0_FF_TX_D_1, CH1_FF_TX_D_1, CH0_FF_TX_D_2, CH1_FF_TX_D_2, CH0_FF_TX_D_3, CH1_FF_TX_D_3, - input CH0_FF_TX_D_4, CH1_FF_TX_D_4, CH0_FF_TX_D_5, CH1_FF_TX_D_5, CH0_FF_TX_D_6, CH1_FF_TX_D_6, CH0_FF_TX_D_7, CH1_FF_TX_D_7, - input CH0_FF_TX_D_8, CH1_FF_TX_D_8, CH0_FF_TX_D_9, CH1_FF_TX_D_9, CH0_FF_TX_D_10, CH1_FF_TX_D_10, CH0_FF_TX_D_11, CH1_FF_TX_D_11, - input CH0_FF_TX_D_12, CH1_FF_TX_D_12, CH0_FF_TX_D_13, CH1_FF_TX_D_13, CH0_FF_TX_D_14, CH1_FF_TX_D_14, CH0_FF_TX_D_15, CH1_FF_TX_D_15, - input CH0_FF_TX_D_16, CH1_FF_TX_D_16, CH0_FF_TX_D_17, CH1_FF_TX_D_17, CH0_FF_TX_D_18, CH1_FF_TX_D_18, CH0_FF_TX_D_19, CH1_FF_TX_D_19, - input CH0_FF_TX_D_20, CH1_FF_TX_D_20, CH0_FF_TX_D_21, CH1_FF_TX_D_21, CH0_FF_TX_D_22, CH1_FF_TX_D_22, CH0_FF_TX_D_23, CH1_FF_TX_D_23, - input CH0_FFC_EI_EN, CH1_FFC_EI_EN, CH0_FFC_PCIE_DET_EN, CH1_FFC_PCIE_DET_EN, CH0_FFC_PCIE_CT, CH1_FFC_PCIE_CT, CH0_FFC_SB_INV_RX, CH1_FFC_SB_INV_RX, - input CH0_FFC_ENABLE_CGALIGN, CH1_FFC_ENABLE_CGALIGN, CH0_FFC_SIGNAL_DETECT, CH1_FFC_SIGNAL_DETECT, CH0_FFC_FB_LOOPBACK, CH1_FFC_FB_LOOPBACK, CH0_FFC_SB_PFIFO_LP, CH1_FFC_SB_PFIFO_LP, - input CH0_FFC_PFIFO_CLR, CH1_FFC_PFIFO_CLR, CH0_FFC_RATE_MODE_RX, CH1_FFC_RATE_MODE_RX, CH0_FFC_RATE_MODE_TX, CH1_FFC_RATE_MODE_TX, CH0_FFC_DIV11_MODE_RX, CH1_FFC_DIV11_MODE_RX, CH0_FFC_RX_GEAR_MODE, CH1_FFC_RX_GEAR_MODE, CH0_FFC_TX_GEAR_MODE, CH1_FFC_TX_GEAR_MODE, - input CH0_FFC_DIV11_MODE_TX, CH1_FFC_DIV11_MODE_TX, CH0_FFC_LDR_CORE2TX_EN, CH1_FFC_LDR_CORE2TX_EN, CH0_FFC_LANE_TX_RST, CH1_FFC_LANE_TX_RST, CH0_FFC_LANE_RX_RST, CH1_FFC_LANE_RX_RST, - input CH0_FFC_RRST, CH1_FFC_RRST, CH0_FFC_TXPWDNB, CH1_FFC_TXPWDNB, CH0_FFC_RXPWDNB, CH1_FFC_RXPWDNB, CH0_LDR_CORE2TX, CH1_LDR_CORE2TX, - input D_SCIWDATA0, D_SCIWDATA1, D_SCIWDATA2, D_SCIWDATA3, D_SCIWDATA4, D_SCIWDATA5, D_SCIWDATA6, D_SCIWDATA7, - input D_SCIADDR0, D_SCIADDR1, D_SCIADDR2, D_SCIADDR3, D_SCIADDR4, D_SCIADDR5, D_SCIENAUX, D_SCISELAUX, - input CH0_SCIEN, CH1_SCIEN, CH0_SCISEL, CH1_SCISEL, D_SCIRD, D_SCIWSTN, D_CYAWSTN, D_FFC_SYNC_TOGGLE, - input D_FFC_DUAL_RST, D_FFC_MACRO_RST, D_FFC_MACROPDB, D_FFC_TRST, CH0_FFC_CDR_EN_BITSLIP, CH1_FFC_CDR_EN_BITSLIP, D_SCAN_ENABLE, D_SCAN_IN_0, - input D_SCAN_IN_1, D_SCAN_IN_2, D_SCAN_IN_3, D_SCAN_IN_4, D_SCAN_IN_5, D_SCAN_IN_6, D_SCAN_IN_7, D_SCAN_MODE, - input D_SCAN_RESET, D_CIN0, D_CIN1, D_CIN2, D_CIN3, D_CIN4, D_CIN5, D_CIN6,D_CIN7, D_CIN8, D_CIN9, D_CIN10, D_CIN11, - output CH0_HDOUTP, CH1_HDOUTP, CH0_HDOUTN, CH1_HDOUTN, D_TXBIT_CLKP_TO_ND, D_TXBIT_CLKN_TO_ND, D_SYNC_PULSE2ND, D_TXPLL_LOL_TO_ND, - output CH0_FF_RX_F_CLK, CH1_FF_RX_F_CLK, CH0_FF_RX_H_CLK, CH1_FF_RX_H_CLK, CH0_FF_TX_F_CLK, CH1_FF_TX_F_CLK, CH0_FF_TX_H_CLK, CH1_FF_TX_H_CLK, - output CH0_FF_RX_PCLK, CH1_FF_RX_PCLK, CH0_FF_TX_PCLK, CH1_FF_TX_PCLK, CH0_FF_RX_D_0, CH1_FF_RX_D_0, CH0_FF_RX_D_1, CH1_FF_RX_D_1, - output CH0_FF_RX_D_2, CH1_FF_RX_D_2, CH0_FF_RX_D_3, CH1_FF_RX_D_3, CH0_FF_RX_D_4, CH1_FF_RX_D_4, CH0_FF_RX_D_5, CH1_FF_RX_D_5, - output CH0_FF_RX_D_6, CH1_FF_RX_D_6, CH0_FF_RX_D_7, CH1_FF_RX_D_7, CH0_FF_RX_D_8, CH1_FF_RX_D_8, CH0_FF_RX_D_9, CH1_FF_RX_D_9, - output CH0_FF_RX_D_10, CH1_FF_RX_D_10, CH0_FF_RX_D_11, CH1_FF_RX_D_11, CH0_FF_RX_D_12, CH1_FF_RX_D_12, CH0_FF_RX_D_13, CH1_FF_RX_D_13, - output CH0_FF_RX_D_14, CH1_FF_RX_D_14, CH0_FF_RX_D_15, CH1_FF_RX_D_15, CH0_FF_RX_D_16, CH1_FF_RX_D_16, CH0_FF_RX_D_17, CH1_FF_RX_D_17, - output CH0_FF_RX_D_18, CH1_FF_RX_D_18, CH0_FF_RX_D_19, CH1_FF_RX_D_19, CH0_FF_RX_D_20, CH1_FF_RX_D_20, CH0_FF_RX_D_21, CH1_FF_RX_D_21, - output CH0_FF_RX_D_22, CH1_FF_RX_D_22, CH0_FF_RX_D_23, CH1_FF_RX_D_23, CH0_FFS_PCIE_DONE, CH1_FFS_PCIE_DONE, CH0_FFS_PCIE_CON, CH1_FFS_PCIE_CON, - output CH0_FFS_RLOS, CH1_FFS_RLOS, CH0_FFS_LS_SYNC_STATUS, CH1_FFS_LS_SYNC_STATUS, CH0_FFS_CC_UNDERRUN, CH1_FFS_CC_UNDERRUN, CH0_FFS_CC_OVERRUN, CH1_FFS_CC_OVERRUN, - output CH0_FFS_RXFBFIFO_ERROR, CH1_FFS_RXFBFIFO_ERROR, CH0_FFS_TXFBFIFO_ERROR, CH1_FFS_TXFBFIFO_ERROR, CH0_FFS_RLOL, CH1_FFS_RLOL, CH0_FFS_SKP_ADDED, CH1_FFS_SKP_ADDED, - output CH0_FFS_SKP_DELETED, CH1_FFS_SKP_DELETED, CH0_LDR_RX2CORE, CH1_LDR_RX2CORE, D_SCIRDATA0, D_SCIRDATA1, D_SCIRDATA2, D_SCIRDATA3, - output D_SCIRDATA4, D_SCIRDATA5, D_SCIRDATA6, D_SCIRDATA7, D_SCIINT, D_SCAN_OUT_0, D_SCAN_OUT_1, D_SCAN_OUT_2, D_SCAN_OUT_3, D_SCAN_OUT_4, D_SCAN_OUT_5, D_SCAN_OUT_6, D_SCAN_OUT_7, - output D_COUT0, D_COUT1, D_COUT2, D_COUT3, D_COUT4, D_COUT5, D_COUT6, D_COUT7, D_COUT8, D_COUT9, D_COUT10, D_COUT11, D_COUT12, D_COUT13, D_COUT14, D_COUT15, D_COUT16, D_COUT17, D_COUT18, D_COUT19, - - input D_REFCLKI, - output D_FFS_PLOL -); - parameter CH0_AUTO_CALIB_EN = "0b0"; - parameter CH0_AUTO_FACQ_EN = "0b0"; - parameter CH0_BAND_THRESHOLD = "0b000000"; - parameter CH0_CALIB_CK_MODE = "0b0"; - parameter CH0_CC_MATCH_1 = "0b0000000000"; - parameter CH0_CC_MATCH_2 = "0b0000000000"; - parameter CH0_CC_MATCH_3 = "0b0000000000"; - parameter CH0_CC_MATCH_4 = "0b0000000000"; - parameter CH0_CDR_CNT4SEL = "0b00"; - parameter CH0_CDR_CNT8SEL = "0b00"; - parameter CH0_CTC_BYPASS = "0b0"; - parameter CH0_DCOATDCFG = "0b00"; - parameter CH0_DCOATDDLY = "0b00"; - parameter CH0_DCOBYPSATD = "0b0"; - parameter CH0_DCOCALDIV = "0b000"; - parameter CH0_DCOCTLGI = "0b000"; - parameter CH0_DCODISBDAVOID = "0b0"; - parameter CH0_DCOFLTDAC = "0b00"; - parameter CH0_DCOFTNRG = "0b000"; - parameter CH0_DCOIOSTUNE = "0b000"; - parameter CH0_DCOITUNE = "0b00"; - parameter CH0_DCOITUNE4LSB = "0b000"; - parameter CH0_DCOIUPDNX2 = "0b0"; - parameter CH0_DCONUOFLSB = "0b000"; - parameter CH0_DCOSCALEI = "0b00"; - parameter CH0_DCOSTARTVAL = "0b000"; - parameter CH0_DCOSTEP = "0b00"; - parameter CH0_DEC_BYPASS = "0b0"; - parameter CH0_ENABLE_CG_ALIGN = "0b0"; - parameter CH0_ENC_BYPASS = "0b0"; - parameter CH0_FF_RX_F_CLK_DIS = "0b0"; - parameter CH0_FF_RX_H_CLK_EN = "0b0"; - parameter CH0_FF_TX_F_CLK_DIS = "0b0"; - parameter CH0_FF_TX_H_CLK_EN = "0b0"; - parameter CH0_GE_AN_ENABLE = "0b0"; - parameter CH0_INVERT_RX = "0b0"; - parameter CH0_INVERT_TX = "0b0"; - parameter CH0_LDR_CORE2TX_SEL = "0b0"; - parameter CH0_LDR_RX2CORE_SEL = "0b0"; - parameter CH0_LEQ_OFFSET_SEL = "0b0"; - parameter CH0_LEQ_OFFSET_TRIM = "0b000"; - parameter CH0_LSM_DISABLE = "0b0"; - parameter CH0_MATCH_2_ENABLE = "0b0"; - parameter CH0_MATCH_4_ENABLE = "0b0"; - parameter CH0_MIN_IPG_CNT = "0b00"; - parameter CH0_PCIE_EI_EN = "0b0"; - parameter CH0_PCIE_MODE = "0b0"; - parameter CH0_PCS_DET_TIME_SEL = "0b00"; - parameter CH0_PDEN_SEL = "0b0"; - parameter CH0_PRBS_ENABLE = "0b0"; - parameter CH0_PRBS_LOCK = "0b0"; - parameter CH0_PRBS_SELECTION = "0b0"; - parameter CH0_RATE_MODE_RX = "0b0"; - parameter CH0_RATE_MODE_TX = "0b0"; - parameter CH0_RCV_DCC_EN = "0b0"; - parameter CH0_REG_BAND_OFFSET = "0b0000"; - parameter CH0_REG_BAND_SEL = "0b000000"; - parameter CH0_REG_IDAC_EN = "0b0"; - parameter CH0_REG_IDAC_SEL = "0b0000000000"; - parameter CH0_REQ_EN = "0b0"; - parameter CH0_REQ_LVL_SET = "0b00"; - parameter CH0_RIO_MODE = "0b0"; - parameter CH0_RLOS_SEL = "0b0"; - parameter CH0_RPWDNB = "0b0"; - parameter CH0_RTERM_RX = "0b00000"; - parameter CH0_RTERM_TX = "0b00000"; - parameter CH0_RXIN_CM = "0b00"; - parameter CH0_RXTERM_CM = "0b00"; - parameter CH0_RX_DCO_CK_DIV = "0b000"; - parameter CH0_RX_DIV11_SEL = "0b0"; - parameter CH0_RX_GEAR_BYPASS = "0b0"; - parameter CH0_RX_GEAR_MODE = "0b0"; - parameter CH0_RX_LOS_CEQ = "0b00"; - parameter CH0_RX_LOS_EN = "0b0"; - parameter CH0_RX_LOS_HYST_EN = "0b0"; - parameter CH0_RX_LOS_LVL = "0b000"; - parameter CH0_RX_RATE_SEL = "0b0000"; - parameter CH0_RX_SB_BYPASS = "0b0"; - parameter CH0_SB_BYPASS = "0b0"; - parameter CH0_SEL_SD_RX_CLK = "0b0"; - parameter CH0_TDRV_DAT_SEL = "0b00"; - parameter CH0_TDRV_POST_EN = "0b0"; - parameter CH0_TDRV_PRE_EN = "0b0"; - parameter CH0_TDRV_SLICE0_CUR = "0b000"; - parameter CH0_TDRV_SLICE0_SEL = "0b00"; - parameter CH0_TDRV_SLICE1_CUR = "0b000"; - parameter CH0_TDRV_SLICE1_SEL = "0b00"; - parameter CH0_TDRV_SLICE2_CUR = "0b00"; - parameter CH0_TDRV_SLICE2_SEL = "0b00"; - parameter CH0_TDRV_SLICE3_CUR = "0b00"; - parameter CH0_TDRV_SLICE3_SEL = "0b00"; - parameter CH0_TDRV_SLICE4_CUR = "0b00"; - parameter CH0_TDRV_SLICE4_SEL = "0b00"; - parameter CH0_TDRV_SLICE5_CUR = "0b00"; - parameter CH0_TDRV_SLICE5_SEL = "0b00"; - parameter CH0_TPWDNB = "0b0"; - parameter CH0_TX_CM_SEL = "0b00"; - parameter CH0_TX_DIV11_SEL = "0b0"; - parameter CH0_TX_GEAR_BYPASS = "0b0"; - parameter CH0_TX_GEAR_MODE = "0b0"; - parameter CH0_TX_POST_SIGN = "0b0"; - parameter CH0_TX_PRE_SIGN = "0b0"; - parameter CH0_UC_MODE = "0b0"; - parameter CH0_UDF_COMMA_A = "0b0000000000"; - parameter CH0_UDF_COMMA_B = "0b0000000000"; - parameter CH0_UDF_COMMA_MASK = "0b0000000000"; - parameter CH0_WA_BYPASS = "0b0"; - parameter CH0_WA_MODE = "0b0"; - parameter CH1_AUTO_CALIB_EN = "0b0"; - parameter CH1_AUTO_FACQ_EN = "0b0"; - parameter CH1_BAND_THRESHOLD = "0b000000"; - parameter CH1_CALIB_CK_MODE = "0b0"; - parameter CH1_CC_MATCH_1 = "0b0000000000"; - parameter CH1_CC_MATCH_2 = "0b0000000000"; - parameter CH1_CC_MATCH_3 = "0b0000000000"; - parameter CH1_CC_MATCH_4 = "0b0000000000"; - parameter CH1_CDR_CNT4SEL = "0b00"; - parameter CH1_CDR_CNT8SEL = "0b00"; - parameter CH1_CTC_BYPASS = "0b0"; - parameter CH1_DCOATDCFG = "0b00"; - parameter CH1_DCOATDDLY = "0b00"; - parameter CH1_DCOBYPSATD = "0b0"; - parameter CH1_DCOCALDIV = "0b000"; - parameter CH1_DCOCTLGI = "0b000"; - parameter CH1_DCODISBDAVOID = "0b0"; - parameter CH1_DCOFLTDAC = "0b00"; - parameter CH1_DCOFTNRG = "0b000"; - parameter CH1_DCOIOSTUNE = "0b000"; - parameter CH1_DCOITUNE = "0b00"; - parameter CH1_DCOITUNE4LSB = "0b000"; - parameter CH1_DCOIUPDNX2 = "0b0"; - parameter CH1_DCONUOFLSB = "0b000"; - parameter CH1_DCOSCALEI = "0b00"; - parameter CH1_DCOSTARTVAL = "0b000"; - parameter CH1_DCOSTEP = "0b00"; - parameter CH1_DEC_BYPASS = "0b0"; - parameter CH1_ENABLE_CG_ALIGN = "0b0"; - parameter CH1_ENC_BYPASS = "0b0"; - parameter CH1_FF_RX_F_CLK_DIS = "0b0"; - parameter CH1_FF_RX_H_CLK_EN = "0b0"; - parameter CH1_FF_TX_F_CLK_DIS = "0b0"; - parameter CH1_FF_TX_H_CLK_EN = "0b0"; - parameter CH1_GE_AN_ENABLE = "0b0"; - parameter CH1_INVERT_RX = "0b0"; - parameter CH1_INVERT_TX = "0b0"; - parameter CH1_LDR_CORE2TX_SEL = "0b0"; - parameter CH1_LDR_RX2CORE_SEL = "0b0"; - parameter CH1_LEQ_OFFSET_SEL = "0b0"; - parameter CH1_LEQ_OFFSET_TRIM = "0b000"; - parameter CH1_LSM_DISABLE = "0b0"; - parameter CH1_MATCH_2_ENABLE = "0b0"; - parameter CH1_MATCH_4_ENABLE = "0b0"; - parameter CH1_MIN_IPG_CNT = "0b00"; - parameter CH1_PCIE_EI_EN = "0b0"; - parameter CH1_PCIE_MODE = "0b0"; - parameter CH1_PCS_DET_TIME_SEL = "0b00"; - parameter CH1_PDEN_SEL = "0b0"; - parameter CH1_PRBS_ENABLE = "0b0"; - parameter CH1_PRBS_LOCK = "0b0"; - parameter CH1_PRBS_SELECTION = "0b0"; - parameter CH1_RATE_MODE_RX = "0b0"; - parameter CH1_RATE_MODE_TX = "0b0"; - parameter CH1_RCV_DCC_EN = "0b0"; - parameter CH1_REG_BAND_OFFSET = "0b0000"; - parameter CH1_REG_BAND_SEL = "0b000000"; - parameter CH1_REG_IDAC_EN = "0b0"; - parameter CH1_REG_IDAC_SEL = "0b0000000000"; - parameter CH1_REQ_EN = "0b0"; - parameter CH1_REQ_LVL_SET = "0b00"; - parameter CH1_RIO_MODE = "0b0"; - parameter CH1_RLOS_SEL = "0b0"; - parameter CH1_RPWDNB = "0b0"; - parameter CH1_RTERM_RX = "0b00000"; - parameter CH1_RTERM_TX = "0b00000"; - parameter CH1_RXIN_CM = "0b00"; - parameter CH1_RXTERM_CM = "0b00"; - parameter CH1_RX_DCO_CK_DIV = "0b000"; - parameter CH1_RX_DIV11_SEL = "0b0"; - parameter CH1_RX_GEAR_BYPASS = "0b0"; - parameter CH1_RX_GEAR_MODE = "0b0"; - parameter CH1_RX_LOS_CEQ = "0b00"; - parameter CH1_RX_LOS_EN = "0b0"; - parameter CH1_RX_LOS_HYST_EN = "0b0"; - parameter CH1_RX_LOS_LVL = "0b000"; - parameter CH1_RX_RATE_SEL = "0b0000"; - parameter CH1_RX_SB_BYPASS = "0b0"; - parameter CH1_SB_BYPASS = "0b0"; - parameter CH1_SEL_SD_RX_CLK = "0b0"; - parameter CH1_TDRV_DAT_SEL = "0b00"; - parameter CH1_TDRV_POST_EN = "0b0"; - parameter CH1_TDRV_PRE_EN = "0b0"; - parameter CH1_TDRV_SLICE0_CUR = "0b000"; - parameter CH1_TDRV_SLICE0_SEL = "0b00"; - parameter CH1_TDRV_SLICE1_CUR = "0b000"; - parameter CH1_TDRV_SLICE1_SEL = "0b00"; - parameter CH1_TDRV_SLICE2_CUR = "0b00"; - parameter CH1_TDRV_SLICE2_SEL = "0b00"; - parameter CH1_TDRV_SLICE3_CUR = "0b00"; - parameter CH1_TDRV_SLICE3_SEL = "0b00"; - parameter CH1_TDRV_SLICE4_CUR = "0b00"; - parameter CH1_TDRV_SLICE4_SEL = "0b00"; - parameter CH1_TDRV_SLICE5_CUR = "0b00"; - parameter CH1_TDRV_SLICE5_SEL = "0b00"; - parameter CH1_TPWDNB = "0b0"; - parameter CH1_TX_CM_SEL = "0b00"; - parameter CH1_TX_DIV11_SEL = "0b0"; - parameter CH1_TX_GEAR_BYPASS = "0b0"; - parameter CH1_TX_GEAR_MODE = "0b0"; - parameter CH1_TX_POST_SIGN = "0b0"; - parameter CH1_TX_PRE_SIGN = "0b0"; - parameter CH1_UC_MODE = "0b0"; - parameter CH1_UDF_COMMA_A = "0b0000000000"; - parameter CH1_UDF_COMMA_B = "0b0000000000"; - parameter CH1_UDF_COMMA_MASK = "0b0000000000"; - parameter CH1_WA_BYPASS = "0b0"; - parameter CH1_WA_MODE = "0b0"; - parameter D_BITCLK_FROM_ND_EN = "0b0"; - parameter D_BITCLK_LOCAL_EN = "0b0"; - parameter D_BITCLK_ND_EN = "0b0"; - parameter D_BUS8BIT_SEL = "0b0"; - parameter D_CDR_LOL_SET = "0b00"; - parameter D_CMUSETBIASI = "0b00"; - parameter D_CMUSETI4CPP = "0b0000"; - parameter D_CMUSETI4CPZ = "0b0000"; - parameter D_CMUSETI4VCO = "0b00"; - parameter D_CMUSETICP4P = "0b00"; - parameter D_CMUSETICP4Z = "0b000"; - parameter D_CMUSETINITVCT = "0b00"; - parameter D_CMUSETISCL4VCO = "0b000"; - parameter D_CMUSETP1GM = "0b000"; - parameter D_CMUSETP2AGM = "0b000"; - parameter D_CMUSETZGM = "0b000"; - parameter D_DCO_CALIB_TIME_SEL = "0b00"; - parameter D_HIGH_MARK = "0b0000"; - parameter D_IB_PWDNB = "0b0"; - parameter D_ISETLOS = "0b00000000"; - parameter D_LOW_MARK = "0b0000"; - parameter D_MACROPDB = "0b0"; - parameter D_PD_ISET = "0b00"; - parameter D_PLL_LOL_SET = "0b00"; - parameter D_REFCK_MODE = "0b000"; - parameter D_REQ_ISET = "0b000"; - parameter D_RG_EN = "0b0"; - parameter D_RG_SET = "0b00"; - parameter D_SETICONST_AUX = "0b00"; - parameter D_SETICONST_CH = "0b00"; - parameter D_SETIRPOLY_AUX = "0b00"; - parameter D_SETIRPOLY_CH = "0b00"; - parameter D_SETPLLRC = "0b000000"; - parameter D_SYNC_LOCAL_EN = "0b0"; - parameter D_SYNC_ND_EN = "0b0"; - parameter D_TXPLL_PWDNB = "0b0"; - parameter D_TX_VCO_CK_DIV = "0b000"; - parameter D_XGE_MODE = "0b0"; - -// These parameters don't do anything but are -// needed for compatibility with Diamond - parameter D_TX_MAX_RATE = "2.5"; - parameter D_RX_MAX_RATE = "2.5"; - parameter CH0_TXAMPLITUDE = "0d1300"; - parameter CH1_TXAMPLITUDE = "0d1300"; - parameter CH0_PROTOCOL = "8B10B"; - parameter CH1_PROTOCOL = "8B10B"; - parameter CH0_CDR_MAX_RATE = "2.5"; - parameter CH1_CDR_MAX_RATE = "2.5"; - parameter CH0_TXDEPRE = "DISABLED"; - parameter CH1_TXDEPRE = "DISABLED"; - parameter CH0_TXDEPOST = "DISABLED"; - parameter CH1_TXDEPOST = "DISABLED"; +(* blackbox *) +module ODDRX2DQSB (...); + parameter GSR = "ENABLED"; + input D3; + input D2; + input D1; + input D0; + input SCLK; + input ECLK; + input DQSW; + input RST; + output Q; endmodule (* blackbox *) -module EXTREFB ( - (* iopad_external_pin *) - input REFCLKP, - (* iopad_external_pin *) - input REFCLKN, - output REFCLKO -); - parameter REFCK_PWDNB = "0b0"; - parameter REFCK_RTERM = "0b0"; - parameter REFCK_DCBIAS_EN = "0b0"; +module EHXPLLL (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "DISABLED"; + parameter CLKOS2_ENABLE = "DISABLED"; + parameter CLKOS3_ENABLE = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter OUTDIVIDER_MUXA = "DIVA"; + parameter OUTDIVIDER_MUXB = "DIVB"; + parameter OUTDIVIDER_MUXC = "DIVC"; + parameter OUTDIVIDER_MUXD = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter PLL_LOCK_DELAY = 200; + parameter STDBY_ENABLE = "DISABLED"; + parameter REFIN_RESET = "DISABLED"; + parameter SYNC_ENABLE = "DISABLED"; + parameter INT_LOCK_STICKY = "ENABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input PHASELOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output CLKINTFB; endmodule (* blackbox *) -module PCSCLKDIV ( - input CLKI, RST, SEL2, SEL1, SEL0, - output CDIV1, CDIVX -); - parameter GSR = "DISABLED"; +module DTR (...); + parameter DTR_TEMP = 25; + input STARTPULSE; + output DTROUT7; + output DTROUT6; + output DTROUT5; + output DTROUT4; + output DTROUT3; + output DTROUT2; + output DTROUT1; + output DTROUT0; endmodule -// Note: this module is not marked keep as we want it swept away in synth (sim use only) (* blackbox *) -module PUR ( - input PUR -); - parameter RST_PULSE = 1; +module OSCG (...); + parameter DIV = 128; + output OSC; endmodule -(* blackbox, keep *) -module GSR ( - input GSR -); +(* blackbox *) +module EXTREFB (...); + parameter REFCK_PWDNB = "DONTCARE"; + parameter REFCK_RTERM = "DONTCARE"; + parameter REFCK_DCBIAS_EN = "DONTCARE"; + (* iopad_external_pin *) + input REFCLKP; + (* iopad_external_pin *) + input REFCLKN; + output REFCLKO; + output ; endmodule -(* blackbox, keep *) -module SGSR ( - input GSR, CLK -); +(* blackbox *) (* keep *) +module JTAGG (...); + parameter ER1 = "ENABLED"; + parameter ER2 = "ENABLED"; + (* iopad_external_pin *) + input TCK; + (* iopad_external_pin *) + input TMS; + (* iopad_external_pin *) + input TDI; + input JTDO2; + input JTDO1; + (* iopad_external_pin *) + output TDO; + output JTDI; + output JTCK; + output JRTI2; + output JRTI1; + output JSHIFT; + output JUPDATE; + output JRSTN; + output JCE2; + output JCE1; endmodule - -(* blackbox *) -module PDPW16KD ( - input DI35, DI34, DI33, DI32, DI31, DI30, DI29, DI28, DI27, DI26, DI25, DI24, DI23, DI22, DI21, DI20, DI19, DI18, - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE3, BE2, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, - input ADR13, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO35, DO34, DO33, DO32, DO31, DO30, DO29, DO28, DO27, DO26, DO25, DO24, DO23, DO22, DO21, DO20, DO19, DO18, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); - parameter DATA_WIDTH_W = 36; - parameter DATA_WIDTH_R = 36; - parameter GSR = "ENABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_W = "0b000"; - parameter CSDECODE_R = "0b000"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - parameter CLKWMUX = "CLKW"; - parameter CLKRMUX = "CLKR"; - +(* blackbox *) (* keep *) +module DCUA (...); + parameter D_MACROPDB = "DONTCARE"; + parameter D_IB_PWDNB = "DONTCARE"; + parameter D_XGE_MODE = "DONTCARE"; + parameter D_LOW_MARK = "DONTCARE"; + parameter D_HIGH_MARK = "DONTCARE"; + parameter D_BUS8BIT_SEL = "DONTCARE"; + parameter D_CDR_LOL_SET = "DONTCARE"; + parameter D_BITCLK_LOCAL_EN = "DONTCARE"; + parameter D_BITCLK_ND_EN = "DONTCARE"; + parameter D_BITCLK_FROM_ND_EN = "DONTCARE"; + parameter D_SYNC_LOCAL_EN = "DONTCARE"; + parameter D_SYNC_ND_EN = "DONTCARE"; + parameter CH0_UC_MODE = "DONTCARE"; + parameter CH1_UC_MODE = "DONTCARE"; + parameter CH0_PCIE_MODE = "DONTCARE"; + parameter CH1_PCIE_MODE = "DONTCARE"; + parameter CH0_RIO_MODE = "DONTCARE"; + parameter CH1_RIO_MODE = "DONTCARE"; + parameter CH0_WA_MODE = "DONTCARE"; + parameter CH1_WA_MODE = "DONTCARE"; + parameter CH0_INVERT_RX = "DONTCARE"; + parameter CH1_INVERT_RX = "DONTCARE"; + parameter CH0_INVERT_TX = "DONTCARE"; + parameter CH1_INVERT_TX = "DONTCARE"; + parameter CH0_PRBS_SELECTION = "DONTCARE"; + parameter CH1_PRBS_SELECTION = "DONTCARE"; + parameter CH0_GE_AN_ENABLE = "DONTCARE"; + parameter CH1_GE_AN_ENABLE = "DONTCARE"; + parameter CH0_PRBS_LOCK = "DONTCARE"; + parameter CH1_PRBS_LOCK = "DONTCARE"; + parameter CH0_PRBS_ENABLE = "DONTCARE"; + parameter CH1_PRBS_ENABLE = "DONTCARE"; + parameter CH0_ENABLE_CG_ALIGN = "DONTCARE"; + parameter CH1_ENABLE_CG_ALIGN = "DONTCARE"; + parameter CH0_TX_GEAR_MODE = "DONTCARE"; + parameter CH1_TX_GEAR_MODE = "DONTCARE"; + parameter CH0_RX_GEAR_MODE = "DONTCARE"; + parameter CH1_RX_GEAR_MODE = "DONTCARE"; + parameter CH0_PCS_DET_TIME_SEL = "DONTCARE"; + parameter CH1_PCS_DET_TIME_SEL = "DONTCARE"; + parameter CH0_PCIE_EI_EN = "DONTCARE"; + parameter CH1_PCIE_EI_EN = "DONTCARE"; + parameter CH0_TX_GEAR_BYPASS = "DONTCARE"; + parameter CH1_TX_GEAR_BYPASS = "DONTCARE"; + parameter CH0_ENC_BYPASS = "DONTCARE"; + parameter CH1_ENC_BYPASS = "DONTCARE"; + parameter CH0_SB_BYPASS = "DONTCARE"; + parameter CH1_SB_BYPASS = "DONTCARE"; + parameter CH0_RX_SB_BYPASS = "DONTCARE"; + parameter CH1_RX_SB_BYPASS = "DONTCARE"; + parameter CH0_WA_BYPASS = "DONTCARE"; + parameter CH1_WA_BYPASS = "DONTCARE"; + parameter CH0_DEC_BYPASS = "DONTCARE"; + parameter CH1_DEC_BYPASS = "DONTCARE"; + parameter CH0_CTC_BYPASS = "DONTCARE"; + parameter CH1_CTC_BYPASS = "DONTCARE"; + parameter CH0_RX_GEAR_BYPASS = "DONTCARE"; + parameter CH1_RX_GEAR_BYPASS = "DONTCARE"; + parameter CH0_LSM_DISABLE = "DONTCARE"; + parameter CH1_LSM_DISABLE = "DONTCARE"; + parameter CH0_MATCH_2_ENABLE = "DONTCARE"; + parameter CH1_MATCH_2_ENABLE = "DONTCARE"; + parameter CH0_MATCH_4_ENABLE = "DONTCARE"; + parameter CH1_MATCH_4_ENABLE = "DONTCARE"; + parameter CH0_MIN_IPG_CNT = "DONTCARE"; + parameter CH1_MIN_IPG_CNT = "DONTCARE"; + parameter CH0_CC_MATCH_1 = "DONTCARE"; + parameter CH1_CC_MATCH_1 = "DONTCARE"; + parameter CH0_CC_MATCH_2 = "DONTCARE"; + parameter CH1_CC_MATCH_2 = "DONTCARE"; + parameter CH0_CC_MATCH_3 = "DONTCARE"; + parameter CH1_CC_MATCH_3 = "DONTCARE"; + parameter CH0_CC_MATCH_4 = "DONTCARE"; + parameter CH1_CC_MATCH_4 = "DONTCARE"; + parameter CH0_UDF_COMMA_MASK = "DONTCARE"; + parameter CH1_UDF_COMMA_MASK = "DONTCARE"; + parameter CH0_UDF_COMMA_A = "DONTCARE"; + parameter CH1_UDF_COMMA_A = "DONTCARE"; + parameter CH0_UDF_COMMA_B = "DONTCARE"; + parameter CH1_UDF_COMMA_B = "DONTCARE"; + parameter CH0_RX_DCO_CK_DIV = "DONTCARE"; + parameter CH1_RX_DCO_CK_DIV = "DONTCARE"; + parameter CH0_RCV_DCC_EN = "DONTCARE"; + parameter CH1_RCV_DCC_EN = "DONTCARE"; + parameter CH0_REQ_LVL_SET = "DONTCARE"; + parameter CH1_REQ_LVL_SET = "DONTCARE"; + parameter CH0_REQ_EN = "DONTCARE"; + parameter CH1_REQ_EN = "DONTCARE"; + parameter CH0_RTERM_RX = "DONTCARE"; + parameter CH1_RTERM_RX = "DONTCARE"; + parameter CH0_PDEN_SEL = "DONTCARE"; + parameter CH1_PDEN_SEL = "DONTCARE"; + parameter CH0_LDR_RX2CORE_SEL = "DONTCARE"; + parameter CH1_LDR_RX2CORE_SEL = "DONTCARE"; + parameter CH0_LDR_CORE2TX_SEL = "DONTCARE"; + parameter CH1_LDR_CORE2TX_SEL = "DONTCARE"; + parameter CH0_TPWDNB = "DONTCARE"; + parameter CH1_TPWDNB = "DONTCARE"; + parameter CH0_RATE_MODE_TX = "DONTCARE"; + parameter CH1_RATE_MODE_TX = "DONTCARE"; + parameter CH0_RTERM_TX = "DONTCARE"; + parameter CH1_RTERM_TX = "DONTCARE"; + parameter CH0_TX_CM_SEL = "DONTCARE"; + parameter CH1_TX_CM_SEL = "DONTCARE"; + parameter CH0_TDRV_PRE_EN = "DONTCARE"; + parameter CH1_TDRV_PRE_EN = "DONTCARE"; + parameter CH0_TDRV_SLICE0_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE0_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE1_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE1_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE2_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE2_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE3_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE3_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE4_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE4_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE5_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE5_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE0_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE0_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE1_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE1_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE2_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE2_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE3_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE3_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE4_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE4_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE5_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE5_CUR = "DONTCARE"; + parameter CH0_TDRV_DAT_SEL = "DONTCARE"; + parameter CH1_TDRV_DAT_SEL = "DONTCARE"; + parameter CH0_TX_DIV11_SEL = "DONTCARE"; + parameter CH1_TX_DIV11_SEL = "DONTCARE"; + parameter CH0_RPWDNB = "DONTCARE"; + parameter CH1_RPWDNB = "DONTCARE"; + parameter CH0_RATE_MODE_RX = "DONTCARE"; + parameter CH1_RATE_MODE_RX = "DONTCARE"; + parameter CH0_RLOS_SEL = "DONTCARE"; + parameter CH1_RLOS_SEL = "DONTCARE"; + parameter CH0_RX_LOS_LVL = "DONTCARE"; + parameter CH1_RX_LOS_LVL = "DONTCARE"; + parameter CH0_RX_LOS_CEQ = "DONTCARE"; + parameter CH1_RX_LOS_CEQ = "DONTCARE"; + parameter CH0_RX_LOS_HYST_EN = "DONTCARE"; + parameter CH1_RX_LOS_HYST_EN = "DONTCARE"; + parameter CH0_RX_LOS_EN = "DONTCARE"; + parameter CH1_RX_LOS_EN = "DONTCARE"; + parameter CH0_RX_DIV11_SEL = "DONTCARE"; + parameter CH1_RX_DIV11_SEL = "DONTCARE"; + parameter CH0_SEL_SD_RX_CLK = "DONTCARE"; + parameter CH1_SEL_SD_RX_CLK = "DONTCARE"; + parameter CH0_FF_RX_H_CLK_EN = "DONTCARE"; + parameter CH1_FF_RX_H_CLK_EN = "DONTCARE"; + parameter CH0_FF_RX_F_CLK_DIS = "DONTCARE"; + parameter CH1_FF_RX_F_CLK_DIS = "DONTCARE"; + parameter CH0_FF_TX_H_CLK_EN = "DONTCARE"; + parameter CH1_FF_TX_H_CLK_EN = "DONTCARE"; + parameter CH0_FF_TX_F_CLK_DIS = "DONTCARE"; + parameter CH1_FF_TX_F_CLK_DIS = "DONTCARE"; + parameter CH0_RX_RATE_SEL = "DONTCARE"; + parameter CH1_RX_RATE_SEL = "DONTCARE"; + parameter CH0_TDRV_POST_EN = "DONTCARE"; + parameter CH1_TDRV_POST_EN = "DONTCARE"; + parameter CH0_TX_POST_SIGN = "DONTCARE"; + parameter CH1_TX_POST_SIGN = "DONTCARE"; + parameter CH0_TX_PRE_SIGN = "DONTCARE"; + parameter CH1_TX_PRE_SIGN = "DONTCARE"; + parameter CH0_RXTERM_CM = "DONTCARE"; + parameter CH1_RXTERM_CM = "DONTCARE"; + parameter CH0_RXIN_CM = "DONTCARE"; + parameter CH1_RXIN_CM = "DONTCARE"; + parameter CH0_LEQ_OFFSET_SEL = "DONTCARE"; + parameter CH1_LEQ_OFFSET_SEL = "DONTCARE"; + parameter CH0_LEQ_OFFSET_TRIM = "DONTCARE"; + parameter CH1_LEQ_OFFSET_TRIM = "DONTCARE"; + parameter D_TX_MAX_RATE = "DONTCARE"; + parameter CH0_CDR_MAX_RATE = "DONTCARE"; + parameter CH1_CDR_MAX_RATE = "DONTCARE"; + parameter CH0_TXAMPLITUDE = "DONTCARE"; + parameter CH1_TXAMPLITUDE = "DONTCARE"; + parameter CH0_TXDEPRE = "DONTCARE"; + parameter CH1_TXDEPRE = "DONTCARE"; + parameter CH0_TXDEPOST = "DONTCARE"; + parameter CH1_TXDEPOST = "DONTCARE"; + parameter CH0_PROTOCOL = "DONTCARE"; + parameter CH1_PROTOCOL = "DONTCARE"; + parameter D_ISETLOS = "DONTCARE"; + parameter D_SETIRPOLY_AUX = "DONTCARE"; + parameter D_SETICONST_AUX = "DONTCARE"; + parameter D_SETIRPOLY_CH = "DONTCARE"; + parameter D_SETICONST_CH = "DONTCARE"; + parameter D_REQ_ISET = "DONTCARE"; + parameter D_PD_ISET = "DONTCARE"; + parameter D_DCO_CALIB_TIME_SEL = "DONTCARE"; + parameter CH0_DCOCTLGI = "DONTCARE"; + parameter CH1_DCOCTLGI = "DONTCARE"; + parameter CH0_DCOATDDLY = "DONTCARE"; + parameter CH1_DCOATDDLY = "DONTCARE"; + parameter CH0_DCOATDCFG = "DONTCARE"; + parameter CH1_DCOATDCFG = "DONTCARE"; + parameter CH0_DCOBYPSATD = "DONTCARE"; + parameter CH1_DCOBYPSATD = "DONTCARE"; + parameter CH0_DCOSCALEI = "DONTCARE"; + parameter CH1_DCOSCALEI = "DONTCARE"; + parameter CH0_DCOITUNE4LSB = "DONTCARE"; + parameter CH1_DCOITUNE4LSB = "DONTCARE"; + parameter CH0_DCOIOSTUNE = "DONTCARE"; + parameter CH1_DCOIOSTUNE = "DONTCARE"; + parameter CH0_DCODISBDAVOID = "DONTCARE"; + parameter CH1_DCODISBDAVOID = "DONTCARE"; + parameter CH0_DCOCALDIV = "DONTCARE"; + parameter CH1_DCOCALDIV = "DONTCARE"; + parameter CH0_DCONUOFLSB = "DONTCARE"; + parameter CH1_DCONUOFLSB = "DONTCARE"; + parameter CH0_DCOIUPDNX2 = "DONTCARE"; + parameter CH1_DCOIUPDNX2 = "DONTCARE"; + parameter CH0_DCOSTEP = "DONTCARE"; + parameter CH1_DCOSTEP = "DONTCARE"; + parameter CH0_DCOSTARTVAL = "DONTCARE"; + parameter CH1_DCOSTARTVAL = "DONTCARE"; + parameter CH0_DCOFLTDAC = "DONTCARE"; + parameter CH1_DCOFLTDAC = "DONTCARE"; + parameter CH0_DCOITUNE = "DONTCARE"; + parameter CH1_DCOITUNE = "DONTCARE"; + parameter CH0_DCOFTNRG = "DONTCARE"; + parameter CH1_DCOFTNRG = "DONTCARE"; + parameter CH0_CDR_CNT4SEL = "DONTCARE"; + parameter CH1_CDR_CNT4SEL = "DONTCARE"; + parameter CH0_CDR_CNT8SEL = "DONTCARE"; + parameter CH1_CDR_CNT8SEL = "DONTCARE"; + parameter CH0_BAND_THRESHOLD = "DONTCARE"; + parameter CH1_BAND_THRESHOLD = "DONTCARE"; + parameter CH0_AUTO_FACQ_EN = "DONTCARE"; + parameter CH1_AUTO_FACQ_EN = "DONTCARE"; + parameter CH0_AUTO_CALIB_EN = "DONTCARE"; + parameter CH1_AUTO_CALIB_EN = "DONTCARE"; + parameter CH0_CALIB_CK_MODE = "DONTCARE"; + parameter CH1_CALIB_CK_MODE = "DONTCARE"; + parameter CH0_REG_BAND_OFFSET = "DONTCARE"; + parameter CH1_REG_BAND_OFFSET = "DONTCARE"; + parameter CH0_REG_BAND_SEL = "DONTCARE"; + parameter CH1_REG_BAND_SEL = "DONTCARE"; + parameter CH0_REG_IDAC_SEL = "DONTCARE"; + parameter CH1_REG_IDAC_SEL = "DONTCARE"; + parameter CH0_REG_IDAC_EN = "DONTCARE"; + parameter CH1_REG_IDAC_EN = "DONTCARE"; + parameter D_TXPLL_PWDNB = "DONTCARE"; + parameter D_SETPLLRC = "DONTCARE"; + parameter D_REFCK_MODE = "DONTCARE"; + parameter D_TX_VCO_CK_DIV = "DONTCARE"; + parameter D_PLL_LOL_SET = "DONTCARE"; + parameter D_RG_EN = "DONTCARE"; + parameter D_RG_SET = "DONTCARE"; + parameter D_CMUSETISCL4VCO = "DONTCARE"; + parameter D_CMUSETI4VCO = "DONTCARE"; + parameter D_CMUSETINITVCT = "DONTCARE"; + parameter D_CMUSETZGM = "DONTCARE"; + parameter D_CMUSETP2AGM = "DONTCARE"; + parameter D_CMUSETP1GM = "DONTCARE"; + parameter D_CMUSETI4CPZ = "DONTCARE"; + parameter D_CMUSETI4CPP = "DONTCARE"; + parameter D_CMUSETICP4Z = "DONTCARE"; + parameter D_CMUSETICP4P = "DONTCARE"; + parameter D_CMUSETBIASI = "DONTCARE"; + (* iopad_external_pin *) + (* iopad_external_pin *) + input CH0_HDINP; + (* iopad_external_pin *) + input CH1_HDINP; + (* iopad_external_pin *) + input CH0_HDINN; + (* iopad_external_pin *) + input CH1_HDINN; + input D_TXBIT_CLKP_FROM_ND; + input D_TXBIT_CLKN_FROM_ND; + input D_SYNC_ND; + input D_TXPLL_LOL_FROM_ND; + input CH0_RX_REFCLK; + input CH1_RX_REFCLK; + input CH0_FF_RXI_CLK; + input CH1_FF_RXI_CLK; + input CH0_FF_TXI_CLK; + input CH1_FF_TXI_CLK; + input CH0_FF_EBRD_CLK; + input CH1_FF_EBRD_CLK; + input CH0_FF_TX_D_0; + input CH1_FF_TX_D_0; + input CH0_FF_TX_D_1; + input CH1_FF_TX_D_1; + input CH0_FF_TX_D_2; + input CH1_FF_TX_D_2; + input CH0_FF_TX_D_3; + input CH1_FF_TX_D_3; + input CH0_FF_TX_D_4; + input CH1_FF_TX_D_4; + input CH0_FF_TX_D_5; + input CH1_FF_TX_D_5; + input CH0_FF_TX_D_6; + input CH1_FF_TX_D_6; + input CH0_FF_TX_D_7; + input CH1_FF_TX_D_7; + input CH0_FF_TX_D_8; + input CH1_FF_TX_D_8; + input CH0_FF_TX_D_9; + input CH1_FF_TX_D_9; + input CH0_FF_TX_D_10; + input CH1_FF_TX_D_10; + input CH0_FF_TX_D_11; + input CH1_FF_TX_D_11; + input CH0_FF_TX_D_12; + input CH1_FF_TX_D_12; + input CH0_FF_TX_D_13; + input CH1_FF_TX_D_13; + input CH0_FF_TX_D_14; + input CH1_FF_TX_D_14; + input CH0_FF_TX_D_15; + input CH1_FF_TX_D_15; + input CH0_FF_TX_D_16; + input CH1_FF_TX_D_16; + input CH0_FF_TX_D_17; + input CH1_FF_TX_D_17; + input CH0_FF_TX_D_18; + input CH1_FF_TX_D_18; + input CH0_FF_TX_D_19; + input CH1_FF_TX_D_19; + input CH0_FF_TX_D_20; + input CH1_FF_TX_D_20; + input CH0_FF_TX_D_21; + input CH1_FF_TX_D_21; + input CH0_FF_TX_D_22; + input CH1_FF_TX_D_22; + input CH0_FF_TX_D_23; + input CH1_FF_TX_D_23; + input CH0_FFC_EI_EN; + input CH1_FFC_EI_EN; + input CH0_FFC_PCIE_DET_EN; + input CH1_FFC_PCIE_DET_EN; + input CH0_FFC_PCIE_CT; + input CH1_FFC_PCIE_CT; + input CH0_FFC_SB_INV_RX; + input CH1_FFC_SB_INV_RX; + input CH0_FFC_ENABLE_CGALIGN; + input CH1_FFC_ENABLE_CGALIGN; + input CH0_FFC_SIGNAL_DETECT; + input CH1_FFC_SIGNAL_DETECT; + input CH0_FFC_FB_LOOPBACK; + input CH1_FFC_FB_LOOPBACK; + input CH0_FFC_SB_PFIFO_LP; + input CH1_FFC_SB_PFIFO_LP; + input CH0_FFC_PFIFO_CLR; + input CH1_FFC_PFIFO_CLR; + input CH0_FFC_RATE_MODE_RX; + input CH1_FFC_RATE_MODE_RX; + input CH0_FFC_RATE_MODE_TX; + input CH1_FFC_RATE_MODE_TX; + input CH0_FFC_DIV11_MODE_RX; + input CH1_FFC_DIV11_MODE_RX; + input CH0_FFC_RX_GEAR_MODE; + input CH1_FFC_RX_GEAR_MODE; + input CH0_FFC_TX_GEAR_MODE; + input CH1_FFC_TX_GEAR_MODE; + input CH0_FFC_DIV11_MODE_TX; + input CH1_FFC_DIV11_MODE_TX; + input CH0_FFC_LDR_CORE2TX_EN; + input CH1_FFC_LDR_CORE2TX_EN; + input CH0_FFC_LANE_TX_RST; + input CH1_FFC_LANE_TX_RST; + input CH0_FFC_LANE_RX_RST; + input CH1_FFC_LANE_RX_RST; + input CH0_FFC_RRST; + input CH1_FFC_RRST; + input CH0_FFC_TXPWDNB; + input CH1_FFC_TXPWDNB; + input CH0_FFC_RXPWDNB; + input CH1_FFC_RXPWDNB; + input CH0_LDR_CORE2TX; + input CH1_LDR_CORE2TX; + input D_SCIWDATA0; + input D_SCIWDATA1; + input D_SCIWDATA2; + input D_SCIWDATA3; + input D_SCIWDATA4; + input D_SCIWDATA5; + input D_SCIWDATA6; + input D_SCIWDATA7; + input D_SCIADDR0; + input D_SCIADDR1; + input D_SCIADDR2; + input D_SCIADDR3; + input D_SCIADDR4; + input D_SCIADDR5; + input D_SCIENAUX; + input D_SCISELAUX; + input CH0_SCIEN; + input CH1_SCIEN; + input CH0_SCISEL; + input CH1_SCISEL; + input D_SCIRD; + input D_SCIWSTN; + input D_CYAWSTN; + input D_FFC_SYNC_TOGGLE; + input D_FFC_DUAL_RST; + input D_FFC_MACRO_RST; + input D_FFC_MACROPDB; + input D_FFC_TRST; + input CH0_FFC_CDR_EN_BITSLIP; + input CH1_FFC_CDR_EN_BITSLIP; + input D_SCAN_ENABLE; + input D_SCAN_IN_0; + input D_SCAN_IN_1; + input D_SCAN_IN_2; + input D_SCAN_IN_3; + input D_SCAN_IN_4; + input D_SCAN_IN_5; + input D_SCAN_IN_6; + input D_SCAN_IN_7; + input D_SCAN_MODE; + input D_SCAN_RESET; + input D_CIN0; + input D_CIN1; + input D_CIN2; + input D_CIN3; + input D_CIN4; + input D_CIN5; + input D_CIN6; + input D_CIN7; + input D_CIN8; + input D_CIN9; + input D_CIN10; + input D_CIN11; + output CH0_HDOUTP; + output CH1_HDOUTP; + output CH0_HDOUTN; + output CH1_HDOUTN; + output D_TXBIT_CLKP_TO_ND; + output D_TXBIT_CLKN_TO_ND; + output D_SYNC_PULSE2ND; + output D_TXPLL_LOL_TO_ND; + output CH0_FF_RX_F_CLK; + output CH1_FF_RX_F_CLK; + output CH0_FF_RX_H_CLK; + output CH1_FF_RX_H_CLK; + output CH0_FF_TX_F_CLK; + output CH1_FF_TX_F_CLK; + output CH0_FF_TX_H_CLK; + output CH1_FF_TX_H_CLK; + output CH0_FF_RX_PCLK; + output CH1_FF_RX_PCLK; + output CH0_FF_TX_PCLK; + output CH1_FF_TX_PCLK; + output CH0_FF_RX_D_0; + output CH1_FF_RX_D_0; + output CH0_FF_RX_D_1; + output CH1_FF_RX_D_1; + output CH0_FF_RX_D_2; + output CH1_FF_RX_D_2; + output CH0_FF_RX_D_3; + output CH1_FF_RX_D_3; + output CH0_FF_RX_D_4; + output CH1_FF_RX_D_4; + output CH0_FF_RX_D_5; + output CH1_FF_RX_D_5; + output CH0_FF_RX_D_6; + output CH1_FF_RX_D_6; + output CH0_FF_RX_D_7; + output CH1_FF_RX_D_7; + output CH0_FF_RX_D_8; + output CH1_FF_RX_D_8; + output CH0_FF_RX_D_9; + output CH1_FF_RX_D_9; + output CH0_FF_RX_D_10; + output CH1_FF_RX_D_10; + output CH0_FF_RX_D_11; + output CH1_FF_RX_D_11; + output CH0_FF_RX_D_12; + output CH1_FF_RX_D_12; + output CH0_FF_RX_D_13; + output CH1_FF_RX_D_13; + output CH0_FF_RX_D_14; + output CH1_FF_RX_D_14; + output CH0_FF_RX_D_15; + output CH1_FF_RX_D_15; + output CH0_FF_RX_D_16; + output CH1_FF_RX_D_16; + output CH0_FF_RX_D_17; + output CH1_FF_RX_D_17; + output CH0_FF_RX_D_18; + output CH1_FF_RX_D_18; + output CH0_FF_RX_D_19; + output CH1_FF_RX_D_19; + output CH0_FF_RX_D_20; + output CH1_FF_RX_D_20; + output CH0_FF_RX_D_21; + output CH1_FF_RX_D_21; + output CH0_FF_RX_D_22; + output CH1_FF_RX_D_22; + output CH0_FF_RX_D_23; + output CH1_FF_RX_D_23; + output CH0_FFS_PCIE_DONE; + output CH1_FFS_PCIE_DONE; + output CH0_FFS_PCIE_CON; + output CH1_FFS_PCIE_CON; + output CH0_FFS_RLOS; + output CH1_FFS_RLOS; + output CH0_FFS_LS_SYNC_STATUS; + output CH1_FFS_LS_SYNC_STATUS; + output CH0_FFS_CC_UNDERRUN; + output CH1_FFS_CC_UNDERRUN; + output CH0_FFS_CC_OVERRUN; + output CH1_FFS_CC_OVERRUN; + output CH0_FFS_RXFBFIFO_ERROR; + output CH1_FFS_RXFBFIFO_ERROR; + output CH0_FFS_TXFBFIFO_ERROR; + output CH1_FFS_TXFBFIFO_ERROR; + output CH0_FFS_RLOL; + output CH1_FFS_RLOL; + output CH0_FFS_SKP_ADDED; + output CH1_FFS_SKP_ADDED; + output CH0_FFS_SKP_DELETED; + output CH1_FFS_SKP_DELETED; + output CH0_LDR_RX2CORE; + output CH1_LDR_RX2CORE; + output D_SCIRDATA0; + output D_SCIRDATA1; + output D_SCIRDATA2; + output D_SCIRDATA3; + output D_SCIRDATA4; + output D_SCIRDATA5; + output D_SCIRDATA6; + output D_SCIRDATA7; + output D_SCIINT; + output D_SCAN_OUT_0; + output D_SCAN_OUT_1; + output D_SCAN_OUT_2; + output D_SCAN_OUT_3; + output D_SCAN_OUT_4; + output D_SCAN_OUT_5; + output D_SCAN_OUT_6; + output D_SCAN_OUT_7; + output D_COUT0; + output D_COUT1; + output D_COUT2; + output D_COUT3; + output D_COUT4; + output D_COUT5; + output D_COUT6; + output D_COUT7; + output D_COUT8; + output D_COUT9; + output D_COUT10; + output D_COUT11; + output D_COUT12; + output D_COUT13; + output D_COUT14; + output D_COUT15; + output D_COUT16; + output D_COUT17; + output D_COUT18; + output D_COUT19; + input D_REFCLKI; + output D_FFS_PLOL; + output ; endmodule + diff --git a/techlibs/lattice/cells_bb_xo2.v b/techlibs/lattice/cells_bb_xo2.v index 3363ed5710d..6e6b655c919 100644 --- a/techlibs/lattice/cells_bb_xo2.v +++ b/techlibs/lattice/cells_bb_xo2.v @@ -1,179 +1,153 @@ -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; +// Created by cells_xtra.py from Lattice models - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); +module DP8KC (...); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module PDPW8KC (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b000"; parameter CSDECODE_R = "0b000"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -206,29 +180,90 @@ module PDPW8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module SP8KC (...); parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE = "0b000"; - parameter WRITEMODE = "NORMAL"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -261,33 +296,240 @@ module SP8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input AD12; + input AD11; + input AD10; + input AD9; + input AD8; + input AD7; + input AD6; + input AD5; + input AD4; + input AD3; + input AD2; + input AD1; + input AD0; + input CE; + input OCE; + input CLK; + input WE; + input CS2; + input CS1; + input CS0; + input RST; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); +module FIFO8KB (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - parameter REGMODE = "NOREG"; - parameter RESETMODE = "ASYNC"; parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b00"; parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; parameter FULLPOINTER1 = "0b00000000000000"; + parameter GSR = "DISABLED"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input CSW0; + input CSW1; + input CSR0; + input CSR1; + input WE; + input RE; + input ORE; + input CLKW; + input CLKR; + input RST; + input RPRST; + input FULLI; + input EMPTYI; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output EF; + output AEF; + output AFF; + output FF; +endmodule + +(* blackbox *) +module DCMA (...); + input CLK0; + input CLK1; + input SEL; + output DCMOUT; +endmodule + +(* blackbox *) +module DCCA (...); + input CLKI; + input CE; + output CLKO; +endmodule + +(* blackbox *) +module EHXPLLJ (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input LOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input RESETM; + input RESETC; + input RESETD; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input PLLCLK; + input PLLRST; + input PLLSTB; + input PLLWE; + input PLLDATI7; + input PLLDATI6; + input PLLDATI5; + input PLLDATI4; + input PLLDATI3; + input PLLDATI2; + input PLLDATI1; + input PLLDATI0; + input PLLADDR4; + input PLLADDR3; + input PLLADDR2; + input PLLADDR1; + input PLLADDR0; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output PLLDATO7; + output PLLDATO6; + output PLLDATO5; + output PLLDATO4; + output PLLDATO3; + output PLLDATO2; + output PLLDATO1; + output PLLDATO0; + output PLLACK; + output DPHSRC; + output CLKINTFB; endmodule + +(* blackbox *) +module OSCH (...); + parameter NOM_FREQ = "2.08"; + input STDBY; + output OSC; + output SEDSTDBY; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3.v b/techlibs/lattice/cells_bb_xo3.v index 3363ed5710d..6e6b655c919 100644 --- a/techlibs/lattice/cells_bb_xo3.v +++ b/techlibs/lattice/cells_bb_xo3.v @@ -1,179 +1,153 @@ -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; +// Created by cells_xtra.py from Lattice models - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); +module DP8KC (...); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module PDPW8KC (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b000"; parameter CSDECODE_R = "0b000"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -206,29 +180,90 @@ module PDPW8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module SP8KC (...); parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE = "0b000"; - parameter WRITEMODE = "NORMAL"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -261,33 +296,240 @@ module SP8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input AD12; + input AD11; + input AD10; + input AD9; + input AD8; + input AD7; + input AD6; + input AD5; + input AD4; + input AD3; + input AD2; + input AD1; + input AD0; + input CE; + input OCE; + input CLK; + input WE; + input CS2; + input CS1; + input CS0; + input RST; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); +module FIFO8KB (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - parameter REGMODE = "NOREG"; - parameter RESETMODE = "ASYNC"; parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b00"; parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; parameter FULLPOINTER1 = "0b00000000000000"; + parameter GSR = "DISABLED"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input CSW0; + input CSW1; + input CSR0; + input CSR1; + input WE; + input RE; + input ORE; + input CLKW; + input CLKR; + input RST; + input RPRST; + input FULLI; + input EMPTYI; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output EF; + output AEF; + output AFF; + output FF; +endmodule + +(* blackbox *) +module DCMA (...); + input CLK0; + input CLK1; + input SEL; + output DCMOUT; +endmodule + +(* blackbox *) +module DCCA (...); + input CLKI; + input CE; + output CLKO; +endmodule + +(* blackbox *) +module EHXPLLJ (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input LOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input RESETM; + input RESETC; + input RESETD; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input PLLCLK; + input PLLRST; + input PLLSTB; + input PLLWE; + input PLLDATI7; + input PLLDATI6; + input PLLDATI5; + input PLLDATI4; + input PLLDATI3; + input PLLDATI2; + input PLLDATI1; + input PLLDATI0; + input PLLADDR4; + input PLLADDR3; + input PLLADDR2; + input PLLADDR1; + input PLLADDR0; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output PLLDATO7; + output PLLDATO6; + output PLLDATO5; + output PLLDATO4; + output PLLDATO3; + output PLLDATO2; + output PLLDATO1; + output PLLDATO0; + output PLLACK; + output DPHSRC; + output CLKINTFB; endmodule + +(* blackbox *) +module OSCH (...); + parameter NOM_FREQ = "2.08"; + input STDBY; + output OSC; + output SEDSTDBY; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3d.v b/techlibs/lattice/cells_bb_xo3d.v index 3363ed5710d..c957b00293e 100644 --- a/techlibs/lattice/cells_bb_xo3d.v +++ b/techlibs/lattice/cells_bb_xo3d.v @@ -1,179 +1,153 @@ -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; +// Created by cells_xtra.py from Lattice models - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); +module DP8KC (...); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module PDPW8KC (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b000"; parameter CSDECODE_R = "0b000"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -206,29 +180,90 @@ module PDPW8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module SP8KC (...); parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE = "0b000"; - parameter WRITEMODE = "NORMAL"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -261,33 +296,241 @@ module SP8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input AD12; + input AD11; + input AD10; + input AD9; + input AD8; + input AD7; + input AD6; + input AD5; + input AD4; + input AD3; + input AD2; + input AD1; + input AD0; + input CE; + input OCE; + input CLK; + input WE; + input CS2; + input CS1; + input CS0; + input RST; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); +module FIFO8KB (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - parameter REGMODE = "NOREG"; - parameter RESETMODE = "ASYNC"; parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b00"; parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; parameter FULLPOINTER1 = "0b00000000000000"; + parameter GSR = "DISABLED"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input CSW0; + input CSW1; + input CSR0; + input CSR1; + input WE; + input RE; + input ORE; + input CLKW; + input CLKR; + input RST; + input RPRST; + input FULLI; + input EMPTYI; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output EF; + output AEF; + output AFF; + output FF; +endmodule + +(* blackbox *) +module DCMA (...); + input CLK0; + input CLK1; + input SEL; + output DCMOUT; +endmodule + +(* blackbox *) +module DCCA (...); + input CLKI; + input CE; + output CLKO; +endmodule + +(* blackbox *) +module EHXPLLJ (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input LOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input RESETM; + input RESETC; + input RESETD; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input PLLCLK; + input PLLRST; + input PLLSTB; + input PLLWE; + input PLLDATI7; + input PLLDATI6; + input PLLDATI5; + input PLLDATI4; + input PLLDATI3; + input PLLDATI2; + input PLLDATI1; + input PLLDATI0; + input PLLADDR4; + input PLLADDR3; + input PLLADDR2; + input PLLADDR1; + input PLLADDR0; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output PLLDATO7; + output PLLDATO6; + output PLLDATO5; + output PLLDATO4; + output PLLDATO3; + output PLLDATO2; + output PLLDATO1; + output PLLDATO0; + output PLLACK; + output DPHSRC; + output CLKINTFB; endmodule + +(* blackbox *) +module OSCJ (...); + parameter NOM_FREQ = "2.08"; + input STDBY; + output OSC; + output SEDSTDBY; + output OSCESB; +endmodule + diff --git a/techlibs/lattice/cells_xtra.py b/techlibs/lattice/cells_xtra.py new file mode 100644 index 00000000000..f2dd1f29749 --- /dev/null +++ b/techlibs/lattice/cells_xtra.py @@ -0,0 +1,854 @@ +#!/usr/bin/env python3 + +# Based on Xilinx cells_xtra.py; modified for Lattice's structure + +from argparse import ArgumentParser +from io import StringIO +from enum import Enum, auto +import os.path +import sys +import re + + +class Cell: + def __init__(self, name, keep=False, port_attrs={}): + self.name = name + self.keep = keep + self.port_attrs = port_attrs + self.found = False + +class State(Enum): + OUTSIDE = auto() + IN_MODULE = auto() + IN_OTHER_MODULE = auto() + IN_FUNCTION = auto() + IN_TASK = auto() + +devices = [ + ("cells_bb_ecp5.v", "ecp5u", [ + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("CCU2C"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("PFUMX"), + Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + Cell("SGSR", True), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + Cell("DP16KD"), + Cell("PDPW16KD"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + #Cell("LVDSOB"), + #Cell("IMIPI"), + #Cell("MULT9X9C"), + #Cell("MULT9X9D"), + #Cell("MULT18X18C"), + Cell("MULT18X18D"), + #Cell("ALU24A"), + #Cell("ALU54A"), + #Cell("ALU24B"), + Cell("ALU54B"), + #Cell("PRADD9A"), + #Cell("PRADD18A"), + #Cell("BCINRD"), + #Cell("BCLVDSOB"), + #Cell("INRDB"), + Cell("CLKDIVF"), + Cell("PCSCLKDIV"), + Cell("DCSC"), + Cell("DCCA"), + Cell("ECLKSYNCB"), + Cell("ECLKBRIDGECS"), + #Cell("PLLREFCS"), + Cell("DELAYF"), + Cell("DELAYG"), + #Cell("START"), + Cell("USRMCLK", True), + Cell("DQSBUFM"), + Cell("DDRDLLA"), + Cell("DLLDELD"), + Cell("IDDRX1F"), + Cell("IDDRX2F"), + Cell("IDDR71B"), + Cell("IDDRX2DQA"), + Cell("ODDRX1F"), + Cell("ODDRX2F"), + Cell("ODDR71B"), + Cell("OSHX2A"), + Cell("TSHX2DQA"), + Cell("TSHX2DQSA"), + Cell("ODDRX2DQA"), + Cell("ODDRX2DQSB"), + Cell("EHXPLLL"), + Cell("DTR"), + Cell("OSCG"), + Cell("EXTREFB"), + Cell("JTAGG", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + #Cell("SEDGA"), + Cell("DCUA", True, port_attrs={'CH0_HDINP': ['iopad_external_pin'], 'CH1_HDINP': ['iopad_external_pin'], 'CH0_HDINN': ['iopad_external_pin'], 'CH1_HDINN': ['iopad_external_pin']}), + ]), + ("cells_bb_xo2.v", "machxo2", [ + #Cell("AGEB2"), + #Cell("ALEB2"), + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("ANEB2"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("BBW"), + #Cell("CB2"), + #Cell("CD2"), + #Cell("CU2"), + #Cell("FADD2B"), + #Cell("FADSU2"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S1A"), + #Cell("FD1S1AY"), + #Cell("FD1S1B"), + #Cell("FD1S1D"), + #Cell("FD1S1I"), + #Cell("FD1S1J"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S1A"), + #Cell("FL1S1AY"), + #Cell("FL1S1B"), + #Cell("FL1S1D"), + #Cell("FL1S1I"), + #Cell("FL1S1J"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + #Cell("FSUB2B"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LB2P3AX"), + #Cell("LB2P3AY"), + #Cell("LB2P3BX"), + #Cell("LB2P3DX"), + #Cell("LB2P3IX"), + #Cell("LB2P3JX"), + #Cell("LD2P3AX"), + #Cell("LD2P3AY"), + #Cell("LD2P3BX"), + #Cell("LD2P3DX"), + #Cell("LD2P3IX"), + #Cell("LD2P3JX"), + #Cell("LU2P3AX"), + #Cell("LU2P3AY"), + #Cell("LU2P3BX"), + #Cell("LU2P3DX"), + #Cell("LU2P3IX"), + #Cell("LU2P3JX"), + #Cell("MULT2"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("PFUMX"), + #Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + #Cell("CCU2D"), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + Cell("SGSR", True), + Cell("DP8KC"), + Cell("PDPW8KC"), + Cell("SP8KC"), + Cell("FIFO8KB"), + #Cell("CLKDIVC"), + Cell("DCMA"), + #Cell("ECLKSYNCA"), + #Cell("ECLKBRIDGECS"), + Cell("DCCA"), + #Cell("JTAGF"), + #Cell("START"), + #Cell("SEDFA"), + #Cell("SEDFB"), + #Cell("IDDRXE"), + #Cell("IDDRX2E"), + #Cell("IDDRX4B"), + #Cell("IDDRDQSX1A"), + #Cell("IDDRX71A"), + #Cell("ODDRXE"), + #Cell("ODDRX2E"), + #Cell("ODDRX4B"), + #Cell("ODDRDQSX1A"), + #Cell("ODDRX71A"), + #Cell("TDDRA"), + #Cell("DQSBUFH"), + #Cell("DQSDLLC"), + #Cell("DELAYE"), + #Cell("DELAYD"), + #Cell("DLLDELC"), + #Cell("CLKFBBUFA"), + #Cell("PCNTR"), + #Cell("BCINRD"), + #Cell("BCLVDSO"), + #Cell("INRDB"), + #Cell("LVDSOB"), + #Cell("PG"), + Cell("EHXPLLJ"), + #Cell("PLLREFCS"), + Cell("OSCH"), + #Cell("EFB"), + #Cell("TSALL"), + ]), + ("cells_bb_xo3.v", "machxo3lf", [ + #Cell("AGEB2"), + #Cell("ALEB2"), + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("ANEB2"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("BBW"), + #Cell("CB2"), + #Cell("CD2"), + #Cell("CU2"), + #Cell("FADD2B"), + #Cell("FADSU2"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S1A"), + #Cell("FD1S1AY"), + #Cell("FD1S1B"), + #Cell("FD1S1D"), + #Cell("FD1S1I"), + #Cell("FD1S1J"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S1A"), + #Cell("FL1S1AY"), + #Cell("FL1S1B"), + #Cell("FL1S1D"), + #Cell("FL1S1I"), + #Cell("FL1S1J"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + #Cell("FSUB2B"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LB2P3AX"), + #Cell("LB2P3AY"), + #Cell("LB2P3BX"), + #Cell("LB2P3DX"), + #Cell("LB2P3IX"), + #Cell("LB2P3JX"), + #Cell("LD2P3AX"), + #Cell("LD2P3AY"), + #Cell("LD2P3BX"), + #Cell("LD2P3DX"), + #Cell("LD2P3IX"), + #Cell("LD2P3JX"), + #Cell("LU2P3AX"), + #Cell("LU2P3AY"), + #Cell("LU2P3BX"), + #Cell("LU2P3DX"), + #Cell("LU2P3IX"), + #Cell("LU2P3JX"), + #Cell("MULT2"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("PFUMX"), + #Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + #Cell("CCU2D"), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + Cell("SGSR", True), + Cell("DP8KC"), + Cell("PDPW8KC"), + Cell("SP8KC"), + Cell("FIFO8KB"), + #Cell("CLKDIVC"), + Cell("DCMA"), + #Cell("ECLKSYNCA"), + #Cell("ECLKBRIDGECS"), + Cell("DCCA"), + #Cell("JTAGF"), + #Cell("START"), + #Cell("SEDFA"), + #Cell("SEDFB"), + #Cell("IDDRXE"), + #Cell("IDDRX2E"), + #Cell("IDDRX4B"), + #Cell("IDDRX71A"), + #Cell("ODDRXE"), + #Cell("ODDRX2E"), + #Cell("ODDRX4B"), + #Cell("ODDRX71A"), + #Cell("DQSDLLC"), + #Cell("DELAYE"), + #Cell("DELAYD"), + #Cell("DLLDELC"), + #Cell("CLKFBBUFA"), + #Cell("PCNTR"), + #Cell("BCINRD"), + #Cell("BCLVDSO"), + #Cell("INRDB"), + #Cell("LVDSOB"), + #Cell("PG"), + Cell("EHXPLLJ"), + #Cell("PLLREFCS"), + Cell("OSCH"), + #Cell("EFB"), + #Cell("TSALL"), + ]), + ("cells_bb_xo3d.v", "machxo3d", [ + #Cell("AGEB2"), + #Cell("ALEB2"), + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("ANEB2"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("BBI3C"), + #Cell("BBW"), + #Cell("CB2"), + #Cell("CD2"), + #Cell("CU2"), + #Cell("FADD2B"), + #Cell("FADSU2"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S1A"), + #Cell("FD1S1AY"), + #Cell("FD1S1B"), + #Cell("FD1S1D"), + #Cell("FD1S1I"), + #Cell("FD1S1J"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S1A"), + #Cell("FL1S1AY"), + #Cell("FL1S1B"), + #Cell("FL1S1D"), + #Cell("FL1S1I"), + #Cell("FL1S1J"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + #Cell("FSUB2B"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LB2P3AX"), + #Cell("LB2P3AY"), + #Cell("LB2P3BX"), + #Cell("LB2P3DX"), + #Cell("LB2P3IX"), + #Cell("LB2P3JX"), + #Cell("LD2P3AX"), + #Cell("LD2P3AY"), + #Cell("LD2P3BX"), + #Cell("LD2P3DX"), + #Cell("LD2P3IX"), + #Cell("LD2P3JX"), + #Cell("LU2P3AX"), + #Cell("LU2P3AY"), + #Cell("LU2P3BX"), + #Cell("LU2P3DX"), + #Cell("LU2P3IX"), + #Cell("LU2P3JX"), + #Cell("MULT2"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("PFUMX"), + #Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + #Cell("CCU2D"), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + Cell("SGSR", True), + Cell("DP8KC"), + Cell("PDPW8KC"), + Cell("SP8KC"), + Cell("FIFO8KB"), + #Cell("CLKDIVC"), + Cell("DCMA"), + #Cell("ECLKSYNCA"), + #Cell("ECLKBRIDGECS"), + Cell("DCCA"), + #Cell("JTAGF"), + #Cell("START"), + #Cell("SEDFA"), + #Cell("SEDFB"), + #Cell("IDDRXE"), + #Cell("IDDRX2E"), + #Cell("IDDRX4B"), + #Cell("IDDRX71A"), + #Cell("ODDRXE"), + #Cell("ODDRX2E"), + #Cell("ODDRX4B"), + #Cell("ODDRX71A"), + #Cell("DQSDLLC"), + #Cell("DELAYE"), + #Cell("DELAYD"), + #Cell("DLLDELC"), + #Cell("CLKFBBUFA"), + #Cell("PCNTR"), + #Cell("BCINRD"), + #Cell("BCLVDSO"), + #Cell("INRDB"), + #Cell("LVDSOB"), + #Cell("PG"), + Cell("EHXPLLJ"), + #Cell("PLLREFCS"), + Cell("OSCJ"), + #Cell("EFBB"), + #Cell("TSALL"), + #Cell("ESBA"), + #Cell("BCSLEWRATEA"), + ]) +] + +def xtract_cells_decl(device, cells, dirs, outf): + fname = os.path.join(dir, device + '.v') + with open(fname) as f: + state = State.OUTSIDE + # Probably the most horrible Verilog "parser" ever written. + cell = None + kind = None + for l in f: + l, _, comment = l.partition('//') + l = l.strip() + m = re.search(r'synthesis .*black_box_pad_pin="([^"]*)"', comment) + if m: + iopad_pin = set(m.group(1).split(",")) + + if l.startswith("module "): + cell_name = l[7:l.find('(')].strip() + cell = None + kind = None + module_ports = [] + iopad_pin = set() + if state != State.OUTSIDE: + print('Nested modules in {}.'.format(fname)) + sys.exit(1) + for c in cells: + if c.name != cell_name: + continue + cell = c + state = State.IN_MODULE + outf.write('(* blackbox *)') + if cell.keep: + outf.write(' (* keep *)\n') + else: + outf.write('\n') + outf.write('module {} (...);\n'.format(cell.name)) + cell.found = True + if cell is None: + state = State.IN_OTHER_MODULE + elif l.startswith('task '): + if state == State.IN_MODULE: + state = State.IN_TASK + elif l.startswith('function '): + if state == State.IN_MODULE: + state = State.IN_FUNCTION + elif l == 'endtask': + if state == State.IN_TASK: + state = State.IN_MODULE + elif l == 'endfunction': + if state == State.IN_FUNCTION: + state = State.IN_MODULE + elif l == 'endmodule': + if state == State.IN_MODULE: + for kind, rng, port in module_ports: + for attr in cell.port_attrs.get(port, []): + outf.write(' (* {} *)\n'.format(attr)) + if port in iopad_pin: + outf.write(' (* iopad_external_pin *)\n') + if rng is None: + outf.write(' {} {};\n'.format(kind, port)) + else: + outf.write(' {} {} {};\n'.format(kind, rng, port)) + outf.write(l + '\n') + outf.write('\n') + elif state != State.IN_OTHER_MODULE: + print('endmodule in weird place in {}.'.format(cell.name, fname)) + sys.exit(1) + state = State.OUTSIDE + elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE: + l = l.strip() + if l == "": + continue + if l.endswith((';', ',', ")")): + l = l[:-1] + l = l.replace(")","") + if ';' in l: + print('Weird port line in {} [{}].'.format(fname, l)) + sys.exit(1) + kind, _, ports = l.partition(' ') + for port in ports.split(','): + port = port.strip() + if port.startswith('['): + rng, port = port.split() + else: + rng = None + module_ports.append((kind, rng, port)) + elif l.startswith('parameter ') and state == State.IN_MODULE: + l = l.strip() + if l.endswith((';', ',')): + l = l[:-1] + while ' ' in l: + l = l.replace(' ', ' ') + + if "INITVAL" in l: + l = l.replace('"0x', "320'h") + l = l.replace('"', '') + if ';' in l: + print('Weird parameter line in {} [{}].'.format(fname, l)) + sys.exit(1) + outf.write(' {};\n'.format(l)) + elif kind is not None and state == State.IN_MODULE: + l = l.strip() + if l == "": + continue + if l.endswith((';', ',', ")")): + l = l[:-1] + l = l.replace(")","") + if ';' in l: + print('Weird port line in {} [{}].'.format(fname, l)) + sys.exit(1) + ports = l + for port in ports.split(','): + port = port.strip() + if port.startswith('['): + rng, port = port.split() + else: + rng = None + module_ports.append((kind, rng, port)) + + if state != State.OUTSIDE: + print('endmodule not found in {}.'.format(fname)) + sys.exit(1) + for cell in cells: + if not cell.found: + print('cell {} not found in {}.'.format(cell.name, fname)) +if __name__ == '__main__': + parser = ArgumentParser(description='Extract Lattice blackbox cell definitions from Lattice Diamond.') + parser.add_argument('diamond_dir', nargs='?', default='/usr/local/diamond/3.12/') + args = parser.parse_args() + + dirs = [ + os.path.join(args.diamond_dir, 'cae_library/synthesis/verilog/'), + ] + for dir in dirs: + if not os.path.isdir(dir): + print('{} is not a directory'.format(dir)) + + for fn, device, cells in devices: + out = StringIO() + xtract_cells_decl(device, cells, dirs, out) + with open(fn, 'w') as f: + f.write('// Created by cells_xtra.py from Lattice models\n') + f.write('\n') + f.write(out.getvalue()) From 3b9ebfa672c2ecd413123368aff7eba64aecf0e6 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 25 Aug 2023 11:10:20 +0200 Subject: [PATCH 064/119] Addressed code review comments --- techlibs/lattice/synth_lattice.cc | 91 ++----------------------------- tests/arch/machxo2/add_sub.ys | 2 +- tests/arch/machxo2/adffs.ys | 8 +-- tests/arch/machxo2/counter.ys | 2 +- tests/arch/machxo2/dffs.ys | 4 +- tests/arch/machxo2/fsm.ys | 2 +- tests/arch/machxo2/logic.ys | 2 +- tests/arch/machxo2/lutram.ys | 2 +- tests/arch/machxo2/mux.ys | 8 +-- tests/arch/machxo2/shifter.ys | 2 +- tests/arch/machxo2/tribuf.ys | 2 +- 11 files changed, 21 insertions(+), 104 deletions(-) diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index edca6855e08..ff5070b8073 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -41,7 +41,7 @@ struct SynthLatticePass : public ScriptPass log("\n"); log(" synth_lattice [options]\n"); log("\n"); - log("This command runs synthesis for Lattice FPGAs.\n"); + log("This command runs synthesis for Lattice FPGAs (excluding iCE40 and Nexus).\n"); log("\n"); log(" -top \n"); log(" use the specified module as top module\n"); @@ -66,10 +66,6 @@ struct SynthLatticePass : public ScriptPass //log(" - lifmd: LIFMD (EXPERIMENTAL)\n"); //log(" - lifmdf: LIFMDF (EXPERIMENTAL)\n"); log("\n"); - log(" -blif \n"); - log(" write the design to the specified BLIF file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); log(" -edif \n"); log(" write the design to the specified EDIF file. writing of an output file\n"); log(" is omitted if this parameter is not specified.\n"); @@ -116,10 +112,6 @@ struct SynthLatticePass : public ScriptPass log(" -abc9\n"); log(" use new ABC9 flow (EXPERIMENTAL)\n"); log("\n"); - log(" -vpr\n"); - log(" generate an output netlist (and BLIF file) suitable for VPR\n"); - log(" (this feature is experimental and incomplete)\n"); - log("\n"); log(" -iopad\n"); log(" insert IO buffers\n"); log("\n"); @@ -137,14 +129,13 @@ struct SynthLatticePass : public ScriptPass log("\n"); } - string top_opt, blif_file, edif_file, json_file, family; - bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, vpr, no_rw_check, have_dsp; + string top_opt, edif_file, json_file, family; + bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, no_rw_check, have_dsp; string postfix, arith_map, brams_map, dsp_map; void clear_flags() override { top_opt = "-auto-top"; - blif_file = ""; edif_file = ""; json_file = ""; family = ""; @@ -158,7 +149,6 @@ struct SynthLatticePass : public ScriptPass dff = false; retime = false; abc2 = false; - vpr = false; abc9 = false; iopad = false; nodsp = false; @@ -186,10 +176,6 @@ struct SynthLatticePass : public ScriptPass family = args[++argidx]; continue; } - if (args[argidx] == "-blif" && argidx+1 < args.size()) { - blif_file = args[++argidx]; - continue; - } if (args[argidx] == "-edif" && argidx+1 < args.size()) { edif_file = args[++argidx]; continue; @@ -250,10 +236,6 @@ struct SynthLatticePass : public ScriptPass abc2 = true; continue; } - if (args[argidx] == "-vpr") { - vpr = true; - continue; - } if (args[argidx] == "-abc9") { abc9 = true; continue; @@ -461,10 +443,7 @@ struct SynthLatticePass : public ScriptPass if (check_label("map_cells")) { - if (help_mode) - run("techmap -map +/lattice/cells_map.v", "(skip if -vpr)"); - else if (!vpr) - run("techmap -map +/lattice/cells_map.v"); + run("techmap -map +/lattice/cells_map.v"); run("opt_lut_ins -tech lattice"); run("clean"); } @@ -478,23 +457,6 @@ struct SynthLatticePass : public ScriptPass run("blackbox =A:whitebox"); } - if (check_label("blif")) - { - if (!blif_file.empty() || help_mode) { - if (vpr || help_mode) { - run(stringf("opt_clean -purge"), - " (vpr mode)"); - run(stringf("write_blif -attr -cname -conn -param %s", - help_mode ? "" : blif_file.c_str()), - " (vpr mode)"); - } - if (!vpr) - run(stringf("write_blif -gates -attr -param %s", - help_mode ? "" : blif_file.c_str()), - " (non-vpr mode)"); - } - } - if (check_label("edif")) { if (!edif_file.empty() || help_mode) @@ -526,49 +488,4 @@ struct SynthEcp5Pass : public Pass } SynthEcp5Pass; */ -struct SynthMachXO2Pass : public Pass -{ - SynthMachXO2Pass() : Pass("synth_machxo2", "synthesis for MachXO2 FPGAs.") { } - - void execute(std::vector args, RTLIL::Design *design) override - { - args[0] = "synth_lattice"; - args.insert(args.begin()+1, std::string()); - args.insert(args.begin()+1, std::string()); - args[1] = "-family"; - args[2] = "xo2"; - Pass::call(design, args); - } -} SynthMachXO2Pass; - -struct SynthMachXO3Pass : public Pass -{ - SynthMachXO3Pass() : Pass("synth_machxo3", "synthesis for MachXO3 FPGAs.") { } - - void execute(std::vector args, RTLIL::Design *design) override - { - args[0] = "synth_lattice"; - args.insert(args.begin()+1, std::string()); - args.insert(args.begin()+1, std::string()); - args[1] = "-family"; - args[2] = "xo3"; - Pass::call(design, args); - } -} SynthMachXO3Pass; - -struct SynthMachXO3DPass : public Pass -{ - SynthMachXO3DPass() : Pass("synth_machxo3d", "synthesis for MachXO3D FPGAs.") { } - - void execute(std::vector args, RTLIL::Design *design) override - { - args[0] = "synth_lattice"; - args.insert(args.begin()+1, std::string()); - args.insert(args.begin()+1, std::string()); - args[1] = "-family"; - args[2] = "xo3d"; - Pass::call(design, args); - } -} SynthMachXO3DPass; - PRIVATE_NAMESPACE_END diff --git a/tests/arch/machxo2/add_sub.ys b/tests/arch/machxo2/add_sub.ys index 6897363aaee..cc6ffb41a29 100644 --- a/tests/arch/machxo2/add_sub.ys +++ b/tests/arch/machxo2/add_sub.ys @@ -1,7 +1,7 @@ read_verilog ../common/add_sub.v hierarchy -top top proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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 10 t:LUT4 diff --git a/tests/arch/machxo2/adffs.ys b/tests/arch/machxo2/adffs.ys index f1134a6ac67..49e93f9ac30 100644 --- a/tests/arch/machxo2/adffs.ys +++ b/tests/arch/machxo2/adffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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:TRELLIS_FF @@ -12,7 +12,7 @@ select -assert-none t:TRELLIS_FF %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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:TRELLIS_FF @@ -22,7 +22,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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:TRELLIS_FF @@ -32,7 +32,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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:TRELLIS_FF diff --git a/tests/arch/machxo2/counter.ys b/tests/arch/machxo2/counter.ys index 11560b551fc..3d68c9900fa 100644 --- a/tests/arch/machxo2/counter.ys +++ b/tests/arch/machxo2/counter.ys @@ -2,7 +2,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -assert -multiclock -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -multiclock -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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 4 t:CCU2D diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys index 663a64294bf..531d5ca5a27 100644 --- a/tests/arch/machxo2/dffs.ys +++ b/tests/arch/machxo2/dffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top dff proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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:TRELLIS_FF @@ -12,7 +12,7 @@ select -assert-none t:TRELLIS_FF t:TRELLIS_IO %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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:TRELLIS_FF t:LUT4 diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys index 70e1a632bdf..43dd0c80e35 100644 --- a/tests/arch/machxo2/fsm.ys +++ b/tests/arch/machxo2/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut 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 diff --git a/tests/arch/machxo2/logic.ys b/tests/arch/machxo2/logic.ys index 5c799530519..dbd702f905e 100644 --- a/tests/arch/machxo2/logic.ys +++ b/tests/arch/machxo2/logic.ys @@ -1,7 +1,7 @@ read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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 9 t:LUT4 diff --git a/tests/arch/machxo2/lutram.ys b/tests/arch/machxo2/lutram.ys index 8f1918587c9..bc81c9c8b29 100644 --- a/tests/arch/machxo2/lutram.ys +++ b/tests/arch/machxo2/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut memory opt -full diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 4fa1bd2fcc8..0ae9559cb48 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # 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:LUT4 @@ -12,7 +12,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # 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 2 t:LUT4 @@ -22,7 +22,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # 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 5 t:LUT4 @@ -32,7 +32,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # 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-max 12 t:LUT4 diff --git a/tests/arch/machxo2/shifter.ys b/tests/arch/machxo2/shifter.ys index f6440c025e8..ca7abb8098b 100644 --- a/tests/arch/machxo2/shifter.ys +++ b/tests/arch/machxo2/shifter.ys @@ -2,7 +2,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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 diff --git a/tests/arch/machxo2/tribuf.ys b/tests/arch/machxo2/tribuf.ys index 08c86008da5..00c7012d748 100644 --- a/tests/arch/machxo2/tribuf.ys +++ b/tests/arch/machxo2/tribuf.ys @@ -2,7 +2,7 @@ read_verilog ../common/tribuf.v hierarchy -top tristate proc flatten -equiv_opt -assert -map +/lattice/cells_sim_xo2.v -map +/simcells.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v -map +/simcells.v synth_lattice -family xo2 # 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 select -assert-count 1 t:$_TBUF_ From 0756285710b8ee0e561e9d2f961e3d873921db13 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 25 Aug 2023 11:45:25 +0200 Subject: [PATCH 065/119] enable more primitives supported with nextpnr --- techlibs/lattice/cells_bb_xo2.v | 36 ++++++++++++++++++++++++++++++++ techlibs/lattice/cells_bb_xo3.v | 36 ++++++++++++++++++++++++++++++++ techlibs/lattice/cells_bb_xo3d.v | 36 ++++++++++++++++++++++++++++++++ techlibs/lattice/cells_xtra.py | 36 ++++++++++++++++---------------- techlibs/lattice/common_sim.vh | 9 ++++++++ 5 files changed, 135 insertions(+), 18 deletions(-) diff --git a/techlibs/lattice/cells_bb_xo2.v b/techlibs/lattice/cells_bb_xo2.v index 6e6b655c919..fdf8331b731 100644 --- a/techlibs/lattice/cells_bb_xo2.v +++ b/techlibs/lattice/cells_bb_xo2.v @@ -408,6 +408,17 @@ module FIFO8KB (...); output FF; endmodule +(* blackbox *) +module CLKDIVC (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input RST; + input CLKI; + input ALIGNWD; + output CDIV1; + output CDIVX; +endmodule + (* blackbox *) module DCMA (...); input CLK0; @@ -416,6 +427,21 @@ module DCMA (...); output DCMOUT; endmodule +(* blackbox *) +module ECLKSYNCA (...); + input ECLKI; + input STOP; + output ECLKO; +endmodule + +(* blackbox *) +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; +endmodule + (* blackbox *) module DCCA (...); input CLKI; @@ -423,6 +449,11 @@ module DCCA (...); output CLKO; endmodule +(* blackbox *) (* keep *) +module START (...); + input STARTCLK; +endmodule + (* blackbox *) module EHXPLLJ (...); parameter CLKI_DIV = 1; @@ -533,3 +564,8 @@ module OSCH (...); output SEDSTDBY; endmodule +(* blackbox *) (* keep *) +module TSALL (...); + input TSALL; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3.v b/techlibs/lattice/cells_bb_xo3.v index 6e6b655c919..fdf8331b731 100644 --- a/techlibs/lattice/cells_bb_xo3.v +++ b/techlibs/lattice/cells_bb_xo3.v @@ -408,6 +408,17 @@ module FIFO8KB (...); output FF; endmodule +(* blackbox *) +module CLKDIVC (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input RST; + input CLKI; + input ALIGNWD; + output CDIV1; + output CDIVX; +endmodule + (* blackbox *) module DCMA (...); input CLK0; @@ -416,6 +427,21 @@ module DCMA (...); output DCMOUT; endmodule +(* blackbox *) +module ECLKSYNCA (...); + input ECLKI; + input STOP; + output ECLKO; +endmodule + +(* blackbox *) +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; +endmodule + (* blackbox *) module DCCA (...); input CLKI; @@ -423,6 +449,11 @@ module DCCA (...); output CLKO; endmodule +(* blackbox *) (* keep *) +module START (...); + input STARTCLK; +endmodule + (* blackbox *) module EHXPLLJ (...); parameter CLKI_DIV = 1; @@ -533,3 +564,8 @@ module OSCH (...); output SEDSTDBY; endmodule +(* blackbox *) (* keep *) +module TSALL (...); + input TSALL; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3d.v b/techlibs/lattice/cells_bb_xo3d.v index c957b00293e..84d7d960198 100644 --- a/techlibs/lattice/cells_bb_xo3d.v +++ b/techlibs/lattice/cells_bb_xo3d.v @@ -408,6 +408,17 @@ module FIFO8KB (...); output FF; endmodule +(* blackbox *) +module CLKDIVC (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input RST; + input CLKI; + input ALIGNWD; + output CDIV1; + output CDIVX; +endmodule + (* blackbox *) module DCMA (...); input CLK0; @@ -416,6 +427,21 @@ module DCMA (...); output DCMOUT; endmodule +(* blackbox *) +module ECLKSYNCA (...); + input ECLKI; + input STOP; + output ECLKO; +endmodule + +(* blackbox *) +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; +endmodule + (* blackbox *) module DCCA (...); input CLKI; @@ -423,6 +449,11 @@ module DCCA (...); output CLKO; endmodule +(* blackbox *) (* keep *) +module START (...); + input STARTCLK; +endmodule + (* blackbox *) module EHXPLLJ (...); parameter CLKI_DIV = 1; @@ -534,3 +565,8 @@ module OSCJ (...); output OSCESB; endmodule +(* blackbox *) (* keep *) +module TSALL (...); + input TSALL; +endmodule + diff --git a/techlibs/lattice/cells_xtra.py b/techlibs/lattice/cells_xtra.py index f2dd1f29749..fa4e38ace03 100644 --- a/techlibs/lattice/cells_xtra.py +++ b/techlibs/lattice/cells_xtra.py @@ -315,13 +315,13 @@ class State(Enum): Cell("PDPW8KC"), Cell("SP8KC"), Cell("FIFO8KB"), - #Cell("CLKDIVC"), + Cell("CLKDIVC"), Cell("DCMA"), - #Cell("ECLKSYNCA"), - #Cell("ECLKBRIDGECS"), + Cell("ECLKSYNCA"), + Cell("ECLKBRIDGECS"), Cell("DCCA"), - #Cell("JTAGF"), - #Cell("START"), + #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + Cell("START", True), #Cell("SEDFA"), #Cell("SEDFB"), #Cell("IDDRXE"), @@ -351,7 +351,7 @@ class State(Enum): #Cell("PLLREFCS"), Cell("OSCH"), #Cell("EFB"), - #Cell("TSALL"), + Cell("TSALL", True), ]), ("cells_bb_xo3.v", "machxo3lf", [ #Cell("AGEB2"), @@ -495,13 +495,13 @@ class State(Enum): Cell("PDPW8KC"), Cell("SP8KC"), Cell("FIFO8KB"), - #Cell("CLKDIVC"), + Cell("CLKDIVC"), Cell("DCMA"), - #Cell("ECLKSYNCA"), - #Cell("ECLKBRIDGECS"), + Cell("ECLKSYNCA"), + Cell("ECLKBRIDGECS"), Cell("DCCA"), - #Cell("JTAGF"), - #Cell("START"), + #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + Cell("START", True), #Cell("SEDFA"), #Cell("SEDFB"), #Cell("IDDRXE"), @@ -527,7 +527,7 @@ class State(Enum): #Cell("PLLREFCS"), Cell("OSCH"), #Cell("EFB"), - #Cell("TSALL"), + Cell("TSALL", True), ]), ("cells_bb_xo3d.v", "machxo3d", [ #Cell("AGEB2"), @@ -672,13 +672,13 @@ class State(Enum): Cell("PDPW8KC"), Cell("SP8KC"), Cell("FIFO8KB"), - #Cell("CLKDIVC"), + Cell("CLKDIVC"), Cell("DCMA"), - #Cell("ECLKSYNCA"), - #Cell("ECLKBRIDGECS"), + Cell("ECLKSYNCA"), + Cell("ECLKBRIDGECS"), Cell("DCCA"), - #Cell("JTAGF"), - #Cell("START"), + #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + Cell("START", True), #Cell("SEDFA"), #Cell("SEDFB"), #Cell("IDDRXE"), @@ -704,7 +704,7 @@ class State(Enum): #Cell("PLLREFCS"), Cell("OSCJ"), #Cell("EFBB"), - #Cell("TSALL"), + Cell("TSALL", True), #Cell("ESBA"), #Cell("BCSLEWRATEA"), ]) diff --git a/techlibs/lattice/common_sim.vh b/techlibs/lattice/common_sim.vh index e6c2e57b507..2f8e1db1a82 100644 --- a/techlibs/lattice/common_sim.vh +++ b/techlibs/lattice/common_sim.vh @@ -394,6 +394,15 @@ module TRELLIS_COMB( endmodule +// Constants +module VLO(output Z); + assign Z = 1'b0; +endmodule + +module VHI(output Z); + assign Z = 1'b1; +endmodule + `ifndef NO_INCLUDES `include "cells_ff.vh" From de54cf1a0c76b67052248f9c1a2428039f398dc6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 26 Aug 2023 00:13:58 +0000 Subject: [PATCH 066/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 09cf4992dab..f0d94b0c91d 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+51 +YOSYS_VER := 0.32+63 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From e017f6603ce98fd80199598efd5d6b65c2df11bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gr=C3=B6ber?= Date: Tue, 22 Aug 2023 19:58:03 +0200 Subject: [PATCH 067/119] Fix i386 FP excess-precision issue in fstapi (Fixes: #3898) Likely related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c225 Thanks to @jix for digging this up --- libs/fst/fstapi.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/fst/fstapi.cc b/libs/fst/fstapi.cc index da0d959a0de..dddf7d39a54 100644 --- a/libs/fst/fstapi.cc +++ b/libs/fst/fstapi.cc @@ -4334,7 +4334,7 @@ int fstReaderInit(struct fstReaderContext *xc) hdr_incomplete = (xc->start_time == 0) && (xc->end_time == 0); fstFread(&dcheck, 8, 1, xc->f); - xc->double_endian_match = (dcheck == FST_DOUBLE_ENDTEST); + xc->double_endian_match = (dcheck == (double)FST_DOUBLE_ENDTEST); if (!xc->double_endian_match) { union { From e4189ddfd1259adf164dd506a1ff896598151c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gr=C3=B6ber?= Date: Sun, 27 Aug 2023 15:01:27 +0200 Subject: [PATCH 068/119] Fix fstGetUint32 crash on mips64el due to misaligned access See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1025307 --- libs/fst/fstapi.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/fst/fstapi.cc b/libs/fst/fstapi.cc index da0d959a0de..ac1a0afa3d5 100644 --- a/libs/fst/fstapi.cc +++ b/libs/fst/fstapi.cc @@ -348,17 +348,17 @@ static void *fstMmap2(size_t __len, int __fd, fst_off_t __off) #ifdef FST_DO_MISALIGNED_OPS #define fstGetUint32(x) (*(uint32_t *)(x)) #else -static uint32_t fstGetUint32(unsigned char *mem) +static inline uint32_t fstGetUint32(unsigned char *mem) { - uint32_t u32; - unsigned char *buf = (unsigned char *)(&u32); + union { + uint8_t u8[sizeof(uint32_t)]; + uint32_t u32; + } u; - buf[0] = mem[0]; - buf[1] = mem[1]; - buf[2] = mem[2]; - buf[3] = mem[3]; + for (size_t i=0; i < sizeof(u.u8); i++) + u.u8[i] = mem[i]; - return (*(uint32_t *)buf); + return u.u32; } #endif From 2f901a82979d05893ff24997968a84f9fa477199 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 00:15:18 +0000 Subject: [PATCH 069/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f0d94b0c91d..c0b7c88c0d9 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+63 +YOSYS_VER := 0.32+66 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From b168ff99d07041284cf8f2ee16678d8ed5bd2305 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 28 Aug 2023 16:26:26 +0200 Subject: [PATCH 070/119] fix generated blackboxes for ecp5 --- techlibs/lattice/cells_bb_ecp5.v | 2 -- techlibs/lattice/cells_xtra.py | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/lattice/cells_bb_ecp5.v b/techlibs/lattice/cells_bb_ecp5.v index 9c4d1fde4ef..fc22495e2ff 100644 --- a/techlibs/lattice/cells_bb_ecp5.v +++ b/techlibs/lattice/cells_bb_ecp5.v @@ -1580,7 +1580,6 @@ module EXTREFB (...); (* iopad_external_pin *) input REFCLKN; output REFCLKO; - output ; endmodule (* blackbox *) (* keep *) @@ -2172,6 +2171,5 @@ module DCUA (...); output D_COUT19; input D_REFCLKI; output D_FFS_PLOL; - output ; endmodule diff --git a/techlibs/lattice/cells_xtra.py b/techlibs/lattice/cells_xtra.py index fa4e38ace03..c17281cc753 100644 --- a/techlibs/lattice/cells_xtra.py +++ b/techlibs/lattice/cells_xtra.py @@ -815,6 +815,8 @@ def xtract_cells_decl(device, cells, dirs, outf): if l.endswith((';', ',', ")")): l = l[:-1] l = l.replace(")","") + if l == "": + continue if ';' in l: print('Weird port line in {} [{}].'.format(fname, l)) sys.exit(1) From 572ad341b7190a4596e99edf6b81f5a1c29e9afb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 00:14:35 +0000 Subject: [PATCH 071/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c0b7c88c0d9..f146210e5c7 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+66 +YOSYS_VER := 0.32+70 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 792cf8326eb2b825ac0039f18cad9fb3deea47c0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 29 Aug 2023 10:08:55 +0200 Subject: [PATCH 072/119] defult nowidelut for xo2/3/3d --- techlibs/lattice/synth_lattice.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index ff5070b8073..e2987d0259e 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -102,6 +102,10 @@ struct SynthLatticePass : public ScriptPass log("\n"); log(" -nowidelut\n"); log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); + log(" (by default enabled on MachXO2/XO3/XO3D)\n"); + log("\n"); + log(" -widelut\n"); + log(" force use of PFU muxes to implement LUTs larger than LUT4s\n"); log("\n"); log(" -asyncprld\n"); log(" use async PRLD mode to implement ALDFF (EXPERIMENTAL)\n"); @@ -163,6 +167,7 @@ struct SynthLatticePass : public ScriptPass void execute(std::vector args, RTLIL::Design *design) override { string run_from, run_to; + bool force_widelut = false; clear_flags(); size_t argidx; @@ -230,6 +235,12 @@ struct SynthLatticePass : public ScriptPass } if (args[argidx] == "-nowidelut" || /*deprecated alias*/ args[argidx] == "-nomux") { nowidelut = true; + force_widelut = true; + continue; + } + if (args[argidx] == "-widelut") { + nowidelut = false; + force_widelut = true; continue; } if (args[argidx] == "-abc2") { @@ -273,6 +284,7 @@ struct SynthLatticePass : public ScriptPass arith_map = "_ccu2d"; brams_map = "_8kc"; have_dsp = false; + if (!force_widelut) nowidelut = true; /* } else if (family == "xo" || family == "pm") { } else if (family == "xp" || From a42c630264f8e76ae788707af6e76a8156b21ad6 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 29 Aug 2023 10:21:58 +0200 Subject: [PATCH 073/119] put back previous test state, due to default change --- tests/arch/machxo2/fsm.ys | 2 +- tests/arch/machxo2/lutram.ys | 2 +- tests/arch/machxo2/mux.ys | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys index 43dd0c80e35..3e10a069a74 100644 --- a/tests/arch/machxo2/fsm.ys +++ b/tests/arch/machxo2/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 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 diff --git a/tests/arch/machxo2/lutram.ys b/tests/arch/machxo2/lutram.ys index bc81c9c8b29..65af7b2c267 100644 --- a/tests/arch/machxo2/lutram.ys +++ b/tests/arch/machxo2/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 memory opt -full diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 0ae9559cb48..6d4e10dc7e7 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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:LUT4 @@ -12,7 +12,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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 2 t:LUT4 @@ -22,7 +22,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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 5 t:LUT4 @@ -32,7 +32,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # 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-max 12 t:LUT4 From b739213d9f00b409ef7b9a9e1834d659ea8008d9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 00:14:38 +0000 Subject: [PATCH 074/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f146210e5c7..4f7f94cf167 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+70 +YOSYS_VER := 0.32+74 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 72bec94ef4f0ce8090f22c16cd5163b816e8c698 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 1 Sep 2023 10:15:51 +0200 Subject: [PATCH 075/119] Add missing file for XO3D --- techlibs/lattice/Makefile.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/lattice/Makefile.inc b/techlibs/lattice/Makefile.inc index 4a908fa3ead..fd9ec2ed5e0 100644 --- a/techlibs/lattice/Makefile.inc +++ b/techlibs/lattice/Makefile.inc @@ -15,6 +15,7 @@ $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3d.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_ecp5.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo2.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3d.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_map.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams.txt)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_16kd.v)) From 73cb4977b2e493b840b23419919a63be7c83e6df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:14:04 +0000 Subject: [PATCH 076/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4f7f94cf167..960a31a01f3 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+74 +YOSYS_VER := 0.32+76 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 50d117956c7913d2bb661a948f0a1bff6bd0f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:49:19 +0200 Subject: [PATCH 077/119] sim: Add print support --- passes/sat/sim.cc | 92 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 325e123201c..7b2236ad6fa 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -25,6 +25,7 @@ #include "kernel/ff.h" #include "kernel/yw.h" #include "kernel/json.h" +#include "kernel/fmt.h" #include @@ -168,11 +169,38 @@ struct SimInstance Const data; }; + struct print_state_t + { + Const past_trg; + Const past_en; + Const past_args; + + Cell *cell; + Fmt fmt; + + std::tuple _sort_label() const + { + return std::make_tuple( + cell->getParam(ID::TRG_ENABLE).as_bool(), // Group by trigger + cell->getPort(ID::TRG), + cell->getParam(ID::TRG_POLARITY), + -cell->getParam(ID::PRIORITY).as_int(), // Then sort by descending PRIORITY + cell + ); + } + + bool operator<(const print_state_t &other) const + { + return _sort_label() < other._sort_label(); + } + }; + dict ff_database; dict mem_database; pool formal_database; pool initstate_database; dict mem_cells; + std::vector print_database; std::vector memories; @@ -289,13 +317,26 @@ struct SimInstance if (shared->fst) fst_memories[name] = shared->fst->getMemoryHandles(scope + "." + RTLIL::unescape_id(name)); } - if (cell->type.in(ID($assert), ID($cover), ID($assume))) { + + if (cell->type.in(ID($assert), ID($cover), ID($assume))) formal_database.insert(cell); - } + if (cell->type == ID($initstate)) initstate_database.insert(cell); + + if (cell->type == ID($print)) { + print_database.emplace_back(); + auto &print = print_database.back(); + print.cell = cell; + print.fmt.parse_rtlil(cell); + print.past_trg = Const(State::Sx, cell->getPort(ID::TRG).size()); + print.past_args = Const(State::Sx, cell->getPort(ID::ARGS).size()); + print.past_en = State::Sx; + } } + std::sort(print_database.begin(), print_database.end()); + if (shared->zinit) { for (auto &it : ff_database) @@ -519,6 +560,9 @@ struct SimInstance return; } + if (cell->type == ID($print)) + return; + log_error("Unsupported cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); } @@ -760,6 +804,50 @@ struct SimInstance } } + // Do prints *before* assertions + for (auto &print : print_database) { + Cell *cell = print.cell; + bool triggered = false; + + Const trg = get_state(cell->getPort(ID::TRG)); + Const en = get_state(cell->getPort(ID::EN)); + Const args = get_state(cell->getPort(ID::ARGS)); + + if (!en.as_bool()) + goto update_print; + + if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + Const trg_pol = cell->getParam(ID::TRG_POLARITY); + for (int i = 0; i < trg.size(); i++) { + bool pol = trg_pol[i] == State::S1; + State curr = trg[i], past = print.past_trg[i]; + if (pol && curr == State::S1 && past == State::S0) + triggered = true; + if (!pol && curr == State::S0 && past == State::S1) + triggered = true; + } + } else { + if (args != print.past_args || en != print.past_en) + triggered = true; + } + + if (triggered) { + int pos = 0; + for (auto &part : print.fmt.parts) { + part.sig = args.extract(pos, part.sig.size()); + pos += part.sig.size(); + } + + std::string rendered = print.fmt.render(); + log("%s", rendered.c_str()); + } + + update_print: + print.past_trg = trg; + print.past_en = en; + print.past_args = args; + } + if (check_assertions) { for (auto cell : formal_database) From 3de84b959f2d77244d1a5d8a18aac4d8c67a8de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:48:49 +0200 Subject: [PATCH 078/119] memory_libmap: Tweak whitespace --- passes/memory/memory_libmap.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index 6e5a806fd0e..f8b0eec1d8d 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -667,7 +667,7 @@ void MemMapping::assign_wr_ports() { if (used >= GetSize(pg.names)) { log_reject(*cfg.def, pg, "not enough unassigned ports remaining"); continue; - } + } for (int pvi = 0; pvi < GetSize(pg.variants); pvi++) { auto &def = pg.variants[pvi]; // Make sure the target is a write port. @@ -2114,7 +2114,7 @@ struct MemoryLibMapPass : public Pass { log(" memory_libmap -lib [-D ] [selection]\n"); log("\n"); log("This pass takes a description of available RAM cell types and maps\n"); - log("all selected memories to one of them, or leaves them to be mapped to FFs.\n"); + log("all selected memories to one of them, or leaves them to be mapped to FFs.\n"); log("\n"); log(" -lib \n"); log(" Selects a library file containing RAM cell definitions. This option\n"); From c6566b660f8343be882cbb4fadedfa823f48e7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:49:01 +0200 Subject: [PATCH 079/119] memlib.md: Fix typo --- passes/memory/memlib.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/memory/memlib.md b/passes/memory/memlib.md index fdc2d4bed27..855aa1345fb 100644 --- a/passes/memory/memlib.md +++ b/passes/memory/memlib.md @@ -267,7 +267,7 @@ The address is always `abits` wide. If a non-narrowest width is used, the appro bits will be tied to 0. -### Port `width` prooperty +### Port `width` property If the RAM has `per_port` widths, the available width selection can be further described on per-port basis, by using one of the following properties: From b75959f1f25573d8c67436e748223290a3645074 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 00:14:21 +0000 Subject: [PATCH 080/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 960a31a01f3..492ea14832c 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+76 +YOSYS_VER := 0.32+79 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 2584903a0605cc7ffdfc1996254ccc1f548403f2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 5 Sep 2023 08:08:51 +0200 Subject: [PATCH 081/119] Release version 0.33 --- CHANGELOG | 12 +++++++++++- Makefile | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 027187b6d9f..f388705ccf3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,18 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.32 .. Yosys 0.33-dev +Yosys 0.32 .. Yosys 0.33 -------------------------- + * Various + - Added "$print" cell, produced by "$display" and "$write" + Verilog tasks. + - Added "$print" cell handling in CXXRTL. + + * Lattice FPGA support + - Added generic "synth_lattice" pass (for now MachXO2/XO3/XO3D) + - Removed "synth_machxo2" pass + - Pass "ecp5_gsr" renamed to "lattice_gsr" + - "synth_machxo2" equivalent is "synth_lattice -family xo2" Yosys 0.31 .. Yosys 0.32 -------------------------- diff --git a/Makefile b/Makefile index 492ea14832c..c7a9ed6b63a 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+79 +YOSYS_VER := 0.33 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 11a2de815ae6e799dd37c4d220255042f1bd5608 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 5 Sep 2023 08:11:03 +0200 Subject: [PATCH 082/119] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f388705ccf3..465918a36d8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.33 .. Yosys 0.34-dev +-------------------------- + Yosys 0.32 .. Yosys 0.33 -------------------------- * Various diff --git a/Makefile b/Makefile index c7a9ed6b63a..fa95b7b7035 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33 +YOSYS_VER := 0.33+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 2584903.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From e995dddeaaa4bcdefdeebb082e1f1a8215d467bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 16 Aug 2023 12:42:00 +0200 Subject: [PATCH 083/119] abc: Warn about replacing undef bits --- passes/techmap/abc.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 364a8e54458..b2d5c5e36f3 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -127,10 +127,15 @@ bool clk_polarity, en_polarity, arst_polarity, srst_polarity; RTLIL::SigSpec clk_sig, en_sig, arst_sig, srst_sig; dict pi_map, po_map; +int undef_bits_lost; + int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1) { assign_map.apply(bit); + if (bit == State::Sx) + undef_bits_lost++; + if (signal_map.count(bit) == 0) { gate_t gate; gate.id = signal_list.size(); @@ -880,10 +885,15 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } } + undef_bits_lost = 0; + had_init = false; for (auto c : cells) extract_cell(c, keepff); + if (undef_bits_lost) + log("Replacing %d occurrences of constant undef bits with constant zero bits\n", undef_bits_lost); + for (auto wire : module->wires()) { if (wire->port_id > 0 || wire->get_bool_attribute(ID::keep)) mark_port(wire); From d4d951657fbf273d58070076009453d541361f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:55:11 +0200 Subject: [PATCH 084/119] sim: Add `-assert` option to fail on failed assertions --- passes/sat/sim.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 325e123201c..e04fa564235 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -109,6 +109,7 @@ struct SimShared int next_output_id = 0; int step = 0; std::vector triggered_assertions; + bool serious_asserts = false; }; void zinit(State &v) @@ -781,8 +782,12 @@ struct SimInstance 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 == 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()); + if (cell->type == ID($assert) && en == State::S1 && a != State::S1) { + if (shared->serious_asserts) + log_error("Assert %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str()); + else + log_warning("Assert %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str()); + } } } @@ -2497,6 +2502,10 @@ struct SimPass : public Pass { log(" -sim-gate\n"); log(" co-simulation, x in FST can match any value in simulation\n"); log("\n"); + log(" -assert\n"); + log(" fail the simulation command if, in the course of simulating,\n"); + log(" any of the asserts in the design fail\n"); + log("\n"); log(" -q\n"); log(" disable per-cycle/sample log message\n"); log("\n"); @@ -2651,6 +2660,10 @@ struct SimPass : public Pass { worker.sim_mode = SimulationMode::gate; continue; } + if (args[argidx] == "-assert") { + worker.serious_asserts = true; + continue; + } if (args[argidx] == "-x") { worker.ignore_x = true; continue; From 2d0fc040cfe4413e3b2c8209b4b5a23b5866374b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 5 Sep 2023 21:40:24 +0200 Subject: [PATCH 085/119] ast: Substitute rvalues when parsing out print arguments Apply the local substitutions stemming from process context when parsing out format arguments to `$display` or other statements. --- frontends/ast/genrtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 81fb3189d94..d62f06ae549 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -759,7 +759,7 @@ struct AST_INTERNAL::ProcessGenerator arg.realtime = true; } else { arg.type = VerilogFmtArg::INTEGER; - arg.sig = node->genRTLIL(); + arg.sig = node->genWidthRTLIL(-1, false, &subst_rvalue_map.stdmap()); arg.signed_ = is_signed; } args.push_back(arg); From 83b1a57eed27604fa1a45193ee6894a5e0764971 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 00:14:34 +0000 Subject: [PATCH 086/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fa95b7b7035..907891db33f 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+0 +YOSYS_VER := 0.33+3 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From e187fc915e87ee3b24b0f6b351862c32bbe91a89 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Wed, 6 Sep 2023 19:25:47 +0200 Subject: [PATCH 087/119] xprop: Fix polarity errors and generate hdlnames * Fixes a non-deterministic polarity error for $eqx/$nex cells * Fixes a deterministic polarity error for $_NOR_ and $_ORNOT_ cells * Generates hdlnames when xprop is run after flatten --- passes/cmds/xprop.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/passes/cmds/xprop.cc b/passes/cmds/xprop.cc index 5e78ff9fce4..310d6d773d5 100644 --- a/passes/cmds/xprop.cc +++ b/passes/cmds/xprop.cc @@ -493,8 +493,9 @@ struct XpropWorker auto sig_b = cell->getPort(ID::B); auto name = cell->name; + auto type = cell->type; module->remove(cell); - if (cell->type == ID($eqx)) + if (type == ID($eqx)) module->addEq(name, sig_a, sig_b, sig_y); else module->addNe(name, sig_a, sig_b, sig_y); @@ -534,7 +535,7 @@ struct XpropWorker auto enc_b = encoded(sig_b); auto enc_y = encoded(sig_y, true); - if (cell->type.in(ID($or), ID($_OR_))) + if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_), ID($_ORNOT_))) enc_a.invert(), enc_b.invert(), enc_y.invert(); if (cell->type.in(ID($_NAND_), ID($_NOR_))) enc_y.invert(); @@ -1027,12 +1028,25 @@ struct XpropWorker for (auto wire : module->selected_wires()) { if (wire->port_input || wire->port_output || !wire->name.isPublic()) continue; - auto name_d = module->uniquify(stringf("%s_d", wire->name.c_str())); - auto name_x = module->uniquify(stringf("%s_x", wire->name.c_str())); + int index_d = 0; + int index_x = 0; + auto name_d = module->uniquify(stringf("%s_d", wire->name.c_str()), index_d); + auto name_x = module->uniquify(stringf("%s_x", wire->name.c_str()), index_x); + + auto hdlname = wire->get_hdlname_attribute(); auto wire_d = module->addWire(name_d, GetSize(wire)); auto wire_x = module->addWire(name_x, GetSize(wire)); + if (!hdlname.empty()) { + auto hdlname_d = hdlname; + auto hdlname_x = hdlname; + hdlname_d.back() += index_d ? stringf("_d_%d", index_d) : "_d"; + hdlname_x.back() += index_x ? stringf("_x_%d", index_x) : "_x"; + wire_d->set_hdlname_attribute(hdlname_d); + wire_x->set_hdlname_attribute(hdlname_x); + } + auto enc = encoded(wire); module->connect(wire_d, enc.is_1); module->connect(wire_x, enc.is_x); From fedefa26bccaf023fdf4ee82d51fe63ecdbf6191 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Wed, 6 Sep 2023 16:35:17 -0700 Subject: [PATCH 088/119] multpass -- create Booth Encoded multipliers for --- passes/techmap/Makefile.inc | 1 + passes/techmap/multpass.cc | 1541 +++++++++++++++++++++++++++++++++++ 2 files changed, 1542 insertions(+) create mode 100644 passes/techmap/multpass.cc diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 1b834fabc3b..8b0b2aa23b7 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -4,6 +4,7 @@ OBJS += passes/techmap/techmap.o OBJS += passes/techmap/simplemap.o OBJS += passes/techmap/dfflibmap.o OBJS += passes/techmap/maccmap.o +OBJS += passes/techmap/multpass.o OBJS += passes/techmap/libparse.o ifeq ($(ENABLE_ABC),1) diff --git a/passes/techmap/multpass.cc b/passes/techmap/multpass.cc new file mode 100644 index 00000000000..e55a0441448 --- /dev/null +++ b/passes/techmap/multpass.cc @@ -0,0 +1,1541 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * + * 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. + * + */ + +/* + MultPass + -------- + + Replace $mul with booth encoded multipliers. Two different + architectures used for signed/unsigned. + + References: + Signed architecture: A Low Power Radix-4 Booth Multipliers with Pre-Encoded Mechanism, IEEE Access + https://ieeexplore.ieee.org/document/9121226 + + Unsigned architecture: Gary Bewick, Fast Multiplication algorithms and implementation. Stanford PhD: + http://i.stanford.edu/pub/cstr/reports/csl/tr/94/617/CSL-TR-94-617.pdf + + How to use: + Add multpass to your yosys script eg: + + read_verilog smultiply5_rtl.v + opt + wreduce + opt + multpass + alumacc + maccmap + opt + techmap -map ./techmap.v + dfflibmap -liberty NangateOpenCellLibrary_typical.lib + abc -liberty NangateOpenCellLibrary_typical.lib + stat -liberty NangateOpenCellLibrary_typical.lib + write_verilog -norename booth_final.v +*/ + +#include "kernel/sigtools.h" +#include "kernel/yosys.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct MultPassWorker { + + RTLIL::Module *module; + SigMap sigmap; + int booth_counter; + + MultPassWorker(RTLIL::Module *module) : module(module), sigmap(module) { booth_counter = 0; } + + // Helper routines for building architecture subcomponents + + void connect_sigSpecToWire(RTLIL::Wire *ip, const SigSpec &v) + { + auto g = module->addCell(NEW_ID, ID($pos)); + g->setParam(ID::A_WIDTH, 1); + g->setParam(ID::Y_WIDTH, 1); + g->setParam(ID::A_SIGNED, false); + g->setPort(ID::A, ip); + g->setPort(ID::Y, v); + } + + RTLIL::Wire *mk_wireFromSigSpec(const SigSpec &v) + { + + auto g = module->addCell(NEW_ID, ID($pos)); + Wire *ret = module->addWire(NEW_ID, 1); + g->setPort(ID::A, v); + g->setPort(ID::Y, ret); + g->setParam(ID::A_WIDTH, 1); + g->setParam(ID::Y_WIDTH, 1); + g->setParam(ID::A_SIGNED, false); + return ret; + } + + // fuse wires. + void join_wires_with_buffer(RTLIL::Wire *ip, RTLIL::Wire *op) + { + std::string wire_name = "join_"; + auto g = module->addCell(new_id(wire_name, __LINE__, ""), ID($pos)); + g->setParam(ID::A_WIDTH, 1); + g->setParam(ID::Y_WIDTH, 1); + g->setParam(ID::A_SIGNED, false); + g->setPort(ID::A, ip); + g->setPort(ID::Y, op); + } + + // Unary gate + RTLIL::Wire *mk_ugate1(const RTLIL::IdString &red_typ, std::string &name, RTLIL::Wire *ip1, std::string &op_name) + { + std::string op_wire_name; + if (op_name.empty()) + op_wire_name = name + "_o"; + else + op_wire_name = op_name; + RTLIL::Wire *ret = module->addWire(new_id(op_wire_name, __LINE__, ""), 1); + auto g = module->addCell(new_id(name, __LINE__, ""), red_typ); + g->setPort(ID::A, ip1); + g->setPort(ID::Y, ret); + g->setParam(ID::A_SIGNED, false); + g->setParam(ID::A_WIDTH, 1); + g->setParam(ID::Y_WIDTH, 1); + return ret; + } + + // Binary gate + RTLIL::Wire *mk_ugate2(const RTLIL::IdString &red_typ, std::string &name, RTLIL::Wire *ip1, RTLIL::Wire *ip2, std::string &op_name) + { + auto g = module->addCell(new_id(name, __LINE__, ""), red_typ); + std::string op_wire_name; + if (op_name.empty()) + op_wire_name = name + "_o"; + else + op_wire_name = op_name; + + auto ret = module->addWire(new_id(op_wire_name, __LINE__, ""), 1); + + g->setPort(ID::A, ip1); + g->setPort(ID::B, ip2); + g->setPort(ID::Y, ret); + g->setParam(ID::A_SIGNED, false); + g->setParam(ID::B_SIGNED, false); + g->setParam(ID::A_WIDTH, 1); + g->setParam(ID::B_WIDTH, 1); + g->setParam(ID::Y_WIDTH, 1); + return ret; + } + + // Booth unsigned decoder lsb + void BuildBur4d_lsb(std::string &name, RTLIL::Wire *lsb_i, RTLIL::Wire *one_i, RTLIL::Wire *s_i, RTLIL::Wire *&ppij_o, + std::string op_wire_name) + { + std::string empty; + auto and_op = mk_ugate2(ID($and), name, lsb_i, one_i, empty); + ppij_o = mk_ugate2(ID($xor), name, and_op, s_i, op_wire_name); + } + + // Booth unsigned radix4 decoder + void BuildBur4d_n(std::string &name, RTLIL::Wire *yn_i, RTLIL::Wire *ynm1_i, RTLIL::Wire *one_i, RTLIL::Wire *two_i, RTLIL::Wire *s_i, + RTLIL::Wire *&ppij_o) + { + // ppij = ((yn & one) | (ynm1 & two)) ^ s; + std::string empty; + auto an1 = mk_ugate2(ID($and), name, yn_i, one_i, empty); + auto an2 = mk_ugate2(ID($and), name, ynm1_i, two_i, empty); + auto or1 = mk_ugate2(ID($or), name, an1, an2, empty); + ppij_o = mk_ugate2(ID($xor), name, s_i, or1, empty); + } + + // Booth unsigned radix4 decoder + void BuildBur4d_msb(std::string &name, RTLIL::Wire *msb_i, RTLIL::Wire *two_i, RTLIL::Wire *s_i, RTLIL::Wire *&ppij_o) + { + // ppij = (msb & two) ^ s; + std::string empty; + auto an1 = mk_ugate2(ID($and), name, msb_i, two_i, empty); + ppij_o = mk_ugate2(ID($xor), name, s_i, an1, empty); + } + + // half adder, used in CPA + void BuildHa(std::string &name, RTLIL::Wire *a_i, RTLIL::Wire *b_i, RTLIL::Wire *&s_o, RTLIL::Wire *&c_o) + { + std::string empty; + s_o = mk_ugate2(ID($xor), name, a_i, b_i, empty); + c_o = mk_ugate2(ID($and), name, a_i, b_i, empty); + } + + // Booth unsigned radix 4 encoder + void BuildBur4e(std::string &name, RTLIL::Wire *y0_i, RTLIL::Wire *y1_i, RTLIL::Wire *y2_i, + + RTLIL::Wire *&one_o, RTLIL::Wire *&two_o, RTLIL::Wire *&s_o, RTLIL::Wire *&sb_o) + { + + std::string empty; + one_o = mk_ugate2(ID($xor), name, y0_i, y1_i, empty); + s_o = y2_i; + sb_o = mk_ugate1(ID($not), name, y2_i, empty); + auto inv_y1_xor_y2 = mk_ugate1(ID($not), name, mk_ugate2(ID($xor), name, y1_i, y2_i, empty), empty); + two_o = mk_ugate1(ID($not), name, mk_ugate2(ID($or), name, inv_y1_xor_y2, one_o, empty), empty); + } + + void BuildBr4e(std::string &name, RTLIL::Wire *y2_m1_i, + RTLIL::Wire *y2_i, // y2i + RTLIL::Wire *y2_p1_i, + + RTLIL::Wire *&negi_o, RTLIL::Wire *&twoi_n_o, RTLIL::Wire *&onei_n_o, RTLIL::Wire *&cori_o) + { + + std::string empty; + auto y2_p1_n = mk_ugate1(ID($not), name, y2_p1_i, empty); + auto y2_n = mk_ugate1(ID($not), name, y2_i, empty); + auto y2_m1_n = mk_ugate1(ID($not), name, y2_m1_i, empty); + + // negi_o = y2_p1_i + negi_o = mk_ugate1(ID($pos), name, y2_p1_i, empty); + // twoi_n = ~( + // (y2_p1_n & y2_i & y2_m1_i) | + // (y2_p1 & y2_n & y2_m1_n) + // ) + auto and3_1 = mk_ugate2(ID($and), name, y2_p1_n, mk_ugate2(ID($and), name, y2_i, y2_m1_i, empty), empty); + auto and3_2 = mk_ugate2(ID($and), name, y2_p1_i, mk_ugate2(ID($and), name, y2_n, y2_m1_n, empty), empty); + + twoi_n_o = mk_ugate1(ID($not), name, mk_ugate2(ID($or), name, and3_1, and3_2, empty), empty); + // onei_n = ~(y2_m1_i ^ y2_i); + onei_n_o = mk_ugate1(ID($not), name, mk_ugate2(ID($xor), name, y2_m1_i, y2_i, empty), empty); + // cori = (y2_m1_n | y2_n) & y2_p1_i; + cori_o = mk_ugate2(ID($and), name, y2_p1_i, mk_ugate2(ID($or), name, y2_m1_n, y2_n, empty), empty); + } + + // + // signed booth radix 4 decoder + // + void BuildBr4d(std::string &name, RTLIL::Wire *nxj_m1_i, RTLIL::Wire *twoi_n_i, RTLIL::Wire *xj_i, RTLIL::Wire *negi_i, RTLIL::Wire *onei_n_i, + + RTLIL::Wire *&ppij_o, RTLIL::Wire *&nxj_o) + { + + std::string empty; + // nxj_in = xnor(xj,negi) + // nxj_o = xnj_in, + // ppij = ~( (nxj_m1_i | twoi_n_i) & (nxj_int | onei_n_i)); + nxj_o = mk_ugate2(ID($xnor), name, xj_i, negi_i, empty); + RTLIL::Wire *or1 = mk_ugate2(ID($or), name, nxj_m1_i, twoi_n_i, empty); + RTLIL::Wire *or2 = mk_ugate2(ID($or), name, nxj_o, onei_n_i, empty); + ppij_o = mk_ugate1(ID($not), name, mk_ugate2(ID($and), name, or1, or2, empty), empty); + } + + /* + In signed case 1st two bits best realised + using non-booth encoded logic. We can save a booth + encoder for the first couple of bits. + */ + void BuildBoothQ1(std::string &name, RTLIL::Wire *negi_i, RTLIL::Wire *cori_i, RTLIL::Wire *x0_i, RTLIL::Wire *x1_i, RTLIL::Wire *y0_i, + RTLIL::Wire *y1_i, + + RTLIL::Wire *&nxj_o, RTLIL::Wire *&cor_o, RTLIL::Wire *&pp0_o, RTLIL::Wire *&pp1_o + + ) + { + /* + assign NXJO = ~(X1 ^ NEGI); + assign PP0 = (X0 & Y0); + //and terms for multiply + wire pp1_1_int = X1 & Y0; + wire pp1_2_int = X0 & Y1; + //sum generation for pp[1] + assign PP1 = pp1_1_int ^ pp1_2_int; + //correction propagation + assign CORO = (~PP1 & ~PP0)? CORI : 1'b0; + */ + std::string empty; + nxj_o = mk_ugate2(ID($xnor), name, x1_i, negi_i, empty); + pp0_o = mk_ugate2(ID($and), name, x0_i, y0_i, empty); + RTLIL::Wire *pp1_1_int = mk_ugate2(ID($and), name, x1_i, y0_i, empty); + RTLIL::Wire *pp1_2_int = mk_ugate2(ID($and), name, x0_i, y1_i, empty); + pp1_o = mk_ugate2(ID($xor), name, pp1_1_int, pp1_2_int, empty); + + RTLIL::Wire *pp1_nor_pp0 = mk_ugate1(ID($not), name, mk_ugate2(ID($or), name, pp1_o, pp0_o, empty), empty); + cor_o = mk_ugate2(ID($and), name, pp1_nor_pp0, cori_i, empty); + } + + void run() + { + log("Extracting $mul cells in module %s and generating Booth Realization:\n", log_id(module)); + for (auto cell : module->selected_cells()) { + if (cell->type.in(ID($mul))) { + RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); + RTLIL::SigSpec B = sigmap(cell->getPort(ID::B)); + RTLIL::SigSpec Y = sigmap(cell->getPort(ID::Y)); + if (GetSize(A) >= 4 && GetSize(B) >= 4 && GetSize(Y) >= 8 && + ((cell->getParam(ID::A_SIGNED).as_bool() && cell->getParam(ID::B_SIGNED).as_bool()) || + (!cell->getParam(ID::A_SIGNED).as_bool() && !cell->getParam(ID::B_SIGNED).as_bool()))) { + bool is_signed = false; + if (cell->getParam(ID::A_SIGNED).as_bool()) { + log(" By passing macc inferencing for signed multiplier -- generating booth\n"); + is_signed = true; + } else + log(" By passing macc inferencing for unsigned multiplier -- generating booth\n"); + + if (is_signed == false) /* unsigned multiplier */ { + int x_sz = GetSize(A); + int y_sz = GetSize(B); + int z_sz = GetSize(Y); + + // create a buffer for each ip + std::string buf_name = "u_mult_multiplicand_buf_"; + auto A_Buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + A_Buf->setParam(ID::A_WIDTH, x_sz); + A_Buf->setParam(ID::Y_WIDTH, x_sz); + A_Buf->setPort(ID::A, SigSpec(A)); + A_Buf->setParam(ID::A_SIGNED, false); + + std::string wire_name = "u_mult_A"; + auto A_Wire = module->addWire(new_id(wire_name, __LINE__, ""), x_sz); + + A_Buf->setPort(ID::Y, A_Wire); + + buf_name = "u_mult_multiplier_buf_"; + auto B_Buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + B_Buf->setParam(ID::A_WIDTH, y_sz); + B_Buf->setParam(ID::Y_WIDTH, y_sz); + B_Buf->setPort(ID::A, SigSpec(B)); + B_Buf->setParam(ID::A_SIGNED, false); + + wire_name = "u_mult_B"; + auto B_Wire = module->addWire(new_id(wire_name, __LINE__, ""), y_sz); + B_Buf->setPort(ID::Y, B_Wire); + + buf_name = "u_mult_result_buf_"; + auto Z_Buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + Z_Buf->setParam(ID::A_WIDTH, z_sz); + Z_Buf->setParam(ID::Y_WIDTH, z_sz); + Z_Buf->setPort(ID::Y, SigSpec(Y)); + Z_Buf->setParam(ID::A_SIGNED, false); + wire_name = "u_mult_Z"; + auto Z_Wire = module->addWire(new_id(wire_name, __LINE__, ""), z_sz); + Z_Buf->setPort(ID::A, Z_Wire); + + CreateBoothUMult(module, x_sz, y_sz, z_sz, + A_Wire, // multiplicand + B_Wire, // multiplier(scanned) + Z_Wire // result + ); + module->remove(cell); + booth_counter++; + continue; + } + + else /*signed multiplier */ { + int x_sz = GetSize(A); + int y_sz = GetSize(B); + int z_sz = GetSize(Y); + + // make wire of correct size to feed multiplier + Wire *expanded_A = module->addWire(NEW_ID, x_sz); + + Wire *expanded_B = module->addWire(NEW_ID, y_sz); + + std::string buf_name = "expand_a_buf_"; + auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setParam(ID::A_WIDTH, x_sz); + buf->setParam(ID::Y_WIDTH, x_sz); + buf->setPort(ID::A, SigSpec(A)); + buf->setParam(ID::A_SIGNED, is_signed ? true : false); + buf->setPort(ID::Y, SigSpec(expanded_A)); + + buf_name = "expand_b_buf_"; + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, SigSpec(B)); + buf->setParam(ID::A_WIDTH, y_sz); + buf->setParam(ID::Y_WIDTH, y_sz); + + buf->setParam(ID::A_SIGNED, is_signed ? true : false); + buf->setPort(ID::Y, SigSpec(expanded_B)); + + // + // Make a wire to take the expanded output + // wires + // + + Wire *expanded_Y = module->addWire(NEW_ID, (is_signed == false ? z_sz + 2 : z_sz)); + CreateBoothSMult(module, x_sz, y_sz, (is_signed == false ? z_sz + 2 : z_sz), + expanded_A, // multiplicand + expanded_B, // multiplier(scanned) + expanded_Y // result + ); + // now connect the expanded_Y with a tap to fill out sig Spec Y + + buf_name = "reducer_buf_"; + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, expanded_Y); + buf->setParam(ID::A_WIDTH, is_signed == false ? z_sz + 2 : z_sz); + buf->setParam(ID::Y_WIDTH, z_sz); + buf->setParam(ID::A_SIGNED, is_signed ? true : false); + // wire in output Y + buf->setPort(ID::Y, SigSpec(Y)); + + // kill original multiplier + module->remove(cell); + booth_counter++; + continue; + } + } + } + } + } + + /* + Build Unsigned Multiplier. + ------------------------- + Create a booth unsigned multiplier. + Uses a generic booth multiplier with + extra row of decoders and extended multiplier + */ + + void CreateBoothUMult(RTLIL::Module *module, int x_sz, int y_sz, int z_sz, + RTLIL::Wire *X, // multiplicand + RTLIL::Wire *Y, // multiplier + RTLIL::Wire *Z) + { // result + + std::vector one_int; + std::vector two_int; + std::vector s_int; + std::vector sb_int; + int encoder_count = 0; + + BuildBoothUMultEncoders(Y, y_sz, one_int, two_int, s_int, sb_int, module, encoder_count); + + // Build the decoder rows + // format of each Partial product to be passed to CSA + // tree builder: + // + // Bits to be added + // Shift + // Sign bit to be added + // + std::vector, int, RTLIL::Wire *>> ppij_int; + + static int constant_ix; + constant_ix++; + std::string buf_name = "constant_buf_" + std::to_string(constant_ix); + auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + RTLIL::Wire *constant_one = module->addWire(new_id(buf_name, __LINE__, ""), 1); + buf->setPort(ID::A, State::S1); + buf->setParam(ID::A_WIDTH, 1); + buf->setParam(ID::Y_WIDTH, 1); + buf->setParam(ID::A_SIGNED, true); + buf->setPort(ID::Y, constant_one); + + constant_ix++; + buf_name = "constant_buf_" + std::to_string(constant_ix); + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + RTLIL::Wire *constant_zero = module->addWire(new_id(buf_name, __LINE__, ""), 1); + buf->setPort(ID::A, State::S0); + buf->setParam(ID::A_WIDTH, 1); + buf->setParam(ID::Y_WIDTH, 1); + buf->setParam(ID::A_SIGNED, true); + buf->setPort(ID::Y, constant_zero); + + // Row 0: special case 1. Format S/.S.S.C.Data + std::vector ppij_row_0; + BuildBoothUMultDecoderRow0(module, X, s_int, sb_int, one_int, two_int, ppij_row_0); + + // data, shift, sign + ppij_int.push_back(std::make_tuple(ppij_row_0, 0, s_int[0])); + + for (int i = 1; i < encoder_count - 2; i++) { + // format 1,S.Data.shift = encoder_ix*2,sign = sb_int[i] + std::vector ppij_row_n; + + BuildBoothUMultDecoderRowN(module, + X, // multiplicand + one_int[i], two_int[i], s_int[i], sb_int[i], ppij_row_n, constant_one, i, + false, // include sign + false // include constant + ); + // data, shift, sign + ppij_int.push_back(std::make_tuple(ppij_row_n, i * 2, s_int[i])); + } + + // Build second to last row + // format S/,Data + sign bit + std::vector ppij_row_em1; + BuildBoothUMultDecoderRowN(module, X, one_int[encoder_count - 2], two_int[encoder_count - 2], s_int[encoder_count - 2], + sb_int[encoder_count - 2], ppij_row_em1, constant_one, encoder_count - 2, + false, // include sign + true // no constant + ); + ppij_int.push_back(std::make_tuple(ppij_row_em1, (encoder_count - 2) * 2, s_int[encoder_count - 2])); + // Build last row + // format Data + sign bit + std::vector ppij_row_e; + BuildBoothUMultDecoderRowN(module, X, one_int[encoder_count - 1], two_int[encoder_count - 1], s_int[encoder_count - 1], + sb_int[encoder_count - 1], ppij_row_e, constant_one, encoder_count - 1, + true, // no sign + true // no constant + ); + ppij_int.push_back(std::make_tuple(ppij_row_e, (encoder_count - 1) * 2, s_int[encoder_count - 1])); + + // Debug dump out partial products + // DebugDumpPP(ppij_int); + + // Summation of Partial Products (Wallace Tree) + std::vector> aligned_pp; + aligned_pp.resize(encoder_count + 1); // make an entirely redundant row + // just for sign bit in lsb. (We then filter this out). + + // resize all to be same size as z + for (int i = 0; i < encoder_count + 1; i++) + aligned_pp[i].resize(z_sz); + + AlignPP(x_sz, z_sz, ppij_int, aligned_pp); + + // Debug: dump out aligned partial products. + // Later on yosys will clean up unused constants + // DebugDumpAlignPP(aligned_pp); + + std::vector s_vec; + std::vector c_vec; + std::vector> debug_csa_trees; + + debug_csa_trees.resize(z_sz); + + BuildCSATree(module, aligned_pp, s_vec, c_vec, debug_csa_trees); + + // Debug code: Dump out the csa trees + // DumpCSATrees(debug_csa_trees); + // Build the CPA to do the final accumulation. + BuildCPA(module, s_vec, c_vec, Z); + } + + /* + Build Row 0 of decoders + */ + + void BuildBoothUMultDecoderRow0(RTLIL::Module *module, + RTLIL::Wire *X, // multiplicand + std::vector &s_int, std::vector &sb_int, std::vector &one_int, + std::vector &two_int, std::vector &ppij_vec) + { + (void)module; + int x_sz = GetSize(X); + + // lsb + std::string dec_name = "row0_lsb_dec"; + + RTLIL::Wire *ppij; + std::string ppij_name = "ppij_0_0"; + BuildBur4d_lsb(dec_name, mk_wireFromSigSpec(SigSpec(X, 0, 1)), one_int[0], s_int[0], ppij, ppij_name); + ppij_vec.push_back(ppij); + + // 1..xsize -1 + for (int i = 1; i < x_sz; i++) { + dec_name = "row0_dec_" + std::to_string(i); + RTLIL::Wire *ppij; + BuildBur4d_n(dec_name, mk_wireFromSigSpec(SigSpec(X, i, 1)), mk_wireFromSigSpec(SigSpec(X, i - 1, 1)), one_int[0], two_int[0], + s_int[0], ppij); + ppij_vec.push_back(ppij); + } + + // The redundant bit. Duplicate decoding of last bit. + dec_name = "row0_dec_msb"; + BuildBur4d_msb(dec_name, mk_wireFromSigSpec(SigSpec(X, x_sz - 1, 1)), two_int[0], s_int[0], ppij); + ppij_vec.push_back(ppij); + + // append the sign bits + ppij_vec.push_back(s_int[0]); + ppij_vec.push_back(s_int[0]); + ppij_vec.push_back(sb_int[0]); + } + + // Build a generic row of decoders. + + void BuildBoothUMultDecoderRowN(RTLIL::Module *module, + RTLIL::Wire *X, // multiplicand + RTLIL::Wire *one_int, RTLIL::Wire *two_int, RTLIL::Wire *s_int, RTLIL::Wire *sb_int, + std::vector &ppij_vec, RTLIL::Wire *constant_one, int row_ix, bool no_sign, bool no_constant) + { + (void)module; + int x_sz = GetSize(X); + + // lsb + std::string ppij_name = "ppij_" + std::to_string(row_ix) + "_0"; + RTLIL::Wire *ppij = nullptr; + std::string empty; + std::string dec_name = "row" + std::to_string(row_ix) + "_lsb_dec"; + BuildBur4d_lsb(dec_name, mk_wireFromSigSpec(SigSpec(X, 0, 1)), one_int, s_int, ppij, empty); + + ppij_vec.push_back(ppij); + + // core bits + for (int i = 1; i < x_sz; i++) { + + dec_name = "row_" + std::to_string(row_ix) + "_dec_" + std::to_string(i); + RTLIL::Wire *ppij = nullptr; + BuildBur4d_n(dec_name, mk_wireFromSigSpec(SigSpec(X, i, 1)), mk_wireFromSigSpec(SigSpec(X, i - 1, 1)), one_int, two_int, + s_int, ppij); + ppij_vec.push_back(ppij); + } + + // redundant bit + + dec_name = "row_dec_red"; + BuildBur4d_msb(dec_name, mk_wireFromSigSpec(SigSpec(X, x_sz - 1, 1)), two_int, s_int, ppij); + ppij_vec.push_back(ppij); + + // sign bit + if (no_sign == false) // if no sign is false then make a sign bit + ppij_vec.push_back(sb_int); + + // constant bit + if (no_constant == false) { // if non constant is false make a constant bit + ppij_vec.push_back(constant_one); + } + } + + void DebugDumpAlignPP(std::vector> &aligned_pp) + { + printf("Aligned & Padded Partial products\n"); + int pp_ix = 0; + for (auto pp_row : aligned_pp) { + printf("PP_%d \t", pp_ix); + for (unsigned i = 0; i < pp_row.size(); i++) + printf("[%d] %s ", i, pp_row[i] == nullptr ? " 0 " : pp_row[i]->name.c_str()); + printf("\n"); + pp_ix++; + } + } + + // Debug routines to inspect intermediate results + void DebugDumpPP(std::vector, int, RTLIL::Wire *>> &ppij_int) + { + printf("Debug dump of partial products\n"); + int pp_ix = 0; + + for (auto pp : ppij_int) { + int shift = get<1>(pp); + RTLIL::Wire *sign_bit = get<2>(pp); + + printf("PP %d\n", pp_ix); + printf("\tShift %d\n", shift); + printf("\tData (0 lsb)\n\t"); + int ix = 0; + + for (auto pp_wire : get<0>(pp)) { + RTLIL::IdString wire_name = pp_wire->name; + + printf(" [%d]:%s ", ix, wire_name.c_str()); + ix++; + } + printf("\n"); + printf("\tSign bit to add in: %s\n", sign_bit->name.c_str()); + + pp_ix++; + } + } + + void DumpCSATrees(std::vector> &debug_csa_trees) + { + int i = 0; + for (auto csa_tree : debug_csa_trees) { + printf("CSA Tree column %d\n", i); + int ix = 0; + for (auto csa_elem : csa_tree) { + printf("\tCell %d %s type %s\n", ix, csa_elem->name.c_str(), csa_elem->type.c_str()); + if (csa_elem->getPort(ID::A) == State::S0) + printf("\tA set to constant 0\n"); + else if (csa_elem->getPort(ID::A) == State::S1) + printf("\tA set to constant 1\n"); + else + printf("\tA driven by %s\n", csa_elem->getPort(ID::A).as_wire()->name.c_str()); + + if (csa_elem->getPort(ID::B) == State::S0) + printf("\tB set to constant 0\n"); + else if (csa_elem->getPort(ID::B) == State::S1) + printf("\tB set to constant 1\n"); + else + printf("\tB driven by %s\n", csa_elem->getPort(ID::B).as_wire()->name.c_str()); + + if (csa_elem->getPort(ID::C) == State::S0) + printf("\tC set to constant 0\n"); + else if (csa_elem->getPort(ID::C) == State::S1) + printf("\tC set to constant 1\n"); + else + printf("\tC driven by %s\n", csa_elem->getPort(ID::C).as_wire()->name.c_str()); + + printf("Carry out: %s\n", csa_elem->getPort(ID::X).as_wire()->name.c_str()); + printf("Sum out: %s\n", csa_elem->getPort(ID::Y).as_wire()->name.c_str()); + + ix++; + } + i++; + } + } + + void BuildCSATree(RTLIL::Module *module, std::vector> &bits_to_reduce, std::vector &s_vec, + std::vector &c_vec, std::vector> &debug_csa_trees) + { + + if (!(bits_to_reduce.size() > 0)) + return; + + int column_size = bits_to_reduce[0].size(); + int row_size = bits_to_reduce.size(); + std::vector carry_bits_to_add_to_next_column; + + for (int column_ix = 0; column_ix < column_size; column_ix++) { + + // get the bits in this column. + std::vector column_bits; + for (int row_ix = 0; row_ix < row_size; row_ix++) { + if (bits_to_reduce[row_ix].at(column_ix)) + column_bits.push_back(bits_to_reduce[row_ix].at(column_ix)); + } + for (auto c : carry_bits_to_add_to_next_column) { +#ifdef DEBUG_CSA + printf("\t Propagating column bit %s to column %d from column %d\n", c->name.c_str(), column_ix, column_ix - 1); +#endif + column_bits.push_back(c); + } + + carry_bits_to_add_to_next_column.resize(0); + +#ifdef DEBUG_CSA + printf("Column %d Reducing %d bits\n", column_ix, column_bits.size()); + for (auto b : column_bits) { + printf("\t %s\n", b->name.c_str()); + } + printf("\n"); +#endif + + RTLIL::Wire *s = nullptr; + RTLIL::Wire *c = nullptr; +#ifdef DEBUG_CSA + int csa_count_before = debug_csa_trees[column_ix].size(); +#endif + + ReduceBits(module, column_ix, column_bits, s, c, carry_bits_to_add_to_next_column, debug_csa_trees); + + s_vec.push_back(s); + c_vec.push_back(c); + +#ifdef DEBUG_CSA + int csa_count_after = debug_csa_trees[column_ix].size(); + + printf("Column %d Created %d csa tree elements\n", column_ix, csa_count_after - csa_count_before); +#endif + } + } + + /* + Alignment: + --------- + + Concept traverse from last row. + Pad row by shift + Add sign bit from prior row to 2 bits right of end of data. + + Example + + SCDDDDDDD- +S + DDDDDDDD_ + + ==> + SCDDDDDDD- + DDDDDDDD_S <-- prior rows sign bit added 2 columns to right on next row. + + Pad out rows with zeros and left the opt pass clean them up. + + */ + void AlignPP(int x_sz, int z_sz, std::vector, int, RTLIL::Wire *>> &ppij_int, + std::vector> &aligned_pp) + { + unsigned aligned_pp_ix = aligned_pp.size() - 1; + + // default is zero for everything (so don't have to think to hard + // about padding). + + for (unsigned i = 0; i < aligned_pp.size(); i++) { + for (int j = 0; j < z_sz; j++) { + aligned_pp[i][j] = nullptr; + } + } + + // for very last row we just have the sign bit + // Note that the aligned_pp is one row bigger + // than the ppij_int. We put the sign bit + // in first column of the last partial product + // which is at index corresponding to size of multiplicand + { + RTLIL::Wire *prior_row_sign = nullptr; + prior_row_sign = get<2>(ppij_int[aligned_pp_ix - 1]); + if (prior_row_sign) { + log_assert(aligned_pp_ix < aligned_pp.size()); + log_assert(x_sz - 1 < (int)(aligned_pp[aligned_pp_ix].size())); + aligned_pp[aligned_pp_ix][x_sz - 1] = prior_row_sign; + } + } + + for (int row_ix = aligned_pp_ix - 1; row_ix >= 0; row_ix--) { + int shift_amount = get<1>(ppij_int[row_ix]); + RTLIL::Wire *prior_row_sign = nullptr; + + // copy in data + unsigned copy_ix = shift_amount; + for (auto w : get<0>(ppij_int[row_ix])) { + if (copy_ix < aligned_pp[row_ix].size()) { + aligned_pp[row_ix][copy_ix] = w; + } + copy_ix++; + } + + // copy in the sign bit from the prior row + if (row_ix > 0) { + // if sign bit on prior row, copy in + // the destination of the sign bit is the (row_ix -1)*2 + // eg destination for sign bit for row 0 is 0. + // eg destination for sign bit for row 1 is 1 + prior_row_sign = get<2>(ppij_int[row_ix - 1]); + copy_ix = (row_ix - 1) * 2; + aligned_pp[row_ix][copy_ix] = prior_row_sign; + } + } + } + + /* + Build a Carry Propagate Adder + ----------------------------- + First build the sum and carry vectors to be added. + Axioms: + c_vec.size() == s_vec.size() + result.size() == s_vec.size() + 2; (assume result is reserved to hold correct size) + */ + void BuildCPA(RTLIL::Module *module, std::vector &s_vec, std::vector &c_vec, RTLIL::Wire *result) + { + + static int cpa_id; + cpa_id++; + + RTLIL::Wire *carry = nullptr; + + log_assert(s_vec.size() == c_vec.size()); + + for (unsigned n = 0; n < s_vec.size(); n++) { + std::string carry_name; + + // Base Case: Bit 0 is sum 0 + if (n == 0) { + std::string buf_name = "base_buf_" + std::to_string(cpa_id) + "_" + std::to_string(n); + auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, s_vec[0]); + buf->setParam(ID::A_WIDTH, 1); + buf->setParam(ID::Y_WIDTH, 1); + buf->setParam(ID::A_SIGNED, false); + buf->setPort(ID::Y, SigSpec(result, 0, 1)); + +#ifdef DEBUG_CPA + printf("CPA bit [%d] Cell %s IP 0 %s \n", n, buf->name.c_str(), s_vec[0]->name.c_str()); +#endif + } + + // + // Base Case + // c,s = ha(s_vec[1],c_vec[0]) + // + else if (n == 1) { + std::string ha_name = "cpa_" + std::to_string(cpa_id) + "_ha_" + std::to_string(n); + RTLIL::Wire *ha_op; + BuildHa(ha_name, s_vec[n], c_vec[n - 1], ha_op, carry); + + connect_sigSpecToWire(ha_op, SigSpec(result, n, 1)); + +#ifdef DEBUG_CPA + printf("CPA bit [%d] Cell %s IPs [%s] [%s] \n", n, ha_cell->name.c_str(), s_vec[n]->name.c_str(), + c_vec[n - 1]->name.c_str()); +#endif + + } + // End Case + else if (n == (unsigned)((s_vec.size() - 1))) { + // Make the carry results.. Two extra bits after fa. + std::string fa_name = "cpa_" + std::to_string(cpa_id) + "_fa_" + std::to_string(n); + auto fa_cell = module->addCell(new_id(fa_name, __LINE__, ""), ID($fa)); + fa_cell->setParam(ID::WIDTH, 1); + carry_name = "cpa_" + std::to_string(cpa_id) + "carry_" + std::to_string(n); + fa_cell->setPort(ID::A, s_vec[n]); + fa_cell->setPort(ID::B, c_vec[n - 1]); + fa_cell->setPort(ID::C, carry); + // wire in result and carry out + fa_cell->setPort(ID::Y, SigSpec(result, n, 1)); + + // make a new carry bit for carry out... + carry = module->addWire(new_id(carry_name, __LINE__, ""), 1); + fa_cell->setPort(ID::X, carry); + +#ifdef DEBUG_CPA + printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(), + c_vec[n - 1]->name.c_str(), carry->name.c_str()); +#endif + if (n + 1 < (unsigned)(GetSize(result))) { + // Now make a half adder: c_vec[n] = carry + std::string ha_name = "cpa_" + std::to_string(cpa_id) + "_ha_" + std::to_string(n); + RTLIL::Wire *ha_sum; + RTLIL::Wire *ha_carry; + BuildHa(ha_name, c_vec[n], carry, ha_sum, ha_carry); + + if (n + 1 < (unsigned)GetSize(result)) + connect_sigSpecToWire(ha_sum, SigSpec(result, n + 1, 1)); + if (n + 2 < (unsigned)GetSize(result)) + connect_sigSpecToWire(ha_carry, SigSpec(result, n + 2, 1)); + } + } + // Step case + else { + std::string fa_name = "cpa_" + std::to_string(cpa_id) + "_fa_" + std::to_string(n); + auto fa_cell = module->addCell(new_id(fa_name, __LINE__, ""), ID($fa)); + fa_cell->setParam(ID::WIDTH, 1); + + carry_name = "cpa_" + std::to_string(cpa_id) + "carry_" + std::to_string(n); + fa_cell->setPort(ID::A, s_vec[n]); + fa_cell->setPort(ID::B, c_vec[n - 1]); + fa_cell->setPort(ID::C, carry); + // wire in result and carry out + fa_cell->setPort(ID::Y, SigSpec(result, n, 1)); + // make a new carry bit for carry out... + carry = module->addWire(new_id(carry_name, __LINE__, ""), 1); + fa_cell->setPort(ID::X, carry); + +#ifdef DEBUG_CPA + printf("CPA bit [%d] Cell %s IPs [%s] [%s] [%s]\n", n, fa_cell->name.c_str(), s_vec[n]->name.c_str(), + c_vec[n - 1]->name.c_str(), carry->name.c_str()); +#endif + } + } + } + + // Sum the bits in the current column + // Pass the carry bits from each csa to the next + // column for summation. + + void ReduceBits(RTLIL::Module *module, int column_ix, std::vector &column_bits, RTLIL::Wire *&s_result, RTLIL::Wire *&c_result, + std::vector &carry_bits_to_sum, std::vector> &debug_csa_trees) + { + + int csa_ix = 0; + int column_size = column_bits.size(); + static int unique_id = 0; + + unique_id++; + + if (column_size > 0) { + unsigned var_ix = 0; + std::vector first_csa_ips; + // get the first 3 inputs, if possible + for (var_ix = 0; var_ix < column_bits.size() && first_csa_ips.size() != 3; var_ix++) { + if (column_bits[var_ix]) + first_csa_ips.push_back(column_bits[var_ix]); + } + + if (first_csa_ips.size() > 0) { + // build the first csa + std::string csa_name = + "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_" + std::to_string(unique_id) + "_"; + auto csa = module->addCell(NEW_ID, + // new_id(csa_name, + // __LINE__, + // ""), + ID($fa)); + csa->setParam(ID::WIDTH, 1); + debug_csa_trees[column_ix].push_back(csa); + csa_ix++; + + csa->setPort(ID::A, first_csa_ips[0]); + + if (first_csa_ips.size() > 1) + csa->setPort(ID::B, first_csa_ips[1]); + else + csa->setPort(ID::B, State::S0); + + if (first_csa_ips.size() > 2) + csa->setPort(ID::C, first_csa_ips[2]); + else + csa->setPort(ID::C, State::S0); + + std::string sum_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_s"; + auto s_wire = module->addWire(new_id(sum_wire_name, __LINE__, ""), 1); + csa->setPort(ID::Y, s_wire); + s_result = s_wire; + std::string carry_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_c"; + auto c_wire = module->addWire(new_id(carry_wire_name, __LINE__, ""), 1); + csa->setPort(ID::X, c_wire); + c_result = c_wire; + + if (var_ix <= column_bits.size() - 1) + carry_bits_to_sum.push_back(c_wire); + + // Now build the rest of the tree if we can + while (var_ix <= column_bits.size() - 1) { + std::vector csa_ips; + // get the next two variables to sum + for (; var_ix <= column_bits.size() - 1 && csa_ips.size() < 2;) { + // skip any empty bits + if (column_bits[var_ix] != nullptr) + csa_ips.push_back(column_bits[var_ix]); + var_ix++; + } + + if (csa_ips.size() > 0) { + csa_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix); + auto csa = module->addCell(new_id(csa_name, __LINE__, ""), ID($fa)); + csa->setParam(ID::WIDTH, 1); + debug_csa_trees[column_ix].push_back(csa); + + csa_ix++; + // prior level + csa->setPort(ID::A, s_wire); + csa->setPort(ID::B, csa_ips[0]); + if (csa_ips.size() > 1) + csa->setPort(ID::C, csa_ips[1]); + else + csa->setPort(ID::C, State::S0); + + carry_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_c"; + c_wire = module->addWire(new_id(carry_wire_name, __LINE__, ""), 1); + + if (var_ix <= column_bits.size() - 1) + carry_bits_to_sum.push_back(c_wire); + + sum_wire_name = "csa_" + std::to_string(column_ix) + "_" + std::to_string(csa_ix) + "_s"; + s_wire = module->addWire(new_id(sum_wire_name, __LINE__, ""), 1); + + csa->setPort(ID::X, c_wire); + csa->setPort(ID::Y, s_wire); + + s_result = s_wire; + c_result = c_wire; + } + } + } + } + } + + void BuildBoothUMultEncoders(RTLIL::Wire *Y, int y_sz, std::vector &one_int, std::vector &two_int, + std::vector &s_int, std::vector &sb_int, RTLIL::Module *module, int &encoder_ix) + { + for (int y_ix = 0; y_ix < y_sz;) { + std::string enc_name = "bur_enc_" + std::to_string(encoder_ix) + "_"; + log("Created booth encoder %s\n", enc_name.c_str()); + + std::string two_name = "two_int" + std::to_string(encoder_ix); + two_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1)); + + std::string one_name = "one_int" + std::to_string(encoder_ix); + one_int.push_back(module->addWire(new_id(one_name, __LINE__, ""), 1)); + + std::string s_name = "s_int" + std::to_string(encoder_ix); + s_int.push_back(module->addWire(new_id(s_name, __LINE__, ""), 1)); + + std::string sb_name = "sb_int" + std::to_string(encoder_ix); + sb_int.push_back(module->addWire(new_id(sb_name, __LINE__, ""), 1)); + + if (y_ix == 0) { + + BuildBur4e(enc_name, mk_wireFromSigSpec(State::S0), mk_wireFromSigSpec(SigSpec(Y, y_ix, 1)), + mk_wireFromSigSpec(SigSpec(Y, y_ix + 1, 1)), one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix], + sb_int[encoder_ix]); + + y_ix = y_ix + 1; + encoder_ix++; + } else { + // + // step case. If multiplier ends on a boundary + // then add an extra booth encoder bounded by + // zeroes to ensure unsigned works. + // + RTLIL::Wire *y0_wire; + RTLIL::Wire *y1_wire; + RTLIL::Wire *y2_wire; + + bool need_padded_cell = false; + + if (y_ix > y_sz - 1) { + y0_wire = mk_wireFromSigSpec(SigSpec(Y, State::S0)); + need_padded_cell = false; + } else { + y0_wire = mk_wireFromSigSpec(SigSpec(Y, y_ix, 1)); + y_ix++; + } + + if (y_ix > y_sz - 1) { + need_padded_cell = false; + y1_wire = mk_wireFromSigSpec(SigSpec(Y, State::S0)); + } else { + y1_wire = mk_wireFromSigSpec(SigSpec(Y, y_ix, 1)); + y_ix++; + } + + if (y_ix > y_sz - 1) { + need_padded_cell = false; + y2_wire = mk_wireFromSigSpec(SigSpec(Y, State::S0)); + } else { + if (y_ix == y_sz - 1) + need_padded_cell = true; + else + need_padded_cell = false; + y2_wire = mk_wireFromSigSpec(SigSpec(Y, y_ix, 1)); + + BuildBur4e(enc_name, y0_wire, y1_wire, y2_wire, one_int[encoder_ix], two_int[encoder_ix], s_int[encoder_ix], + sb_int[encoder_ix]); + } + + encoder_ix++; + + if (need_padded_cell == true) { + + log(" Creating padded encoder for unsigned\n"); + + // make extra encoder cell + // y_ix at y0, rest 0 + + std::string enc_name = "br_enc_pad" + std::to_string(encoder_ix) + "_"; + log("Created (padded) booth encoder %s\n", enc_name.c_str()); + + std::string two_name = "two_int" + std::to_string(encoder_ix); + two_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1)); + + std::string one_name = "one_int" + std::to_string(encoder_ix); + one_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1)); + + std::string s_name = "s_int" + std::to_string(encoder_ix); + s_int.push_back(module->addWire(new_id(s_name, __LINE__, ""), 1)); + + std::string sb_name = "sb_int" + std::to_string(encoder_ix); + sb_int.push_back(module->addWire(new_id(sb_name, __LINE__, ""), 1)); + + RTLIL::Wire *one_o_int, *two_o_int, *s_o_int, *sb_o_int; + BuildBur4e(enc_name, mk_wireFromSigSpec(SigSpec(Y, y_ix, 1)), mk_wireFromSigSpec(State::S0), + mk_wireFromSigSpec(State::S0), one_o_int, two_o_int, s_o_int, sb_o_int); + + join_wires_with_buffer(one_o_int, one_int[encoder_ix]); + join_wires_with_buffer(two_o_int, two_int[encoder_ix]); + join_wires_with_buffer(s_o_int, s_int[encoder_ix]); + join_wires_with_buffer(sb_o_int, sb_int[encoder_ix]); + y_ix++; + encoder_ix++; + } + } + } + } + + /* + Signed Multiplier + */ + + void CreateBoothSMult(RTLIL::Module *module, int x_sz, int y_sz, int z_sz, RTLIL::Wire *X, RTLIL::Wire *Y, RTLIL::Wire *Z) + { // product + unsigned enc_count = (y_sz / 2) + (((y_sz % 2) != 0) ? 1 : 0); + int dec_count = x_sz + 1; + + int fa_count = x_sz + 4; + int fa_row_count = enc_count - 1; + + log("Signed multiplier generator using low Power Negative First Booth Algorithm. Multiplicand of size %d Multiplier of size %d. " + "Result of size %d. %d encoders %d decoders\n", + x_sz, y_sz, z_sz, enc_count, dec_count); + + RTLIL::Wire *negi_n_int[enc_count]; + RTLIL::Wire *twoi_n_int[enc_count]; + RTLIL::Wire *onei_n_int[enc_count]; + RTLIL::Wire *cori_n_int[enc_count]; + + for (unsigned encoder_ix = 1; encoder_ix <= enc_count; encoder_ix++) { + std::string enc_name = "enc_" + std::to_string(encoder_ix) + "_"; + std::string negi_name = "negi_n_int" + std::to_string(encoder_ix) + "_"; + negi_n_int[encoder_ix - 1] = module->addWire(new_id(negi_name, __LINE__, ""), 1); + std::string twoi_name = "twoi_n_int_" + std::to_string(encoder_ix) + "_"; + twoi_n_int[encoder_ix - 1] = module->addWire(new_id(twoi_name, __LINE__, ""), 1); + std::string onei_name = "onei_n_int_" + std::to_string(encoder_ix) + "_"; + onei_n_int[encoder_ix - 1] = module->addWire(new_id(onei_name, __LINE__, ""), 1); + std::string cori_name = "cori_n_int_" + std::to_string(encoder_ix) + "_"; + cori_n_int[encoder_ix - 1] = module->addWire(new_id(cori_name, __LINE__, ""), 1); + + if (encoder_ix == 1) { + + BuildBr4e(enc_name, mk_wireFromSigSpec(SigSpec(State::S0)), mk_wireFromSigSpec(SigSpec(Y, 0, 1)), + mk_wireFromSigSpec(SigSpec(Y, 1, 1)), + + negi_n_int[encoder_ix - 1], twoi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], + cori_n_int[encoder_ix - 1]); + + } else { + RTLIL::Wire *y1_wire; + RTLIL::Wire *y2_wire; + RTLIL::Wire *y3_wire; + + y1_wire = mk_wireFromSigSpec(SigSpec(Y, ((encoder_ix - 1) * 2 - 1), 1)); //-1 + if ((encoder_ix - 1) * 2 >= (unsigned)y_sz) + y2_wire = mk_wireFromSigSpec(SigSpec(State::S0)); // constant 0 + else + y2_wire = mk_wireFromSigSpec(SigSpec(Y, ((encoder_ix - 1) * 2), 1)); // 0 + + if (((encoder_ix - 1) * 2 + 1) >= (unsigned)y_sz) + y3_wire = mk_wireFromSigSpec(SigSpec(State::S0)); // constant 0 + else + y3_wire = mk_wireFromSigSpec(SigSpec(Y, ((encoder_ix - 1) * 2 + 1), 1)); //+1 + + BuildBr4e(enc_name, y1_wire, y2_wire, y3_wire, + + negi_n_int[encoder_ix - 1], twoi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], + cori_n_int[encoder_ix - 1]); + } + } + // Decoders and PP generation + RTLIL::Wire *PPij[enc_count][dec_count]; + RTLIL::Wire *nxj[enc_count][dec_count]; + for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) { + for (int decoder_ix = 1; decoder_ix <= dec_count; decoder_ix++) { + std::string ppij_name = "ppij_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; + PPij[encoder_ix - 1][decoder_ix - 1] = module->addWire(new_id(ppij_name, __LINE__, ""), 1); + std::string nxj_name; + if (decoder_ix == 1) + nxj_name = "nxj_pre_dec" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; + else + nxj_name = "nxj_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; + + nxj[encoder_ix - 1][decoder_ix - 1] = module->addWire(new_id(nxj_name, __LINE__, ""), 1); + } + } + + // + // build decoder array + // + + for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) { + // pre-decoder + std::string pre_dec_name = "pre_dec_" + std::to_string(encoder_ix) + "_"; + + if (encoder_ix == 1) { + // quadrant 1 optimization + } else { + auto cell = module->addCell(new_id(pre_dec_name, __LINE__, ""), ID($_NOT_)); + cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); + cell->setPort(ID::A, negi_n_int[encoder_ix - 1]); + cell->setPort(ID::Y, nxj[encoder_ix - 1][0]); + } + + for (int decoder_ix = 1; decoder_ix < dec_count; decoder_ix++) { + // range 1..8 + + // quadrant 1 optimization. + if ((decoder_ix == 1 || decoder_ix == 2) && encoder_ix == 1) + continue; + + std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; + + BuildBr4d(dec_name, nxj[encoder_ix - 1][decoder_ix - 1], twoi_n_int[encoder_ix - 1], + mk_wireFromSigSpec(SigSpec(X, decoder_ix - 1, 1)), negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], + PPij[encoder_ix - 1][decoder_ix - 1], nxj[encoder_ix - 1][decoder_ix]); + } + + // duplicate end for sign fix + // applies to 9th decoder (xsz+1 decoder). + std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(x_sz + 1) + "_"; + RTLIL::Wire *unused_op = nullptr; + BuildBr4d(dec_name, nxj[encoder_ix - 1][dec_count - 1], twoi_n_int[encoder_ix - 1], + mk_wireFromSigSpec(SigSpec(X, dec_count - 2, 1)), negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], + PPij[encoder_ix - 1][dec_count - 1], unused_op); + } + + // + // sum up the partial products + // + int fa_el_ix = 0; + int fa_row_ix = 0; + RTLIL::Wire *fa_sum_n[fa_row_count][fa_count]; + RTLIL::Wire *fa_carry_n[fa_row_count][fa_count]; + + for (fa_row_ix = 0; fa_row_ix < fa_row_count; fa_row_ix++) { + for (fa_el_ix = 0; fa_el_ix < fa_count; fa_el_ix++) { + + std::string fa_sum_name = "fa_sum_n_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_"; + fa_sum_n[fa_row_ix][fa_el_ix] = module->addWire(new_id(fa_sum_name, __LINE__, ""), 1); + std::string fa_carry_name = "fa_carry_n" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_"; + fa_carry_n[fa_row_ix][fa_el_ix] = module->addWire(new_id(fa_carry_name, __LINE__, ""), 1); + } + } + + // full adder creation + std::string bfa_name; + std::string exc_inv_name; + for (fa_row_ix = 0; fa_row_ix < fa_row_count; fa_row_ix++) { + for (fa_el_ix = 0; fa_el_ix < fa_count; fa_el_ix++) { + // base case: 1st row. Inputs from decoders + // Note in rest of tree inputs from prior addition and a decoder + if (fa_row_ix == 0) { + // beginning + // base case: + // first two cells: have B input hooked to 0. + if (fa_el_ix == 0) { + // quadrant 1: we hard code these using non-booth + fa_el_ix++; + + } + // step case + else if (fa_el_ix >= 2 && fa_el_ix <= x_sz) { + // middle (2...x_sz cells) + bfa_name = "bfa_0_step_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; + auto cell = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell->setParam(ID::WIDTH, 1); + cell->setPort(ID::A, PPij[0][fa_el_ix]); + cell->setPort(ID::B, PPij[1][fa_el_ix - 2]); + cell->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + } + // end 3 cells: x_sz+1.2.3 + // + else { + // fa_el_ix = x_sz+1 + bfa_name = "bfa_0_se_0" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; + auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell1->setParam(ID::WIDTH, 1); + cell1->setPort(ID::A, PPij[0][x_sz]); + cell1->setPort(ID::B, PPij[1][fa_el_ix - 2]); + cell1->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell1->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell1->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + + // exception:invert ppi + fa_el_ix++; + exc_inv_name = "bfa_0_exc_inv1_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; + auto cellinv1 = module->addCell(new_id(exc_inv_name, __LINE__, ""), ID($_NOT_)); + cellinv1->add_strpool_attribute(ID::src, cellinv1->get_strpool_attribute(ID::src)); + + RTLIL::Wire *d08_inv = module->addWire(NEW_ID, 1); + + cellinv1->setPort(ID::A, PPij[0][dec_count - 1]); + cellinv1->setPort(ID::Y, d08_inv); + + exc_inv_name = "bfa_0_exc_inv2_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; + + auto cellinv2 = module->addCell(new_id(exc_inv_name, __LINE__, ""), ID($_NOT_)); + cellinv2->add_strpool_attribute(ID::src, cellinv2->get_strpool_attribute(ID::src)); + RTLIL::Wire *d18_inv = module->addWire(NEW_ID, 1); + cellinv2->setPort(ID::A, PPij[1][dec_count - 1]); + cellinv2->setPort(ID::Y, d18_inv); + + bfa_name = "bfa_0_se_1_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; + + auto cell2 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell2->setParam(ID::WIDTH, 1); + cell2->setPort(ID::A, d08_inv); + cell2->setPort(ID::B, d18_inv); + cell2->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell2->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell2->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + + // sign extension + fa_el_ix++; + bfa_name = "bfa_0_se_2_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; + auto cell3 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell3->setParam(ID::WIDTH, 1); + cell3->setPort(ID::A, State::S0); + cell3->setPort(ID::B, State::S1); + cell3->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell3->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell3->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + } + } + + // step case: 2nd and rest of rows. (fa_row_ix == 1...n) + // special because these are driven by a decoder and prior fa. + else { + // beginning + if (fa_el_ix == 0) { + // first two cells: have B input hooked to 0. + // column is offset by row_ix*2 + bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_base_" + std::to_string(fa_row_ix) + "_" + + std::to_string(fa_el_ix) + "_L"; + auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell1->setParam(ID::WIDTH, 1); + cell1->setPort(ID::A, fa_sum_n[fa_row_ix - 1][2]); // from prior full adder row + cell1->setPort(ID::B, State::S0); + cell1->setPort(ID::C, cori_n_int[fa_row_ix]); + cell1->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell1->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + fa_el_ix++; + + bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_base_" + std::to_string(fa_row_ix) + "_" + + std::to_string(fa_el_ix) + "_L"; + auto cell2 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell2->setParam(ID::WIDTH, 1); + cell2->setPort(ID::A, fa_sum_n[fa_row_ix - 1][3]); // from prior full adder row + cell2->setPort(ID::B, State::S0); + cell2->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell2->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell2->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + } + + else if (fa_el_ix >= 2 && fa_el_ix <= x_sz + 1) { + // middle (2...x_sz+1 cells) + bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_step_" + std::to_string(fa_row_ix) + "_" + + std::to_string(fa_el_ix) + "_L"; + auto cell = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell->setParam(ID::WIDTH, 1); + cell->setPort(ID::A, fa_sum_n[fa_row_ix - 1][fa_el_ix + 2]); + cell->setPort(ID::B, PPij[fa_row_ix + 1][fa_el_ix - 2]); + cell->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + } + + else if (fa_el_ix > x_sz + 1) { + // end two bits: sign extension + std::string se_inv_name; + se_inv_name = "bfa_" + std::to_string(fa_row_ix) + "_se_inv_" + std::to_string(fa_row_ix) + "_" + + std::to_string(fa_el_ix) + "_L"; + auto cellinv = module->addCell(new_id(se_inv_name, __LINE__, ""), ID($_NOT_)); + cellinv->add_strpool_attribute(ID::src, cellinv->get_strpool_attribute(ID::src)); + RTLIL::Wire *d_inv = module->addWire(NEW_ID, 1); + cellinv->setPort(ID::A, PPij[fa_row_ix + 1][dec_count - 1]); + cellinv->setPort(ID::Y, d_inv); + + bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_se_" + std::to_string(fa_row_ix) + "_" + + std::to_string(fa_el_ix) + "_L"; + auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell1->setParam(ID::WIDTH, 1); + cell1->setPort(ID::A, fa_carry_n[fa_row_ix - 1][fa_count - 1]); + cell1->setPort(ID::B, d_inv); + cell1->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell1->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell1->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + fa_el_ix++; + + // sign extension + bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_se_" + std::to_string(fa_row_ix) + "_" + + std::to_string(fa_el_ix) + "_L"; + auto cell2 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); + cell2->setParam(ID::WIDTH, 1); + cell2->setPort(ID::A, State::S0); + cell2->setPort(ID::B, State::S1); + cell2->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); + cell2->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); + cell2->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + } + } + } + } + + // instantiate the cpa + RTLIL::Wire *cpa_carry[z_sz]; + + if (x_sz + y_sz != z_sz) + log("Result of multiplier is incomplete with respect to domain of inputs\n"); + + for (int cix = 0; cix < z_sz; cix++) { + std::string cpa_cix_name = "cpa_carry_" + std::to_string(cix) + "_"; + cpa_carry[cix] = module->addWire(new_id(cpa_cix_name, __LINE__, ""), 1); + } + log(" Building cpa array for booth\n"); + for (int cpa_ix = 0; cpa_ix < z_sz; cpa_ix++) { + + // The end case where we pass the last two summands + // from prior row directly to product output + // without using a cpa cell. This is always + // 0,1 index of prior fa row + if (cpa_ix <= fa_row_count * 2 - 1) { + int fa_row_ix = cpa_ix / 2; + + std::string buf_name = + "pp_buf_" + std::to_string(cpa_ix) + "_" + "driven_by_fa_row_" + std::to_string(fa_row_ix) + "_"; + auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, fa_sum_n[fa_row_ix][0]); + buf->setParam(ID::A_WIDTH, 1); + buf->setParam(ID::Y_WIDTH, 1); + buf->setParam(ID::A_SIGNED, true); + buf->setPort(ID::Y, SigSpec(Z, cpa_ix, 1)); + + cpa_ix++; + buf_name = "pp_buf_" + std::to_string(cpa_ix) + "_" + "driven_by_fa_row_" + std::to_string(fa_row_ix) + "_"; + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, fa_sum_n[fa_row_ix][1]); + buf->setParam(ID::A_WIDTH, 1); + buf->setParam(ID::Y_WIDTH, 1); + buf->setParam(ID::A_SIGNED, true); + buf->setPort(ID::Y, SigSpec(Z, cpa_ix, 1)); + } else { + int offset = fa_row_count * 2; + bool base_case = cpa_ix - offset == 0 ? true : false; + std::string cpa_name = "cpa_" + std::to_string(cpa_ix - offset) + "_"; + + RTLIL::Wire *ci_wire; + if (base_case) + ci_wire = cori_n_int[enc_count - 1]; + else + ci_wire = cpa_carry[cpa_ix - offset - 1]; + + RTLIL::Wire *op_wire = module->addWire(NEW_ID, 1); + BuildHa(cpa_name, fa_sum_n[fa_row_count - 1][cpa_ix - offset + 2], ci_wire, op_wire, cpa_carry[cpa_ix - offset]); + connect_sigSpecToWire(op_wire, SigSpec(Z, cpa_ix, 1)); + } + } + + // + // instantiate the quadrant 1 cell. This is the upper right + // quadrant which can be realized using non-booth encoded logic. + // + std::string q1_name = "icb_booth_q1_"; + + RTLIL::Wire *pp0_o_int; + RTLIL::Wire *pp1_o_int; + RTLIL::Wire *nxj_o_int; + RTLIL::Wire *cor_o_int; + + BuildBoothQ1(q1_name, + negi_n_int[0], // negi + cori_n_int[0], // cori + + mk_wireFromSigSpec(SigSpec(X, 0, 1)), // x0 + mk_wireFromSigSpec(SigSpec(X, 1, 1)), // x1 + mk_wireFromSigSpec(SigSpec(Y, 0, 1)), // y0 + mk_wireFromSigSpec(SigSpec(Y, 1, 1)), // y1 + + nxj_o_int, cor_o_int, pp0_o_int, pp1_o_int); + + join_wires_with_buffer(pp0_o_int, fa_sum_n[0][0]); + join_wires_with_buffer(pp1_o_int, fa_sum_n[0][1]); + join_wires_with_buffer(cor_o_int, fa_carry_n[0][1]); + join_wires_with_buffer(nxj_o_int, nxj[0][2]); + } +}; + +struct MultPass : public Pass { + MultPass() : Pass("multpass") {} + void execute(vector args, RTLIL::Design *design) override + { + (void)args; + log("Multiplier Pass. Generating Booth Multiplier structures for signed/unsigned multipliers of 4 bits or more\n"); + for (auto mod : design->selected_modules()) + if (!mod->has_processes_warn()) { + MultPassWorker worker(mod); + worker.run(); + } + } +} MultPass; + +PRIVATE_NAMESPACE_END From 41b34a19353dbbe00aa08f3561e25e0bfa4c84d2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 00:14:30 +0000 Subject: [PATCH 089/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 907891db33f..9474d37a19d 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+3 +YOSYS_VER := 0.33+6 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 0c2a99ca475dfc912ccc211afb1264a7e8fb8247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 7 Sep 2023 14:46:59 +0200 Subject: [PATCH 090/119] techmap: Test the Booth multiplier --- tests/techmap/booth.ys | 1 + tests/techmap/booth_map_script.ys_ | 1 + 2 files changed, 2 insertions(+) create mode 100644 tests/techmap/booth.ys create mode 100644 tests/techmap/booth_map_script.ys_ diff --git a/tests/techmap/booth.ys b/tests/techmap/booth.ys new file mode 100644 index 00000000000..17e20245693 --- /dev/null +++ b/tests/techmap/booth.ys @@ -0,0 +1 @@ +test_cell -script booth_map_script.ys_ $mul diff --git a/tests/techmap/booth_map_script.ys_ b/tests/techmap/booth_map_script.ys_ new file mode 100644 index 00000000000..0f323bdd863 --- /dev/null +++ b/tests/techmap/booth_map_script.ys_ @@ -0,0 +1 @@ +multpass From 25a33d408280ba496366ef282506521a4caef305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Thu, 7 Sep 2023 14:56:56 +0200 Subject: [PATCH 091/119] techmap: Make the Booth test deterministic --- tests/techmap/booth.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/techmap/booth.ys b/tests/techmap/booth.ys index 17e20245693..f1dce1f3b27 100644 --- a/tests/techmap/booth.ys +++ b/tests/techmap/booth.ys @@ -1 +1 @@ -test_cell -script booth_map_script.ys_ $mul +test_cell -s 1694091355 -n 1000 -script booth_map_script.ys_ $mul From 411acc4a0a27a6b3cb198faa63f6e501a1b8df19 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Fri, 8 Sep 2023 13:41:31 -0700 Subject: [PATCH 092/119] Fixed edge size cases for signed/unsigned booth generator --- passes/techmap/multpass.cc | 195 +++++++++++++++++++++++++------------ 1 file changed, 135 insertions(+), 60 deletions(-) diff --git a/passes/techmap/multpass.cc b/passes/techmap/multpass.cc index e55a0441448..9981250ae08 100644 --- a/passes/techmap/multpass.cc +++ b/passes/techmap/multpass.cc @@ -295,45 +295,85 @@ struct MultPassWorker { int y_sz = GetSize(B); int z_sz = GetSize(Y); - // create a buffer for each ip - std::string buf_name = "u_mult_multiplicand_buf_"; - auto A_Buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - A_Buf->setParam(ID::A_WIDTH, x_sz); - A_Buf->setParam(ID::Y_WIDTH, x_sz); - A_Buf->setPort(ID::A, SigSpec(A)); - A_Buf->setParam(ID::A_SIGNED, false); - - std::string wire_name = "u_mult_A"; - auto A_Wire = module->addWire(new_id(wire_name, __LINE__, ""), x_sz); - - A_Buf->setPort(ID::Y, A_Wire); - - buf_name = "u_mult_multiplier_buf_"; - auto B_Buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - B_Buf->setParam(ID::A_WIDTH, y_sz); - B_Buf->setParam(ID::Y_WIDTH, y_sz); - B_Buf->setPort(ID::A, SigSpec(B)); - B_Buf->setParam(ID::A_SIGNED, false); - - wire_name = "u_mult_B"; - auto B_Wire = module->addWire(new_id(wire_name, __LINE__, ""), y_sz); - B_Buf->setPort(ID::Y, B_Wire); - - buf_name = "u_mult_result_buf_"; - auto Z_Buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - Z_Buf->setParam(ID::A_WIDTH, z_sz); - Z_Buf->setParam(ID::Y_WIDTH, z_sz); - Z_Buf->setPort(ID::Y, SigSpec(Y)); - Z_Buf->setParam(ID::A_SIGNED, false); - wire_name = "u_mult_Z"; - auto Z_Wire = module->addWire(new_id(wire_name, __LINE__, ""), z_sz); - Z_Buf->setPort(ID::A, Z_Wire); - - CreateBoothUMult(module, x_sz, y_sz, z_sz, - A_Wire, // multiplicand - B_Wire, // multiplier(scanned) - Z_Wire // result + // To simplify the generator size the arguments + // to be the same. Then allow logic synthesis to + // clean things up. Size to biggest + + int x_sz_revised = x_sz; + int y_sz_revised = y_sz; + + if (x_sz != y_sz) { + if (x_sz < y_sz) { + if (y_sz % 2 != 0) { + x_sz_revised = y_sz + 1; + y_sz_revised = y_sz + 1; + } else + x_sz_revised = y_sz; + + log("Resized x to %d ", x_sz_revised); + } else { + if (x_sz % 2 != 0) { + y_sz_revised = x_sz + 1; + x_sz_revised = x_sz + 1; + } else + y_sz_revised = x_sz; + log("Resized y to %d ", y_sz_revised); + } + } else { + if (x_sz % 2 != 0) { + y_sz_revised = y_sz + 1; + x_sz_revised = x_sz + 1; + } + } + + log_assert((x_sz_revised == y_sz_revised) && (x_sz_revised % 2 == 0) && (y_sz_revised % 2 == 0)); + + Wire *expanded_A = module->addWire(NEW_ID, x_sz_revised); + Wire *expanded_B = module->addWire(NEW_ID, y_sz_revised); + + std::string buf_name = "expand_a_buf_"; + auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setParam(ID::A_WIDTH, x_sz); + buf->setParam(ID::Y_WIDTH, x_sz_revised); + buf->setPort(ID::A, SigSpec(A)); + buf->setParam(ID::A_SIGNED, false); + buf->setPort(ID::Y, SigSpec(expanded_A)); + + buf_name = "expand_b_buf_"; + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, SigSpec(B)); + buf->setParam(ID::A_WIDTH, y_sz); + buf->setParam(ID::Y_WIDTH, y_sz_revised); + buf->setParam(ID::A_SIGNED, false); + buf->setPort(ID::Y, SigSpec(expanded_B)); + + // Make sure output domain is big enough to take + // all combinations. + // Later logic synthesis will kill unused + // portions of the output domain. + + unsigned required_op_size = x_sz_revised + y_sz_revised; + + Wire *expanded_Y = module->addWire(NEW_ID, required_op_size); + + CreateBoothUMult(module, x_sz_revised, y_sz_revised, required_op_size, + expanded_A, // multiplicand + expanded_B, // multiplier(scanned) + expanded_Y // result ); + + // now connect the expanded_Y with a tap to fill out sig Spec Y + + log("Adding reducer on output from %u to %u ", required_op_size, z_sz); + buf_name = "reducer_buf_"; + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, expanded_Y); + buf->setParam(ID::A_WIDTH, required_op_size); + buf->setParam(ID::Y_WIDTH, z_sz); // The real user width + buf->setParam(ID::A_SIGNED, false); + // wire in output Y + buf->setPort(ID::Y, SigSpec(Y)); + module->remove(cell); booth_counter++; continue; @@ -344,47 +384,81 @@ struct MultPassWorker { int y_sz = GetSize(B); int z_sz = GetSize(Y); - // make wire of correct size to feed multiplier - Wire *expanded_A = module->addWire(NEW_ID, x_sz); - - Wire *expanded_B = module->addWire(NEW_ID, y_sz); + // To simplify the generator size the arguments + // to be the same. Then allow logic synthesis to + // clean things up. Size to biggest + + int x_sz_revised = x_sz; + int y_sz_revised = y_sz; + + if (x_sz != y_sz) { + if (x_sz < y_sz) { + if (y_sz % 2 != 0) { + x_sz_revised = y_sz + 1; + y_sz_revised = y_sz + 1; + } else + x_sz_revised = y_sz; + + log("Resized x to %d ", x_sz_revised); + } else { + if (x_sz % 2 != 0) { + y_sz_revised = x_sz + 1; + x_sz_revised = x_sz + 1; + } else + y_sz_revised = x_sz; + log("Resized y to %d ", y_sz_revised); + } + } else { + if (x_sz % 2 != 0) { + y_sz_revised = y_sz + 1; + x_sz_revised = x_sz + 1; + } + } + + log_assert((x_sz_revised == y_sz_revised) && (x_sz_revised % 2 == 0) && (y_sz_revised % 2 == 0)); + + Wire *expanded_A = module->addWire(NEW_ID, x_sz_revised); + Wire *expanded_B = module->addWire(NEW_ID, y_sz_revised); std::string buf_name = "expand_a_buf_"; auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); buf->setParam(ID::A_WIDTH, x_sz); - buf->setParam(ID::Y_WIDTH, x_sz); + buf->setParam(ID::Y_WIDTH, x_sz_revised); buf->setPort(ID::A, SigSpec(A)); - buf->setParam(ID::A_SIGNED, is_signed ? true : false); + buf->setParam(ID::A_SIGNED, true); buf->setPort(ID::Y, SigSpec(expanded_A)); buf_name = "expand_b_buf_"; buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); buf->setPort(ID::A, SigSpec(B)); buf->setParam(ID::A_WIDTH, y_sz); - buf->setParam(ID::Y_WIDTH, y_sz); - - buf->setParam(ID::A_SIGNED, is_signed ? true : false); + buf->setParam(ID::Y_WIDTH, y_sz_revised); + buf->setParam(ID::A_SIGNED, true); buf->setPort(ID::Y, SigSpec(expanded_B)); - // - // Make a wire to take the expanded output - // wires - // + // Make sure output domain is big enough to take + // all combinations. + // Later logic synthesis will kill unused + // portions of the output domain. + + unsigned required_op_size = x_sz_revised + y_sz_revised; - Wire *expanded_Y = module->addWire(NEW_ID, (is_signed == false ? z_sz + 2 : z_sz)); - CreateBoothSMult(module, x_sz, y_sz, (is_signed == false ? z_sz + 2 : z_sz), + Wire *expanded_Y = module->addWire(NEW_ID, required_op_size); + + CreateBoothSMult(module, x_sz_revised, y_sz_revised, required_op_size, expanded_A, // multiplicand expanded_B, // multiplier(scanned) - expanded_Y // result + expanded_Y // result (sized) ); // now connect the expanded_Y with a tap to fill out sig Spec Y + log("Adding reducer on output from %u to %u ", required_op_size, z_sz); buf_name = "reducer_buf_"; buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); buf->setPort(ID::A, expanded_Y); - buf->setParam(ID::A_WIDTH, is_signed == false ? z_sz + 2 : z_sz); - buf->setParam(ID::Y_WIDTH, z_sz); - buf->setParam(ID::A_SIGNED, is_signed ? true : false); + buf->setParam(ID::A_WIDTH, required_op_size); + buf->setParam(ID::Y_WIDTH, z_sz); // The real user width + buf->setParam(ID::A_SIGNED, true); // wire in output Y buf->setPort(ID::Y, SigSpec(Y)); @@ -1451,7 +1525,7 @@ struct MultPassWorker { std::string cpa_cix_name = "cpa_carry_" + std::to_string(cix) + "_"; cpa_carry[cix] = module->addWire(new_id(cpa_cix_name, __LINE__, ""), 1); } - log(" Building cpa array for booth\n"); + log(" Building cpa array for booth for output size %u\n", z_sz); for (int cpa_ix = 0; cpa_ix < z_sz; cpa_ix++) { // The end case where we pass the last two summands @@ -1525,15 +1599,16 @@ struct MultPassWorker { }; struct MultPass : public Pass { - MultPass() : Pass("multpass") {} + MultPass() : Pass("multpass", "Map $mul to booth multipliers") {} void execute(vector args, RTLIL::Design *design) override { (void)args; - log("Multiplier Pass. Generating Booth Multiplier structures for signed/unsigned multipliers of 4 bits or more\n"); + log_header(design, "Executing multpass. Generating Booth Multiplier structures for signed/unsigned multipliers of 4 bits or more\n"); for (auto mod : design->selected_modules()) if (!mod->has_processes_warn()) { MultPassWorker worker(mod); worker.run(); + log_header(design, "Created %d booth multipliers.\n", worker.booth_counter); } } } MultPass; From 6d29dc659b19a016d33f75561c6f2dd96b42ca8f Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Fri, 8 Sep 2023 15:34:56 -0700 Subject: [PATCH 093/119] renamed passname to booth, replaced connect_sigSpecToWire with connect, updated test script --- passes/techmap/multpass.cc | 264 +++++++++-------------------- tests/techmap/booth_map_script.ys_ | 2 +- 2 files changed, 78 insertions(+), 188 deletions(-) diff --git a/passes/techmap/multpass.cc b/passes/techmap/multpass.cc index 9981250ae08..c0e56f2ad61 100644 --- a/passes/techmap/multpass.cc +++ b/passes/techmap/multpass.cc @@ -64,16 +64,6 @@ struct MultPassWorker { // Helper routines for building architecture subcomponents - void connect_sigSpecToWire(RTLIL::Wire *ip, const SigSpec &v) - { - auto g = module->addCell(NEW_ID, ID($pos)); - g->setParam(ID::A_WIDTH, 1); - g->setParam(ID::Y_WIDTH, 1); - g->setParam(ID::A_SIGNED, false); - g->setPort(ID::A, ip); - g->setPort(ID::Y, v); - } - RTLIL::Wire *mk_wireFromSigSpec(const SigSpec &v) { @@ -274,7 +264,6 @@ struct MultPassWorker { void run() { - log("Extracting $mul cells in module %s and generating Booth Realization:\n", log_id(module)); for (auto cell : module->selected_cells()) { if (cell->type.in(ID($mul))) { RTLIL::SigSpec A = sigmap(cell->getPort(ID::A)); @@ -290,183 +279,92 @@ struct MultPassWorker { } else log(" By passing macc inferencing for unsigned multiplier -- generating booth\n"); - if (is_signed == false) /* unsigned multiplier */ { - int x_sz = GetSize(A); - int y_sz = GetSize(B); - int z_sz = GetSize(Y); - - // To simplify the generator size the arguments - // to be the same. Then allow logic synthesis to - // clean things up. Size to biggest - - int x_sz_revised = x_sz; - int y_sz_revised = y_sz; - - if (x_sz != y_sz) { - if (x_sz < y_sz) { - if (y_sz % 2 != 0) { - x_sz_revised = y_sz + 1; - y_sz_revised = y_sz + 1; - } else - x_sz_revised = y_sz; - - log("Resized x to %d ", x_sz_revised); - } else { - if (x_sz % 2 != 0) { - y_sz_revised = x_sz + 1; - x_sz_revised = x_sz + 1; - } else - y_sz_revised = x_sz; - log("Resized y to %d ", y_sz_revised); - } - } else { - if (x_sz % 2 != 0) { - y_sz_revised = y_sz + 1; - x_sz_revised = x_sz + 1; - } - } - - log_assert((x_sz_revised == y_sz_revised) && (x_sz_revised % 2 == 0) && (y_sz_revised % 2 == 0)); - - Wire *expanded_A = module->addWire(NEW_ID, x_sz_revised); - Wire *expanded_B = module->addWire(NEW_ID, y_sz_revised); + int x_sz = GetSize(A); + int y_sz = GetSize(B); + int z_sz = GetSize(Y); - std::string buf_name = "expand_a_buf_"; - auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setParam(ID::A_WIDTH, x_sz); - buf->setParam(ID::Y_WIDTH, x_sz_revised); - buf->setPort(ID::A, SigSpec(A)); - buf->setParam(ID::A_SIGNED, false); - buf->setPort(ID::Y, SigSpec(expanded_A)); + // To simplify the generator size the arguments + // to be the same. Then allow logic synthesis to + // clean things up. Size to biggest - buf_name = "expand_b_buf_"; - buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setPort(ID::A, SigSpec(B)); - buf->setParam(ID::A_WIDTH, y_sz); - buf->setParam(ID::Y_WIDTH, y_sz_revised); - buf->setParam(ID::A_SIGNED, false); - buf->setPort(ID::Y, SigSpec(expanded_B)); + int x_sz_revised = x_sz; + int y_sz_revised = y_sz; - // Make sure output domain is big enough to take - // all combinations. - // Later logic synthesis will kill unused - // portions of the output domain. - - unsigned required_op_size = x_sz_revised + y_sz_revised; + if (x_sz != y_sz) { + if (x_sz < y_sz) { + if (y_sz % 2 != 0) { + x_sz_revised = y_sz + 1; + y_sz_revised = y_sz + 1; + } else + x_sz_revised = y_sz; - Wire *expanded_Y = module->addWire(NEW_ID, required_op_size); + } else { + if (x_sz % 2 != 0) { + y_sz_revised = x_sz + 1; + x_sz_revised = x_sz + 1; + } else + y_sz_revised = x_sz; + } + } else { + if (x_sz % 2 != 0) { + y_sz_revised = y_sz + 1; + x_sz_revised = x_sz + 1; + } + } + log_assert((x_sz_revised == y_sz_revised) && (x_sz_revised % 2 == 0) && (y_sz_revised % 2 == 0)); + + Wire *expanded_A = module->addWire(NEW_ID, x_sz_revised); + Wire *expanded_B = module->addWire(NEW_ID, y_sz_revised); + + std::string buf_name = "expand_a_buf_"; + auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setParam(ID::A_WIDTH, x_sz); + buf->setParam(ID::Y_WIDTH, x_sz_revised); + buf->setPort(ID::A, SigSpec(A)); + buf->setParam(ID::A_SIGNED, is_signed ? true : false); + buf->setPort(ID::Y, SigSpec(expanded_A)); + + buf_name = "expand_b_buf_"; + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, SigSpec(B)); + buf->setParam(ID::A_WIDTH, y_sz); + buf->setParam(ID::Y_WIDTH, y_sz_revised); + buf->setParam(ID::A_SIGNED, is_signed ? true : false); + buf->setPort(ID::Y, SigSpec(expanded_B)); + + // Make sure output domain is big enough to take + // all combinations. + // Later logic synthesis will kill unused + // portions of the output domain. + + unsigned required_op_size = x_sz_revised + y_sz_revised; + Wire *expanded_Y = module->addWire(NEW_ID, required_op_size); + // now connect the expanded_Y with a tap to fill out sig Spec Y + buf_name = "reducer_buf_"; + buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); + buf->setPort(ID::A, expanded_Y); + buf->setParam(ID::A_WIDTH, required_op_size); + buf->setParam(ID::Y_WIDTH, z_sz); // The real user width + buf->setParam(ID::A_SIGNED, is_signed ? true : false); + // wire in output Y + buf->setPort(ID::Y, SigSpec(Y)); + + if (is_signed == false) /* unsigned multiplier */ CreateBoothUMult(module, x_sz_revised, y_sz_revised, required_op_size, expanded_A, // multiplicand expanded_B, // multiplier(scanned) expanded_Y // result ); - - // now connect the expanded_Y with a tap to fill out sig Spec Y - - log("Adding reducer on output from %u to %u ", required_op_size, z_sz); - buf_name = "reducer_buf_"; - buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setPort(ID::A, expanded_Y); - buf->setParam(ID::A_WIDTH, required_op_size); - buf->setParam(ID::Y_WIDTH, z_sz); // The real user width - buf->setParam(ID::A_SIGNED, false); - // wire in output Y - buf->setPort(ID::Y, SigSpec(Y)); - - module->remove(cell); - booth_counter++; - continue; - } - - else /*signed multiplier */ { - int x_sz = GetSize(A); - int y_sz = GetSize(B); - int z_sz = GetSize(Y); - - // To simplify the generator size the arguments - // to be the same. Then allow logic synthesis to - // clean things up. Size to biggest - - int x_sz_revised = x_sz; - int y_sz_revised = y_sz; - - if (x_sz != y_sz) { - if (x_sz < y_sz) { - if (y_sz % 2 != 0) { - x_sz_revised = y_sz + 1; - y_sz_revised = y_sz + 1; - } else - x_sz_revised = y_sz; - - log("Resized x to %d ", x_sz_revised); - } else { - if (x_sz % 2 != 0) { - y_sz_revised = x_sz + 1; - x_sz_revised = x_sz + 1; - } else - y_sz_revised = x_sz; - log("Resized y to %d ", y_sz_revised); - } - } else { - if (x_sz % 2 != 0) { - y_sz_revised = y_sz + 1; - x_sz_revised = x_sz + 1; - } - } - - log_assert((x_sz_revised == y_sz_revised) && (x_sz_revised % 2 == 0) && (y_sz_revised % 2 == 0)); - - Wire *expanded_A = module->addWire(NEW_ID, x_sz_revised); - Wire *expanded_B = module->addWire(NEW_ID, y_sz_revised); - - std::string buf_name = "expand_a_buf_"; - auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setParam(ID::A_WIDTH, x_sz); - buf->setParam(ID::Y_WIDTH, x_sz_revised); - buf->setPort(ID::A, SigSpec(A)); - buf->setParam(ID::A_SIGNED, true); - buf->setPort(ID::Y, SigSpec(expanded_A)); - - buf_name = "expand_b_buf_"; - buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setPort(ID::A, SigSpec(B)); - buf->setParam(ID::A_WIDTH, y_sz); - buf->setParam(ID::Y_WIDTH, y_sz_revised); - buf->setParam(ID::A_SIGNED, true); - buf->setPort(ID::Y, SigSpec(expanded_B)); - - // Make sure output domain is big enough to take - // all combinations. - // Later logic synthesis will kill unused - // portions of the output domain. - - unsigned required_op_size = x_sz_revised + y_sz_revised; - - Wire *expanded_Y = module->addWire(NEW_ID, required_op_size); - + else /*signed multiplier */ CreateBoothSMult(module, x_sz_revised, y_sz_revised, required_op_size, expanded_A, // multiplicand expanded_B, // multiplier(scanned) expanded_Y // result (sized) ); - // now connect the expanded_Y with a tap to fill out sig Spec Y - - log("Adding reducer on output from %u to %u ", required_op_size, z_sz); - buf_name = "reducer_buf_"; - buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setPort(ID::A, expanded_Y); - buf->setParam(ID::A_WIDTH, required_op_size); - buf->setParam(ID::Y_WIDTH, z_sz); // The real user width - buf->setParam(ID::A_SIGNED, true); - // wire in output Y - buf->setPort(ID::Y, SigSpec(Y)); - - // kill original multiplier - module->remove(cell); - booth_counter++; - continue; - } + module->remove(cell); + booth_counter++; + continue; } } } @@ -936,7 +834,7 @@ struct MultPassWorker { RTLIL::Wire *ha_op; BuildHa(ha_name, s_vec[n], c_vec[n - 1], ha_op, carry); - connect_sigSpecToWire(ha_op, SigSpec(result, n, 1)); + module->connect(ha_op, SigSpec(result, n, 1)); #ifdef DEBUG_CPA printf("CPA bit [%d] Cell %s IPs [%s] [%s] \n", n, ha_cell->name.c_str(), s_vec[n]->name.c_str(), @@ -971,11 +869,10 @@ struct MultPassWorker { RTLIL::Wire *ha_sum; RTLIL::Wire *ha_carry; BuildHa(ha_name, c_vec[n], carry, ha_sum, ha_carry); - if (n + 1 < (unsigned)GetSize(result)) - connect_sigSpecToWire(ha_sum, SigSpec(result, n + 1, 1)); + module->connect(ha_sum, SigSpec(result, n + 1, 1)); if (n + 2 < (unsigned)GetSize(result)) - connect_sigSpecToWire(ha_carry, SigSpec(result, n + 2, 1)); + module->connect(ha_carry, SigSpec(result, n + 2, 1)); } } // Step case @@ -1113,7 +1010,6 @@ struct MultPassWorker { { for (int y_ix = 0; y_ix < y_sz;) { std::string enc_name = "bur_enc_" + std::to_string(encoder_ix) + "_"; - log("Created booth encoder %s\n", enc_name.c_str()); std::string two_name = "two_int" + std::to_string(encoder_ix); two_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1)); @@ -1181,13 +1077,10 @@ struct MultPassWorker { if (need_padded_cell == true) { - log(" Creating padded encoder for unsigned\n"); - // make extra encoder cell // y_ix at y0, rest 0 std::string enc_name = "br_enc_pad" + std::to_string(encoder_ix) + "_"; - log("Created (padded) booth encoder %s\n", enc_name.c_str()); std::string two_name = "two_int" + std::to_string(encoder_ix); two_int.push_back(module->addWire(new_id(two_name, __LINE__, ""), 1)); @@ -1518,14 +1411,11 @@ struct MultPassWorker { // instantiate the cpa RTLIL::Wire *cpa_carry[z_sz]; - if (x_sz + y_sz != z_sz) - log("Result of multiplier is incomplete with respect to domain of inputs\n"); - for (int cix = 0; cix < z_sz; cix++) { std::string cpa_cix_name = "cpa_carry_" + std::to_string(cix) + "_"; cpa_carry[cix] = module->addWire(new_id(cpa_cix_name, __LINE__, ""), 1); } - log(" Building cpa array for booth for output size %u\n", z_sz); + for (int cpa_ix = 0; cpa_ix < z_sz; cpa_ix++) { // The end case where we pass the last two summands @@ -1565,7 +1455,7 @@ struct MultPassWorker { RTLIL::Wire *op_wire = module->addWire(NEW_ID, 1); BuildHa(cpa_name, fa_sum_n[fa_row_count - 1][cpa_ix - offset + 2], ci_wire, op_wire, cpa_carry[cpa_ix - offset]); - connect_sigSpecToWire(op_wire, SigSpec(Z, cpa_ix, 1)); + module->connect(op_wire, SigSpec(Z, cpa_ix, 1)); } } @@ -1599,7 +1489,7 @@ struct MultPassWorker { }; struct MultPass : public Pass { - MultPass() : Pass("multpass", "Map $mul to booth multipliers") {} + MultPass() : Pass("booth", "Map $mul to booth multipliers") {} void execute(vector args, RTLIL::Design *design) override { (void)args; diff --git a/tests/techmap/booth_map_script.ys_ b/tests/techmap/booth_map_script.ys_ index 0f323bdd863..d2fe5d3f0a3 100644 --- a/tests/techmap/booth_map_script.ys_ +++ b/tests/techmap/booth_map_script.ys_ @@ -1 +1 @@ -multpass +booth From 1d92ea8001d7fde5aca8d8fe27c3c4839a97453a Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Fri, 8 Sep 2023 16:16:24 -0700 Subject: [PATCH 094/119] Support for turning on mult pass from generic synth command --- techlibs/common/synth.cc | 70 +++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 63395c36802..01dadae7163 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -17,17 +17,16 @@ * */ -#include "kernel/register.h" #include "kernel/celltypes.h" -#include "kernel/rtlil.h" #include "kernel/log.h" +#include "kernel/register.h" +#include "kernel/rtlil.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct SynthPass : public ScriptPass -{ - SynthPass() : ScriptPass("synth", "generic synthesis script") { } +struct SynthPass : public ScriptPass { + SynthPass() : ScriptPass("synth", "generic synthesis script") {} void help() override { @@ -60,6 +59,9 @@ struct SynthPass : public ScriptPass log(" -noabc\n"); log(" do not run abc (as if yosys was compiled without ABC support)\n"); log("\n"); + log(" -booth\n"); + log(" run the booth pass to convert $mul to Booth encoded multipliers"); + log("\n"); log(" -noalumacc\n"); log(" do not run 'alumacc' pass. i.e. keep arithmetic operators in\n"); log(" their direct form ($add, $sub, etc.).\n"); @@ -93,7 +95,8 @@ struct SynthPass : public ScriptPass } string top_module, fsm_opts, memory_opts, abc; - bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap; + bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, mult; + int lut; void clear_flags() override @@ -110,6 +113,7 @@ struct SynthPass : public ScriptPass noabc = false; noshare = false; flowmap = false; + mult = false; abc = "abc"; } @@ -119,24 +123,23 @@ struct SynthPass : public ScriptPass clear_flags(); size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-top" && argidx+1 < args.size()) { + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-top" && argidx + 1 < args.size()) { top_module = args[++argidx]; continue; } - if (args[argidx] == "-encfile" && argidx+1 < args.size()) { + if (args[argidx] == "-encfile" && argidx + 1 < args.size()) { fsm_opts = " -encfile " + args[++argidx]; continue; } - if (args[argidx] == "-run" && argidx+1 < args.size()) { - size_t pos = args[argidx+1].find(':'); + if (args[argidx] == "-run" && argidx + 1 < args.size()) { + size_t pos = args[argidx + 1].find(':'); if (pos == std::string::npos) { run_from = args[++argidx]; run_to = args[argidx]; } else { run_from = args[++argidx].substr(0, pos); - run_to = args[argidx].substr(pos+1); + run_to = args[argidx].substr(pos + 1); } continue; } @@ -164,6 +167,11 @@ struct SynthPass : public ScriptPass noalumacc = true; continue; } + if (args[argidx] == "-mult") { + mult = true; + continue; + } + if (args[argidx] == "-nordff") { memory_opts += " -nordff"; continue; @@ -206,8 +214,7 @@ struct SynthPass : public ScriptPass void script() override { - if (check_label("begin")) - { + if (check_label("begin")) { if (help_mode) { run("hierarchy -check [-top | -auto-top]"); } else { @@ -221,8 +228,7 @@ struct SynthPass : public ScriptPass } } - if (check_label("coarse")) - { + if (check_label("coarse")) { run("proc"); if (help_mode || flatten) run("flatten", " (if -flatten)"); @@ -240,6 +246,8 @@ struct SynthPass : public ScriptPass 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 (mult) + run("booth"); if (!noalumacc) run("alumacc", " (unless -noalumacc)"); if (!noshare) @@ -249,50 +257,40 @@ struct SynthPass : public ScriptPass run("opt_clean"); } - if (check_label("fine")) - { + if (check_label("fine")) { run("opt -fast -full"); run("memory_map"); run("opt -full"); run("techmap"); - if (help_mode) - { + if (help_mode) { run("techmap -map +/gate2lut.v", "(if -noabc and -lut)"); run("clean; opt_lut", " (if -noabc and -lut)"); run("flowmap -maxlut K", " (if -flowmap and -lut)"); - } - else if (noabc && lut) - { + } else if (noabc && lut) { run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut)); run("clean; opt_lut"); - } - else if (flowmap) - { + } else if (flowmap) { run(stringf("flowmap -maxlut %d", lut)); } run("opt -fast"); if (!noabc && !flowmap) { - #ifdef YOSYS_ENABLE_ABC - if (help_mode) - { +#ifdef YOSYS_ENABLE_ABC + if (help_mode) { run(abc + " -fast", " (unless -noabc, unless -lut)"); run(abc + " -fast -lut k", "(unless -noabc, if -lut)"); - } - else - { + } else { if (lut) run(stringf("%s -fast -lut %d", abc.c_str(), lut)); else run(abc + " -fast"); } run("opt -fast", " (unless -noabc)"); - #endif +#endif } } - if (check_label("check")) - { + if (check_label("check")) { run("hierarchy -check"); run("stat"); run("check"); From 0fa412502cd19deef2d2972391e9b0e7c1726074 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Fri, 8 Sep 2023 16:44:59 -0700 Subject: [PATCH 095/119] mult -> booth in synth.cc, to turn on use synth -booth --- techlibs/common/synth.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index 01dadae7163..006a3c8dd84 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -95,7 +95,7 @@ struct SynthPass : public ScriptPass { } string top_module, fsm_opts, memory_opts, abc; - bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, mult; + bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth; int lut; @@ -113,7 +113,7 @@ struct SynthPass : public ScriptPass { noabc = false; noshare = false; flowmap = false; - mult = false; + booth = false; abc = "abc"; } @@ -167,8 +167,8 @@ struct SynthPass : public ScriptPass { noalumacc = true; continue; } - if (args[argidx] == "-mult") { - mult = true; + if (args[argidx] == "-booth") { + booth = true; continue; } @@ -246,7 +246,7 @@ struct SynthPass : public ScriptPass { 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 (mult) + if (booth) run("booth"); if (!noalumacc) run("alumacc", " (unless -noalumacc)"); From d77fb8150708f2e86bd6caa62424970cb3b71757 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Sun, 10 Sep 2023 12:45:36 -0700 Subject: [PATCH 096/119] 2d array -> 1d array in module generator --- passes/techmap/multpass.cc | 122 +++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 59 deletions(-) diff --git a/passes/techmap/multpass.cc b/passes/techmap/multpass.cc index c0e56f2ad61..5e8dcbc3bd8 100644 --- a/passes/techmap/multpass.cc +++ b/passes/techmap/multpass.cc @@ -1112,7 +1112,6 @@ struct MultPassWorker { /* Signed Multiplier */ - void CreateBoothSMult(RTLIL::Module *module, int x_sz, int y_sz, int z_sz, RTLIL::Wire *X, RTLIL::Wire *Y, RTLIL::Wire *Z) { // product unsigned enc_count = (y_sz / 2) + (((y_sz % 2) != 0) ? 1 : 0); @@ -1171,20 +1170,22 @@ struct MultPassWorker { cori_n_int[encoder_ix - 1]); } } + // Decoders and PP generation - RTLIL::Wire *PPij[enc_count][dec_count]; - RTLIL::Wire *nxj[enc_count][dec_count]; + RTLIL::Wire *PPij[enc_count * dec_count]; + RTLIL::Wire *nxj[enc_count * dec_count]; + for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) { for (int decoder_ix = 1; decoder_ix <= dec_count; decoder_ix++) { std::string ppij_name = "ppij_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; - PPij[encoder_ix - 1][decoder_ix - 1] = module->addWire(new_id(ppij_name, __LINE__, ""), 1); + PPij[((encoder_ix - 1) * dec_count) + decoder_ix - 1] = module->addWire(new_id(ppij_name, __LINE__, ""), 1); std::string nxj_name; if (decoder_ix == 1) nxj_name = "nxj_pre_dec" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; else nxj_name = "nxj_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; - nxj[encoder_ix - 1][decoder_ix - 1] = module->addWire(new_id(nxj_name, __LINE__, ""), 1); + nxj[((encoder_ix - 1) * dec_count) + decoder_ix - 1] = module->addWire(new_id(nxj_name, __LINE__, ""), 1); } } @@ -1202,7 +1203,7 @@ struct MultPassWorker { auto cell = module->addCell(new_id(pre_dec_name, __LINE__, ""), ID($_NOT_)); cell->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src)); cell->setPort(ID::A, negi_n_int[encoder_ix - 1]); - cell->setPort(ID::Y, nxj[encoder_ix - 1][0]); + cell->setPort(ID::Y, nxj[(encoder_ix - 1) * dec_count]); } for (int decoder_ix = 1; decoder_ix < dec_count; decoder_ix++) { @@ -1214,18 +1215,18 @@ struct MultPassWorker { std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(decoder_ix) + "_"; - BuildBr4d(dec_name, nxj[encoder_ix - 1][decoder_ix - 1], twoi_n_int[encoder_ix - 1], + BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + decoder_ix - 1], twoi_n_int[encoder_ix - 1], mk_wireFromSigSpec(SigSpec(X, decoder_ix - 1, 1)), negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], - PPij[encoder_ix - 1][decoder_ix - 1], nxj[encoder_ix - 1][decoder_ix]); + PPij[((encoder_ix - 1) * dec_count) + decoder_ix - 1], nxj[((encoder_ix - 1) * dec_count) + decoder_ix]); } // duplicate end for sign fix // applies to 9th decoder (xsz+1 decoder). std::string dec_name = "dec_" + std::to_string(encoder_ix) + "_" + std::to_string(x_sz + 1) + "_"; RTLIL::Wire *unused_op = nullptr; - BuildBr4d(dec_name, nxj[encoder_ix - 1][dec_count - 1], twoi_n_int[encoder_ix - 1], + BuildBr4d(dec_name, nxj[((encoder_ix - 1) * dec_count) + dec_count - 1], twoi_n_int[encoder_ix - 1], mk_wireFromSigSpec(SigSpec(X, dec_count - 2, 1)), negi_n_int[encoder_ix - 1], onei_n_int[encoder_ix - 1], - PPij[encoder_ix - 1][dec_count - 1], unused_op); + PPij[((encoder_ix - 1) * dec_count) + dec_count - 1], unused_op); } // @@ -1233,16 +1234,17 @@ struct MultPassWorker { // int fa_el_ix = 0; int fa_row_ix = 0; - RTLIL::Wire *fa_sum_n[fa_row_count][fa_count]; - RTLIL::Wire *fa_carry_n[fa_row_count][fa_count]; + // use 1 d arrays (2d cannot have variable sized indices) + RTLIL::Wire *fa_sum_n[fa_row_count * fa_count]; + RTLIL::Wire *fa_carry_n[fa_row_count * fa_count]; for (fa_row_ix = 0; fa_row_ix < fa_row_count; fa_row_ix++) { for (fa_el_ix = 0; fa_el_ix < fa_count; fa_el_ix++) { std::string fa_sum_name = "fa_sum_n_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_"; - fa_sum_n[fa_row_ix][fa_el_ix] = module->addWire(new_id(fa_sum_name, __LINE__, ""), 1); + fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix] = module->addWire(new_id(fa_sum_name, __LINE__, ""), 1); std::string fa_carry_name = "fa_carry_n" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_"; - fa_carry_n[fa_row_ix][fa_el_ix] = module->addWire(new_id(fa_carry_name, __LINE__, ""), 1); + fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix] = module->addWire(new_id(fa_carry_name, __LINE__, ""), 1); } } @@ -1268,11 +1270,11 @@ struct MultPassWorker { bfa_name = "bfa_0_step_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; auto cell = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); cell->setParam(ID::WIDTH, 1); - cell->setPort(ID::A, PPij[0][fa_el_ix]); - cell->setPort(ID::B, PPij[1][fa_el_ix - 2]); - cell->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell->setPort(ID::A, PPij[(0 * dec_count) + fa_el_ix]); + cell->setPort(ID::B, PPij[(1 * dec_count) + fa_el_ix - 2]); + cell->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); } // end 3 cells: x_sz+1.2.3 // @@ -1281,11 +1283,11 @@ struct MultPassWorker { bfa_name = "bfa_0_se_0" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); cell1->setParam(ID::WIDTH, 1); - cell1->setPort(ID::A, PPij[0][x_sz]); - cell1->setPort(ID::B, PPij[1][fa_el_ix - 2]); - cell1->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell1->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell1->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell1->setPort(ID::A, PPij[(0 * dec_count) + x_sz]); + cell1->setPort(ID::B, PPij[(1 * dec_count) + fa_el_ix - 2]); + cell1->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell1->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell1->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); // exception:invert ppi fa_el_ix++; @@ -1295,7 +1297,7 @@ struct MultPassWorker { RTLIL::Wire *d08_inv = module->addWire(NEW_ID, 1); - cellinv1->setPort(ID::A, PPij[0][dec_count - 1]); + cellinv1->setPort(ID::A, PPij[(0 * dec_count) + dec_count - 1]); cellinv1->setPort(ID::Y, d08_inv); exc_inv_name = "bfa_0_exc_inv2_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; @@ -1303,7 +1305,7 @@ struct MultPassWorker { auto cellinv2 = module->addCell(new_id(exc_inv_name, __LINE__, ""), ID($_NOT_)); cellinv2->add_strpool_attribute(ID::src, cellinv2->get_strpool_attribute(ID::src)); RTLIL::Wire *d18_inv = module->addWire(NEW_ID, 1); - cellinv2->setPort(ID::A, PPij[1][dec_count - 1]); + cellinv2->setPort(ID::A, PPij[(1 * dec_count) + dec_count - 1]); cellinv2->setPort(ID::Y, d18_inv); bfa_name = "bfa_0_se_1_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; @@ -1312,9 +1314,9 @@ struct MultPassWorker { cell2->setParam(ID::WIDTH, 1); cell2->setPort(ID::A, d08_inv); cell2->setPort(ID::B, d18_inv); - cell2->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell2->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell2->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell2->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell2->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell2->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); // sign extension fa_el_ix++; @@ -1323,9 +1325,9 @@ struct MultPassWorker { cell3->setParam(ID::WIDTH, 1); cell3->setPort(ID::A, State::S0); cell3->setPort(ID::B, State::S1); - cell3->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell3->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell3->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell3->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell3->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell3->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); } } @@ -1340,22 +1342,23 @@ struct MultPassWorker { std::to_string(fa_el_ix) + "_L"; auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); cell1->setParam(ID::WIDTH, 1); - cell1->setPort(ID::A, fa_sum_n[fa_row_ix - 1][2]); // from prior full adder row + cell1->setPort(ID::A, fa_sum_n[(fa_row_ix - 1) * fa_count + 2]); // from prior full adder row cell1->setPort(ID::B, State::S0); cell1->setPort(ID::C, cori_n_int[fa_row_ix]); - cell1->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell1->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell1->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell1->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); fa_el_ix++; bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_base_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; auto cell2 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); cell2->setParam(ID::WIDTH, 1); - cell2->setPort(ID::A, fa_sum_n[fa_row_ix - 1][3]); // from prior full adder row + cell2->setPort(ID::A, + fa_sum_n[(fa_row_ix - 1) * fa_count + 3]); // from prior full adder row cell2->setPort(ID::B, State::S0); - cell2->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell2->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell2->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell2->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell2->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell2->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); } else if (fa_el_ix >= 2 && fa_el_ix <= x_sz + 1) { @@ -1364,11 +1367,11 @@ struct MultPassWorker { std::to_string(fa_el_ix) + "_L"; auto cell = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); cell->setParam(ID::WIDTH, 1); - cell->setPort(ID::A, fa_sum_n[fa_row_ix - 1][fa_el_ix + 2]); - cell->setPort(ID::B, PPij[fa_row_ix + 1][fa_el_ix - 2]); - cell->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell->setPort(ID::A, fa_sum_n[(fa_row_ix - 1) * fa_count + fa_el_ix + 2]); + cell->setPort(ID::B, PPij[(fa_row_ix + 1) * dec_count + fa_el_ix - 2]); + cell->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); } else if (fa_el_ix > x_sz + 1) { @@ -1379,18 +1382,18 @@ struct MultPassWorker { auto cellinv = module->addCell(new_id(se_inv_name, __LINE__, ""), ID($_NOT_)); cellinv->add_strpool_attribute(ID::src, cellinv->get_strpool_attribute(ID::src)); RTLIL::Wire *d_inv = module->addWire(NEW_ID, 1); - cellinv->setPort(ID::A, PPij[fa_row_ix + 1][dec_count - 1]); + cellinv->setPort(ID::A, PPij[((fa_row_ix + 1) * dec_count) + dec_count - 1]); cellinv->setPort(ID::Y, d_inv); bfa_name = "bfa_" + std::to_string(fa_row_ix) + "_se_" + std::to_string(fa_row_ix) + "_" + std::to_string(fa_el_ix) + "_L"; auto cell1 = module->addCell(new_id(bfa_name, __LINE__, ""), ID($fa)); cell1->setParam(ID::WIDTH, 1); - cell1->setPort(ID::A, fa_carry_n[fa_row_ix - 1][fa_count - 1]); + cell1->setPort(ID::A, fa_carry_n[((fa_row_ix - 1) * fa_count) + fa_count - 1]); cell1->setPort(ID::B, d_inv); - cell1->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell1->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell1->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell1->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell1->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell1->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); fa_el_ix++; // sign extension @@ -1400,9 +1403,9 @@ struct MultPassWorker { cell2->setParam(ID::WIDTH, 1); cell2->setPort(ID::A, State::S0); cell2->setPort(ID::B, State::S1); - cell2->setPort(ID::C, fa_carry_n[fa_row_ix][fa_el_ix - 1]); - cell2->setPort(ID::X, fa_carry_n[fa_row_ix][fa_el_ix]); - cell2->setPort(ID::Y, fa_sum_n[fa_row_ix][fa_el_ix]); + cell2->setPort(ID::C, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix - 1]); + cell2->setPort(ID::X, fa_carry_n[(fa_row_ix * fa_count) + fa_el_ix]); + cell2->setPort(ID::Y, fa_sum_n[(fa_row_ix * fa_count) + fa_el_ix]); } } } @@ -1428,7 +1431,7 @@ struct MultPassWorker { std::string buf_name = "pp_buf_" + std::to_string(cpa_ix) + "_" + "driven_by_fa_row_" + std::to_string(fa_row_ix) + "_"; auto buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setPort(ID::A, fa_sum_n[fa_row_ix][0]); + buf->setPort(ID::A, fa_sum_n[(fa_row_ix * fa_count) + 0]); buf->setParam(ID::A_WIDTH, 1); buf->setParam(ID::Y_WIDTH, 1); buf->setParam(ID::A_SIGNED, true); @@ -1437,7 +1440,7 @@ struct MultPassWorker { cpa_ix++; buf_name = "pp_buf_" + std::to_string(cpa_ix) + "_" + "driven_by_fa_row_" + std::to_string(fa_row_ix) + "_"; buf = module->addCell(new_id(buf_name, __LINE__, ""), ID($pos)); - buf->setPort(ID::A, fa_sum_n[fa_row_ix][1]); + buf->setPort(ID::A, fa_sum_n[(fa_row_ix * fa_count) + 1]); buf->setParam(ID::A_WIDTH, 1); buf->setParam(ID::Y_WIDTH, 1); buf->setParam(ID::A_SIGNED, true); @@ -1454,7 +1457,8 @@ struct MultPassWorker { ci_wire = cpa_carry[cpa_ix - offset - 1]; RTLIL::Wire *op_wire = module->addWire(NEW_ID, 1); - BuildHa(cpa_name, fa_sum_n[fa_row_count - 1][cpa_ix - offset + 2], ci_wire, op_wire, cpa_carry[cpa_ix - offset]); + BuildHa(cpa_name, fa_sum_n[(fa_row_count - 1) * fa_count + cpa_ix - offset + 2], ci_wire, op_wire, + cpa_carry[cpa_ix - offset]); module->connect(op_wire, SigSpec(Z, cpa_ix, 1)); } } @@ -1481,10 +1485,10 @@ struct MultPassWorker { nxj_o_int, cor_o_int, pp0_o_int, pp1_o_int); - join_wires_with_buffer(pp0_o_int, fa_sum_n[0][0]); - join_wires_with_buffer(pp1_o_int, fa_sum_n[0][1]); - join_wires_with_buffer(cor_o_int, fa_carry_n[0][1]); - join_wires_with_buffer(nxj_o_int, nxj[0][2]); + join_wires_with_buffer(pp0_o_int, fa_sum_n[(0 * fa_count) + 0]); + join_wires_with_buffer(pp1_o_int, fa_sum_n[(0 * fa_count) + 1]); + join_wires_with_buffer(cor_o_int, fa_carry_n[(0 * fa_count) + 1]); + join_wires_with_buffer(nxj_o_int, nxj[(0 * dec_count) + 2]); } }; From 8d4b6c2f69b5f6b2fb09289a535b74a20e7a7735 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Sun, 10 Sep 2023 13:31:47 -0700 Subject: [PATCH 097/119] Switched arrays for signed multiplier construction to heap --- passes/techmap/multpass.cc | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/passes/techmap/multpass.cc b/passes/techmap/multpass.cc index 5e8dcbc3bd8..00dcc6e2740 100644 --- a/passes/techmap/multpass.cc +++ b/passes/techmap/multpass.cc @@ -1124,10 +1124,10 @@ struct MultPassWorker { "Result of size %d. %d encoders %d decoders\n", x_sz, y_sz, z_sz, enc_count, dec_count); - RTLIL::Wire *negi_n_int[enc_count]; - RTLIL::Wire *twoi_n_int[enc_count]; - RTLIL::Wire *onei_n_int[enc_count]; - RTLIL::Wire *cori_n_int[enc_count]; + RTLIL::Wire **negi_n_int = new RTLIL::Wire *[enc_count]; + RTLIL::Wire **twoi_n_int = new RTLIL::Wire *[enc_count]; + RTLIL::Wire **onei_n_int = new RTLIL::Wire *[enc_count]; + RTLIL::Wire **cori_n_int = new RTLIL::Wire *[enc_count]; for (unsigned encoder_ix = 1; encoder_ix <= enc_count; encoder_ix++) { std::string enc_name = "enc_" + std::to_string(encoder_ix) + "_"; @@ -1172,8 +1172,8 @@ struct MultPassWorker { } // Decoders and PP generation - RTLIL::Wire *PPij[enc_count * dec_count]; - RTLIL::Wire *nxj[enc_count * dec_count]; + RTLIL::Wire **PPij = new RTLIL::Wire *[enc_count * dec_count]; + RTLIL::Wire **nxj = new RTLIL::Wire *[enc_count * dec_count]; for (int encoder_ix = 1; encoder_ix <= (int)enc_count; encoder_ix++) { for (int decoder_ix = 1; decoder_ix <= dec_count; decoder_ix++) { @@ -1235,8 +1235,8 @@ struct MultPassWorker { int fa_el_ix = 0; int fa_row_ix = 0; // use 1 d arrays (2d cannot have variable sized indices) - RTLIL::Wire *fa_sum_n[fa_row_count * fa_count]; - RTLIL::Wire *fa_carry_n[fa_row_count * fa_count]; + RTLIL::Wire **fa_sum_n = new RTLIL::Wire *[fa_row_count * fa_count]; + RTLIL::Wire **fa_carry_n = new RTLIL::Wire *[fa_row_count * fa_count]; for (fa_row_ix = 0; fa_row_ix < fa_row_count; fa_row_ix++) { for (fa_el_ix = 0; fa_el_ix < fa_count; fa_el_ix++) { @@ -1489,6 +1489,14 @@ struct MultPassWorker { join_wires_with_buffer(pp1_o_int, fa_sum_n[(0 * fa_count) + 1]); join_wires_with_buffer(cor_o_int, fa_carry_n[(0 * fa_count) + 1]); join_wires_with_buffer(nxj_o_int, nxj[(0 * dec_count) + 2]); + + delete[] negi_n_int; + delete[] twoi_n_int; + delete[] onei_n_int; + delete[] cori_n_int; + + delete[] fa_sum_n; + delete[] fa_carry_n; } }; From 1b5287af5908e71edd07d9de2d6872f3c2a389ed Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Sun, 10 Sep 2023 14:20:30 -0700 Subject: [PATCH 098/119] cpa_carry array added to heap --- passes/techmap/multpass.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/techmap/multpass.cc b/passes/techmap/multpass.cc index 00dcc6e2740..9e97fc6741e 100644 --- a/passes/techmap/multpass.cc +++ b/passes/techmap/multpass.cc @@ -1412,7 +1412,7 @@ struct MultPassWorker { } // instantiate the cpa - RTLIL::Wire *cpa_carry[z_sz]; + RTLIL::Wire **cpa_carry = new RTLIL::Wire *[z_sz]; for (int cix = 0; cix < z_sz; cix++) { std::string cpa_cix_name = "cpa_carry_" + std::to_string(cix) + "_"; @@ -1497,6 +1497,7 @@ struct MultPassWorker { delete[] fa_sum_n; delete[] fa_carry_n; + delete[] cpa_carry; } }; From bef7ffccc1103ac6e96934acf3bf8fd806df851a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 11 Sep 2023 16:25:58 +0200 Subject: [PATCH 099/119] Update ABC to latest --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9474d37a19d..c3fc4145837 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = bb64142 +ABCREV = 9537f39 ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From a2c8e47295dbb93faeb2f949ce354c4faa919fc9 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Mon, 11 Sep 2023 11:39:13 -0700 Subject: [PATCH 100/119] multpass.cc -> booth.cc, added author/support contact info --- passes/techmap/Makefile.inc | 5 +---- passes/techmap/{multpass.cc => booth.cc} | 12 ++++++++---- 2 files changed, 9 insertions(+), 8 deletions(-) rename passes/techmap/{multpass.cc => booth.cc} (99%) diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index 8b0b2aa23b7..fb003103d28 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -4,7 +4,7 @@ OBJS += passes/techmap/techmap.o OBJS += passes/techmap/simplemap.o OBJS += passes/techmap/dfflibmap.o OBJS += passes/techmap/maccmap.o -OBJS += passes/techmap/multpass.o +OBJS += passes/techmap/booth.o OBJS += passes/techmap/libparse.o ifeq ($(ENABLE_ABC),1) @@ -30,9 +30,6 @@ OBJS += passes/techmap/extract_reduce.o OBJS += passes/techmap/alumacc.o OBJS += passes/techmap/dffinit.o OBJS += passes/techmap/pmuxtree.o -OBJS += passes/techmap/bmuxmap.o -OBJS += passes/techmap/demuxmap.o -OBJS += passes/techmap/bwmuxmap.o OBJS += passes/techmap/muxcover.o OBJS += passes/techmap/aigmap.o OBJS += passes/techmap/tribuf.o diff --git a/passes/techmap/multpass.cc b/passes/techmap/booth.cc similarity index 99% rename from passes/techmap/multpass.cc rename to passes/techmap/booth.cc index 9e97fc6741e..21f16aec7a8 100644 --- a/passes/techmap/multpass.cc +++ b/passes/techmap/booth.cc @@ -1,6 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * + * Copyright (C) 2023 Andy Fox https://www.linkedin.com/in/awfox/ * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,8 +18,8 @@ */ /* - MultPass - -------- + Booth Pass + ---------- Replace $mul with booth encoded multipliers. Two different architectures used for signed/unsigned. @@ -31,13 +32,13 @@ http://i.stanford.edu/pub/cstr/reports/csl/tr/94/617/CSL-TR-94-617.pdf How to use: - Add multpass to your yosys script eg: + Add booth pass to your yosys script eg: read_verilog smultiply5_rtl.v opt wreduce opt - multpass + booth alumacc maccmap opt @@ -46,6 +47,9 @@ abc -liberty NangateOpenCellLibrary_typical.lib stat -liberty NangateOpenCellLibrary_typical.lib write_verilog -norename booth_final.v + +or in generic synthesis call with -booth argument: +synth -top my_design -booth */ #include "kernel/sigtools.h" From eccc0ae6db50effc7f42d69038918483d6888089 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Mon, 11 Sep 2023 12:14:12 -0700 Subject: [PATCH 101/119] Based passes/techmap/Makefile.inc changes on latest in yosys --- passes/techmap/Makefile.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/techmap/Makefile.inc b/passes/techmap/Makefile.inc index fb003103d28..97d8b76f3b8 100644 --- a/passes/techmap/Makefile.inc +++ b/passes/techmap/Makefile.inc @@ -30,6 +30,9 @@ OBJS += passes/techmap/extract_reduce.o OBJS += passes/techmap/alumacc.o OBJS += passes/techmap/dffinit.o OBJS += passes/techmap/pmuxtree.o +OBJS += passes/techmap/bmuxmap.o +OBJS += passes/techmap/demuxmap.o +OBJS += passes/techmap/bwmuxmap.o OBJS += passes/techmap/muxcover.o OBJS += passes/techmap/aigmap.o OBJS += passes/techmap/tribuf.o From e4fe522767c3ddfeb90c2f4091890cb45584e0e9 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Mon, 11 Sep 2023 13:00:11 -0700 Subject: [PATCH 102/119] MultPassWorker -> BoothPassWorker --- passes/techmap/booth.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/passes/techmap/booth.cc b/passes/techmap/booth.cc index 21f16aec7a8..e749168522d 100644 --- a/passes/techmap/booth.cc +++ b/passes/techmap/booth.cc @@ -58,13 +58,13 @@ synth -top my_design -booth USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct MultPassWorker { +struct BoothPassWorker { RTLIL::Module *module; SigMap sigmap; int booth_counter; - MultPassWorker(RTLIL::Module *module) : module(module), sigmap(module) { booth_counter = 0; } + BoothPassWorker(RTLIL::Module *module) : module(module), sigmap(module) { booth_counter = 0; } // Helper routines for building architecture subcomponents @@ -1505,15 +1505,16 @@ struct MultPassWorker { } }; -struct MultPass : public Pass { - MultPass() : Pass("booth", "Map $mul to booth multipliers") {} +struct BoothPass : public Pass { + BoothPass() : Pass("booth", "Map $mul to booth multipliers") {} void execute(vector args, RTLIL::Design *design) override { (void)args; - log_header(design, "Executing multpass. Generating Booth Multiplier structures for signed/unsigned multipliers of 4 bits or more\n"); + log_header(design, + "Executing booth pass. Generating Booth Multiplier structures for signed/unsigned multipliers of 4 bits or more\n"); for (auto mod : design->selected_modules()) if (!mod->has_processes_warn()) { - MultPassWorker worker(mod); + BoothPassWorker worker(mod); worker.run(); log_header(design, "Created %d booth multipliers.\n", worker.booth_counter); } From 7b134c2a8cd63222fd005315f1a07c20e97fd546 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 12 Sep 2023 11:56:15 +0200 Subject: [PATCH 103/119] verific - respect order of read and write for rams --- frontends/verific/verific.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index b0d789d8fa3..4f4fbcb746e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2951,6 +2951,9 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("db_infer_wide_operators", 1); RuntimeFlags::SetVar("db_infer_set_reset_registers", 0); + // Properly respect order of read and write for rams + RuntimeFlags::SetVar("db_change_inplace_ram_blocking_write_before_read", 1); + RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); RuntimeFlags::SetVar("veri_allow_any_ram_in_loop", 1); From cbc4ec8178ddc67e397ccd0800048a26d1f41451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 12 Sep 2023 14:54:03 +0200 Subject: [PATCH 104/119] mem: Fix index confusion in write port merging Fix mistaking the read-port and write-port indices for each other when we are adding the partial transparency emulation to be able to merge two write ports. --- kernel/mem.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 628f6210499..269a476a125 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -1252,12 +1252,12 @@ void Mem::prepare_wr_merge(int idx1, int idx2, FfInitVals *initvals) { // If transparent with only one, emulate it, and remove the collision-X // flag that emulate_transparency will set (to align with the other port). if (rport.transparency_mask[idx1]) { - emulate_transparency(i, idx1, initvals); + emulate_transparency(idx1, i, initvals); rport.collision_x_mask[idx1] = false; continue; } if (rport.transparency_mask[idx2]) { - emulate_transparency(i, idx2, initvals); + emulate_transparency(idx2, i, initvals); rport.collision_x_mask[idx2] = false; continue; } From 98b9459535681a0c3a4739f208a32dfc50c9bfea Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 12 Sep 2023 18:12:07 +0200 Subject: [PATCH 105/119] fmt: Fix C++ string assertion when buf is empty Signed-off-by: gatecat --- kernel/fmt.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 69bdbb013b0..965e58ebce4 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -740,7 +740,7 @@ std::string Fmt::render() const log_assert(part.width == 0 || part.padding != '\0'); if (part.justify == FmtPart::RIGHT && buf.size() < part.width) { size_t pad_width = part.width - buf.size(); - if (part.padding == '0' && (buf.front() == '+' || buf.front() == '-')) { + if (part.padding == '0' && (!buf.empty() && (buf.front() == '+' || buf.front() == '-'))) { str += buf.front(); buf.erase(0, 1); } From 08f79d111e9be151e9ede91491a6e2c2080ad847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Sat, 9 Sep 2023 22:32:51 +0200 Subject: [PATCH 106/119] ci: Enable extra libstdc++ assertions --- .github/workflows/test-linux.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index eee556794af..a16481726d3 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -43,6 +43,7 @@ jobs: sudo apt-get install $CC $CXX echo "CC=$CC" >> $GITHUB_ENV echo "CXX=$CXX" >> $GITHUB_ENV + echo "CXXFLAGS=-Wp,-D_GLIBCXX_ASSERTIONS" >> $GITHUB_ENV env: CC: ${{ matrix.compiler }} From 9e004426e0783d5bbbe846be54b8266451cd5f7f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:14:55 +0000 Subject: [PATCH 107/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c3fc4145837..0c79636497f 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+6 +YOSYS_VER := 0.33+21 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 54050a8c16dbd9bf8bf17db08201fca23a3b4723 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 7 Jun 2023 10:20:16 +0200 Subject: [PATCH 108/119] Basic support for tag primitives --- frontends/verific/verific.cc | 32 +++++++++++++++ kernel/celltypes.h | 4 ++ kernel/constids.inc | 1 + kernel/rtlil.cc | 77 ++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 5 +++ techlibs/common/simlib.v | 57 ++++++++++++++++++++++++++ 6 files changed, 176 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4f4fbcb746e..6000df9e628 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1103,6 +1103,38 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } + if (inst->Type() == OPER_YOSYSHQ_SET_TAG) + { + RTLIL::SigSpec sig_expr = operatorInport(inst, "expr"); + RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); + RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); + RTLIL::SigSpec sig_o = operatorOutput(inst); + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->connect(sig_o, module->SetTag(new_verific_id(inst), tag, sig_expr, sig_set_mask, sig_clr_mask)); + return true; + } + if (inst->Type() == OPER_YOSYSHQ_GET_TAG) + { + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->connect(operatorOutput(inst),module->GetTag(new_verific_id(inst), tag, operatorInput(inst))); + return true; + } + if (inst->Type() == OPER_YOSYSHQ_OVERWRITE_TAG) + { + RTLIL::SigSpec sig_signal = operatorInport(inst, "signal"); + RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); + RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->addOverwriteTag(new_verific_id(inst), tag, sig_signal, sig_set_mask, sig_clr_mask); + return true; + } + if (inst->Type() == OPER_YOSYSHQ_ORIGINAL_TAG) + { + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->connect(operatorOutput(inst),module->OriginalTag(new_verific_id(inst), tag, operatorInput(inst))); + return true; + } + #undef IN #undef IN1 #undef IN2 diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 4a0621a7386..573ea0b4276 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -102,6 +102,10 @@ struct CellTypes setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool(), true); setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool(), true); setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool()); + setup_type(ID($set_tag), {ID::A, ID::SET, ID::CLR}, {ID::Y}); + setup_type(ID($get_tag), {ID::A}, {ID::Y}); + setup_type(ID($overwrite_tag), {ID::A, ID::SET, ID::CLR}, pool()); + setup_type(ID($original_tag), {ID::A}, {ID::Y}); } void setup_internals_eval() diff --git a/kernel/constids.inc b/kernel/constids.inc index 08b0ecdc2b4..93101282a0b 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -208,6 +208,7 @@ X(syn_romstyle) X(S_WIDTH) X(T) X(TABLE) +X(TAG) X(techmap_autopurge) X(_TECHMAP_BITS_CONNMAP_) X(_TECHMAP_CELLNAME_) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7a59c526275..2563aa21aa6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1828,6 +1828,33 @@ namespace { ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), 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; } + if (cell->type.in(ID($set_tag))) { + param(ID::WIDTH); + param(ID::TAG); + port(ID::A, param(ID::WIDTH)); + port(ID::SET, param(ID::WIDTH)); + port(ID::CLR, param(ID::WIDTH)); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type.in(ID($get_tag),ID($original_tag))) { + param(ID::WIDTH); + param(ID::TAG); + port(ID::A, param(ID::WIDTH)); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type.in(ID($overwrite_tag))) { + param(ID::WIDTH); + param(ID::TAG); + port(ID::A, param(ID::WIDTH)); + port(ID::SET, param(ID::WIDTH)); + port(ID::CLR, param(ID::WIDTH)); + check_expected(); + return; + } error(__LINE__); } }; @@ -3246,6 +3273,56 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string return sig; } +RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($set_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::SET, sig_s); + cell->setPort(ID::CLR, sig_c); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + +RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($get_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + +RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($overwrite_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::SET, sig_s); + cell->setPort(ID::CLR, sig_c); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($original_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + RTLIL::Wire::Wire() { static unsigned int hashidx_count = 123456789; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a69ce480baf..d29150d32ce 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1465,6 +1465,11 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = ""); RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = ""); + RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + #ifdef WITH_PYTHON static std::map *get_all_modules(void); #endif diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index cdb6e02e762..429e95b2853 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2671,3 +2671,60 @@ endmodule `endif // -------------------------------------------------------- + +module \$set_tag (A, SET, CLR, Y); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +input [WIDTH-1:0] SET; +input [WIDTH-1:0] CLR; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- + +module \$get_tag (A, Y); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- + +module \$overwrite_tag (A, SET, CLR); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +input [WIDTH-1:0] SET; +input [WIDTH-1:0] CLR; + +endmodule + +// -------------------------------------------------------- + +module \$original_tag (A, Y); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- From 9c255c98b17a8c5258666edf2d323818431def9d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 21 Jun 2023 17:09:28 +0200 Subject: [PATCH 109/119] unescape string tag attribute --- frontends/verific/verific.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6000df9e628..be417c9dc63 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -251,6 +251,14 @@ static const RTLIL::Const verific_const(const char *value, bool allow_string = t return c; } +static const std::string verific_unescape(const char *value) +{ + std::string val = std::string(value); + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') + return val.substr(1,val.size()-2); + return value; +} + void VerificImporter::import_attributes(dict &attributes, DesignObj *obj, Netlist *nl) { MapIter mi; @@ -1109,13 +1117,13 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); RTLIL::SigSpec sig_o = operatorOutput(inst); - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->connect(sig_o, module->SetTag(new_verific_id(inst), tag, sig_expr, sig_set_mask, sig_clr_mask)); return true; } if (inst->Type() == OPER_YOSYSHQ_GET_TAG) { - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->connect(operatorOutput(inst),module->GetTag(new_verific_id(inst), tag, operatorInput(inst))); return true; } @@ -1124,13 +1132,13 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr RTLIL::SigSpec sig_signal = operatorInport(inst, "signal"); RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->addOverwriteTag(new_verific_id(inst), tag, sig_signal, sig_set_mask, sig_clr_mask); return true; } if (inst->Type() == OPER_YOSYSHQ_ORIGINAL_TAG) { - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->connect(operatorOutput(inst),module->OriginalTag(new_verific_id(inst), tag, operatorInput(inst))); return true; } From 27ac91270991ad7c2304e5f90a5c1001c2f08ec1 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 24 Aug 2023 11:55:30 +0200 Subject: [PATCH 110/119] Support import of $future_ff --- frontends/verific/verific.cc | 5 +++++ kernel/celltypes.h | 1 + kernel/rtlil.cc | 18 ++++++++++++++++++ kernel/rtlil.h | 1 + techlibs/common/simlib.v | 13 +++++++++++++ 5 files changed, 38 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index be417c9dc63..d30b46082e1 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1142,6 +1142,11 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr module->connect(operatorOutput(inst),module->OriginalTag(new_verific_id(inst), tag, operatorInput(inst))); return true; } + if (inst->Type() == OPER_YOSYSHQ_FUTURE_FF) + { + module->connect(operatorOutput(inst),module->FutureFF(new_verific_id(inst), operatorInput(inst))); + return true; + } #undef IN #undef IN1 diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 573ea0b4276..cad505d9afd 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -106,6 +106,7 @@ struct CellTypes setup_type(ID($get_tag), {ID::A}, {ID::Y}); setup_type(ID($overwrite_tag), {ID::A, ID::SET, ID::CLR}, pool()); setup_type(ID($original_tag), {ID::A}, {ID::Y}); + setup_type(ID($future_ff), {ID::A}, {ID::Y}); } void setup_internals_eval() diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2563aa21aa6..7d257714460 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1855,6 +1855,13 @@ namespace { check_expected(); return; } + if (cell->type.in(ID($future_ff))) { + param(ID::WIDTH); + port(ID::A, param(ID::WIDTH)); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } error(__LINE__); } }; @@ -3323,6 +3330,17 @@ RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::strin return sig; } +RTLIL::SigSpec RTLIL::Module::FutureFF(RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($future_ff)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->setPort(ID::A, sig_e); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + RTLIL::Wire::Wire() { static unsigned int hashidx_count = 123456789; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d29150d32ce..012865a75c6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1469,6 +1469,7 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src = ""); #ifdef WITH_PYTHON static std::map *get_all_modules(void); diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 429e95b2853..fd804786fd8 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2728,3 +2728,16 @@ assign Y = A; endmodule // -------------------------------------------------------- + +module \$future_ff (A, Y); + +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- From 7a0c37b62d5fadf1ae95afbc9daced71a44fc724 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 13 Jul 2023 14:04:40 +0200 Subject: [PATCH 111/119] Initial dft_tag implementation This is still missing a mode to rewrite $overwrite_tag and $original_tag by injecting $set_tag and $get_tag in the right places. It's also missing bit-precise propagation models for shifts and arithmetic and requires the design to be flattened. --- passes/cmds/Makefile.inc | 1 + passes/cmds/dft_tag.cc | 932 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 933 insertions(+) create mode 100644 passes/cmds/dft_tag.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 29b3a1132ad..f3cd9b9509b 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -46,3 +46,4 @@ OBJS += passes/cmds/printattrs.o OBJS += passes/cmds/sta.o OBJS += passes/cmds/clean_zerowidth.o OBJS += passes/cmds/xprop.o +OBJS += passes/cmds/dft_tag.o diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc new file mode 100644 index 00000000000..24fdf9714c8 --- /dev/null +++ b/passes/cmds/dft_tag.cc @@ -0,0 +1,932 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2022 Jannis Harder + * + * 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/ff.h" +#include "kernel/modtools.h" +#include "kernel/sigtools.h" +#include "kernel/yosys.h" +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct DftTagOptions { + bool tag_public; +}; + +struct DftTagWorker { + Module *module; + DftTagOptions options; + ModWalker modwalker; + SigMap &sigmap; + FfInitVals initvals; + + struct tag_set { + int index = 0; + + tag_set(int index = 0) : index(index) {} + + bool operator<(const tag_set &other) const { return index < other.index; } + bool operator==(const tag_set &other) const { return index == other.index; } + + unsigned int hash() const { return hash_ops::hash(index); } + + bool empty() const { return index == 0; } + }; + + idict> tag_sets; + + pool tmp_tag_set; + dict, tag_set> tag_set_union_cache; + + dict tagged_signals; + + dict> tag_groups; + dict group_of_tag; + pool all_tags; + + pool pending_cells; + std::deque pending_cell_queue; + + dict, SigBit> tag_signals; + + // Uses SigSpec instead of SigBit so we can use coarse grained cells to combine the individual tags + dict, SigSpec> tag_group_signals; + + pool warned_cells; + + DftTagWorker(Module *module, DftTagOptions options) : + module(module), options(options), modwalker(module->design), sigmap(modwalker.sigmap) + { + modwalker.setup(module); + initvals.set(&modwalker.sigmap, module); + tag_sets(tmp_tag_set); + } + + const pool &tag_pool(tag_set set) { return tag_sets[set.index]; } + + tag_set singleton(IdString tag) + { + tmp_tag_set.clear(); + tmp_tag_set.emplace(tag); + return tag_sets(tmp_tag_set); + } + + tag_set merge(tag_set a, tag_set b) + { + if (b < a) + std::swap(a, b); + if (a.empty() || a == b) + return b; + auto found = tag_set_union_cache.find(std::make_pair(a, b)); + if (found == tag_set_union_cache.end()) { + tmp_tag_set.clear(); + auto &a_tags = tag_pool(a); + auto &b_tags = tag_pool(b); + tmp_tag_set.insert(a_tags.begin(), a_tags.end()); + tmp_tag_set.insert(b_tags.begin(), b_tags.end()); + tag_set result = tag_sets(tmp_tag_set); + tag_set_union_cache.emplace(std::make_pair(a, b), result); + return result; + } + return found->second; + } + + tag_set tags(SigBit bit) + { + sigmap.apply(bit); + auto found = tagged_signals.find(bit); + if (found != tagged_signals.end()) + return found->second; + return tag_set(); + } + + tag_set tags(SigSpec sig) + { + tag_set result; + for (auto bit : sig) + result = merge(result, tags(bit)); + return result; + } + + tag_set tags(Cell *cell) + { + tag_set result; + for (auto &conn : cell->connections()) { + if (cell->input(conn.first)) + result = merge(result, tags(conn.second)); + } + return result; + } + + void add_tags(SigBit bit, tag_set new_tags) + { + sigmap.apply(bit); + auto &tags = tagged_signals[bit]; + tag_set merged_tags = merge(tags, new_tags); + if (merged_tags == tags) + return; + tags = merged_tags; + auto it = modwalker.signal_consumers.find(bit); + if (it == modwalker.signal_consumers.end()) + return; + for (auto &consumer : it->second) + if (pending_cells.insert(consumer.cell).second) + pending_cell_queue.push_back(consumer.cell); + } + + void add_tags(SigSpec sig, tag_set new_tags) + { + for (auto bit : sigmap(sig)) + add_tags(bit, new_tags); + } + + void add_tags(Cell *cell, tag_set new_tags) + { + for (auto &conn : cell->connections()) + if (cell->output(conn.first)) + add_tags(conn.second, new_tags); + } + + void forward_tags(SigSpec dst, SigSpec src) + { + log_assert(GetSize(dst) == GetSize(src)); + for (int i = 0; i < GetSize(dst); i++) + add_tags(dst[i], tags(src[i])); + } + + void propagate_tags() + { + for (auto cell : module->cells()) { + if (cell->type == ID($set_tag)) { + pending_cells.insert(cell); + pending_cell_queue.push_back(cell); + } + } + + while (!pending_cell_queue.empty()) { + Cell *cell = pending_cell_queue.front(); + pending_cell_queue.pop_front(); + pending_cells.erase(cell); + + propagate_tags(cell); + } + } + + SigBit tag_signal(IdString tag, SigBit bit) + { + sigmap.apply(bit); + if (!bit.is_wire()) + return State::S0; // Constant value - no tags + + auto found = tag_signals.find(std::make_pair(tag, bit)); + if (found != tag_signals.end()) + return found->second; + + if (!tag_pool(tags(bit)).count(tag)) + return State::S0; // Statically known to not have this tag + + // TODO handle module inputs + auto drivers = modwalker.signal_drivers.find(bit); + if (drivers == modwalker.signal_drivers.end() || drivers->second.empty()) + return State::S0; // No driver - no tags + + log_assert(drivers->second.size() == 1); + auto driver = *drivers->second.begin(); + + emit_tag_signals(tag, driver.cell); + + found = tag_signals.find(std::make_pair(tag, bit)); + log_assert(found != tag_signals.end()); + return found->second; + } + + SigSpec tag_signal(IdString tag, SigSpec sig) + { + SigSpec result; + for (auto bit : sig) + result.append(tag_signal(tag, bit)); + return result; + } + + SigSpec tag_group_signal(IdString tag_group, SigSpec sig) + { + sigmap.apply(sig); + if (sig.is_fully_const() || tag_groups.count(tag_group) == 0) + return Const(0, GetSize(sig)); + + auto found = tag_group_signals.find(std::make_pair(tag_group, sig)); + if (found != tag_group_signals.end()) + return found->second; + + SigSpec combined; + + for (auto &tag : tag_groups[tag_group]) { + auto tag_sig = tag_signal(tag, sig); + + if (!GetSize(combined)) + combined = tag_sig; + else + combined = autoOr(NEW_ID, combined, tag_sig); + } + + if (!GetSize(combined)) + combined = Const(0, GetSize(sig)); + + tag_group_signals.emplace(std::make_pair(tag_group, sig), combined); + return combined; + } + + void emit_tag_signal(IdString tag, SigBit bit, SigBit tag_bit) + { + sigmap.apply(bit); + sigmap.apply(tag_bit); + + if (!tag_pool(tags(bit)).count(tag)) + return; + + auto key = std::make_pair(tag, bit); + auto found = tag_signals.find(key); + if (found != tag_signals.end()) { + module->connect(found->second, tag_bit); + return; + } + tag_signals.emplace(key, tag_bit); + } + + void emit_tag_signal(IdString tag, SigSpec sig, SigSpec tag_sig) + { + log_assert(GetSize(sig) == GetSize(tag_sig)); + for (int i = 0; i < GetSize(sig); i++) + emit_tag_signal(tag, sig[i], tag_sig[i]); + } + + void emit_tag_signals(IdString tag, Cell *cell) + { + if (!pending_cells.insert(cell).second) { + // We have a cycle, emit placeholder wires which will be connected + // when the outer call for this tag/cell returns + for (auto &conn : cell->connections()) + if (cell->output(conn.first)) + emit_tag_signal(tag, conn.second, module->addWire(NEW_ID, GetSize(conn.second))); + + return; + } + + process_cell(tag, cell); + + pending_cells.erase(cell); + } + + void propagate_tags(Cell *cell) + { + if (cell->type == ID($set_tag)) { + IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + if (all_tags.insert(tag).second) { + auto group_sep = tag.str().find(':'); + IdString tag_group = group_sep != std::string::npos ? tag.str().substr(0, group_sep) : tag; + tag_groups[tag_group].insert(tag); + group_of_tag[tag] = tag_group; + } + + auto &sig_y = cell->getPort(ID::Y); + auto &sig_a = cell->getPort(ID::A); + // TODO handle constant set/clr masks + add_tags(sig_y, singleton(tag)); + forward_tags(sig_y, sig_a); + return; + } + + if (cell->type == ID($get_tag)) { + return; + } + + if (cell->type.in(ID($not), ID($pos))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + if (cell->type.in(ID($not), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + } + forward_tags(sig_y, sig_a); + return; + } + + if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($bweqx))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + if (cell->type.in(ID($and), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); + } + forward_tags(sig_y, sig_a); + forward_tags(sig_y, sig_b); + return; + } + + if (cell->type.in(ID($mux), ID($bwmux))) { + auto &sig_y = cell->getPort(ID::Y); + auto &sig_a = cell->getPort(ID::A); + auto &sig_b = cell->getPort(ID::B); + auto sig_s = cell->getPort(ID::S); + + if (cell->type == ID($mux)) + sig_s = SigSpec(sig_s[0], GetSize(sig_y)); + + forward_tags(sig_y, sig_a); + forward_tags(sig_y, sig_b); + forward_tags(sig_y, sig_s); + return; + } + + if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + FfData ff(&initvals, cell); + + if (ff.has_clk || ff.has_gclk) + forward_tags(ff.sig_q, ff.sig_d); + return; + } + + // Single output but, sensitive to all inputs + if (cell->type.in( + ID($le), ID($lt), ID($ge), ID($gt), + ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), + ID($reduce_bool), ID($logic_not), ID($logic_or), ID($logic_and), + ID($eq), ID($ne) + )) { + auto &sig_y = cell->getPort(ID::Y); + + add_tags(sig_y[0], tags(cell)); + return; + } + + + // Fallback, propagate tags from all inputs to all outputs + add_tags(cell, tags(cell)); + + if (cell->type.in( + ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_), + ID($_XOR_), ID($_XNOR_), ID($_NOT_), ID($_BUF_), ID($_MUX_), + + ID($assert), ID($assume) + )) { + return; + } + + // This isn't a correctness concern (unless cell is a module generating + // tags), but we may end up generating a lot of extra logic when + // reaching this + if (!warned_cells.insert(cell).second) + return; + if (cell->type.isPublic()) + log_warning("Unhandled cell %s (%s) during tag propagation\n", log_id(cell), log_id(cell->type)); + else + log_debug("Unhandled cell %s (%s) during tag propagation\n", log_id(cell), log_id(cell->type)); + } + + void process_cell(IdString tag, Cell *cell) + { + if (cell->type == ID($set_tag)) { + IdString cell_tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + + auto tag_sig_a = tag_signal(tag, cell->getPort(ID::A)); + auto &sig_y = cell->getPort(ID::Y); + + if (cell_tag == tag) { + auto &sig_set = cell->getPort(ID::SET); + auto &sig_clr = cell->getPort(ID::CLR); + tag_sig_a = autoAnd(NEW_ID, tag_sig_a, autoNot(NEW_ID, sig_clr)); + tag_sig_a = autoOr(NEW_ID, tag_sig_a, sig_set); + } + + emit_tag_signal(tag, sig_y, tag_sig_a); + return; + } + + if (cell->type == ID($get_tag)) { + log_assert(false); + } + + if (cell->type.in(ID($not), ID($pos), ID($_NOT_), ID($_BUF_))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + if (cell->type.in(ID($not), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + } + emit_tag_signal(tag, sig_y, tag_signal(tag, sig_a)); + return; + } + + if (cell->type.in( + ID($and), ID($or), + ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_) + )) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + if (cell->type.in(ID($and), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); + } + + bool inv_a = false; + bool inv_b = false; + + if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_), ID($_ORNOT_))) + inv_a ^= true, inv_b ^= true; + if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) + inv_b ^= true; + + if (inv_a) + sig_a = autoNot(NEW_ID, sig_a); + if (inv_b) + sig_b = autoNot(NEW_ID, sig_b); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + + // Does this input allow propagating (doesn't fix output or same tag group) + sig_a = autoOr(NEW_ID, sig_a, group_sig_a); + sig_b = autoOr(NEW_ID, sig_b, group_sig_b); + + // Mask input tags by whether the other side allows propagation + tag_sig_a = autoAnd(NEW_ID, tag_sig_a, sig_b); + tag_sig_b = autoAnd(NEW_ID, tag_sig_b, sig_a); + + + auto tag_sig = autoOr(NEW_ID, tag_sig_a, tag_sig_b); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (cell->type.in(ID($xor), ID($xnor), ID($bweqx), ID($_XOR_), ID($_XNOR_))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + if (cell->type.in(ID($xor), ID($xnor))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); + } + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + auto tag_sig = autoOr(NEW_ID, tag_sig_a, tag_sig_b); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + + if (cell->type.in(ID($_MUX_), ID($mux), ID($bwmux))) { + auto &sig_y = cell->getPort(ID::Y); + auto &sig_a = cell->getPort(ID::A); + auto &sig_b = cell->getPort(ID::B); + auto sig_s = cell->getPort(ID::S); + + if (cell->type == ID($mux)) + sig_s = SigSpec(sig_s[0], GetSize(sig_y)); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + auto group_sig_s = tag_group_signal(tag, sig_s); + + auto prop_s = autoOr(NEW_ID, + autoXor(NEW_ID, sig_a, sig_b), + autoOr(NEW_ID, group_sig_a, group_sig_b)); + + auto prop_a = autoOr(NEW_ID, autoNot(NEW_ID, sig_s), group_sig_s); + auto prop_b = autoOr(NEW_ID, sig_s, group_sig_s); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + auto tag_sig_s = tag_signal(tag, sig_s); + + tag_sig_a = autoAnd(NEW_ID, tag_sig_a, prop_a); + tag_sig_b = autoAnd(NEW_ID, tag_sig_b, prop_b); + tag_sig_s = autoAnd(NEW_ID, tag_sig_s, prop_s); + + auto tag_sig = autoOr(NEW_ID, tag_sig_s, + autoOr(NEW_ID, tag_sig_a, tag_sig_b)); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + int width = std::max(GetSize(sig_a), GetSize(sig_b)); + sig_a.extend_u0(width, cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(width, cell->getParam(ID::B_SIGNED).as_bool()); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + auto group_sig = autoOr(NEW_ID, group_sig_a, group_sig_b); + // The output can only be affected by the tagged inputs if all group-untagged bits are equal + + auto masked_a = autoOr(NEW_ID, sig_a, group_sig); + auto masked_b = autoOr(NEW_ID, sig_b, group_sig); + + auto prop = autoEq(NEW_ID, masked_a, masked_b); + + auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b})); + tag_sig.extend_u0(GetSize(sig_y), false); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + + if (cell->type.in(ID($lt), ID($gt), ID($le), ID($ge))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + int width = std::max(GetSize(sig_a), GetSize(sig_b)); + sig_a.extend_u0(width, cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(width, cell->getParam(ID::B_SIGNED).as_bool()); + + if (cell->type.in(ID($gt), ID($le))) + std::swap(sig_a, sig_b); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + auto group_sig = autoOr(NEW_ID, group_sig_a, group_sig_b); + // The output can only be affected by the tagged inputs if the greatest possible sig_a is + // greater or equal to the least possible sig_b + auto masked_a = autoOr(NEW_ID, sig_a, group_sig); + auto masked_b = autoAnd(NEW_ID, sig_b, autoNot(NEW_ID, group_sig)); + + auto prop = autoGe(NEW_ID, masked_a, masked_b); + + auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b})); + tag_sig.extend_u0(GetSize(sig_y), false); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($logic_not))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + + if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) + sig_a = autoNot(NEW_ID, sig_a); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto tag_sig_a = tag_signal(tag, sig_a); + + auto filled = autoOr(NEW_ID, sig_a, group_sig_a); + + auto prop = autoReduceAnd(NEW_ID, filled); + auto tagged = autoReduceOr(NEW_ID, tag_sig_a); + auto tag_sig = autoAnd(NEW_ID, prop, tagged); + tag_sig.extend_u0(GetSize(sig_y), false); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + FfData ff(&initvals, cell); + // TODO handle some more variants + if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { + if (ff.has_clk && !tags(ff.sig_clk).empty()) + log_warning("Tags on CLK input ignored for %s (%s)\n", log_id(cell), log_id(cell->type)); + + int width = ff.width; + + auto sig_q = ff.sig_q; + auto sig_d = ff.sig_d; + + ff.name = NEW_ID; + ff.cell = nullptr; + ff.sig_d = tag_signal(tag, ff.sig_d); + ff.sig_q = module->addWire(NEW_ID, width); + ff.is_anyinit = false; + ff.val_init = Const(0, width); + ff.emit(); + + emit_tag_signal(tag, sig_q, ff.sig_q); + return; + } else { + log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", log_id(cell), log_id(cell->type)); + + // For unhandled FFs, the default propagation would cause combinational loops + emit_tag_signal(tag, ff.sig_q, Const(0, ff.width)); + return; + } + } + + // Fallback + SigSpec tag_input; + + for (auto &conn : cell->connections()) { + if (cell->input(conn.first)) { + auto tag_sig = tag_signal(tag, conn.second); + tag_input.append(tag_sig); + } + } + + SigBit any_tagged = autoReduceOr(NEW_ID, tag_input); + + for (auto &conn : cell->connections()) { + if (cell->output(conn.first)) { + emit_tag_signal(tag, conn.second, SigSpec(any_tagged, GetSize(conn.second))); + } + } + + // As fallback we propagate all tags from all inputs to all outputs, + // which is an over-approximation (unless the cell is a module that + // generates tags itself in which case it could be arbitrary). + if (warned_cells.insert(cell).second) + log_warning("Unhandled cell %s (%s) while emitting tag signals\n", log_id(cell), log_id(cell->type)); + } + + void emit_tags() + { + warned_cells.clear(); + std::vector get_tag_cells; + for (auto cell : module->selected_cells()) + if (cell->type == ID($get_tag)) + get_tag_cells.push_back(cell); + + for (auto cell : get_tag_cells) { + auto &sig_a = cell->getPort(ID::A); + IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + + tag_signal(tag, sig_a); + } + + if (options.tag_public) + { + std::vector public_wires; + + for (auto wire : module->selected_wires()) + if (wire->name.isPublic()) + public_wires.push_back(wire); + + for (auto wire : public_wires) { + for (auto tag : tag_pool(tags(SigSpec(wire)))) { + auto tag_sig = tag_signal(tag, SigSpec(wire)); + if (tag_sig.is_fully_zero()) + continue; + + int index = 0; + auto name = module->uniquify(stringf("%s:%s", wire->name.c_str(), tag.c_str() + 1), index); + auto hdlname = wire->get_hdlname_attribute(); + + if (!hdlname.empty()) + hdlname.back() += index ? + stringf(":%s_%d", tag.c_str() + 1, index) : + stringf(":%s", tag.c_str() + 1); + + auto tag_wire = module->addWire(name, wire->width); + + tag_wire->set_bool_attribute(ID::keep); + tag_wire->set_bool_attribute(ID(dft_tag)); + if (!hdlname.empty()) + tag_wire->set_hdlname_attribute(hdlname); + + module->connect(tag_wire, tag_sig); + } + } + } + } + + void replace_dft_cells() + { + std::vector get_tag_cells; + std::vector set_tag_cells; + for (auto cell : module->cells()) { + if (cell->type == ID($get_tag)) + get_tag_cells.push_back(cell); + + if (cell->type == ID($set_tag)) + set_tag_cells.push_back(cell); + + if (cell->type.in(ID($overwrite_tag), ID($original_tag))) + log_error("$overwrite_tag and $original_tag are not supported yet\n"); + // TODO these have to be rewritten as early as possible, so it should be a separate pass invocation + } + + for (auto cell : set_tag_cells) { + auto &sig_a = cell->getPort(ID::A); + auto &sig_y = cell->getPort(ID::Y); + module->connect(sig_y, sig_a); + module->remove(cell); + } + + for (auto cell : get_tag_cells) { + auto &sig_a = cell->getPort(ID::A); + auto &sig_y = cell->getPort(ID::Y); + IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + + auto tag_sig = tag_signal(tag, sig_a); + module->connect(sig_y, tag_sig); + module->remove(cell); + } + } + + + SigSpec autoAnd(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a.is_fully_zero() || sig_b.is_fully_ones() || sig_a == sig_b) + return sig_a; + if (sig_a.is_fully_ones() || sig_b.is_fully_zero()) + return sig_b; + + return module->And(name, sig_a, sig_b); + } + + SigSpec autoOr(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a.is_fully_ones() || sig_b.is_fully_zero() || sig_a == sig_b) + return sig_a; + if (sig_a.is_fully_zero() || sig_b.is_fully_ones()) + return sig_b; + + return module->Or(name, sig_a, sig_b); + } + + SigSpec autoXor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b) + return Const(State::S0, GetSize(sig_a)); + if (sig_a.is_fully_zero()) + return sig_b; + if (sig_b.is_fully_zero()) + return sig_a; + if (sig_a.is_fully_ones()) + return autoNot(name, sig_b); + if (sig_b.is_fully_ones()) + return autoNot(name, sig_a); + return module->Xor(name, sig_a, sig_b); + } + + SigSpec autoXnor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b) + return Const(State::S1, GetSize(sig_a)); + if (sig_a.is_fully_ones()) + return sig_b; + if (sig_b.is_fully_ones()) + return sig_a; + if (sig_a.is_fully_zero()) + return autoNot(name, sig_b); + if (sig_b.is_fully_zero()) + return autoNot(name, sig_a); + return module->Xnor(name, sig_a, sig_b); + } + + SigSpec autoNot(IdString name, const SigSpec &sig_a) + { + if (sig_a.is_fully_const()) { + auto const_val = sig_a.as_const(); + for (auto &bit : const_val.bits) + bit = bit == State::S0 ? State::S1 : bit == State::S1 ? State::S0 : bit; + return const_val; + } + return module->Not(name, sig_a); + } + + SigSpec autoEq(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b) + return State::S1; + for (int i = 0; i < GetSize(sig_a); i++) { + auto bit_a = sig_a[i]; + auto bit_b = sig_b[i]; + if (bit_a.is_wire() || bit_b.is_wire()) + continue; + if ((bit_a.data == State::S0 && bit_b.data == State::S1) || + (bit_a.data == State::S1 && bit_b.data == State::S0)) + return State::S0; + } + + return module->Eq(name, sig_a, sig_b); + } + + SigSpec autoGe(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b || sig_a.is_fully_ones()) + return State::S1; + if (sig_b.is_fully_zero()) + return State::S1; + + return module->Ge(name, sig_a, sig_b); + } + + SigSpec autoReduceAnd(IdString name, const SigSpec &sig_a) + { + if (GetSize(sig_a) == 0) + return State::S1; + + if (GetSize(sig_a) == 1 || sig_a == SigSpec(sig_a[0], GetSize(sig_a))) + return sig_a[0]; + for (auto bit : sig_a) + if (!bit.is_wire() && bit.data == State::S0) + return State::S0; + if (sig_a.is_fully_ones()) + return State::S1; + return module->ReduceAnd(name, sig_a); + } + + SigSpec autoReduceOr(IdString name, const SigSpec &sig_a) + { + if (GetSize(sig_a) == 0) + return State::S0; + + if (GetSize(sig_a) == 1 || sig_a == SigSpec(sig_a[0], GetSize(sig_a))) + return sig_a[0]; + for (auto bit : sig_a) + if (!bit.is_wire() && bit.data == State::S1) + return State::S1; + if (sig_a.is_fully_zero()) + return State::S0; + return module->ReduceOr(name, sig_a); + } +}; + +struct DftTagPass : public Pass { + DftTagPass() : Pass("dft_tag", "create tagging logic for data flow tracking") {} + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" dft_tag [options] [selection]\n"); + log("\n"); + log("This pass... TODO\n"); + log("\n"); + log(" -tag-public\n"); + log(" For each public wire that may carry tagged data, create a new public\n"); + log(" wire (named :) that carries the tag bits. Note\n"); + log(" that without this, tagging logic will only be emitted as required\n"); + log(" for uses of $get_tag.\n"); + log("\n"); + } + + void execute(std::vector args, RTLIL::Design *design) override + { + DftTagOptions options; + + log_header(design, "Executing DFT_TAG pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-tag-public") { + options.tag_public = true; + continue; + } + break; + } + + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) { + DftTagWorker worker(module, options); + + log_debug("Propagate tagged signals.\n"); + worker.propagate_tags(); + + log_debug("Emit tag signals and logic.\n"); + worker.emit_tags(); + + log_debug("Replace dft cells.\n"); + worker.replace_dft_cells(); + } + } +} DftTagPass; + +PRIVATE_NAMESPACE_END From 46a35da28cfe832b5da6b87ec6642574efb47d92 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 29 Aug 2023 15:47:05 +0200 Subject: [PATCH 112/119] Add `future` pass to resolve `$future_ff` cells --- passes/cmds/Makefile.inc | 1 + passes/cmds/future.cc | 140 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 passes/cmds/future.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index f3cd9b9509b..d7e572462b0 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -47,3 +47,4 @@ OBJS += passes/cmds/sta.o OBJS += passes/cmds/clean_zerowidth.o OBJS += passes/cmds/xprop.o OBJS += passes/cmds/dft_tag.o +OBJS += passes/cmds/future.o diff --git a/passes/cmds/future.cc b/passes/cmds/future.cc new file mode 100644 index 00000000000..b03613c9bd2 --- /dev/null +++ b/passes/cmds/future.cc @@ -0,0 +1,140 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2023 Jannis Harder + * + * 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/ff.h" +#include "kernel/ffinit.h" +#include "kernel/modtools.h" +#include "kernel/sigtools.h" +#include "kernel/utils.h" +#include "kernel/yosys.h" +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct FutureOptions { +}; + +struct FutureWorker { + Module *module; + FutureOptions options; + ModWalker modwalker; + SigMap &sigmap; + FfInitVals initvals; + + dict future_ff_signals; + + FutureWorker(Module *module, FutureOptions options) : + module(module), options(options), modwalker(module->design), sigmap(modwalker.sigmap) + { + modwalker.setup(module); + initvals.set(&modwalker.sigmap, module); + + std::vector replaced_cells; + for (auto cell : module->selected_cells()) { + if (cell->type != ID($future_ff)) + continue; + + module->connect(cell->getPort(ID::Y), future_ff(cell->getPort(ID::A))); + replaced_cells.push_back(cell); + } + + for (auto cell : replaced_cells) { + module->remove(cell); + } + } + + SigSpec future_ff(SigSpec sig) + { + for (auto &bit : sig) { + bit = future_ff(bit); + } + return sig; + } + + SigBit future_ff(SigBit bit) + { + if (!bit.is_wire()) + return bit; + + auto found = future_ff_signals.find(bit); + if (found != future_ff_signals.end()) + return found->second; + + auto found_driver = modwalker.signal_drivers.find(bit); + if (found_driver == modwalker.signal_drivers.end() || found_driver->second.size() < 1) + log_error("No driver for future_ff target signal %s found\n", log_signal(bit)); + if (found_driver->second.size() > 1) + log_error("Found multiple drivers for future_ff target signal %s\n", log_signal(bit)); + auto driver = *found_driver->second.begin(); + if (!RTLIL::builtin_ff_cell_types().count(driver.cell->type) && driver.cell->type != ID($anyinit)) + log_error("Driver for future_ff target signal %s has non-FF cell type %s\n", log_signal(bit), log_id(driver.cell->type)); + + FfData ff(&initvals, driver.cell); + + if (!ff.has_clk && !ff.has_gclk) + log_error("Driver for future_ff target signal %s has cell type %s, which is not clocked\n", log_signal(bit), + log_id(driver.cell->type)); + + ff.unmap_ce_srst(); + + // We insert all bits into the mapping, because unmap_ce_srst might + // have removed the cell which is still present in the modwalker data. + // By inserting all bits driven by th FF we ensure that we'll never use + // that stale modwalker data again. + + for (int i = 0; i < ff.width; ++i) { + future_ff_signals.emplace(ff.sig_q[i], ff.sig_d[i]); + } + + return future_ff_signals.at(bit); + } +}; + +struct FuturePass : public Pass { + FuturePass() : Pass("future", "resolve future sampled value functions") {} + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" future [options] [selection]\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + FutureOptions options; + + log_header(design, "Executing FUTURE pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + + break; + } + + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) { + FutureWorker worker(module, options); + } + } +} FuturePass; + +PRIVATE_NAMESPACE_END From 78ff40d1b28ed62f3d98c1ed970ce7ba482cf8d6 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 29 Aug 2023 15:50:17 +0200 Subject: [PATCH 113/119] Run `future` as part of `prep` --- techlibs/common/prep.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc index c354956bcf4..e9176304d48 100644 --- a/techlibs/common/prep.cc +++ b/techlibs/common/prep.cc @@ -189,6 +189,7 @@ struct PrepPass : public ScriptPass run(ifxmode ? "proc -ifx" : "proc"); if (help_mode || flatten) run("flatten", "(if -flatten)"); + run("future"); run(nokeepdc ? "opt_expr" : "opt_expr -keepdc"); run("opt_clean"); run("check"); From 62b4df49891034d48b3f24e78b83e7c49b23432c Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 29 Aug 2023 17:40:51 +0200 Subject: [PATCH 114/119] dft_tag: Implement `$overwrite_tag` and `$original_tag` This does not correctly handle an `$overwrite_tag` on a module output, but since we currently require the user to flatten the design for cross-module dft, this cannot be observed from within the design, only by manually inspecting the signals in the design. --- kernel/rtlil.cc | 43 ++++++++++++------- kernel/rtlil.h | 9 ++-- passes/cmds/dft_tag.cc | 91 +++++++++++++++++++++++++++++++++++++++-- passes/opt/opt_clean.cc | 3 ++ 4 files changed, 123 insertions(+), 23 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7d257714460..51d02091308 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3280,13 +3280,13 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string return sig; } -RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) { - RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($set_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::SET, sig_s); cell->setPort(ID::CLR, sig_c); cell->setPort(ID::Y, sig); @@ -3294,37 +3294,50 @@ RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &ta return sig; } -RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +RTLIL::Cell* RTLIL::Module::addSetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const std::string &src) { - RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($set_tag)); + cell->parameters[ID::WIDTH] = sig_a.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_a); + cell->setPort(ID::SET, sig_s); + cell->setPort(ID::CLR, sig_c); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($get_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } -RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($overwrite_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::SET, sig_s); cell->setPort(ID::CLR, sig_c); cell->set_src_attribute(src); return cell; } -RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src) { - RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($original_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 012865a75c6..c50d75e9087 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1465,10 +1465,11 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = ""); RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = ""); - RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); - RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); - RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); - RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::Cell* addSetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const std::string &src = ""); + RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = ""); + RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = ""); RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src = ""); #ifdef WITH_PYTHON diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc index 24fdf9714c8..9fd356ef65d 100644 --- a/passes/cmds/dft_tag.cc +++ b/passes/cmds/dft_tag.cc @@ -28,7 +28,8 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct DftTagOptions { - bool tag_public; + bool tag_public = false; + bool overwrite_only = false; }; struct DftTagWorker { @@ -80,6 +81,78 @@ struct DftTagWorker { tag_sets(tmp_tag_set); } + void resolve_overwrites() + { + std::vector overwrite_cells; + std::vector original_cells; + + bool design_changed = false; + + for (auto cell : module->cells()) { + if (cell->type == ID($overwrite_tag)) + overwrite_cells.push_back(cell); + + if (cell->type == ID($original_tag)) + original_cells.push_back(cell); + } + + for (auto cell : overwrite_cells) { + log_debug("Applying $overwrite_tag %s for signal %s\n", log_id(cell->name), log_signal(cell->getPort(ID::A))); + SigSpec orig_signal = cell->getPort(ID::A); + SigSpec interposed_signal = divert_users(orig_signal); + auto *set_tag_cell = module->addSetTag(NEW_ID, cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(ID::SET), cell->getPort(ID::CLR), interposed_signal); + modwalker.add_cell(set_tag_cell); // Make sure the next $overwrite_tag sees the new connections + design_changed = true; + } + + for (auto cell : overwrite_cells) { + module->remove(cell); + } + for (auto cell : original_cells) { + cell->type = ID($get_tag); + } + + if (design_changed) + modwalker.setup(module); + } + + SigSpec divert_users(SigSpec signal) + { + SigSpec signal_mapped = sigmap(signal); + signal_mapped.sort_and_unify(); + if (GetSize(signal_mapped) < GetSize(signal)) + log_warning("Detected $overwrite_tag on signal %s which contains repeated bits, this can result in unexpected behavior.\n", log_signal(signal)); + SigSpec new_wire = module->addWire(NEW_ID, GetSize(signal)); + for (int i = 0; i < GetSize(new_wire); ++i) + divert_users(signal[i], new_wire[i]); + return new_wire; + } + + void divert_users(SigBit driver_bit, SigBit interposed_bit) + { + dict, SigSpec> updated_ports; + // TODO also check module outputs + auto found = modwalker.signal_consumers.find(driver_bit); + if (found == modwalker.signal_consumers.end()) + return; + for (auto &consumer : found->second) { + if (consumer.cell->type.in(ID($original_tag))) + continue; + if (sigmap(consumer.cell->getPort(consumer.port)[consumer.offset]) != driver_bit) + continue; + std::pair key = {consumer.cell, consumer.port}; + auto found_port = updated_ports.find(key); + if (found_port == updated_ports.end()) { + updated_ports.emplace(key, consumer.cell->getPort(consumer.port)); + } + updated_ports[key][consumer.offset] = interposed_bit; + } + for (auto &update : updated_ports) { + update.first.first->setPort(update.first.second, update.second); + modwalker.add_cell(update.first.first); // Make sure the next $overwrite_tag sees the new connections + } + } + const pool &tag_pool(tag_set set) { return tag_sets[set.index]; } tag_set singleton(IdString tag) @@ -730,9 +803,7 @@ struct DftTagWorker { if (cell->type == ID($set_tag)) set_tag_cells.push_back(cell); - if (cell->type.in(ID($overwrite_tag), ID($original_tag))) - log_error("$overwrite_tag and $original_tag are not supported yet\n"); - // TODO these have to be rewritten as early as possible, so it should be a separate pass invocation + log_assert(!cell->type.in(ID($overwrite_tag), ID($original_tag))); } for (auto cell : set_tag_cells) { @@ -889,6 +960,8 @@ struct DftTagPass : public Pass { log("\n"); log("This pass... TODO\n"); log("\n"); + log(" -overwrite-only\n"); + log(" Only process $overwrite_tag and $original_tag cells.\n"); log(" -tag-public\n"); log(" For each public wire that may carry tagged data, create a new public\n"); log(" wire (named :) that carries the tag bits. Note\n"); @@ -909,6 +982,10 @@ struct DftTagPass : public Pass { options.tag_public = true; continue; } + if (args[argidx] == "-overwrite-only") { + options.overwrite_only = true; + continue; + } break; } @@ -917,6 +994,12 @@ struct DftTagPass : public Pass { for (auto module : design->selected_modules()) { DftTagWorker worker(module, options); + log_debug("Resolve overwrite_tag and original_tag.\n"); + worker.resolve_overwrites(); + + if (options.overwrite_only) + continue; + log_debug("Propagate tagged signals.\n"); worker.propagate_tags(); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 4da67cf630f..a219e470813 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -76,6 +76,9 @@ struct keep_cache_t if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) return true; + if (cell->type.in(ID($overwrite_tag))) + return true; + if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule))) return true; From 0e8a4adb59f34e70acbe1cb1b8af5b015f4eb2b3 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 5 Sep 2023 11:52:21 +0200 Subject: [PATCH 115/119] verific: Update YOSYSHQ_VERIFIC_API_VERSION --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index d30b46082e1..a67244d7ab3 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -74,7 +74,7 @@ USING_YOSYS_NAMESPACE # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20210801 +#if YOSYSHQ_VERIFIC_API_VERSION < 20230901 # error "Please update your version of YosysHQ flavored Verific." #endif From e9a11dd08863ad0bfcb4d21f7d152da710bacdd8 Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 13 Sep 2023 11:35:46 +0000 Subject: [PATCH 116/119] Update ABC for WASI support. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0c79636497f..b5a89ae0782 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 9537f39 +ABCREV = 6b66b81 ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From c7d7cfeaca6c79b871aca39c0878cf189390c497 Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 13 Sep 2023 15:06:27 +0000 Subject: [PATCH 117/119] Update ABC for WASI support. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b5a89ae0782..178d6ee4d30 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 6b66b81 +ABCREV = daad9ed ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From b84ed5d3ad2ac8b533e1d6a83dbdb6d5c2be9ce7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 00:14:42 +0000 Subject: [PATCH 118/119] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 178d6ee4d30..d7ecff99921 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+21 +YOSYS_VER := 0.33+34 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 9042124ba7ab746b466a1450f18462d1741afa79 Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:24:45 -0400 Subject: [PATCH 119/119] Alphabetize headers to be installed, include some missing required ones for plugins, fixes https://github.com/chipsalliance/synlig/pull/1972 https://github.com/dau-dev/tools/issues/6 --- Makefile | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index d7ecff99921..a93930be0c9 100644 --- a/Makefile +++ b/Makefile @@ -606,31 +606,35 @@ Q = S = endif -$(eval $(call add_include_file,kernel/yosys.h)) -$(eval $(call add_include_file,kernel/hashlib.h)) -$(eval $(call add_include_file,kernel/log.h)) -$(eval $(call add_include_file,kernel/rtlil.h)) $(eval $(call add_include_file,kernel/binding.h)) -$(eval $(call add_include_file,kernel/register.h)) $(eval $(call add_include_file,kernel/cellaigs.h)) -$(eval $(call add_include_file,kernel/celltypes.h)) $(eval $(call add_include_file,kernel/celledges.h)) +$(eval $(call add_include_file,kernel/celltypes.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)) -$(eval $(call add_include_file,kernel/utils.h)) -$(eval $(call add_include_file,kernel/satgen.h)) -$(eval $(call add_include_file,kernel/qcsat.h)) +$(eval $(call add_include_file,kernel/cost.h)) $(eval $(call add_include_file,kernel/ff.h)) $(eval $(call add_include_file,kernel/ffinit.h)) +$(eval $(call add_include_file,kernel/ffmerge.h)) +$(eval $(call add_include_file,kernel/fmt.h)) ifeq ($(ENABLE_ZLIB),1) $(eval $(call add_include_file,kernel/fstdata.h)) endif +$(eval $(call add_include_file,kernel/hashlib.h)) +$(eval $(call add_include_file,kernel/json.h)) +$(eval $(call add_include_file,kernel/log.h)) +$(eval $(call add_include_file,kernel/macc.h)) +$(eval $(call add_include_file,kernel/modtools.h)) $(eval $(call add_include_file,kernel/mem.h)) +$(eval $(call add_include_file,kernel/qcsat.h)) +$(eval $(call add_include_file,kernel/register.h)) +$(eval $(call add_include_file,kernel/rtlil.h)) +$(eval $(call add_include_file,kernel/satgen.h)) +$(eval $(call add_include_file,kernel/sigtools.h)) +$(eval $(call add_include_file,kernel/timinginfo.h)) +$(eval $(call add_include_file,kernel/utils.h)) +$(eval $(call add_include_file,kernel/yosys.h)) $(eval $(call add_include_file,kernel/yw.h)) -$(eval $(call add_include_file,kernel/json.h)) $(eval $(call add_include_file,libs/ezsat/ezsat.h)) $(eval $(call add_include_file,libs/ezsat/ezminisat.h)) ifeq ($(ENABLE_ZLIB),1)