Merge updates from 'master' into krys/docs

This commit is contained in:
Krystine Sherwin 2023-09-19 11:28:36 +12:00
commit 98d0e749d6
No known key found for this signature in database
107 changed files with 12414 additions and 1274 deletions

View File

@ -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 }}

View File

@ -2,9 +2,32 @@
List of major changes and improvements between releases
=======================================================
Yosys 0.31 .. Yosys 0.32-dev
Yosys 0.33 .. Yosys 0.34-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
--------------------------
* 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
--------------------------
* New commands and options

View File

@ -141,7 +141,7 @@ LDLIBS += -lrt
endif
endif
YOSYS_VER := 0.31+45
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
@ -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 2584903.. | wc -l`/;" Makefile
# set 'ABCREV = default' to use abc/ as it is
#
@ -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 = daad9ed
ABCPULL = 1
ABCURL ?= https://github.com/YosysHQ/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q)
@ -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/mem.h))
$(eval $(call add_include_file,kernel/yw.h))
$(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,libs/ezsat/ezsat.h))
$(eval $(call add_include_file,libs/ezsat/ezminisat.h))
ifeq ($(ENABLE_ZLIB),1)
@ -652,12 +656,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 +668,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
@ -882,6 +886,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 ""

View File

@ -518,6 +518,14 @@ struct value : public expr_base<value<Bits>> {
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<bool Invert, bool CarryIn>
std::pair<value<Bits>, bool /*CarryOut*/> alu(const value<Bits> &other) const {
value<Bits> result;
@ -575,6 +583,84 @@ struct value : public expr_base<value<Bits>> {
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<Bits> &b, value<Bits> &q) {
assert(this != &q);
if (this == &b || &q == &b) {
value<Bits> tmpB(b);
divideWithRemainder(tmpB, q);
return;
}
q = value<Bits> {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);
}
static chunk::type getShiftedBlock(const value<Bits> &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;
}
};
// Expression template for a slice, usable as lvalue or rvalue, and composable with other expression templates here.
@ -707,6 +793,99 @@ std::ostream &operator<<(std::ostream &os, const value<Bits> &val) {
return os;
}
template<size_t Bits>
struct value_formatted {
const value<Bits> &val;
bool character;
bool justify_left;
char padding;
int width;
int base;
bool signed_;
bool plus;
value_formatted(const value<Bits> &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<Bits> &) = delete;
value_formatted<Bits> &operator=(const value_formatted<Bits> &rhs) = delete;
};
template<size_t Bits>
std::ostream &operator<<(std::ostream &os, const value_formatted<Bits> &vf)
{
value<Bits> 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.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';
while (!val.is_zero()) {
value<Bits> quotient;
val.divideWithRemainder(value<Bits>{10u}, quotient);
buf += '0' + val.template trunc<(Bits > 4 ? 4 : Bits)>().val().template get<uint8_t>();
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<size_t Bits>
struct wire {
static constexpr size_t bits = Bits;
@ -1091,7 +1270,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 {

View File

@ -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)
@ -281,6 +282,7 @@ struct FlowGraph {
CONNECT,
CELL_SYNC,
CELL_EVAL,
PRINT_SYNC,
PROCESS_SYNC,
PROCESS_CASE,
MEM_RDPORT,
@ -290,6 +292,7 @@ struct FlowGraph {
Type type;
RTLIL::SigSig connect = {};
const RTLIL::Cell *cell = nullptr;
std::vector<const RTLIL::Cell*> print_sync_cells;
const RTLIL::Process *process = nullptr;
const Mem *mem = nullptr;
int portidx;
@ -477,6 +480,15 @@ struct FlowGraph {
return node;
}
Node *add_print_sync_node(std::vector<const RTLIL::Cell*> 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_)
{
@ -681,6 +693,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;
@ -1036,6 +1049,63 @@ struct CxxrtlWorker {
f << ".val()";
}
void dump_print(const RTLIL::Cell *cell)
{
Fmt fmt = {};
fmt.parse_rtlil(cell);
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(std::vector<const RTLIL::Cell*> &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];
trg_bit = sigmaps[trg_bit.wire->module](trg_bit);
log_assert(trg_bit.wire);
if (i != 0)
f << " || ";
if (trg_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());
log_assert(cell->getPort(ID::TRG) == trg);
log_assert(cell->getParam(ID::TRG_POLARITY) == trg_polarity);
std::vector<const RTLIL::Cell*> 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<const RTLIL::Cell*> &cells)
{
if (cells.empty()) {
@ -1202,6 +1272,25 @@ struct CxxrtlWorker {
f << " = ";
dump_cell_expr(cell, for_debug);
f << ";\n";
// $print cell
} else if (cell->type == ID($print)) {
log_assert(!for_debug);
// 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 = ";
dump_sigspec_rhs(cell->getPort(ID::EN));
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";
// Flip-flops
} else if (is_ff_cell(cell->type)) {
log_assert(!for_debug);
@ -1946,6 +2035,9 @@ struct CxxrtlWorker {
case FlowGraph::Node::Type::CELL_EVAL:
dump_cell_eval(node.cell);
break;
case FlowGraph::Node::Type::PRINT_SYNC:
dump_sync_print(node.print_sync_cells);
break;
case FlowGraph::Node::Type::PROCESS_CASE:
dump_process_case(node.process);
break;
@ -2291,6 +2383,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);
@ -2377,6 +2474,7 @@ struct CxxrtlWorker {
RTLIL::Module *top_module = nullptr;
std::vector<RTLIL::Module*> modules;
TopoSort<RTLIL::Module*> topo_design;
bool has_prints = false;
for (auto module : design->modules()) {
if (!design->selected_module(module))
continue;
@ -2389,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);
@ -2447,6 +2547,8 @@ struct CxxrtlWorker {
f << "#include \"" << intf_filename << "\"\n";
else
f << "#include <backends/cxxrtl/cxxrtl.h>\n";
if (has_prints)
f << "#include <iostream>\n";
f << "\n";
f << "#if defined(CXXRTL_INCLUDE_CAPI_IMPL) || \\\n";
f << " defined(CXXRTL_INCLUDE_VCD_CAPI_IMPL)\n";
@ -2601,6 +2703,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) {
@ -2736,6 +2848,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))
@ -2792,9 +2906,22 @@ struct CxxrtlWorker {
}
// Emit reachable nodes in eval().
// Accumulate sync $print cells per trigger condition.
dict<std::pair<RTLIL::SigSpec, RTLIL::Const>, std::vector<const RTLIL::Cell*>> 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
@ -3213,6 +3340,11 @@ struct CxxrtlBackend : public Backend {
log(" place the generated code into namespace <ns-name>. if not specified,\n");
log(" \"cxxrtl_design\" is used.\n");
log("\n");
log(" -print-output <stream>\n");
log(" $print cells in the generated code direct their output to <stream>.\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");
log(" present as it is exposed through the C API and has unbuffered outputs\n");
@ -3351,6 +3483,14 @@ struct CxxrtlBackend : public Backend {
worker.design_ns = args[++argidx];
continue;
}
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;
}
extra_args(f, filename, args, argidx);

View File

@ -245,6 +245,7 @@ class SmtIo:
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 @@ class SmtIo:
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)

View File

@ -84,26 +84,65 @@ 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)
@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 clock in inyw.clocks:
outyw.add_clock(clock["path"], clock["offset"], clock["edge"])
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 sig in inyw.signals:
outyw.add_sig(sig.path, sig.offset, sig.width, sig.init_only)
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:
outyw.add_clock(clock["path"], clock["offset"], clock["edge"])
for t, values in inyw.steps():
outyw.step(values)
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 t, values in inyw.steps(1):
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:

View File

@ -165,8 +165,8 @@ class WitnessSig:
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 @@ class WitnessValues:
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,14 +390,37 @@ class ReadWitness:
self.bits = [step["bits"] for step in data["steps"]]
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()
# 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):
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 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)

View File

@ -27,6 +27,7 @@
#include "kernel/sigtools.h"
#include "kernel/ff.h"
#include "kernel/mem.h"
#include "kernel/fmt.h"
#include <string>
#include <sstream>
#include <set>
@ -1005,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, const RTLIL::Cell *cell)
{
Fmt fmt = {};
fmt.parse_rtlil(cell);
std::vector<VerilogFmtArg> 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_)) {
@ -1753,6 +1789,22 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
if (cell->type == ID($print))
{
// 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");
dump_cell_expr_print(f, indent + " ", cell);
return true;
}
// FIXME: $fsm
return false;
@ -1841,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<const RTLIL::Cell*> &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) {
@ -2022,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::pair<RTLIL::SigSpec, RTLIL::Const>, std::vector<const RTLIL::Cell*>> sync_print_cells;
reg_wires.clear();
reset_auto_counter(module);
active_module = module;
@ -2052,6 +2134,11 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
std::set<std::pair<RTLIL::Wire*,int>> 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;
@ -2107,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);

View File

@ -630,6 +630,133 @@ 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`` family of tasks in Verilog. It
has the following parameters:
``\FORMAT``
The internal format string. The syntax is described below.
``\ARGS_WIDTH``
The width (in bits) of the signal on the ``\ARGS`` port.
``\TRG_ENABLE``
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 also apply:
``\TRG_WIDTH``
The number of bits in the ``\TRG`` port.
``\TRG_POLARITY``
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``
The signals that control when this ``$print`` cell is triggered.
``\EN``
Enable signal for the whole cell.
``\ARGS``
The values to be displayed, in format string order.
Format string syntax
^^^^^^^^^^^^^^^^^^^^
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; 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.
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)
* ``c`` for ASCII characters/strings
* ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and :verilog:`$realtime`)
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.
signedness
``u`` for unsigned, ``s`` for signed. This distinction is only respected
when rendering decimals.
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:
``}``
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:< 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.
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.
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.
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.
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:
Gates

View File

@ -30,6 +30,7 @@
#define AST_H
#include "kernel/rtlil.h"
#include "kernel/fmt.h"
#include <stdint.h>
#include <set>
@ -277,7 +278,9 @@ namespace AST
bool replace_variables(std::map<std::string, varinfo_t> &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);
// 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;
std::pair<AstNode*, AstNode*> get_tern_choice();

View File

@ -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);
@ -693,8 +696,86 @@ 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));
set_src_attr(cell, ast);
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->parameters[ID::PRIORITY] = --last_print_priority;
cell->setPort(ID::TRG, triggers);
Wire *wire = current_module->addWire(sstr.str() + "_EN", 1);
set_src_attr(wire, ast);
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<VerilogFmtArg> 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 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->genWidthRTLIL(-1, false, &subst_rvalue_map.stdmap());
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;

View File

@ -43,141 +43,40 @@ 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());
Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_t first_arg_at) {
std::vector<VerilogFmtArg> 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)) { }
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();
}
VerilogFmtArg arg = {};
arg.filename = filename;
arg.first_line = location.first_line;
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 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);
}
// 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 +956,34 @@ 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)) {
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")))
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()));
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;
}
// 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");
delete_children();
str = std::string();
}
@ -3735,13 +3635,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;
}

View File

@ -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
@ -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<RTLIL::IdString, RTLIL::Const> &attributes, DesignObj *obj, Netlist *nl)
{
MapIter mi;
@ -1103,6 +1111,43 @@ 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") ? 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") ? verific_unescape(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") ? 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") ? verific_unescape(inst->GetAttValue("tag")) : "";
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
#undef IN2
@ -2951,6 +2996,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);

View File

@ -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|realtime|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) {
yylval->string = new std::string(yytext);
return TOK_ID;
}

View File

@ -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 {

View File

@ -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<int> A = mk.inport_vec(ID::A, width);
vector<int> 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<int> Y = mk.adder(A, B, carry);

View File

@ -101,6 +101,12 @@ struct CellTypes
setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool<RTLIL::IdString>(), true);
setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool<RTLIL::IdString>(), true);
setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool<RTLIL::IdString>());
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<RTLIL::IdString>());
setup_type(ID($original_tag), {ID::A}, {ID::Y});
setup_type(ID($future_ff), {ID::A}, {ID::Y});
}
void setup_internals_eval()

View File

@ -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)
@ -205,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_)
@ -233,6 +237,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)

758
kernel/fmt.cc Normal file
View File

@ -0,0 +1,758 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2020 whitequark <whitequark@whitequark.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "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(const 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 += '}';
++i;
} else if (fmt.substr(i, 2) == "{{") {
part.str += '{';
++i;
} 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 = {};
}
if (++i == fmt.size())
log_assert(false && "Unexpected end in format substitution");
size_t arg_size = 0;
for (; i < fmt.size(); i++) {
if (fmt[i] >= '0' && fmt[i] <= '9') {
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())
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 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");
}
++i;
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] == '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::TIME:
log_assert(part.sig.size() == 0);
YS_FALLTHROUGH
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.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;
case 8: fmt += 'o'; break;
case 10: fmt += 'd'; break;
case 16: fmt += 'h'; break;
default: log_abort();
}
if (part.plus)
fmt += '+';
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;
default: log_abort();
}
}
cell->setParam(ID(FORMAT), fmt);
cell->setParam(ID(ARGS_WIDTH), args.size());
cell->setPort(ID(ARGS), args);
}
static size_t compute_required_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 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);
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);
}
}
}
void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &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_and_add(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 (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;
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 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);
}
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 && 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 (part.type == FmtPart::INTEGER && !has_leading_zero)
apply_verilog_automatic_sizing_and_add(part);
else
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<VerilogFmtArg> Fmt::emit_verilog() const
{
std::vector<VerilogFmtArg> 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) {
fmt.str += '0';
} else if (part.width > 0) {
log_assert(part.padding == ' ' || part.padding == '0');
if (part.base != 10 || 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;
}
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();
}
}
args.insert(args.begin(), fmt);
return args;
}
void Fmt::emit_cxxrtl(std::ostream &f, std::function<void(const RTLIL::SigSpec &)> 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.plus;
f << ')';
break;
}
case FmtPart::TIME: {
// CXXRTL only records steps taken, so there's no difference between
// the values taken by $time and $realtime.
f << " << value_formatted<64>(";
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.plus;
f << ')';
break;
}
default: log_abort();
}
}
}
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::TIME:
case FmtPart::CHARACTER: {
std::string buf;
if (part.type == FmtPart::INTEGER) {
RTLIL::Const value = part.sig.as_const();
if (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, false, false, 4).as_int();
absvalue = RTLIL::const_div(absvalue, 10, false, 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();
} 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');
if (part.justify == FmtPart::RIGHT && buf.size() < part.width) {
size_t pad_width = part.width - buf.size();
if (part.padding == '0' && (!buf.empty() && (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;
}

106
kernel/fmt.h Normal file
View File

@ -0,0 +1,106 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2020 whitequark <whitequark@whitequark.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#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,
TIME = 2,
} type;
// All types
std::string filename;
unsigned first_line;
// STRING type
std::string str;
// INTEGER type
RTLIL::SigSpec sig;
bool signed_ = false;
// TIME type
bool realtime = false;
};
// RTLIL format part, such as the substitutions in:
// "foo {4:> 4du} bar {2:<01hs}"
struct FmtPart {
enum {
STRING = 0,
INTEGER = 1,
CHARACTER = 2,
TIME = 3,
} type;
// STRING type
std::string str;
// 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 plus = false;
// TIME type
bool realtime = false;
};
struct Fmt {
public:
std::vector<FmtPart> parts;
void append_string(const std::string &str);
void parse_rtlil(const RTLIL::Cell *cell);
void emit_rtlil(RTLIL::Cell *cell) const;
void parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name);
std::vector<VerilogFmtArg> emit_verilog() const;
void emit_cxxrtl(std::ostream &f, std::function<void(const RTLIL::SigSpec &)> emit_sig) const;
std::string render() const;
private:
void apply_verilog_automatic_sizing_and_add(FmtPart &part);
};
YOSYS_NAMESPACE_END
#endif

View File

@ -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;
}

View File

@ -1720,6 +1720,18 @@ namespace {
return;
}
if (cell->type == ID($print)) {
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));
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; }
@ -1816,6 +1828,40 @@ 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;
}
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__);
}
};
@ -3234,6 +3280,80 @@ 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_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src)
{
RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.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);
cell->set_src_attribute(src);
return sig;
}
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)
{
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_a.size();
cell->parameters[ID::TAG] = tag;
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_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_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->set_src_attribute(src);
return cell;
}
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_a.size());
Cell *cell = addCell(name, ID($original_tag));
cell->parameters[ID::WIDTH] = sig_a.size();
cell->parameters[ID::TAG] = tag;
cell->setPort(ID::A, sig_a);
cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
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;

View File

@ -1465,6 +1465,13 @@ public:
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_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
static std::map<unsigned int, RTLIL::Module*> *get_all_modules(void);
#endif

View File

@ -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
@ -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
{

View File

@ -46,3 +46,5 @@ 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
OBJS += passes/cmds/future.o

1015
passes/cmds/dft_tag.cc Normal file

File diff suppressed because it is too large Load Diff

140
passes/cmds/future.cc Normal file
View File

@ -0,0 +1,140 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2023 Jannis Harder <jix@yosyshq.com> <me@jix.one>
*
* 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 <deque>
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct FutureOptions {
};
struct FutureWorker {
Module *module;
FutureOptions options;
ModWalker modwalker;
SigMap &sigmap;
FfInitVals initvals;
dict<SigBit, SigBit> 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<Cell *> 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<std::string> 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

View File

@ -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);

View File

@ -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:

View File

@ -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 <library_file> [-D <condition>] [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 <library_file>\n");
log(" Selects a library file containing RAM cell definitions. This option\n");

View File

@ -76,9 +76,15 @@ 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;
if (cell->type == ID($print))
return true;
if (cell->has_keep_attr())
return true;

View File

@ -39,7 +39,7 @@ struct OptLutInsPass : public Pass {
log("\n");
log(" -tech <technology>\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<std::string> 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]);

View File

@ -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)));
}
}

View File

@ -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++)
@ -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();

View File

@ -25,6 +25,7 @@
#include "kernel/ff.h"
#include "kernel/yw.h"
#include "kernel/json.h"
#include "kernel/fmt.h"
#include <ctime>
@ -109,6 +110,7 @@ struct SimShared
int next_output_id = 0;
int step = 0;
std::vector<TriggeredAssertion> triggered_assertions;
bool serious_asserts = false;
};
void zinit(State &v)
@ -168,11 +170,38 @@ struct SimInstance
Const data;
};
struct print_state_t
{
Const past_trg;
Const past_en;
Const past_args;
Cell *cell;
Fmt fmt;
std::tuple<bool, SigSpec, Const, int, Cell*> _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<Cell*, ff_state_t> ff_database;
dict<IdString, mem_state_t> mem_database;
pool<Cell*> formal_database;
pool<Cell*> initstate_database;
dict<Cell*, IdString> mem_cells;
std::vector<print_state_t> print_database;
std::vector<Mem> memories;
@ -289,13 +318,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 +561,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 +805,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)
@ -781,8 +870,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 +2590,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 +2748,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;

View File

@ -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/booth.o
OBJS += passes/techmap/libparse.o
ifeq ($(ENABLE_ABC),1)

View File

@ -127,10 +127,15 @@ bool clk_polarity, en_polarity, arst_polarity, srst_polarity;
RTLIL::SigSpec clk_sig, en_sig, arst_sig, srst_sig;
dict<int, std::string> 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();
@ -702,7 +707,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
std::vector<std::string> &liberty_files, std::vector<std::string> &genlib_files, std::string constr_file,
bool cleanup, vector<int> 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<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress)
const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector<std::string> &dont_use_cells)
{
module = current_module;
map_autoidx = autoidx++;
@ -795,8 +800,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())
@ -880,10 +890,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);
@ -1503,6 +1518,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 <cell_name>\n");
log(" generate netlists for the specified cell library (using the liberty\n");
log(" file format).\n");
log("\n");
log(" -genlib <file>\n");
log(" generate netlists for the specified cell library (using the SIS Genlib\n");
log(" file format).\n");
@ -1639,7 +1658,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<std::string> liberty_files, genlib_files;
std::vector<std::string> 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 +1741,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 +2051,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 +2213,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);
}
}

1524
passes/techmap/booth.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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");

View File

@ -1799,6 +1799,24 @@ end
endmodule
// --------------------------------------------------------
module \$print (EN, TRG, ARGS);
parameter FORMAT = "";
parameter ARGS_WIDTH = 0;
parameter PRIORITY = 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
@ -2653,3 +2671,73 @@ 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
// --------------------------------------------------------
module \$future_ff (A, Y);
parameter WIDTH = 0;
input [WIDTH-1:0] A;
output [WIDTH-1:0] Y;
assign Y = A;
endmodule
// --------------------------------------------------------

View File

@ -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, booth;
int lut;
void clear_flags() override
@ -110,6 +113,7 @@ struct SynthPass : public ScriptPass
noabc = false;
noshare = false;
flowmap = false;
booth = 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] == "-booth") {
booth = 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 <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 (booth)
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");

View File

@ -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))

View File

@ -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");
}

View File

@ -0,0 +1,28 @@
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/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))
$(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))

View File

@ -0,0 +1,90 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
* Copyright (C) 2018 gatecat <gatecat@ds0.me>
*
* 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

View File

@ -19,7 +19,7 @@
*/
(* techmap_celltype = "$alu" *)
module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
module _80_ccu2d_alu (A, B, CI, BI, X, Y, CO);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,571 @@
// Created by cells_xtra.py from Lattice models
(* blackbox *) (* keep *)
module GSR (...);
input GSR;
endmodule
(* blackbox *) (* keep *)
module SGSR (...);
input GSR;
input CLK;
endmodule
(* blackbox *)
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 (...);
parameter DATA_WIDTH_W = 18;
parameter DATA_WIDTH_R = 9;
parameter REGMODE = "NOREG";
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;
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 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 (...);
parameter DATA_WIDTH = 9;
parameter REGMODE = "NOREG";
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;
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 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 (...);
parameter DATA_WIDTH_W = 18;
parameter DATA_WIDTH_R = 18;
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";
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 CLKDIVC (...);
parameter GSR = "DISABLED";
parameter DIV = "2.0";
input RST;
input CLKI;
input ALIGNWD;
output CDIV1;
output CDIVX;
endmodule
(* blackbox *)
module DCMA (...);
input CLK0;
input CLK1;
input SEL;
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;
input CE;
output CLKO;
endmodule
(* blackbox *) (* keep *)
module START (...);
input STARTCLK;
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
(* blackbox *) (* keep *)
module TSALL (...);
input TSALL;
endmodule

View File

@ -0,0 +1,571 @@
// Created by cells_xtra.py from Lattice models
(* blackbox *) (* keep *)
module GSR (...);
input GSR;
endmodule
(* blackbox *) (* keep *)
module SGSR (...);
input GSR;
input CLK;
endmodule
(* blackbox *)
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 (...);
parameter DATA_WIDTH_W = 18;
parameter DATA_WIDTH_R = 9;
parameter REGMODE = "NOREG";
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;
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 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 (...);
parameter DATA_WIDTH = 9;
parameter REGMODE = "NOREG";
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;
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 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 (...);
parameter DATA_WIDTH_W = 18;
parameter DATA_WIDTH_R = 18;
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";
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 CLKDIVC (...);
parameter GSR = "DISABLED";
parameter DIV = "2.0";
input RST;
input CLKI;
input ALIGNWD;
output CDIV1;
output CDIVX;
endmodule
(* blackbox *)
module DCMA (...);
input CLK0;
input CLK1;
input SEL;
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;
input CE;
output CLKO;
endmodule
(* blackbox *) (* keep *)
module START (...);
input STARTCLK;
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
(* blackbox *) (* keep *)
module TSALL (...);
input TSALL;
endmodule

View File

@ -0,0 +1,572 @@
// Created by cells_xtra.py from Lattice models
(* blackbox *) (* keep *)
module GSR (...);
input GSR;
endmodule
(* blackbox *) (* keep *)
module SGSR (...);
input GSR;
input CLK;
endmodule
(* blackbox *)
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 (...);
parameter DATA_WIDTH_W = 18;
parameter DATA_WIDTH_R = 9;
parameter REGMODE = "NOREG";
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;
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 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 (...);
parameter DATA_WIDTH = 9;
parameter REGMODE = "NOREG";
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;
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 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 (...);
parameter DATA_WIDTH_W = 18;
parameter DATA_WIDTH_R = 18;
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";
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 CLKDIVC (...);
parameter GSR = "DISABLED";
parameter DIV = "2.0";
input RST;
input CLKI;
input ALIGNWD;
output CDIV1;
output CDIVX;
endmodule
(* blackbox *)
module DCMA (...);
input CLK0;
input CLK1;
input SEL;
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;
input CE;
output CLKO;
endmodule
(* blackbox *) (* keep *)
module START (...);
input STARTCLK;
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
(* blackbox *) (* keep *)
module TSALL (...);
input TSALL;
endmodule

View File

@ -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

View File

@ -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

View File

@ -88,30 +88,104 @@ module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"),
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;
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
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
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

View File

@ -0,0 +1,9 @@
`include "common_sim.vh"
`include "ccu2c_sim.vh"
`ifndef NO_INCLUDES
`include "cells_ff.vh"
`include "cells_io.vh"
`endif

View File

@ -0,0 +1,9 @@
`include "common_sim.vh"
`include "ccu2d_sim.vh"
`ifndef NO_INCLUDES
`include "cells_ff.vh"
`include "cells_io.vh"
`endif

View File

@ -0,0 +1,9 @@
`include "common_sim.vh"
`include "ccu2d_sim.vh"
`ifndef NO_INCLUDES
`include "cells_ff.vh"
`include "cells_io.vh"
`endif

View File

@ -0,0 +1,9 @@
`include "common_sim.vh"
`include "ccu2d_sim.vh"
`ifndef NO_INCLUDES
`include "cells_ff.vh"
`include "cells_io.vh"
`endif

View File

@ -0,0 +1,856 @@
#!/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", 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"),
#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", True),
]),
("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", 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"),
#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", True),
]),
("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", 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"),
#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", True),
#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 l == "":
continue
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())

View File

@ -0,0 +1,411 @@
// ---------------------------------------
(* 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
// 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"
`include "cells_io.vh"
`endif

View File

@ -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

View File

@ -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

View File

@ -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<std::string> 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

View File

@ -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" {
}
}

View File

@ -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

View File

@ -0,0 +1,503 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
* Copyright (C) 2018 gatecat <gatecat@ds0.me>
*
* 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 (excluding iCE40 and Nexus).\n");
log("\n");
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -family <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(" -edif <file>\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 <file>\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 <from_label>:<to_label>\n");
log(" only run the commands between the labels (see below). an empty\n");
log(" from label is synonymous to 'begin', and empty to label is\n");
log(" synonymous to the end of the command list.\n");
log("\n");
log(" -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(" (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");
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(" -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, 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";
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;
abc9 = false;
iopad = false;
nodsp = false;
no_rw_check = false;
postfix = "";
arith_map = "";
brams_map = "";
dsp_map = "";
have_dsp = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
string run_from, run_to;
bool force_widelut = false;
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] == "-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;
force_widelut = true;
continue;
}
if (args[argidx] == "-widelut") {
nowidelut = false;
force_widelut = true;
continue;
}
if (args[argidx] == "-abc2") {
abc2 = 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;
if (!force_widelut) nowidelut = true;
/* } 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>" : 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"))
{
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("edif"))
{
if (!edif_file.empty() || help_mode)
run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
}
if (check_label("json"))
{
if (!json_file.empty() || help_mode)
run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
}
}
} SynthLatticePass;
/*
struct SynthEcp5Pass : public Pass
{
SynthEcp5Pass() : Pass("synth_ecp5", "synthesis for ECP5 FPGAs") { }
void execute(std::vector<std::string> 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;
*/
PRIVATE_NAMESPACE_END

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -1,297 +0,0 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2020 William D. Jones <wjones@wdj-consulting.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/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 <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -blif <file>\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 <file>\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 <file>\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 <from_label>:<to_label>\n");
log(" only run the commands between the labels (see below). an empty\n");
log(" from label is synonymous to 'begin', and empty to label is\n");
log(" synonymous to the end of the command list.\n");
log("\n");
log(" -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<std::string> 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>" : 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("ecp5_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 ? "<file-name>" : blif_file.c_str()),
" (vpr mode)");
}
if (!vpr)
run(stringf("write_blif -gates -attr -param %s",
help_mode ? "<file-name>" : blif_file.c_str()),
" (non-vpr mode)");
}
}
if (check_label("edif"))
{
if (!edif_file.empty() || help_mode)
run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
}
if (check_label("json"))
{
if (!json_file.empty() || help_mode)
run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
}
}
} SynthMachXO2Pass;
PRIVATE_NAMESPACE_END

View File

@ -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_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

View File

@ -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_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 +/machxo2/cells_sim.v synth_machxo2 -noiopad # 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 +/machxo2/cells_sim.v synth_machxo2 -noiopad # 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 +/machxo2/cells_sim.v synth_machxo2 -noiopad # 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

View File

@ -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_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

View File

@ -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_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,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_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 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

View File

@ -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_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

View File

@ -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_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

View File

@ -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_lattice -family xo2
memory
opt -full

View File

@ -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_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 +/machxo2/cells_sim.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 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_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 +/machxo2/cells_sim.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 mux16 # Constrain all select calls below inside the top module
select -assert-max 12 t:LUT4

View File

@ -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_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

View File

@ -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_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 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

3
tests/fmt/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.log
iverilog-*
yosys-*

24
tests/fmt/always_comb.v Normal file
View File

@ -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

View File

@ -0,0 +1,16 @@
#include "yosys-always_comb.cc"
int main()
{
cxxrtl_design::p_top uut1, uut2;
for (int i = 0; i < 20; ++i) {
uut1.p_clk.set(!uut1.p_clk);
uut1.step();
uut2.p_clk.set(!uut2.p_clk);
uut2.step();
}
return 0;
}

View File

@ -0,0 +1,9 @@
module tb;
reg clk = 0;
top uut1 (.clk(clk));
top uut2 (.clk(clk));
always #1 clk <= ~clk;
initial #20 $finish;
endmodule

View File

@ -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

236
tests/fmt/always_full.v Normal file
View File

@ -0,0 +1,236 @@
module always_full(input clk);
always @(posedge clk) begin
$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
endmodule

View File

@ -0,0 +1,9 @@
#include "yosys-always_full.cc"
int main()
{
cxxrtl_design::p_always__full uut;
uut.p_clk.set(!uut.p_clk);
uut.step();
return 0;
}

View File

@ -0,0 +1,12 @@
module always_full_tb;
reg clk = 0;
always_full uut (.clk(clk));
always begin
#1 clk <= ~clk;
#1 $finish;
end
endmodule

12
tests/fmt/display_lm.v Normal file
View File

@ -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

View File

@ -0,0 +1,9 @@
#include "yosys-display_lm.cc"
int main()
{
cxxrtl_design::p_top uut;
uut.step();
return 0;
}

2
tests/fmt/fuzz/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
fuzztest
build

View File

@ -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)

44
tests/fmt/fuzz/x_test.cc Normal file
View File

@ -0,0 +1,44 @@
#include "fuzztest/fuzztest.h"
#include "gtest/gtest.h"
#include <sstream>
#include "backends/cxxrtl/cxxrtl.h"
#include "libs/bigint/BigUnsigned.hh"
using namespace cxxrtl_yosys;
void Formats128BitIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3, bool signed_)
{
// Compare output to BigUnsigned.
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, signed_, false, false);
auto actual = oss.str();
BigUnsigned u;
bool negative = signed_ && v.is_neg();
if (negative)
v = v.neg();
u.bitShiftLeft(v.slice<127, 64>().val().get<uint64_t>(), 64);
u.bitOr(u, v.slice<63, 0>().val().get<uint64_t>());
std::string expected;
if (u.isZero()) {
expected = "0";
} else {
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, Formats128BitIntegers);

255
tests/fmt/initial_display.v Normal file
View File

@ -0,0 +1,255 @@
module m;
initial $display("<<<BEGIN>>>");
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("==> 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");
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("<<<END>>>");
endmodule

Some files were not shown because too many files have changed in this diff Show More