mirror of https://github.com/YosysHQ/yosys.git
Merge updates from 'master' into krys/docs
This commit is contained in:
commit
98d0e749d6
|
@ -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 }}
|
||||
|
||||
|
|
25
CHANGELOG
25
CHANGELOG
|
@ -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
|
||||
|
|
51
Makefile
51
Makefile
|
@ -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 ""
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
120
kernel/rtlil.cc
120
kernel/rtlil.cc
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,9 @@
|
|||
`include "common_sim.vh"
|
||||
`include "ccu2c_sim.vh"
|
||||
|
||||
`ifndef NO_INCLUDES
|
||||
|
||||
`include "cells_ff.vh"
|
||||
`include "cells_io.vh"
|
||||
|
||||
`endif
|
|
@ -0,0 +1,9 @@
|
|||
`include "common_sim.vh"
|
||||
`include "ccu2d_sim.vh"
|
||||
|
||||
`ifndef NO_INCLUDES
|
||||
|
||||
`include "cells_ff.vh"
|
||||
`include "cells_io.vh"
|
||||
|
||||
`endif
|
|
@ -0,0 +1,9 @@
|
|||
`include "common_sim.vh"
|
||||
`include "ccu2d_sim.vh"
|
||||
|
||||
`ifndef NO_INCLUDES
|
||||
|
||||
`include "cells_ff.vh"
|
||||
`include "cells_io.vh"
|
||||
|
||||
`endif
|
|
@ -0,0 +1,9 @@
|
|||
`include "common_sim.vh"
|
||||
`include "ccu2d_sim.vh"
|
||||
|
||||
`ifndef NO_INCLUDES
|
||||
|
||||
`include "cells_ff.vh"
|
||||
`include "cells_io.vh"
|
||||
|
||||
`endif
|
|
@ -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())
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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" {
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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))
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
*.log
|
||||
iverilog-*
|
||||
yosys-*
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,9 @@
|
|||
#include "yosys-display_lm.cc"
|
||||
|
||||
int main()
|
||||
{
|
||||
cxxrtl_design::p_top uut;
|
||||
|
||||
uut.step();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
fuzztest
|
||||
build
|
|
@ -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)
|
|
@ -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);
|
|
@ -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
Loading…
Reference in New Issue