mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'origin/master' into xaig_dff
This commit is contained in:
commit
09ee96e8c2
46
CodingReadme
46
CodingReadme
|
@ -202,6 +202,52 @@ of how to use the Yosys API:
|
||||||
manual/PRESENTATION_Prog/my_cmd.cc
|
manual/PRESENTATION_Prog/my_cmd.cc
|
||||||
|
|
||||||
|
|
||||||
|
Script Passes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The ScriptPass base class can be used to implement passes that just call other passes,
|
||||||
|
like a script. Examples for such passes are:
|
||||||
|
|
||||||
|
techlibs/common/prep.cc
|
||||||
|
techlibs/common/synth.cc
|
||||||
|
|
||||||
|
In some cases it is easier to implement such a pass as regular pass, for example when
|
||||||
|
ScriptPass doesn't provide the type of flow control desired. (But many of the
|
||||||
|
script passes in Yosys that don't use ScriptPass simply predate the ScriptPass base
|
||||||
|
class.) Examples for such passes are:
|
||||||
|
|
||||||
|
passes/opt/opt.cc
|
||||||
|
passes/proc/proc.cc
|
||||||
|
|
||||||
|
Whether they use the ScriptPass base-class or not, a pass should always either
|
||||||
|
call other passes without doing any non-trivial work itself, or should implement
|
||||||
|
a non-trivial algorithm but not call any other passes. The reason for this is that
|
||||||
|
this helps containing complexity in individual passes and simplifies debugging the
|
||||||
|
entire system.
|
||||||
|
|
||||||
|
Exceptions to this rule should be rare and limited to cases where calling other
|
||||||
|
passes is optional and only happens when requested by the user (such as for
|
||||||
|
example `techmap -autoproc`), or where it is about commands that are "top-level
|
||||||
|
commands" in their own right, not components to be used in regular synthesis
|
||||||
|
flows (such as the `bugpoint` command).
|
||||||
|
|
||||||
|
A pass that would "naturally" call other passes and also do some work itself
|
||||||
|
should be re-written in one of two ways:
|
||||||
|
|
||||||
|
1) It could be re-written as script pass with the parts that are not calls
|
||||||
|
to other passes factored out into individual new passes. Usually in those
|
||||||
|
cases the new sub passes share the same prefix as the top-level script pass.
|
||||||
|
|
||||||
|
2) It could be re-written so that it already expects the design in a certain
|
||||||
|
state, expecting the calling script to set up this state before calling the
|
||||||
|
pass in questions.
|
||||||
|
|
||||||
|
Many back-ends are examples for the 2nd approach. For example, `write_aiger`
|
||||||
|
does not convert the design into AIG representation, but expects the design
|
||||||
|
to be already in this form, and prints an `Unsupported cell type` error
|
||||||
|
message otherwise.
|
||||||
|
|
||||||
|
|
||||||
Notes on the existing codebase
|
Notes on the existing codebase
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
|
10
Makefile
10
Makefile
|
@ -147,9 +147,9 @@ $(info $(subst $$--$$,$(newline),$(shell sed 's,^,[Makefile.conf] ,; s,$$,$$--$$
|
||||||
include Makefile.conf
|
include Makefile.conf
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
PYTHON_EXECUTABLE := $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi)
|
||||||
ifeq ($(ENABLE_PYOSYS),1)
|
ifeq ($(ENABLE_PYOSYS),1)
|
||||||
PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)"
|
PYTHON_VERSION_TESTCODE := "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));print(t)"
|
||||||
PYTHON_EXECUTABLE := $(shell if python3 -c ""; then echo "python3"; else echo "python"; fi)
|
|
||||||
PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"")
|
PYTHON_VERSION := $(shell $(PYTHON_EXECUTABLE) -c ""$(PYTHON_VERSION_TESTCODE)"")
|
||||||
PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.)
|
PYTHON_MAJOR_VERSION := $(shell echo $(PYTHON_VERSION) | cut -f1 -d.)
|
||||||
PYTHON_PREFIX := $(shell $(PYTHON_EXECUTABLE)-config --prefix)
|
PYTHON_PREFIX := $(shell $(PYTHON_EXECUTABLE)-config --prefix)
|
||||||
|
@ -708,11 +708,17 @@ test: $(TARGETS) $(EXTRA_TARGETS)
|
||||||
+cd tests/various && bash run-test.sh
|
+cd tests/various && bash run-test.sh
|
||||||
+cd tests/sat && bash run-test.sh
|
+cd tests/sat && bash run-test.sh
|
||||||
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
|
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
|
||||||
|
+cd tests/svtypes && bash run-test.sh $(SEEDOPT)
|
||||||
+cd tests/proc && bash run-test.sh
|
+cd tests/proc && bash run-test.sh
|
||||||
+cd tests/opt && bash run-test.sh
|
+cd tests/opt && bash run-test.sh
|
||||||
+cd tests/aiger && bash run-test.sh $(ABCOPT)
|
+cd tests/aiger && bash run-test.sh $(ABCOPT)
|
||||||
+cd tests/arch && bash run-test.sh
|
+cd tests/arch && bash run-test.sh
|
||||||
+cd tests/ice40 && bash run-test.sh $(SEEDOPT)
|
+cd tests/arch/ice40 && bash run-test.sh $(SEEDOPT)
|
||||||
|
+cd tests/arch/xilinx && bash run-test.sh $(SEEDOPT)
|
||||||
|
+cd tests/arch/ecp5 && bash run-test.sh $(SEEDOPT)
|
||||||
|
+cd tests/arch/efinix && bash run-test.sh $(SEEDOPT)
|
||||||
|
+cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT)
|
||||||
|
+cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
|
||||||
+cd tests/rpc && bash run-test.sh
|
+cd tests/rpc && bash run-test.sh
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " Passed \"make test\"."
|
@echo " Passed \"make test\"."
|
||||||
|
|
|
@ -510,6 +510,8 @@ from SystemVerilog:
|
||||||
into a design with ``read_verilog``, all its packages are available to
|
into a design with ``read_verilog``, all its packages are available to
|
||||||
SystemVerilog files being read into the same design afterwards.
|
SystemVerilog files being read into the same design afterwards.
|
||||||
|
|
||||||
|
- typedefs are supported (including inside packages)
|
||||||
|
|
||||||
- SystemVerilog interfaces (SVIs) are supported. Modports for specifying whether
|
- SystemVerilog interfaces (SVIs) are supported. Modports for specifying whether
|
||||||
ports are inputs or outputs are supported.
|
ports are inputs or outputs are supported.
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,9 @@ struct AigerWriter
|
||||||
} else
|
} else
|
||||||
if (alias_map.count(bit)) {
|
if (alias_map.count(bit)) {
|
||||||
a = bit2aig(alias_map.at(bit));
|
a = bit2aig(alias_map.at(bit));
|
||||||
|
} else
|
||||||
|
if (initstate_bits.count(bit)) {
|
||||||
|
a = initstate_ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bit == State::Sx || bit == State::Sz)
|
if (bit == State::Sx || bit == State::Sz)
|
||||||
|
|
|
@ -1070,7 +1070,12 @@ struct BtorWorker
|
||||||
bad_properties.push_back(nid_en_and_not_a);
|
bad_properties.push_back(nid_en_and_not_a);
|
||||||
} else {
|
} else {
|
||||||
int nid = next_nid++;
|
int nid = next_nid++;
|
||||||
btorf("%d bad %d\n", nid, nid_en_and_not_a);
|
string infostr = log_id(cell);
|
||||||
|
if (infostr[0] == '$' && cell->attributes.count("\\src")) {
|
||||||
|
infostr = cell->attributes.at("\\src").decode_string().c_str();
|
||||||
|
std::replace(infostr.begin(), infostr.end(), ' ', '_');
|
||||||
|
}
|
||||||
|
btorf("%d bad %d %s\n", nid, nid_en_and_not_a, infostr.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
btorf_pop(log_id(cell));
|
btorf_pop(log_id(cell));
|
||||||
|
|
|
@ -1032,12 +1032,17 @@ class MkVcd:
|
||||||
print("$var integer 32 t smt_step $end", file=self.f)
|
print("$var integer 32 t smt_step $end", file=self.f)
|
||||||
print("$var event 1 ! smt_clock $end", file=self.f)
|
print("$var event 1 ! smt_clock $end", file=self.f)
|
||||||
|
|
||||||
|
def vcdescape(n):
|
||||||
|
if n.startswith("$") or ":" in n:
|
||||||
|
return "\\" + n
|
||||||
|
return n
|
||||||
|
|
||||||
scope = []
|
scope = []
|
||||||
for path in sorted(self.nets):
|
for path in sorted(self.nets):
|
||||||
key, width = self.nets[path]
|
key, width = self.nets[path]
|
||||||
|
|
||||||
uipath = list(path)
|
uipath = list(path)
|
||||||
if "." in uipath[-1]:
|
if "." in uipath[-1] and not uipath[-1].startswith("$"):
|
||||||
uipath = uipath[0:-1] + uipath[-1].split(".")
|
uipath = uipath[0:-1] + uipath[-1].split(".")
|
||||||
for i in range(len(uipath)):
|
for i in range(len(uipath)):
|
||||||
uipath[i] = re.sub(r"\[([^\]]*)\]", r"<\1>", uipath[i])
|
uipath[i] = re.sub(r"\[([^\]]*)\]", r"<\1>", uipath[i])
|
||||||
|
@ -1048,15 +1053,13 @@ class MkVcd:
|
||||||
|
|
||||||
while uipath[:-1] != scope:
|
while uipath[:-1] != scope:
|
||||||
scopename = uipath[len(scope)]
|
scopename = uipath[len(scope)]
|
||||||
if scopename.startswith("$"):
|
print("$scope module %s $end" % vcdescape(scopename), file=self.f)
|
||||||
scopename = "\\" + scopename
|
|
||||||
print("$scope module %s $end" % scopename, file=self.f)
|
|
||||||
scope.append(uipath[len(scope)])
|
scope.append(uipath[len(scope)])
|
||||||
|
|
||||||
if path in self.clocks and self.clocks[path][1] == "event":
|
if path in self.clocks and self.clocks[path][1] == "event":
|
||||||
print("$var event 1 %s %s $end" % (key, uipath[-1]), file=self.f)
|
print("$var event 1 %s %s $end" % (key, vcdescape(uipath[-1])), file=self.f)
|
||||||
else:
|
else:
|
||||||
print("$var wire %d %s %s $end" % (width, key, uipath[-1]), file=self.f)
|
print("$var wire %d %s %s $end" % (width, key, vcdescape(uipath[-1])), file=self.f)
|
||||||
|
|
||||||
for i in range(len(scope)):
|
for i in range(len(scope)):
|
||||||
print("$upscope $end", file=self.f)
|
print("$upscope $end", file=self.f)
|
||||||
|
|
|
@ -33,11 +33,11 @@
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, defparam, decimal, siminit;
|
bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit;
|
||||||
int auto_name_counter, auto_name_offset, auto_name_digits;
|
int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter;
|
||||||
std::map<RTLIL::IdString, int> auto_name_map;
|
std::map<RTLIL::IdString, int> auto_name_map;
|
||||||
std::set<RTLIL::IdString> reg_wires, reg_ct;
|
std::set<RTLIL::IdString> reg_wires, reg_ct;
|
||||||
std::string auto_prefix;
|
std::string auto_prefix, extmem_prefix;
|
||||||
|
|
||||||
RTLIL::Module *active_module;
|
RTLIL::Module *active_module;
|
||||||
dict<RTLIL::SigBit, RTLIL::State> active_initdata;
|
dict<RTLIL::SigBit, RTLIL::State> active_initdata;
|
||||||
|
@ -371,13 +371,14 @@ void dump_sigspec(std::ostream &f, const RTLIL::SigSpec &sig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false, bool as_comment = false)
|
void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString, RTLIL::Const> &attributes, char term = '\n', bool modattr = false, bool regattr = false, bool as_comment = false)
|
||||||
{
|
{
|
||||||
if (noattr)
|
if (noattr)
|
||||||
return;
|
return;
|
||||||
if (attr2comment)
|
if (attr2comment)
|
||||||
as_comment = true;
|
as_comment = true;
|
||||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||||
|
if (it->first == "\\init" && regattr) continue;
|
||||||
f << stringf("%s" "%s %s", indent.c_str(), as_comment ? "/*" : "(*", id(it->first).c_str());
|
f << stringf("%s" "%s %s", indent.c_str(), as_comment ? "/*" : "(*", id(it->first).c_str());
|
||||||
f << stringf(" = ");
|
f << stringf(" = ");
|
||||||
if (modattr && (it->second == State::S0 || it->second == Const(0)))
|
if (modattr && (it->second == State::S0 || it->second == Const(0)))
|
||||||
|
@ -392,7 +393,7 @@ void dump_attributes(std::ostream &f, std::string indent, dict<RTLIL::IdString,
|
||||||
|
|
||||||
void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)
|
void dump_wire(std::ostream &f, std::string indent, RTLIL::Wire *wire)
|
||||||
{
|
{
|
||||||
dump_attributes(f, indent, wire->attributes);
|
dump_attributes(f, indent, wire->attributes, '\n', /*modattr=*/false, /*regattr=*/reg_wires.count(wire->name));
|
||||||
#if 0
|
#if 0
|
||||||
if (wire->port_input && !wire->port_output)
|
if (wire->port_input && !wire->port_output)
|
||||||
f << stringf("%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
|
f << stringf("%s" "input %s", indent.c_str(), reg_wires.count(wire->name) ? "reg " : "");
|
||||||
|
@ -1067,6 +1068,55 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
||||||
// end
|
// end
|
||||||
f << stringf("%s" "reg [%d:%d] %s [%d:%d];\n", indent.c_str(), width-1, 0, mem_id.c_str(), size+offset-1, offset);
|
f << stringf("%s" "reg [%d:%d] %s [%d:%d];\n", indent.c_str(), width-1, 0, mem_id.c_str(), size+offset-1, offset);
|
||||||
if (use_init)
|
if (use_init)
|
||||||
|
{
|
||||||
|
if (extmem)
|
||||||
|
{
|
||||||
|
std::string extmem_filename = stringf("%s-%d.mem", extmem_prefix.c_str(), extmem_counter++);
|
||||||
|
|
||||||
|
std::string extmem_filename_esc;
|
||||||
|
for (auto c : extmem_filename)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
extmem_filename_esc += "\\n";
|
||||||
|
else if (c == '\t')
|
||||||
|
extmem_filename_esc += "\\t";
|
||||||
|
else if (c < 32)
|
||||||
|
extmem_filename_esc += stringf("\\%03o", c);
|
||||||
|
else if (c == '"')
|
||||||
|
extmem_filename_esc += "\\\"";
|
||||||
|
else if (c == '\\')
|
||||||
|
extmem_filename_esc += "\\\\";
|
||||||
|
else
|
||||||
|
extmem_filename_esc += c;
|
||||||
|
}
|
||||||
|
f << stringf("%s" "initial $readmemb(\"%s\", %s);\n", indent.c_str(), extmem_filename_esc.c_str(), mem_id.c_str());
|
||||||
|
|
||||||
|
std::ofstream extmem_f(extmem_filename, std::ofstream::trunc);
|
||||||
|
if (extmem_f.fail())
|
||||||
|
log_error("Can't open file `%s' for writing: %s\n", extmem_filename.c_str(), strerror(errno));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i=0; i<size; i++)
|
||||||
|
{
|
||||||
|
RTLIL::Const element = cell->parameters["\\INIT"].extract(i*width, width);
|
||||||
|
for (int j=0; j<element.size(); j++)
|
||||||
|
{
|
||||||
|
switch (element[element.size()-j-1])
|
||||||
|
{
|
||||||
|
case State::S0: extmem_f << '0'; break;
|
||||||
|
case State::S1: extmem_f << '1'; break;
|
||||||
|
case State::Sx: extmem_f << 'x'; break;
|
||||||
|
case State::Sz: extmem_f << 'z'; break;
|
||||||
|
case State::Sa: extmem_f << '_'; break;
|
||||||
|
case State::Sm: log_error("Found marker state in final netlist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extmem_f << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
f << stringf("%s" "initial begin\n", indent.c_str());
|
f << stringf("%s" "initial begin\n", indent.c_str());
|
||||||
for (int i=0; i<size; i++)
|
for (int i=0; i<size; i++)
|
||||||
|
@ -1077,6 +1127,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
||||||
}
|
}
|
||||||
f << stringf("%s" "end\n", indent.c_str());
|
f << stringf("%s" "end\n", indent.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create a map : "edge clk" -> expressions within that clock domain
|
// create a map : "edge clk" -> expressions within that clock domain
|
||||||
dict<std::string, std::vector<std::string>> clk_to_lof_body;
|
dict<std::string, std::vector<std::string>> clk_to_lof_body;
|
||||||
|
@ -1521,7 +1572,7 @@ void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw
|
||||||
|
|
||||||
bool got_default = false;
|
bool got_default = false;
|
||||||
for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) {
|
for (auto it = sw->cases.begin(); it != sw->cases.end(); ++it) {
|
||||||
dump_attributes(f, indent + " ", (*it)->attributes, '\n', /*modattr=*/false, /*as_comment=*/true);
|
dump_attributes(f, indent + " ", (*it)->attributes, '\n', /*modattr=*/false, /*regattr=*/false, /*as_comment=*/true);
|
||||||
if ((*it)->compare.size() == 0) {
|
if ((*it)->compare.size() == 0) {
|
||||||
if (got_default)
|
if (got_default)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1686,7 +1737,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_attributes(f, indent, module->attributes, '\n', /*attr2comment=*/true);
|
dump_attributes(f, indent, module->attributes, '\n', /*modattr=*/true);
|
||||||
f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str());
|
f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str());
|
||||||
bool keep_running = true;
|
bool keep_running = true;
|
||||||
for (int port_id = 1; keep_running; port_id++) {
|
for (int port_id = 1; keep_running; port_id++) {
|
||||||
|
@ -1776,8 +1827,16 @@ struct VerilogBackend : public Backend {
|
||||||
log(" deactivates this feature and instead will write string constants\n");
|
log(" deactivates this feature and instead will write string constants\n");
|
||||||
log(" as binary numbers.\n");
|
log(" as binary numbers.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -extmem\n");
|
||||||
|
log(" instead of initializing memories using assignments to individual\n");
|
||||||
|
log(" elements, use the '$readmemh' function to read initialization data\n");
|
||||||
|
log(" from a file. This data is written to a file named by appending\n");
|
||||||
|
log(" a sequential index to the Verilog filename and replacing the extension\n");
|
||||||
|
log(" with '.mem', e.g. 'write_verilog -extmem foo.v' writes 'foo-1.mem',\n");
|
||||||
|
log(" 'foo-2.mem' and so on.\n");
|
||||||
|
log("\n");
|
||||||
log(" -defparam\n");
|
log(" -defparam\n");
|
||||||
log(" Use 'defparam' statements instead of the Verilog-2001 syntax for\n");
|
log(" use 'defparam' statements instead of the Verilog-2001 syntax for\n");
|
||||||
log(" cell parameters.\n");
|
log(" cell parameters.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -blackboxes\n");
|
log(" -blackboxes\n");
|
||||||
|
@ -1811,6 +1870,7 @@ struct VerilogBackend : public Backend {
|
||||||
nodec = false;
|
nodec = false;
|
||||||
nohex = false;
|
nohex = false;
|
||||||
nostr = false;
|
nostr = false;
|
||||||
|
extmem = false;
|
||||||
defparam = false;
|
defparam = false;
|
||||||
decimal = false;
|
decimal = false;
|
||||||
siminit = false;
|
siminit = false;
|
||||||
|
@ -1884,6 +1944,11 @@ struct VerilogBackend : public Backend {
|
||||||
nostr = true;
|
nostr = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (arg == "-extmem") {
|
||||||
|
extmem = true;
|
||||||
|
extmem_counter = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (arg == "-defparam") {
|
if (arg == "-defparam") {
|
||||||
defparam = true;
|
defparam = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1911,6 +1976,12 @@ struct VerilogBackend : public Backend {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(f, filename, args, argidx);
|
extra_args(f, filename, args, argidx);
|
||||||
|
if (extmem)
|
||||||
|
{
|
||||||
|
if (filename.empty())
|
||||||
|
log_cmd_error("Option -extmem must be used with a filename.\n");
|
||||||
|
extmem_prefix = filename.substr(0, filename.rfind('.'));
|
||||||
|
}
|
||||||
|
|
||||||
design->sort();
|
design->sort();
|
||||||
|
|
||||||
|
|
|
@ -1,41 +1,10 @@
|
||||||
// 50 MHz Clock
|
IO_LOC "clk" 35;
|
||||||
IO_LOC "clk" D11;
|
//IO_LOC "rst_n" 77;
|
||||||
|
IO_LOC "leds[0]" 79;
|
||||||
// LEDs
|
IO_LOC "leds[1]" 80;
|
||||||
IO_LOC "leds[0]" D22;
|
IO_LOC "leds[2]" 81;
|
||||||
IO_LOC "leds[1]" E22;
|
IO_LOC "leds[3]" 82;
|
||||||
IO_LOC "leds[2]" G22;
|
IO_LOC "leds[4]" 83;
|
||||||
IO_LOC "leds[3]" J22;
|
IO_LOC "leds[5]" 84;
|
||||||
IO_LOC "leds[4]" L22;
|
IO_LOC "leds[6]" 85;
|
||||||
IO_LOC "leds[5]" L19;
|
IO_LOC "leds[7]" 86;
|
||||||
IO_LOC "leds[6]" L20;
|
|
||||||
IO_LOC "leds[7]" M21;
|
|
||||||
IO_LOC "leds[8]" N19;
|
|
||||||
IO_LOC "leds[9]" R19;
|
|
||||||
IO_LOC "leds[10]" T18;
|
|
||||||
IO_LOC "leds[11]" AA22;
|
|
||||||
IO_LOC "leds[12]" U18;
|
|
||||||
IO_LOC "leds[13]" V20;
|
|
||||||
IO_LOC "leds[14]" AA21;
|
|
||||||
IO_LOC "leds[15]" AB21;
|
|
||||||
|
|
||||||
|
|
||||||
// 7-Segment Display
|
|
||||||
IO_LOC "seg7dig[0]" E20;
|
|
||||||
IO_LOC "seg7dig[1]" G18;
|
|
||||||
IO_LOC "seg7dig[2]" G20;
|
|
||||||
IO_LOC "seg7dig[3]" F21;
|
|
||||||
IO_LOC "seg7dig[4]" J20;
|
|
||||||
IO_LOC "seg7dig[5]" H21;
|
|
||||||
IO_LOC "seg7dig[6]" H18;
|
|
||||||
IO_LOC "seg7dig[7]" D20;
|
|
||||||
IO_LOC "seg7sel[0]" C19;
|
|
||||||
IO_LOC "seg7sel[1]" B22;
|
|
||||||
IO_LOC "seg7sel[2]" C20;
|
|
||||||
IO_LOC "seg7sel[3]" C21;
|
|
||||||
|
|
||||||
// Switches
|
|
||||||
IO_LOC "sw[0]" AB20;
|
|
||||||
IO_LOC "sw[1]" AB19;
|
|
||||||
IO_LOC "sw[2]" AB18;
|
|
||||||
IO_LOC "sw[3]" AB17;
|
|
|
@ -1,9 +1,7 @@
|
||||||
module demo (
|
module demo (
|
||||||
input clk,
|
input clk,
|
||||||
input [3:0] sw,
|
|
||||||
output [15:0] leds,
|
output [15:0] leds,
|
||||||
output [7:0] seg7dig,
|
output unused
|
||||||
output [3:0] seg7sel
|
|
||||||
);
|
);
|
||||||
localparam PRESCALE = 20;
|
localparam PRESCALE = 20;
|
||||||
reg [PRESCALE+3:0] counter = 0;
|
reg [PRESCALE+3:0] counter = 0;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
set JTAG regular_io = false
|
||||||
|
set SSPI regular_io = false
|
||||||
|
set MSPI regular_io = false
|
||||||
|
set READY regular_io = false
|
||||||
|
set DONE regular_io = false
|
||||||
|
set RECONFIG_N regular_io = false
|
||||||
|
set MODE regular_io = false
|
||||||
|
set CRC_check = true
|
||||||
|
set compress = false
|
||||||
|
set encryption = false
|
||||||
|
set security_bit_enable = true
|
||||||
|
set bsram_init_fuse_print = true
|
||||||
|
set download_speed = 250/100
|
||||||
|
set spi_flash_address = 0x00FFF000
|
||||||
|
set format = txt
|
||||||
|
set background_programming = false
|
|
@ -0,0 +1,8 @@
|
||||||
|
-sdf
|
||||||
|
-oc
|
||||||
|
-ibs
|
||||||
|
-posp
|
||||||
|
-o
|
||||||
|
-warning_all
|
||||||
|
-tt
|
||||||
|
-timing
|
|
@ -1,8 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -ex
|
set -ex
|
||||||
yosys -p "synth_gowin -top demo -vout demo_syn.v" demo.v
|
yosys -p "synth_gowin -top demo -vout demo_syn.v" demo.v
|
||||||
$GOWIN_HOME/bin/gowin -d demo_syn.v -cst demo.cst -sdc demo.sdc -p GW2A55-PBGA484-6 \
|
$GOWIN_HOME/bin/gowin -d demo_syn.v -cst demo.cst -sdc demo.sdc -p GW1NR-9-QFN88-6 -pn GW1NR-LV9QN88C6/I5 -cfg device.cfg -bit -tr -ph -timing -gpa -rpt -warning_all
|
||||||
-warning_all -out demo_out.v -rpt demo.rpt -tr demo_tr.html -bit demo.bit
|
|
||||||
|
|
||||||
# post place&route simulation (icarus verilog)
|
# post place&route simulation (icarus verilog)
|
||||||
if false; then
|
if false; then
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# gw_sh run.tcl
|
||||||
|
exec yosys -p "synth_gowin -top demo -vout demo_syn.v" demo.v
|
||||||
|
add_file -cst demo.cst
|
||||||
|
add_file -sdc demo.sdc
|
||||||
|
add_file -vm demo_syn.v
|
||||||
|
add_file -cfg device.cfg
|
||||||
|
set_option -device GW1NR-9-QFN88-6
|
||||||
|
set_option -pn GW1NR-LV9QN88C6/I5
|
||||||
|
run_pnr -opt pnr.cfg
|
|
@ -164,6 +164,8 @@ std::string AST::type2str(AstNodeType type)
|
||||||
X(AST_MODPORT)
|
X(AST_MODPORT)
|
||||||
X(AST_MODPORTMEMBER)
|
X(AST_MODPORTMEMBER)
|
||||||
X(AST_PACKAGE)
|
X(AST_PACKAGE)
|
||||||
|
X(AST_WIRETYPE)
|
||||||
|
X(AST_TYPEDEF)
|
||||||
#undef X
|
#undef X
|
||||||
default:
|
default:
|
||||||
log_abort();
|
log_abort();
|
||||||
|
@ -206,6 +208,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch
|
||||||
was_checked = false;
|
was_checked = false;
|
||||||
range_valid = false;
|
range_valid = false;
|
||||||
range_swapped = false;
|
range_swapped = false;
|
||||||
|
is_custom_type = false;
|
||||||
port_id = 0;
|
port_id = 0;
|
||||||
range_left = -1;
|
range_left = -1;
|
||||||
range_right = 0;
|
range_right = 0;
|
||||||
|
|
|
@ -148,7 +148,10 @@ namespace AST
|
||||||
AST_INTERFACEPORTTYPE,
|
AST_INTERFACEPORTTYPE,
|
||||||
AST_MODPORT,
|
AST_MODPORT,
|
||||||
AST_MODPORTMEMBER,
|
AST_MODPORTMEMBER,
|
||||||
AST_PACKAGE
|
AST_PACKAGE,
|
||||||
|
|
||||||
|
AST_WIRETYPE,
|
||||||
|
AST_TYPEDEF
|
||||||
};
|
};
|
||||||
|
|
||||||
// convert an node type to a string (e.g. for debug output)
|
// convert an node type to a string (e.g. for debug output)
|
||||||
|
@ -174,7 +177,7 @@ namespace AST
|
||||||
// node content - most of it is unused in most node types
|
// node content - most of it is unused in most node types
|
||||||
std::string str;
|
std::string str;
|
||||||
std::vector<RTLIL::State> bits;
|
std::vector<RTLIL::State> bits;
|
||||||
bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized;
|
bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized, is_custom_type;
|
||||||
int port_id, range_left, range_right;
|
int port_id, range_left, range_right;
|
||||||
uint32_t integer;
|
uint32_t integer;
|
||||||
double realvalue;
|
double realvalue;
|
||||||
|
|
|
@ -863,6 +863,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
case AST_PACKAGE:
|
case AST_PACKAGE:
|
||||||
case AST_MODPORT:
|
case AST_MODPORT:
|
||||||
case AST_MODPORTMEMBER:
|
case AST_MODPORTMEMBER:
|
||||||
|
case AST_TYPEDEF:
|
||||||
break;
|
break;
|
||||||
case AST_INTERFACEPORT: {
|
case AST_INTERFACEPORT: {
|
||||||
// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
|
// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
|
||||||
|
|
|
@ -318,7 +318,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
|
|
||||||
// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
|
// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
|
||||||
if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
|
if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX || type == AST_TYPEDEF)
|
||||||
const_fold = true;
|
const_fold = true;
|
||||||
if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
|
if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
|
||||||
const_fold = true;
|
const_fold = true;
|
||||||
|
@ -336,6 +336,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
std::map<std::string, AstNode*> this_wire_scope;
|
std::map<std::string, AstNode*> this_wire_scope;
|
||||||
for (size_t i = 0; i < children.size(); i++) {
|
for (size_t i = 0; i < children.size(); i++) {
|
||||||
AstNode *node = children[i];
|
AstNode *node = children[i];
|
||||||
|
|
||||||
if (node->type == AST_WIRE) {
|
if (node->type == AST_WIRE) {
|
||||||
if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
|
if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
|
||||||
for (auto c : node->children[0]->children) {
|
for (auto c : node->children[0]->children) {
|
||||||
|
@ -405,14 +406,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
this_wire_scope[node->str] = node;
|
this_wire_scope[node->str] = node;
|
||||||
}
|
}
|
||||||
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
|
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
|
||||||
node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) {
|
node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL ||
|
||||||
|
node->type == AST_TYPEDEF) {
|
||||||
backup_scope[node->str] = current_scope[node->str];
|
backup_scope[node->str] = current_scope[node->str];
|
||||||
current_scope[node->str] = node;
|
current_scope[node->str] = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < children.size(); i++) {
|
for (size_t i = 0; i < children.size(); i++) {
|
||||||
AstNode *node = children[i];
|
AstNode *node = children[i];
|
||||||
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
|
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY || node->type == AST_TYPEDEF)
|
||||||
while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
|
while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
|
@ -780,6 +782,99 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
delete_children();
|
delete_children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolve typedefs
|
||||||
|
if (type == AST_TYPEDEF) {
|
||||||
|
log_assert(children.size() == 1);
|
||||||
|
log_assert(children[0]->type == AST_WIRE || children[0]->type == AST_MEMORY);
|
||||||
|
while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param))
|
||||||
|
did_something = true;
|
||||||
|
log_assert(!children[0]->is_custom_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve types of wires
|
||||||
|
if (type == AST_WIRE || type == AST_MEMORY) {
|
||||||
|
if (is_custom_type) {
|
||||||
|
log_assert(children.size() >= 1);
|
||||||
|
log_assert(children[0]->type == AST_WIRETYPE);
|
||||||
|
if (!current_scope.count(children[0]->str))
|
||||||
|
log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str());
|
||||||
|
AstNode *resolved_type = current_scope.at(children[0]->str);
|
||||||
|
if (resolved_type->type != AST_TYPEDEF)
|
||||||
|
log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str());
|
||||||
|
log_assert(resolved_type->children.size() == 1);
|
||||||
|
AstNode *templ = resolved_type->children[0];
|
||||||
|
// Remove type reference
|
||||||
|
delete children[0];
|
||||||
|
children.erase(children.begin());
|
||||||
|
|
||||||
|
// Ensure typedef itself is fully simplified
|
||||||
|
while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
|
||||||
|
|
||||||
|
if (type == AST_WIRE)
|
||||||
|
type = templ->type;
|
||||||
|
is_reg = templ->is_reg;
|
||||||
|
is_logic = templ->is_logic;
|
||||||
|
is_signed = templ->is_signed;
|
||||||
|
is_string = templ->is_string;
|
||||||
|
is_custom_type = templ->is_custom_type;
|
||||||
|
|
||||||
|
range_valid = templ->range_valid;
|
||||||
|
range_swapped = templ->range_swapped;
|
||||||
|
range_left = templ->range_left;
|
||||||
|
range_right = templ->range_right;
|
||||||
|
|
||||||
|
// Insert clones children from template at beginning
|
||||||
|
for (int i = 0; i < GetSize(templ->children); i++)
|
||||||
|
children.insert(children.begin() + i, templ->children[i]->clone());
|
||||||
|
|
||||||
|
if (type == AST_MEMORY && GetSize(children) == 1) {
|
||||||
|
// Single-bit memories must have [0:0] range
|
||||||
|
AstNode *rng = new AstNode(AST_RANGE);
|
||||||
|
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
|
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
|
children.insert(children.begin(), rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
did_something = true;
|
||||||
|
}
|
||||||
|
log_assert(!is_custom_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve types of parameters
|
||||||
|
if (type == AST_LOCALPARAM || type == AST_PARAMETER) {
|
||||||
|
if (is_custom_type) {
|
||||||
|
log_assert(children.size() == 2);
|
||||||
|
log_assert(children[1]->type == AST_WIRETYPE);
|
||||||
|
if (!current_scope.count(children[1]->str))
|
||||||
|
log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str());
|
||||||
|
AstNode *resolved_type = current_scope.at(children[1]->str);
|
||||||
|
if (resolved_type->type != AST_TYPEDEF)
|
||||||
|
log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str());
|
||||||
|
log_assert(resolved_type->children.size() == 1);
|
||||||
|
AstNode *templ = resolved_type->children[0];
|
||||||
|
delete children[1];
|
||||||
|
children.pop_back();
|
||||||
|
|
||||||
|
// Ensure typedef itself is fully simplified
|
||||||
|
while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
|
||||||
|
|
||||||
|
if (templ->type == AST_MEMORY)
|
||||||
|
log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
|
||||||
|
is_signed = templ->is_signed;
|
||||||
|
is_string = templ->is_string;
|
||||||
|
is_custom_type = templ->is_custom_type;
|
||||||
|
|
||||||
|
range_valid = templ->range_valid;
|
||||||
|
range_swapped = templ->range_swapped;
|
||||||
|
range_left = templ->range_left;
|
||||||
|
range_right = templ->range_right;
|
||||||
|
for (auto template_child : templ->children)
|
||||||
|
children.push_back(template_child->clone());
|
||||||
|
did_something = true;
|
||||||
|
}
|
||||||
|
log_assert(!is_custom_type);
|
||||||
|
}
|
||||||
|
|
||||||
// resolve constant prefixes
|
// resolve constant prefixes
|
||||||
if (type == AST_PREFIX) {
|
if (type == AST_PREFIX) {
|
||||||
if (children[0]->type != AST_CONSTANT) {
|
if (children[0]->type != AST_CONSTANT) {
|
||||||
|
@ -1194,7 +1289,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (type == AST_BLOCK && str.empty())
|
if (type == AST_BLOCK && str.empty())
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < children.size(); i++)
|
for (size_t i = 0; i < children.size(); i++)
|
||||||
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM)
|
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF)
|
||||||
log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");
|
log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,7 +1301,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
|
|
||||||
std::vector<AstNode*> new_children;
|
std::vector<AstNode*> new_children;
|
||||||
for (size_t i = 0; i < children.size(); i++)
|
for (size_t i = 0; i < children.size(); i++)
|
||||||
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM) {
|
if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) {
|
||||||
children[i]->simplify(false, false, false, stage, -1, false, false);
|
children[i]->simplify(false, false, false, stage, -1, false, false);
|
||||||
current_ast_mod->children.push_back(children[i]);
|
current_ast_mod->children.push_back(children[i]);
|
||||||
current_scope[children[i]->str] = children[i];
|
current_scope[children[i]->str] = children[i];
|
||||||
|
@ -2906,7 +3001,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0)
|
if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) && name_map.count(str) > 0)
|
||||||
str = name_map[str];
|
str = name_map[str];
|
||||||
|
|
||||||
std::map<std::string, std::string> backup_name_map;
|
std::map<std::string, std::string> backup_name_map;
|
||||||
|
@ -2914,7 +3009,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
|
||||||
for (size_t i = 0; i < children.size(); i++) {
|
for (size_t i = 0; i < children.size(); i++) {
|
||||||
AstNode *child = children[i];
|
AstNode *child = children[i];
|
||||||
if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
|
if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
|
||||||
child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) {
|
child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF) {
|
||||||
if (backup_name_map.size() == 0)
|
if (backup_name_map.size() == 0)
|
||||||
backup_name_map = name_map;
|
backup_name_map = name_map;
|
||||||
std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
|
std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
|
||||||
|
@ -2945,6 +3040,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
|
||||||
child->expand_genblock(index_var, prefix, name_map);
|
child->expand_genblock(index_var, prefix, name_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (backup_name_map.size() > 0)
|
if (backup_name_map.size() > 0)
|
||||||
name_map.swap(backup_name_map);
|
name_map.swap(backup_name_map);
|
||||||
}
|
}
|
||||||
|
@ -2998,6 +3094,9 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
|
||||||
uint32_t children_flags = 0;
|
uint32_t children_flags = 0;
|
||||||
int lhs_children_counter = 0;
|
int lhs_children_counter = 0;
|
||||||
|
|
||||||
|
if (type == AST_TYPEDEF)
|
||||||
|
return; // don't touch content of typedefs
|
||||||
|
|
||||||
if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
|
if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
|
||||||
{
|
{
|
||||||
// mark all memories that are used in a complex expression on the left side of an assignment
|
// mark all memories that are used in a complex expression on the left side of an assignment
|
||||||
|
@ -3155,6 +3254,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
|
||||||
if (type == AST_FUNCTION || type == AST_TASK)
|
if (type == AST_FUNCTION || type == AST_TASK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (type == AST_TYPEDEF)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
|
if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
|
||||||
{
|
{
|
||||||
log_assert(children[0]->type == AST_CONSTANT);
|
log_assert(children[0]->type == AST_CONSTANT);
|
||||||
|
|
|
@ -174,6 +174,12 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||||
if (module == nullptr)
|
if (module == nullptr)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (!strcmp(cmd, ".blackbox"))
|
||||||
|
{
|
||||||
|
module->attributes["\\blackbox"] = RTLIL::Const(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(cmd, ".end"))
|
if (!strcmp(cmd, ".end"))
|
||||||
{
|
{
|
||||||
for (auto &wp : wideports_cache)
|
for (auto &wp : wideports_cache)
|
||||||
|
@ -280,7 +286,7 @@ void parse_blif(RTLIL::Design *design, std::istream &f, IdString dff_name, bool
|
||||||
goto error_with_reason;
|
goto error_with_reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
module->rename(lastcell, p);
|
module->rename(lastcell, RTLIL::escape_id(p));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -787,7 +787,18 @@ void VerificImporter::merge_past_ffs(pool<RTLIL::Cell*> &candidates)
|
||||||
void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*> &nl_todo)
|
void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::set<Netlist*> &nl_todo)
|
||||||
{
|
{
|
||||||
std::string netlist_name = nl->GetAtt(" \\top") ? nl->CellBaseName() : nl->Owner()->Name();
|
std::string netlist_name = nl->GetAtt(" \\top") ? nl->CellBaseName() : nl->Owner()->Name();
|
||||||
std::string module_name = nl->IsOperator() ? "$verific$" + netlist_name : RTLIL::escape_id(netlist_name);
|
std::string module_name = netlist_name;
|
||||||
|
|
||||||
|
if (nl->IsOperator()) {
|
||||||
|
module_name = "$verific$" + module_name;
|
||||||
|
} else {
|
||||||
|
if (*nl->Name()) {
|
||||||
|
module_name += "(";
|
||||||
|
module_name += nl->Name();
|
||||||
|
module_name += ")";
|
||||||
|
}
|
||||||
|
module_name = "\\" + module_name;
|
||||||
|
}
|
||||||
|
|
||||||
netlist = nl;
|
netlist = nl;
|
||||||
|
|
||||||
|
@ -1256,7 +1267,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
|
||||||
if (inst->Type() == PRIM_SVA_ASSERT || inst->Type() == PRIM_SVA_IMMEDIATE_ASSERT)
|
if (inst->Type() == PRIM_SVA_ASSERT || inst->Type() == PRIM_SVA_IMMEDIATE_ASSERT)
|
||||||
sva_asserts.insert(inst);
|
sva_asserts.insert(inst);
|
||||||
|
|
||||||
if (inst->Type() == PRIM_SVA_ASSUME || inst->Type() == PRIM_SVA_IMMEDIATE_ASSUME)
|
if (inst->Type() == PRIM_SVA_ASSUME || inst->Type() == PRIM_SVA_IMMEDIATE_ASSUME || inst->Type() == PRIM_SVA_RESTRICT)
|
||||||
sva_assumes.insert(inst);
|
sva_assumes.insert(inst);
|
||||||
|
|
||||||
if (inst->Type() == PRIM_SVA_COVER || inst->Type() == PRIM_SVA_IMMEDIATE_COVER)
|
if (inst->Type() == PRIM_SVA_COVER || inst->Type() == PRIM_SVA_IMMEDIATE_COVER)
|
||||||
|
@ -1396,8 +1407,20 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
|
||||||
import_verific_cells:
|
import_verific_cells:
|
||||||
nl_todo.insert(inst->View());
|
nl_todo.insert(inst->View());
|
||||||
|
|
||||||
RTLIL::Cell *cell = module->addCell(inst_name, inst->IsOperator() ?
|
std::string inst_type = inst->View()->Owner()->Name();
|
||||||
std::string("$verific$") + inst->View()->Owner()->Name() : RTLIL::escape_id(inst->View()->Owner()->Name()));
|
|
||||||
|
if (inst->View()->IsOperator()) {
|
||||||
|
inst_type = "$verific$" + inst_type;
|
||||||
|
} else {
|
||||||
|
if (*inst->View()->Name()) {
|
||||||
|
inst_type += "(";
|
||||||
|
inst_type += inst->View()->Name();
|
||||||
|
inst_type += ")";
|
||||||
|
}
|
||||||
|
inst_type = "\\" + inst_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::Cell *cell = module->addCell(inst_name, inst_type);
|
||||||
|
|
||||||
if (inst->IsPrimitive() && mode_keep)
|
if (inst->IsPrimitive() && mode_keep)
|
||||||
cell->attributes["\\keep"] = 1;
|
cell->attributes["\\keep"] = 1;
|
||||||
|
@ -1939,12 +1962,18 @@ struct VerificPass : public Pass {
|
||||||
log("Load the specified VHDL files into Verific.\n");
|
log("Load the specified VHDL files into Verific.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" verific -work <libname> {-sv|-vhdl|...} <hdl-file>\n");
|
log(" verific [-work <libname>] {-sv|-vhdl|...} <hdl-file>\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("Load the specified Verilog/SystemVerilog/VHDL file into the specified library.\n");
|
log("Load the specified Verilog/SystemVerilog/VHDL file into the specified library.\n");
|
||||||
log("(default library when -work is not present: \"work\")\n");
|
log("(default library when -work is not present: \"work\")\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" verific [-L <libname>] {-sv|-vhdl|...} <hdl-file>\n");
|
||||||
|
log("\n");
|
||||||
|
log("Look up external definitions in the specified library.\n");
|
||||||
|
log("(-L may be used more than once)\n");
|
||||||
|
log("\n");
|
||||||
|
log("\n");
|
||||||
log(" verific -vlog-incdir <directory>..\n");
|
log(" verific -vlog-incdir <directory>..\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("Add Verilog include directories.\n");
|
log("Add Verilog include directories.\n");
|
||||||
|
@ -2158,12 +2187,17 @@ struct VerificPass : public Pass {
|
||||||
goto check_error;
|
goto check_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
veri_file::RemoveAllLOptions();
|
||||||
for (; argidx < GetSize(args); argidx++)
|
for (; argidx < GetSize(args); argidx++)
|
||||||
{
|
{
|
||||||
if (args[argidx] == "-work" && argidx+1 < GetSize(args)) {
|
if (args[argidx] == "-work" && argidx+1 < GetSize(args)) {
|
||||||
work = args[++argidx];
|
work = args[++argidx];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-L" && argidx+1 < GetSize(args)) {
|
||||||
|
veri_file::AddLOption(args[++argidx].c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -490,6 +490,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
|
||||||
}
|
}
|
||||||
while (newline_count-- > 0)
|
while (newline_count-- > 0)
|
||||||
return_char('\n');
|
return_char('\n');
|
||||||
|
if (strchr("abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789", name[0])) {
|
||||||
// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
|
// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
|
||||||
defines_map[name] = value;
|
defines_map[name] = value;
|
||||||
if (state == 2)
|
if (state == 2)
|
||||||
|
@ -497,6 +498,9 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons
|
||||||
else
|
else
|
||||||
defines_with_args.erase(name);
|
defines_with_args.erase(name);
|
||||||
global_defines_cache[name] = std::pair<std::string, bool>(value, state == 2);
|
global_defines_cache[name] = std::pair<std::string, bool>(value, state == 2);
|
||||||
|
} else {
|
||||||
|
log_file_error(filename, 0, "Invalid name for macro definition: >>%s<<.\n", name.c_str());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -553,6 +553,12 @@ struct VerilogDefines : public Pass {
|
||||||
log(" -Uname[=definition]\n");
|
log(" -Uname[=definition]\n");
|
||||||
log(" undefine the preprocessor symbol 'name'\n");
|
log(" undefine the preprocessor symbol 'name'\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -reset\n");
|
||||||
|
log(" clear list of defined preprocessor symbols\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -list\n");
|
||||||
|
log(" list currently defined preprocessor symbols\n");
|
||||||
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
{
|
{
|
||||||
|
@ -588,6 +594,16 @@ struct VerilogDefines : public Pass {
|
||||||
design->verilog_defines.erase(name);
|
design->verilog_defines.erase(name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (arg == "-reset") {
|
||||||
|
design->verilog_defines.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (arg == "-list") {
|
||||||
|
for (auto &it : design->verilog_defines) {
|
||||||
|
log("`define %s%s %s\n", it.first.c_str(), it.second.second ? "()" : "", it.second.first.c_str());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ struct specify_rise_fall {
|
||||||
|
|
||||||
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
|
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
|
||||||
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
|
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
|
||||||
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id
|
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id
|
||||||
%type <boolean> opt_signed opt_property unique_case_attr
|
%type <boolean> opt_signed opt_property unique_case_attr
|
||||||
%type <al> attr case_attr
|
%type <al> attr case_attr
|
||||||
|
|
||||||
|
@ -206,6 +206,7 @@ design:
|
||||||
task_func_decl design |
|
task_func_decl design |
|
||||||
param_decl design |
|
param_decl design |
|
||||||
localparam_decl design |
|
localparam_decl design |
|
||||||
|
typedef_decl design |
|
||||||
package design |
|
package design |
|
||||||
interface design |
|
interface design |
|
||||||
/* empty */;
|
/* empty */;
|
||||||
|
@ -290,6 +291,9 @@ hierarchical_id:
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hierarchical_type_id:
|
||||||
|
'(' hierarchical_id ')' { $$ = $2; };
|
||||||
|
|
||||||
module:
|
module:
|
||||||
attr TOK_MODULE TOK_ID {
|
attr TOK_MODULE TOK_ID {
|
||||||
do_not_require_port_stubs = false;
|
do_not_require_port_stubs = false;
|
||||||
|
@ -324,13 +328,13 @@ single_module_para:
|
||||||
astbuf1 = new AstNode(AST_PARAMETER);
|
astbuf1 = new AstNode(AST_PARAMETER);
|
||||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
append_attr(astbuf1, $1);
|
append_attr(astbuf1, $1);
|
||||||
} param_signed param_integer param_range single_param_decl |
|
} param_type single_param_decl |
|
||||||
attr TOK_LOCALPARAM {
|
attr TOK_LOCALPARAM {
|
||||||
if (astbuf1) delete astbuf1;
|
if (astbuf1) delete astbuf1;
|
||||||
astbuf1 = new AstNode(AST_LOCALPARAM);
|
astbuf1 = new AstNode(AST_LOCALPARAM);
|
||||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
append_attr(astbuf1, $1);
|
append_attr(astbuf1, $1);
|
||||||
} param_signed param_integer param_range single_param_decl |
|
} param_type single_param_decl |
|
||||||
single_param_decl;
|
single_param_decl;
|
||||||
|
|
||||||
module_args_opt:
|
module_args_opt:
|
||||||
|
@ -426,6 +430,7 @@ package_body:
|
||||||
package_body package_body_stmt |;
|
package_body package_body_stmt |;
|
||||||
|
|
||||||
package_body_stmt:
|
package_body_stmt:
|
||||||
|
typedef_decl |
|
||||||
localparam_decl;
|
localparam_decl;
|
||||||
|
|
||||||
interface:
|
interface:
|
||||||
|
@ -452,7 +457,7 @@ interface_body:
|
||||||
interface_body interface_body_stmt |;
|
interface_body interface_body_stmt |;
|
||||||
|
|
||||||
interface_body_stmt:
|
interface_body_stmt:
|
||||||
param_decl | localparam_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
|
param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
|
||||||
modport_stmt;
|
modport_stmt;
|
||||||
|
|
||||||
non_opt_delay:
|
non_opt_delay:
|
||||||
|
@ -475,8 +480,14 @@ wire_type:
|
||||||
};
|
};
|
||||||
|
|
||||||
wire_type_token_list:
|
wire_type_token_list:
|
||||||
wire_type_token | wire_type_token_list wire_type_token |
|
wire_type_token |
|
||||||
wire_type_token_io ;
|
wire_type_token_list wire_type_token |
|
||||||
|
wire_type_token_io |
|
||||||
|
hierarchical_type_id {
|
||||||
|
astbuf3->is_custom_type = true;
|
||||||
|
astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
|
||||||
|
astbuf3->children.back()->str = *$1;
|
||||||
|
};
|
||||||
|
|
||||||
wire_type_token_io:
|
wire_type_token_io:
|
||||||
TOK_INPUT {
|
TOK_INPUT {
|
||||||
|
@ -591,7 +602,7 @@ module_body:
|
||||||
/* empty */;
|
/* empty */;
|
||||||
|
|
||||||
module_body_stmt:
|
module_body_stmt:
|
||||||
task_func_decl | specify_block |param_decl | localparam_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
|
task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
|
||||||
always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
|
always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
|
||||||
|
|
||||||
checker_decl:
|
checker_decl:
|
||||||
|
@ -1149,12 +1160,20 @@ param_range:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
param_type:
|
||||||
|
param_signed param_integer param_real param_range |
|
||||||
|
hierarchical_type_id {
|
||||||
|
astbuf1->is_custom_type = true;
|
||||||
|
astbuf1->children.push_back(new AstNode(AST_WIRETYPE));
|
||||||
|
astbuf1->children.back()->str = *$1;
|
||||||
|
};
|
||||||
|
|
||||||
param_decl:
|
param_decl:
|
||||||
attr TOK_PARAMETER {
|
attr TOK_PARAMETER {
|
||||||
astbuf1 = new AstNode(AST_PARAMETER);
|
astbuf1 = new AstNode(AST_PARAMETER);
|
||||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
append_attr(astbuf1, $1);
|
append_attr(astbuf1, $1);
|
||||||
} param_signed param_integer param_real param_range param_decl_list ';' {
|
} param_type param_decl_list ';' {
|
||||||
delete astbuf1;
|
delete astbuf1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1163,7 +1182,7 @@ localparam_decl:
|
||||||
astbuf1 = new AstNode(AST_LOCALPARAM);
|
astbuf1 = new AstNode(AST_LOCALPARAM);
|
||||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
append_attr(astbuf1, $1);
|
append_attr(astbuf1, $1);
|
||||||
} param_signed param_integer param_real param_range param_decl_list ';' {
|
} param_type param_decl_list ';' {
|
||||||
delete astbuf1;
|
delete astbuf1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1327,7 +1346,7 @@ wire_name:
|
||||||
if ($2 != NULL) {
|
if ($2 != NULL) {
|
||||||
if (node->is_input || node->is_output)
|
if (node->is_input || node->is_output)
|
||||||
frontend_verilog_yyerror("input/output/inout ports cannot have unpacked dimensions.");
|
frontend_verilog_yyerror("input/output/inout ports cannot have unpacked dimensions.");
|
||||||
if (!astbuf2) {
|
if (!astbuf2 && !node->is_custom_type) {
|
||||||
AstNode *rng = new AstNode(AST_RANGE);
|
AstNode *rng = new AstNode(AST_RANGE);
|
||||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
rng->children.push_back(AstNode::mkconst_int(0, true));
|
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
|
@ -1377,6 +1396,45 @@ assign_expr:
|
||||||
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
|
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef_decl:
|
||||||
|
TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
|
||||||
|
astbuf1 = $2;
|
||||||
|
astbuf2 = $3;
|
||||||
|
if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
|
||||||
|
if (astbuf2) {
|
||||||
|
frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
|
||||||
|
} else {
|
||||||
|
astbuf2 = new AstNode(AST_RANGE);
|
||||||
|
astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
|
||||||
|
astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (astbuf2 && astbuf2->children.size() != 2)
|
||||||
|
frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
|
||||||
|
if (astbuf2)
|
||||||
|
astbuf1->children.push_back(astbuf2);
|
||||||
|
|
||||||
|
if ($5 != NULL) {
|
||||||
|
if (!astbuf2) {
|
||||||
|
AstNode *rng = new AstNode(AST_RANGE);
|
||||||
|
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
|
rng->children.push_back(AstNode::mkconst_int(0, true));
|
||||||
|
astbuf1->children.push_back(rng);
|
||||||
|
}
|
||||||
|
astbuf1->type = AST_MEMORY;
|
||||||
|
auto *rangeNode = $5;
|
||||||
|
if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
|
||||||
|
// SV array size [n], rewrite as [n-1:0]
|
||||||
|
rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
|
||||||
|
rangeNode->children.push_back(AstNode::mkconst_int(0, false));
|
||||||
|
}
|
||||||
|
astbuf1->children.push_back(rangeNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
|
||||||
|
ast_stack.back()->children.back()->str = *$4;
|
||||||
|
};
|
||||||
|
|
||||||
cell_stmt:
|
cell_stmt:
|
||||||
attr TOK_ID {
|
attr TOK_ID {
|
||||||
astbuf1 = new AstNode(AST_CELL);
|
astbuf1 = new AstNode(AST_CELL);
|
||||||
|
@ -1823,7 +1881,7 @@ simple_behavioral_stmt:
|
||||||
|
|
||||||
// this production creates the obligatory if-else shift/reduce conflict
|
// this production creates the obligatory if-else shift/reduce conflict
|
||||||
behavioral_stmt:
|
behavioral_stmt:
|
||||||
defattr | assert | wire_decl | param_decl | localparam_decl |
|
defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
|
||||||
non_opt_delay behavioral_stmt |
|
non_opt_delay behavioral_stmt |
|
||||||
simple_behavioral_stmt ';' | ';' |
|
simple_behavioral_stmt ';' | ';' |
|
||||||
hierarchical_id attr {
|
hierarchical_id attr {
|
||||||
|
|
|
@ -253,6 +253,8 @@ class WContainer:
|
||||||
candidate = WType.from_string(arg.strip(), containing_file, line_number)
|
candidate = WType.from_string(arg.strip(), containing_file, line_number)
|
||||||
if candidate == None:
|
if candidate == None:
|
||||||
return None
|
return None
|
||||||
|
if candidate.name == "void":
|
||||||
|
return None
|
||||||
cont.args.append(candidate)
|
cont.args.append(candidate)
|
||||||
return cont
|
return cont
|
||||||
|
|
||||||
|
@ -880,11 +882,8 @@ class WClass:
|
||||||
text += fun.gen_def_virtual()
|
text += fun.gen_def_virtual()
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def gen_boost_py(self):
|
def gen_boost_py_body(self):
|
||||||
text = "\n\t\tclass_<" + self.name
|
text = ""
|
||||||
if self.link_type == link_types.derive:
|
|
||||||
text += "Wrap, boost::noncopyable"
|
|
||||||
text += ">(\"" + self.name + "\""
|
|
||||||
if self.printable_constrs() == 0 or not self.contains_default_constr():
|
if self.printable_constrs() == 0 or not self.contains_default_constr():
|
||||||
text += ", no_init"
|
text += ", no_init"
|
||||||
text += ")"
|
text += ")"
|
||||||
|
@ -907,6 +906,21 @@ class WClass:
|
||||||
text += "\n\t\t\t;\n"
|
text += "\n\t\t\t;\n"
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
def gen_boost_py(self):
|
||||||
|
body = self.gen_boost_py_body()
|
||||||
|
if self.link_type == link_types.derive:
|
||||||
|
text = "\n\t\tclass_<" + self.name + ">(\"Cpp" + self.name + "\""
|
||||||
|
text += body
|
||||||
|
text += "\n\t\tclass_<" + self.name
|
||||||
|
text += "Wrap, boost::noncopyable"
|
||||||
|
text += ">(\"" + self.name + "\""
|
||||||
|
text += body
|
||||||
|
else:
|
||||||
|
text = "\n\t\tclass_<" + self.name + ">(\"" + self.name + "\""
|
||||||
|
text += body
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
def contains_default_constr(self):
|
def contains_default_constr(self):
|
||||||
for c in self.found_constrs:
|
for c in self.found_constrs:
|
||||||
if len(c.args) == 0:
|
if len(c.args) == 0:
|
||||||
|
@ -974,6 +988,7 @@ blacklist_methods = ["YOSYS_NAMESPACE::Pass::run_register", "YOSYS_NAMESPACE::Mo
|
||||||
enum_names = ["State","SyncType","ConstFlags"]
|
enum_names = ["State","SyncType","ConstFlags"]
|
||||||
|
|
||||||
enums = [] #Do not edit
|
enums = [] #Do not edit
|
||||||
|
glbls = []
|
||||||
|
|
||||||
unowned_functions = []
|
unowned_functions = []
|
||||||
|
|
||||||
|
@ -1723,6 +1738,159 @@ class WMember:
|
||||||
text += ")"
|
text += ")"
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
class WGlobal:
|
||||||
|
orig_text = None
|
||||||
|
wtype = attr_types.default
|
||||||
|
name = None
|
||||||
|
containing_file = None
|
||||||
|
namespace = ""
|
||||||
|
is_const = False
|
||||||
|
|
||||||
|
def from_string(str_def, containing_file, line_number, namespace):
|
||||||
|
glbl = WGlobal()
|
||||||
|
glbl.orig_text = str_def
|
||||||
|
glbl.wtype = None
|
||||||
|
glbl.name = ""
|
||||||
|
glbl.containing_file = containing_file
|
||||||
|
glbl.namespace = namespace
|
||||||
|
glbl.is_const = False
|
||||||
|
|
||||||
|
if not str.startswith(str_def, "extern"):
|
||||||
|
return None
|
||||||
|
str_def = str_def[7:]
|
||||||
|
|
||||||
|
if str.startswith(str_def, "const "):
|
||||||
|
glbl.is_const = True
|
||||||
|
str_def = str_def[6:]
|
||||||
|
|
||||||
|
if str_def.count(" ") == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
parts = split_list(str_def.strip(), " ")
|
||||||
|
|
||||||
|
prefix = ""
|
||||||
|
i = 0
|
||||||
|
for part in parts:
|
||||||
|
if part in ["unsigned", "long", "short"]:
|
||||||
|
prefix += part + " "
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
parts = parts[i:]
|
||||||
|
|
||||||
|
if len(parts) <= 1:
|
||||||
|
return None
|
||||||
|
|
||||||
|
glbl.wtype = WType.from_string(prefix + parts[0], containing_file, line_number)
|
||||||
|
|
||||||
|
if glbl.wtype == None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
str_def = parts[1]
|
||||||
|
for part in parts[2:]:
|
||||||
|
str_def = str_def + " " + part
|
||||||
|
|
||||||
|
if str_def.find("(") != -1 or str_def.find(")") != -1 or str_def.find("{") != -1 or str_def.find("}") != -1:
|
||||||
|
return None
|
||||||
|
|
||||||
|
found = str_def.find(";")
|
||||||
|
if found == -1:
|
||||||
|
return None
|
||||||
|
|
||||||
|
found_eq = str_def.find("=")
|
||||||
|
if found_eq != -1:
|
||||||
|
found = found_eq
|
||||||
|
|
||||||
|
glbl.name = str_def[:found]
|
||||||
|
str_def = str_def[found+1:]
|
||||||
|
if glbl.name.find("*") == 0:
|
||||||
|
glbl.name = glbl.name.replace("*", "")
|
||||||
|
glbl.wtype.attr_type = attr_types.star
|
||||||
|
if glbl.name.find("&&") == 0:
|
||||||
|
glbl.name = glbl.name.replace("&&", "")
|
||||||
|
glbl.wtype.attr_type = attr_types.ampamp
|
||||||
|
if glbl.name.find("&") == 0:
|
||||||
|
glbl.name = glbl.name.replace("&", "")
|
||||||
|
glbl.wtype.attr_type = attr_types.amp
|
||||||
|
|
||||||
|
if(len(str_def.strip()) != 0):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if len(glbl.name.split(",")) > 1:
|
||||||
|
glbl_list = []
|
||||||
|
for name in glbl.name.split(","):
|
||||||
|
name = name.strip();
|
||||||
|
glbl_list.append(WGlobal())
|
||||||
|
glbl_list[-1].orig_text = glbl.orig_text
|
||||||
|
glbl_list[-1].wtype = glbl.wtype
|
||||||
|
glbl_list[-1].name = name
|
||||||
|
glbl_list[-1].containing_file = glbl.containing_file
|
||||||
|
glbl_list[-1].namespace = glbl.namespace
|
||||||
|
glbl_list[-1].is_const = glbl.is_const
|
||||||
|
return glbl_list
|
||||||
|
|
||||||
|
return glbl
|
||||||
|
|
||||||
|
def gen_def(self):
|
||||||
|
text = "\n\t"
|
||||||
|
if self.is_const:
|
||||||
|
text += "const "
|
||||||
|
text += self.wtype.gen_text() + " get_var_py_" + self.name + "()"
|
||||||
|
text += "\n\t{\n\t\t"
|
||||||
|
if self.wtype.attr_type == attr_types.star:
|
||||||
|
text += "if(" + self.namespace + "::" + self.name + " == NULL)\n\t\t\t"
|
||||||
|
text += "throw std::runtime_error(\"" + self.namespace + "::" + self.name + " is NULL\");\n\t\t"
|
||||||
|
if self.wtype.name in known_containers:
|
||||||
|
text += self.wtype.gen_text_cpp()
|
||||||
|
else:
|
||||||
|
if self.is_const:
|
||||||
|
text += "const "
|
||||||
|
text += self.wtype.gen_text()
|
||||||
|
|
||||||
|
if self.wtype.name in classnames or (self.wtype.name in known_containers and self.wtype.attr_type == attr_types.star):
|
||||||
|
text += "*"
|
||||||
|
text += " ret_ = "
|
||||||
|
if self.wtype.name in classnames:
|
||||||
|
text += self.wtype.name + "::get_py_obj("
|
||||||
|
if self.wtype.attr_type != attr_types.star:
|
||||||
|
text += "&"
|
||||||
|
text += self.namespace + "::" + self.name
|
||||||
|
if self.wtype.name in classnames:
|
||||||
|
text += ")"
|
||||||
|
text += ";"
|
||||||
|
|
||||||
|
if self.wtype.name in classnames:
|
||||||
|
text += "\n\t\treturn *ret_;"
|
||||||
|
elif self.wtype.name in known_containers:
|
||||||
|
text += known_containers[self.wtype.name].translate_cpp("ret_", self.wtype.cont.args, "\n\t\t", self.wtype.attr_type == attr_types.star)
|
||||||
|
text += "\n\t\treturn ret____tmp;"
|
||||||
|
else:
|
||||||
|
text += "\n\t\treturn ret_;"
|
||||||
|
text += "\n\t}\n"
|
||||||
|
|
||||||
|
if self.is_const:
|
||||||
|
return text
|
||||||
|
|
||||||
|
ret = Attribute(self.wtype, "rhs");
|
||||||
|
|
||||||
|
if self.wtype.name in classnames:
|
||||||
|
text += "\n\tvoid set_var_py_" + self.name + "(" + self.wtype.gen_text() + " *rhs)"
|
||||||
|
else:
|
||||||
|
text += "\n\tvoid set_var_py_" + self.name + "(" + self.wtype.gen_text() + " rhs)"
|
||||||
|
text += "\n\t{"
|
||||||
|
text += ret.gen_translation()
|
||||||
|
text += "\n\t\t" + self.namespace + "::" + self.name + " = " + ret.gen_call() + ";"
|
||||||
|
text += "\n\t}\n"
|
||||||
|
|
||||||
|
return text;
|
||||||
|
|
||||||
|
def gen_boost_py(self):
|
||||||
|
text = "\n\t\t\t.add_static_property(\"" + self.name + "\", &" + "YOSYS_PYTHON::get_var_py_" + self.name
|
||||||
|
if not self.is_const:
|
||||||
|
text += ", &YOSYS_PYTHON::set_var_py_" + self.name
|
||||||
|
text += ")"
|
||||||
|
return text
|
||||||
|
|
||||||
def concat_namespace(tuple_list):
|
def concat_namespace(tuple_list):
|
||||||
if len(tuple_list) == 0:
|
if len(tuple_list) == 0:
|
||||||
return ""
|
return ""
|
||||||
|
@ -1859,6 +2027,16 @@ def parse_header(source):
|
||||||
else:
|
else:
|
||||||
debug("\t\tFound member \"" + candidate.name + "\" of class \"" + class_[0].name + "\" of type \"" + candidate.wtype.name + "\"", 2)
|
debug("\t\tFound member \"" + candidate.name + "\" of class \"" + class_[0].name + "\" of type \"" + candidate.wtype.name + "\"", 2)
|
||||||
class_[0].found_vars.append(candidate)
|
class_[0].found_vars.append(candidate)
|
||||||
|
if candidate == None and class_ == None:
|
||||||
|
candidate = WGlobal.from_string(ugly_line, source.name, i, concat_namespace(namespaces))
|
||||||
|
if candidate != None:
|
||||||
|
if type(candidate) == list:
|
||||||
|
for c in candidate:
|
||||||
|
glbls.append(c)
|
||||||
|
debug("\tFound global \"" + c.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||||
|
else:
|
||||||
|
glbls.append(candidate)
|
||||||
|
debug("\tFound global \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||||
|
|
||||||
j = i
|
j = i
|
||||||
line = unpretty_string(line)
|
line = unpretty_string(line)
|
||||||
|
@ -1888,6 +2066,17 @@ def parse_header(source):
|
||||||
debug("\t\tFound constructor of class \"" + class_[0].name + "\" in namespace " + concat_namespace(namespaces),2)
|
debug("\t\tFound constructor of class \"" + class_[0].name + "\" in namespace " + concat_namespace(namespaces),2)
|
||||||
class_[0].found_constrs.append(candidate)
|
class_[0].found_constrs.append(candidate)
|
||||||
continue
|
continue
|
||||||
|
if class_ == None:
|
||||||
|
candidate = WGlobal.from_string(line, source.name, i, concat_namespace(namespaces))
|
||||||
|
if candidate != None:
|
||||||
|
if type(candidate) == list:
|
||||||
|
for c in candidate:
|
||||||
|
glbls.append(c)
|
||||||
|
debug("\tFound global \"" + c.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||||
|
else:
|
||||||
|
glbls.append(candidate)
|
||||||
|
debug("\tFound global \"" + candidate.name + "\" in namespace " + concat_namespace(namespaces), 2)
|
||||||
|
continue
|
||||||
if candidate != None:
|
if candidate != None:
|
||||||
while i < j:
|
while i < j:
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -1990,6 +2179,7 @@ def gen_wrappers(filename, debug_level_ = 0):
|
||||||
if len(class_.found_constrs) == 0:
|
if len(class_.found_constrs) == 0:
|
||||||
class_.found_constrs.append(WConstructor(source.name, class_))
|
class_.found_constrs.append(WConstructor(source.name, class_))
|
||||||
debug(str(len(unowned_functions)) + " functions are unowned", 1)
|
debug(str(len(unowned_functions)) + " functions are unowned", 1)
|
||||||
|
debug(str(len(unowned_functions)) + " global variables", 1)
|
||||||
for enum in enums:
|
for enum in enums:
|
||||||
debug("Enum " + assure_length(enum.name, len(max(enum_names, key=len)), True) + " contains " + assure_length(str(len(enum.values)), 2, False) + " values", 1)
|
debug("Enum " + assure_length(enum.name, len(max(enum_names, key=len)), True) + " contains " + assure_length(str(len(enum.values)), 2, False) + " values", 1)
|
||||||
debug("-"*col, 1)
|
debug("-"*col, 1)
|
||||||
|
@ -2025,10 +2215,15 @@ def gen_wrappers(filename, debug_level_ = 0):
|
||||||
#include <boost/python/wrapper.hpp>
|
#include <boost/python/wrapper.hpp>
|
||||||
#include <boost/python/call.hpp>
|
#include <boost/python/call.hpp>
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
|
#include <iosfwd> // std::streamsize
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/iostreams/concepts.hpp> // boost::iostreams::sink
|
||||||
|
#include <boost/iostreams/stream.hpp>
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
|
||||||
namespace YOSYS_PYTHON {
|
namespace YOSYS_PYTHON {
|
||||||
|
|
||||||
|
struct YosysStatics{};
|
||||||
""")
|
""")
|
||||||
|
|
||||||
for source in sources:
|
for source in sources:
|
||||||
|
@ -2050,6 +2245,9 @@ namespace YOSYS_PYTHON {
|
||||||
for fun in unowned_functions:
|
for fun in unowned_functions:
|
||||||
wrapper_file.write(fun.gen_def())
|
wrapper_file.write(fun.gen_def())
|
||||||
|
|
||||||
|
for glbl in glbls:
|
||||||
|
wrapper_file.write(glbl.gen_def())
|
||||||
|
|
||||||
wrapper_file.write(""" struct Initializer
|
wrapper_file.write(""" struct Initializer
|
||||||
{
|
{
|
||||||
Initializer() {
|
Initializer() {
|
||||||
|
@ -2068,12 +2266,89 @@ namespace YOSYS_PYTHON {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// source: https://stackoverflow.com/questions/26033781/converting-python-io-object-to-stdostream-when-using-boostpython?noredirect=1&lq=1
|
||||||
|
/// @brief Type that implements the Boost.IOStream's Sink and Flushable
|
||||||
|
/// concept for writing data to Python object that support:
|
||||||
|
/// n = object.write(str) # n = None or bytes written
|
||||||
|
/// object.flush() # if flush exists, then it is callable
|
||||||
|
class PythonOutputDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// This class models both the Sink and Flushable concepts.
|
||||||
|
struct category
|
||||||
|
: boost::iostreams::sink_tag,
|
||||||
|
boost::iostreams::flushable_tag
|
||||||
|
{};
|
||||||
|
|
||||||
|
explicit
|
||||||
|
PythonOutputDevice(boost::python::object object)
|
||||||
|
: object_(object)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Sink concept.
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef char char_type;
|
||||||
|
|
||||||
|
std::streamsize write(const char* buffer, std::streamsize buffer_size)
|
||||||
|
{
|
||||||
|
namespace python = boost::python;
|
||||||
|
// Copy the buffer to a python string.
|
||||||
|
python::str data(buffer, buffer_size);
|
||||||
|
|
||||||
|
// Invoke write on the python object, passing in the data. The following
|
||||||
|
// is equivalent to:
|
||||||
|
// n = object_.write(data)
|
||||||
|
python::extract<std::streamsize> bytes_written(
|
||||||
|
object_.attr("write")(data));
|
||||||
|
|
||||||
|
// Per the Sink concept, return the number of bytes written. If the
|
||||||
|
// Python return value provides a numeric result, then use it. Otherwise,
|
||||||
|
// such as the case of a File object, use the buffer_size.
|
||||||
|
return bytes_written.check()
|
||||||
|
? bytes_written
|
||||||
|
: buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flushable concept.
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool flush()
|
||||||
|
{
|
||||||
|
// If flush exists, then call it.
|
||||||
|
boost::python::object flush = object_.attr("flush");
|
||||||
|
if (!flush.is_none())
|
||||||
|
{
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always return true. If an error occurs, an exception should be thrown.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::python::object object_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief Use an auxiliary function to adapt the legacy function.
|
||||||
|
void log_to_stream(boost::python::object object)
|
||||||
|
{
|
||||||
|
// Create an ostream that delegates to the python object.
|
||||||
|
boost::iostreams::stream<PythonOutputDevice>* output = new boost::iostreams::stream<PythonOutputDevice>(object);
|
||||||
|
Yosys::log_streams.insert(Yosys::log_streams.begin(), output);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE(libyosys)
|
BOOST_PYTHON_MODULE(libyosys)
|
||||||
{
|
{
|
||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
|
|
||||||
class_<Initializer>("Initializer");
|
class_<Initializer>("Initializer");
|
||||||
scope().attr("_hidden") = new Initializer();
|
scope().attr("_hidden") = new Initializer();
|
||||||
|
|
||||||
|
def("log_to_stream", &log_to_stream);
|
||||||
""")
|
""")
|
||||||
|
|
||||||
for enum in enums:
|
for enum in enums:
|
||||||
|
@ -2086,6 +2361,11 @@ namespace YOSYS_PYTHON {
|
||||||
for fun in unowned_functions:
|
for fun in unowned_functions:
|
||||||
wrapper_file.write(fun.gen_boost_py())
|
wrapper_file.write(fun.gen_boost_py())
|
||||||
|
|
||||||
|
wrapper_file.write("\n\n\t\tclass_<YosysStatics>(\"Yosys\")\n")
|
||||||
|
for glbl in glbls:
|
||||||
|
wrapper_file.write(glbl.gen_boost_py())
|
||||||
|
wrapper_file.write("\t\t;\n")
|
||||||
|
|
||||||
wrapper_file.write("\n\t}\n}\n#endif")
|
wrapper_file.write("\n\t}\n}\n#endif")
|
||||||
|
|
||||||
def print_includes():
|
def print_includes():
|
||||||
|
|
|
@ -5,6 +5,7 @@ OBJS += passes/cmds/design.o
|
||||||
OBJS += passes/cmds/select.o
|
OBJS += passes/cmds/select.o
|
||||||
OBJS += passes/cmds/show.o
|
OBJS += passes/cmds/show.o
|
||||||
OBJS += passes/cmds/rename.o
|
OBJS += passes/cmds/rename.o
|
||||||
|
OBJS += passes/cmds/autoname.o
|
||||||
OBJS += passes/cmds/connect.o
|
OBJS += passes/cmds/connect.o
|
||||||
OBJS += passes/cmds/scatter.o
|
OBJS += passes/cmds/scatter.o
|
||||||
OBJS += passes/cmds/setundef.o
|
OBJS += passes/cmds/setundef.o
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* yosys -- Yosys Open SYnthesis Suite
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel/yosys.h"
|
||||||
|
|
||||||
|
USING_YOSYS_NAMESPACE
|
||||||
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
int autoname_worker(Module *module)
|
||||||
|
{
|
||||||
|
dict<Cell*, pair<int, IdString>> proposed_cell_names;
|
||||||
|
dict<Wire*, pair<int, IdString>> proposed_wire_names;
|
||||||
|
dict<Wire*, int> wire_score;
|
||||||
|
int best_score = -1;
|
||||||
|
|
||||||
|
for (auto cell : module->selected_cells())
|
||||||
|
for (auto &conn : cell->connections())
|
||||||
|
for (auto bit : conn.second)
|
||||||
|
if (bit.wire != nullptr)
|
||||||
|
wire_score[bit.wire]++;
|
||||||
|
|
||||||
|
for (auto cell : module->selected_cells()) {
|
||||||
|
if (cell->name[0] == '$') {
|
||||||
|
for (auto &conn : cell->connections()) {
|
||||||
|
string suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first));
|
||||||
|
for (auto bit : conn.second)
|
||||||
|
if (bit.wire != nullptr && bit.wire->name[0] != '$') {
|
||||||
|
IdString new_name(bit.wire->name.str() + suffix);
|
||||||
|
int score = wire_score.at(bit.wire);
|
||||||
|
if (cell->output(conn.first)) score = 0;
|
||||||
|
score = 10000*score + new_name.size();
|
||||||
|
if (!proposed_cell_names.count(cell) || score < proposed_cell_names.at(cell).first) {
|
||||||
|
if (best_score < 0 || score < best_score)
|
||||||
|
best_score = score;
|
||||||
|
proposed_cell_names[cell] = make_pair(score, new_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto &conn : cell->connections()) {
|
||||||
|
string suffix = stringf("_%s", log_id(conn.first));
|
||||||
|
for (auto bit : conn.second)
|
||||||
|
if (bit.wire != nullptr && bit.wire->name[0] == '$') {
|
||||||
|
IdString new_name(cell->name.str() + suffix);
|
||||||
|
int score = wire_score.at(bit.wire);
|
||||||
|
if (cell->output(conn.first)) score = 0;
|
||||||
|
score = 10000*score + new_name.size();
|
||||||
|
if (!proposed_wire_names.count(bit.wire) || score < proposed_wire_names.at(bit.wire).first) {
|
||||||
|
if (best_score < 0 || score < best_score)
|
||||||
|
best_score = score;
|
||||||
|
proposed_wire_names[bit.wire] = make_pair(score, new_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &it : proposed_cell_names) {
|
||||||
|
if (best_score*2 < it.second.first)
|
||||||
|
continue;
|
||||||
|
IdString n = module->uniquify(it.second.second);
|
||||||
|
log_debug("Rename cell %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
|
||||||
|
module->rename(it.first, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &it : proposed_wire_names) {
|
||||||
|
if (best_score*2 < it.second.first)
|
||||||
|
continue;
|
||||||
|
IdString n = module->uniquify(it.second.second);
|
||||||
|
log_debug("Rename wire %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
|
||||||
|
module->rename(it.first, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return proposed_cell_names.size() + proposed_wire_names.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AutonamePass : public Pass {
|
||||||
|
AutonamePass() : Pass("autoname", "automatically assign names to objects") { }
|
||||||
|
void help() YS_OVERRIDE
|
||||||
|
{
|
||||||
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
log("\n");
|
||||||
|
log(" autoname [selection]\n");
|
||||||
|
log("\n");
|
||||||
|
log("Assign auto-generated public names to objects with private names (the ones\n");
|
||||||
|
log("with $-prefix).\n");
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
|
{
|
||||||
|
size_t argidx;
|
||||||
|
for (argidx = 1; argidx < args.size(); argidx++)
|
||||||
|
{
|
||||||
|
// if (args[argidx] == "-foo") {
|
||||||
|
// foo = true;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_header(design, "Executing AUTONAME pass.\n");
|
||||||
|
|
||||||
|
for (auto module : design->selected_modules())
|
||||||
|
{
|
||||||
|
int count = 0, iter = 0;
|
||||||
|
while (1) {
|
||||||
|
iter++;
|
||||||
|
int n = autoname_worker(module);
|
||||||
|
if (!n) break;
|
||||||
|
count += n;
|
||||||
|
}
|
||||||
|
if (count > 0)
|
||||||
|
log("Renamed %d objects in module %s (%d iterations).\n", count, log_id(module), iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} AutonamePass;
|
||||||
|
|
||||||
|
PRIVATE_NAMESPACE_END
|
|
@ -158,22 +158,25 @@ static void detect_fsm(RTLIL::Wire *wire)
|
||||||
std::set<sig2driver_entry_t> cellport_list;
|
std::set<sig2driver_entry_t> cellport_list;
|
||||||
sig2user.find(sig_q, cellport_list);
|
sig2user.find(sig_q, cellport_list);
|
||||||
|
|
||||||
|
auto sig_q_bits = sig_q.to_sigbit_pool();
|
||||||
|
|
||||||
for (auto &cellport : cellport_list)
|
for (auto &cellport : cellport_list)
|
||||||
{
|
{
|
||||||
RTLIL::Cell *cell = cellport.first;
|
RTLIL::Cell *cell = cellport.first;
|
||||||
bool set_output = false, clr_output = false;
|
bool set_output = false, clr_output = false;
|
||||||
|
|
||||||
if (cell->type == "$ne")
|
if (cell->type.in("$ne", "$reduce_or", "$reduce_bool"))
|
||||||
set_output = true;
|
set_output = true;
|
||||||
|
|
||||||
if (cell->type == "$eq")
|
if (cell->type.in("$eq", "$logic_not", "$reduce_and"))
|
||||||
clr_output = true;
|
clr_output = true;
|
||||||
|
|
||||||
if (!set_output && !clr_output) {
|
if (set_output || clr_output) {
|
||||||
clr_output = true;
|
|
||||||
for (auto &port_it : cell->connections())
|
for (auto &port_it : cell->connections())
|
||||||
if (port_it.first != "\\A" || port_it.first != "\\Y")
|
if (cell->input(port_it.first))
|
||||||
clr_output = false;
|
for (auto bit : assign_map(port_it.second))
|
||||||
|
if (bit.wire != nullptr && !sig_q_bits.count(bit))
|
||||||
|
goto next_cellport;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_output || clr_output) {
|
if (set_output || clr_output) {
|
||||||
|
@ -184,6 +187,7 @@ static void detect_fsm(RTLIL::Wire *wire)
|
||||||
ce.set(sig, val);
|
ce.set(sig, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next_cellport:;
|
||||||
}
|
}
|
||||||
|
|
||||||
SigSpec sig_y = sig_d, sig_undef;
|
SigSpec sig_y = sig_d, sig_undef;
|
||||||
|
|
|
@ -143,13 +143,18 @@ struct WreduceWorker
|
||||||
|
|
||||||
SigSpec sig_d = mi.sigmap(cell->getPort(ID(D)));
|
SigSpec sig_d = mi.sigmap(cell->getPort(ID(D)));
|
||||||
SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q)));
|
SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q)));
|
||||||
Const initval;
|
bool is_adff = (cell->type == ID($adff));
|
||||||
|
Const initval, arst_value;
|
||||||
|
|
||||||
int width_before = GetSize(sig_q);
|
int width_before = GetSize(sig_q);
|
||||||
|
|
||||||
if (width_before == 0)
|
if (width_before == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (cell->parameters.count(ID(ARST_VALUE))) {
|
||||||
|
arst_value = cell->parameters[ID(ARST_VALUE)];
|
||||||
|
}
|
||||||
|
|
||||||
bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0;
|
bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0;
|
||||||
bool sign_ext = !zero_ext;
|
bool sign_ext = !zero_ext;
|
||||||
|
|
||||||
|
@ -163,7 +168,8 @@ struct WreduceWorker
|
||||||
|
|
||||||
for (int i = GetSize(sig_q)-1; i >= 0; i--)
|
for (int i = GetSize(sig_q)-1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (zero_ext && sig_d[i] == State::S0 && (initval[i] == State::S0 || initval[i] == State::Sx)) {
|
if (zero_ext && sig_d[i] == State::S0 && (initval[i] == State::S0 || initval[i] == State::Sx) &&
|
||||||
|
(!is_adff || i >= GetSize(arst_value) || arst_value[i] == State::S0 || arst_value[i] == State::Sx)) {
|
||||||
module->connect(sig_q[i], State::S0);
|
module->connect(sig_q[i], State::S0);
|
||||||
remove_init_bits.insert(sig_q[i]);
|
remove_init_bits.insert(sig_q[i]);
|
||||||
sig_d.remove(i);
|
sig_d.remove(i);
|
||||||
|
@ -171,7 +177,8 @@ struct WreduceWorker
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1] && initval[i] == initval[i-1]) {
|
if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1] && initval[i] == initval[i-1] &&
|
||||||
|
(!is_adff || i >= GetSize(arst_value) || arst_value[i] == arst_value[i-1])) {
|
||||||
module->connect(sig_q[i], sig_q[i-1]);
|
module->connect(sig_q[i], sig_q[i-1]);
|
||||||
remove_init_bits.insert(sig_q[i]);
|
remove_init_bits.insert(sig_q[i]);
|
||||||
sig_d.remove(i);
|
sig_d.remove(i);
|
||||||
|
@ -214,7 +221,6 @@ struct WreduceWorker
|
||||||
|
|
||||||
// Narrow ARST_VALUE parameter to new size.
|
// Narrow ARST_VALUE parameter to new size.
|
||||||
if (cell->parameters.count(ID(ARST_VALUE))) {
|
if (cell->parameters.count(ID(ARST_VALUE))) {
|
||||||
Const arst_value = cell->getParam(ID(ARST_VALUE));
|
|
||||||
arst_value.bits.resize(GetSize(sig_q));
|
arst_value.bits.resize(GetSize(sig_q));
|
||||||
cell->setParam(ID(ARST_VALUE), arst_value);
|
cell->setParam(ID(ARST_VALUE), arst_value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
%_pm.h: passes/pmgen/pmgen.py %.pmg
|
%_pm.h: passes/pmgen/pmgen.py %.pmg
|
||||||
$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p $(subst _pm.h,,$(notdir $@)) $(filter-out $<,$^)
|
$(P) mkdir -p passes/pmgen && $(PYTHON_EXECUTABLE) $< -o $@ -p $(subst _pm.h,,$(notdir $@)) $(filter-out $<,$^)
|
||||||
|
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ PEEPOPT_PATTERN += passes/pmgen/peepopt_muldiv.pmg
|
||||||
PEEPOPT_PATTERN += passes/pmgen/peepopt_dffmux.pmg
|
PEEPOPT_PATTERN += passes/pmgen/peepopt_dffmux.pmg
|
||||||
|
|
||||||
passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
|
passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
|
||||||
$(P) mkdir -p passes/pmgen && python3 $< -o $@ -p peepopt $(filter-out $<,$^)
|
$(P) mkdir -p passes/pmgen && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^)
|
||||||
|
|
||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* yosys -- Yosys Open SYnthesis Suite
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PMGEN_GENERATE
|
||||||
|
#define PMGEN_GENERATE
|
||||||
|
|
||||||
|
#define GENERATE_PATTERN(pmclass, pattern) \
|
||||||
|
generate_pattern<pmclass>([](pmclass &pm, std::function<void()> f){ return pm.run_ ## pattern(f); }, #pmclass, #pattern, design)
|
||||||
|
|
||||||
|
void pmtest_addports(Module *module)
|
||||||
|
{
|
||||||
|
pool<SigBit> driven_bits, used_bits;
|
||||||
|
SigMap sigmap(module);
|
||||||
|
int icnt = 0, ocnt = 0;
|
||||||
|
|
||||||
|
for (auto cell : module->cells())
|
||||||
|
for (auto conn : cell->connections())
|
||||||
|
{
|
||||||
|
if (cell->input(conn.first))
|
||||||
|
for (auto bit : sigmap(conn.second))
|
||||||
|
used_bits.insert(bit);
|
||||||
|
if (cell->output(conn.first))
|
||||||
|
for (auto bit : sigmap(conn.second))
|
||||||
|
driven_bits.insert(bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto wire : vector<Wire*>(module->wires()))
|
||||||
|
{
|
||||||
|
SigSpec ibits, obits;
|
||||||
|
for (auto bit : sigmap(wire)) {
|
||||||
|
if (!used_bits.count(bit))
|
||||||
|
obits.append(bit);
|
||||||
|
if (!driven_bits.count(bit))
|
||||||
|
ibits.append(bit);
|
||||||
|
}
|
||||||
|
if (!ibits.empty()) {
|
||||||
|
Wire *w = module->addWire(stringf("\\i%d", icnt++), GetSize(ibits));
|
||||||
|
w->port_input = true;
|
||||||
|
module->connect(ibits, w);
|
||||||
|
}
|
||||||
|
if (!obits.empty()) {
|
||||||
|
Wire *w = module->addWire(stringf("\\o%d", ocnt++), GetSize(obits));
|
||||||
|
w->port_output = true;
|
||||||
|
module->connect(w, obits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module->fixup_ports();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class pm>
|
||||||
|
void generate_pattern(std::function<void(pm&,std::function<void()>)> run, const char *pmclass, const char *pattern, Design *design)
|
||||||
|
{
|
||||||
|
log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern, pmclass);
|
||||||
|
|
||||||
|
int modcnt = 0;
|
||||||
|
int maxmodcnt = 100;
|
||||||
|
int maxsubcnt = 4;
|
||||||
|
int timeout = 0;
|
||||||
|
vector<Module*> mods;
|
||||||
|
|
||||||
|
while (modcnt < maxmodcnt)
|
||||||
|
{
|
||||||
|
int submodcnt = 0, itercnt = 0, cellcnt = 0;
|
||||||
|
Module *mod = design->addModule(NEW_ID);
|
||||||
|
|
||||||
|
while (modcnt < maxmodcnt && submodcnt < maxsubcnt && itercnt++ < 1000)
|
||||||
|
{
|
||||||
|
if (timeout++ > 10000)
|
||||||
|
log_error("pmgen generator is stuck: 10000 iterations with no matching module generated.\n");
|
||||||
|
|
||||||
|
pm matcher(mod, mod->cells());
|
||||||
|
|
||||||
|
matcher.rng(1);
|
||||||
|
matcher.rngseed += modcnt;
|
||||||
|
matcher.rng(1);
|
||||||
|
matcher.rngseed += submodcnt;
|
||||||
|
matcher.rng(1);
|
||||||
|
matcher.rngseed += itercnt;
|
||||||
|
matcher.rng(1);
|
||||||
|
matcher.rngseed += cellcnt;
|
||||||
|
matcher.rng(1);
|
||||||
|
|
||||||
|
if (GetSize(mod->cells()) != cellcnt)
|
||||||
|
{
|
||||||
|
bool found_match = false;
|
||||||
|
run(matcher, [&](){ found_match = true; });
|
||||||
|
cellcnt = GetSize(mod->cells());
|
||||||
|
|
||||||
|
if (found_match) {
|
||||||
|
Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d",
|
||||||
|
pmclass, pattern, modcnt++));
|
||||||
|
log("Creating module %s with %d cells.\n", log_id(m), cellcnt);
|
||||||
|
mod->cloneInto(m);
|
||||||
|
pmtest_addports(m);
|
||||||
|
mods.push_back(m);
|
||||||
|
submodcnt++;
|
||||||
|
timeout = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matcher.generate_mode = true;
|
||||||
|
run(matcher, [](){});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (submodcnt && maxsubcnt < (1 << 16))
|
||||||
|
maxsubcnt *= 2;
|
||||||
|
|
||||||
|
design->remove(mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
Module *m = design->addModule(stringf("\\pmtest_%s_%s", pmclass, pattern));
|
||||||
|
log("Creating module %s with %d cells.\n", log_id(m), GetSize(mods));
|
||||||
|
for (auto mod : mods) {
|
||||||
|
Cell *c = m->addCell(mod->name, mod->name);
|
||||||
|
for (auto port : mod->ports) {
|
||||||
|
Wire *w = m->addWire(NEW_ID, GetSize(mod->wire(port)));
|
||||||
|
c->setPort(port, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pmtest_addports(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -24,8 +24,11 @@ USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
bool did_something;
|
bool did_something;
|
||||||
|
dict<SigBit, State> initbits;
|
||||||
|
pool<SigBit> rminitbits;
|
||||||
|
|
||||||
#include "passes/pmgen/peepopt_pm.h"
|
#include "passes/pmgen/peepopt_pm.h"
|
||||||
|
#include "generate.h"
|
||||||
|
|
||||||
struct PeepoptPass : public Pass {
|
struct PeepoptPass : public Pass {
|
||||||
PeepoptPass() : Pass("peepopt", "collection of peephole optimizers") { }
|
PeepoptPass() : Pass("peepopt", "collection of peephole optimizers") { }
|
||||||
|
@ -40,27 +43,86 @@ struct PeepoptPass : public Pass {
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
{
|
{
|
||||||
|
std::string genmode;
|
||||||
|
|
||||||
log_header(design, "Executing PEEPOPT pass (run peephole optimizers).\n");
|
log_header(design, "Executing PEEPOPT pass (run peephole optimizers).\n");
|
||||||
|
|
||||||
size_t argidx;
|
size_t argidx;
|
||||||
for (argidx = 1; argidx < args.size(); argidx++)
|
for (argidx = 1; argidx < args.size(); argidx++)
|
||||||
{
|
{
|
||||||
// if (args[argidx] == "-singleton") {
|
if (args[argidx] == "-generate" && argidx+1 < args.size()) {
|
||||||
// singleton_mode = true;
|
genmode = args[++argidx];
|
||||||
// continue;
|
continue;
|
||||||
// }
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
for (auto module : design->selected_modules()) {
|
if (!genmode.empty())
|
||||||
|
{
|
||||||
|
initbits.clear();
|
||||||
|
rminitbits.clear();
|
||||||
|
|
||||||
|
if (genmode == "shiftmul")
|
||||||
|
GENERATE_PATTERN(peepopt_pm, shiftmul);
|
||||||
|
else if (genmode == "muldiv")
|
||||||
|
GENERATE_PATTERN(peepopt_pm, muldiv);
|
||||||
|
else if (genmode == "dffmux")
|
||||||
|
GENERATE_PATTERN(peepopt_pm, dffmux);
|
||||||
|
else
|
||||||
|
log_abort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto module : design->selected_modules())
|
||||||
|
{
|
||||||
did_something = true;
|
did_something = true;
|
||||||
while (did_something) {
|
|
||||||
|
while (did_something)
|
||||||
|
{
|
||||||
did_something = false;
|
did_something = false;
|
||||||
peepopt_pm pm(module, module->selected_cells());
|
initbits.clear();
|
||||||
|
rminitbits.clear();
|
||||||
|
|
||||||
|
peepopt_pm pm(module);
|
||||||
|
|
||||||
|
for (auto w : module->wires()) {
|
||||||
|
auto it = w->attributes.find(ID(init));
|
||||||
|
if (it != w->attributes.end()) {
|
||||||
|
SigSpec sig = pm.sigmap(w);
|
||||||
|
Const val = it->second;
|
||||||
|
int len = std::min(GetSize(sig), GetSize(val));
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (sig[i].wire == nullptr)
|
||||||
|
continue;
|
||||||
|
if (val[i] != State::S0 && val[i] != State::S1)
|
||||||
|
continue;
|
||||||
|
initbits[sig[i]] = val[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pm.setup(module->selected_cells());
|
||||||
|
|
||||||
pm.run_shiftmul();
|
pm.run_shiftmul();
|
||||||
pm.run_muldiv();
|
pm.run_muldiv();
|
||||||
pm.run_dffmux();
|
pm.run_dffmux();
|
||||||
|
|
||||||
|
for (auto w : module->wires()) {
|
||||||
|
auto it = w->attributes.find(ID(init));
|
||||||
|
if (it != w->attributes.end()) {
|
||||||
|
SigSpec sig = pm.sigmap(w);
|
||||||
|
Const &val = it->second;
|
||||||
|
int len = std::min(GetSize(sig), GetSize(val));
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (rminitbits.count(sig[i]))
|
||||||
|
val[i] = State::Sx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initbits.clear();
|
||||||
|
rminitbits.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,12 +60,13 @@ code
|
||||||
SigSpec Q = port(dff, \Q);
|
SigSpec Q = port(dff, \Q);
|
||||||
int width = GetSize(D);
|
int width = GetSize(D);
|
||||||
|
|
||||||
SigSpec &dffD = dff->connections_.at(\D);
|
SigSpec dffD = dff->getPort(\D);
|
||||||
SigSpec &dffQ = dff->connections_.at(\Q);
|
SigSpec dffQ = dff->getPort(\Q);
|
||||||
Const init;
|
|
||||||
for (const auto &b : Q) {
|
Const initval;
|
||||||
auto it = b.wire->attributes.find(\init);
|
for (auto b : Q) {
|
||||||
init.bits.push_back(it == b.wire->attributes.end() ? State::Sx : it->second[b.offset]);
|
auto it = initbits.find(b);
|
||||||
|
initval.bits.push_back(it == initbits.end() ? State::Sx : it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cmpx = [=](State lhs, State rhs) {
|
auto cmpx = [=](State lhs, State rhs) {
|
||||||
|
@ -76,56 +77,68 @@ code
|
||||||
|
|
||||||
int i = width-1;
|
int i = width-1;
|
||||||
while (i > 1) {
|
while (i > 1) {
|
||||||
log_dump(i, D[i], D[i-1], rst[i], rst[i-1], init[i], init[i-1]);
|
|
||||||
if (D[i] != D[i-1])
|
if (D[i] != D[i-1])
|
||||||
break;
|
break;
|
||||||
if (!cmpx(rst[i], rst[i-1]))
|
if (!cmpx(rst[i], rst[i-1]))
|
||||||
break;
|
break;
|
||||||
if (!cmpx(init[i], init[i-1]))
|
if (!cmpx(initval[i], initval[i-1]))
|
||||||
break;
|
break;
|
||||||
if (!cmpx(rst[i], init[i]))
|
if (!cmpx(rst[i], initval[i]))
|
||||||
break;
|
break;
|
||||||
|
rminitbits.insert(Q[i]);
|
||||||
module->connect(Q[i], Q[i-1]);
|
module->connect(Q[i], Q[i-1]);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
if (i < width-1) {
|
if (i < width-1) {
|
||||||
did_something = true;
|
did_something = true;
|
||||||
if (cemux) {
|
if (cemux) {
|
||||||
SigSpec &ceA = cemux->connections_.at(\A);
|
SigSpec ceA = cemux->getPort(\A);
|
||||||
SigSpec &ceB = cemux->connections_.at(\B);
|
SigSpec ceB = cemux->getPort(\B);
|
||||||
SigSpec &ceY = cemux->connections_.at(\Y);
|
SigSpec ceY = cemux->getPort(\Y);
|
||||||
ceA.remove(i, width-1-i);
|
ceA.remove(i, width-1-i);
|
||||||
ceB.remove(i, width-1-i);
|
ceB.remove(i, width-1-i);
|
||||||
ceY.remove(i, width-1-i);
|
ceY.remove(i, width-1-i);
|
||||||
|
cemux->setPort(\A, ceA);
|
||||||
|
cemux->setPort(\B, ceB);
|
||||||
|
cemux->setPort(\Y, ceY);
|
||||||
cemux->fixup_parameters();
|
cemux->fixup_parameters();
|
||||||
|
blacklist(cemux);
|
||||||
}
|
}
|
||||||
if (rstmux) {
|
if (rstmux) {
|
||||||
SigSpec &rstA = rstmux->connections_.at(\A);
|
SigSpec rstA = rstmux->getPort(\A);
|
||||||
SigSpec &rstB = rstmux->connections_.at(\B);
|
SigSpec rstB = rstmux->getPort(\B);
|
||||||
SigSpec &rstY = rstmux->connections_.at(\Y);
|
SigSpec rstY = rstmux->getPort(\Y);
|
||||||
rstA.remove(i, width-1-i);
|
rstA.remove(i, width-1-i);
|
||||||
rstB.remove(i, width-1-i);
|
rstB.remove(i, width-1-i);
|
||||||
rstY.remove(i, width-1-i);
|
rstY.remove(i, width-1-i);
|
||||||
|
rstmux->setPort(\A, rstA);
|
||||||
|
rstmux->setPort(\B, rstB);
|
||||||
|
rstmux->setPort(\Y, rstY);
|
||||||
rstmux->fixup_parameters();
|
rstmux->fixup_parameters();
|
||||||
|
blacklist(rstmux);
|
||||||
}
|
}
|
||||||
dffD.remove(i, width-1-i);
|
dffD.remove(i, width-1-i);
|
||||||
dffQ.remove(i, width-1-i);
|
dffQ.remove(i, width-1-i);
|
||||||
|
dff->setPort(\D, dffD);
|
||||||
|
dff->setPort(\Q, dffQ);
|
||||||
dff->fixup_parameters();
|
dff->fixup_parameters();
|
||||||
|
blacklist(dff);
|
||||||
|
|
||||||
log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(cemux, "n/a"), log_id(rstmux, "n/a"), width-1-i);
|
log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed top %d bits.\n", log_id(module), log_id(dff), log_id(cemux, "n/a"), log_id(rstmux, "n/a"), width-1-i);
|
||||||
width = i+1;
|
width = i+1;
|
||||||
}
|
}
|
||||||
if (cemux) {
|
if (cemux) {
|
||||||
SigSpec &ceA = cemux->connections_.at(\A);
|
SigSpec ceA = cemux->getPort(\A);
|
||||||
SigSpec &ceB = cemux->connections_.at(\B);
|
SigSpec ceB = cemux->getPort(\B);
|
||||||
SigSpec &ceY = cemux->connections_.at(\Y);
|
SigSpec ceY = cemux->getPort(\Y);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = width-1; i >= 0; i--) {
|
for (int i = width-1; i >= 0; i--) {
|
||||||
if (D[i].wire)
|
if (D[i].wire)
|
||||||
continue;
|
continue;
|
||||||
if (cmpx(rst[i], D[i].data) && cmpx(init[i], D[i].data)) {
|
if (cmpx(rst[i], D[i].data) && cmpx(initval[i], D[i].data)) {
|
||||||
count++;
|
count++;
|
||||||
|
rminitbits.insert(Q[i]);
|
||||||
module->connect(Q[i], D[i]);
|
module->connect(Q[i], D[i]);
|
||||||
ceA.remove(i);
|
ceA.remove(i);
|
||||||
ceB.remove(i);
|
ceB.remove(i);
|
||||||
|
@ -134,10 +147,21 @@ code
|
||||||
dffQ.remove(i);
|
dffQ.remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count > 0) {
|
if (count > 0)
|
||||||
|
{
|
||||||
did_something = true;
|
did_something = true;
|
||||||
|
|
||||||
|
cemux->setPort(\A, ceA);
|
||||||
|
cemux->setPort(\B, ceB);
|
||||||
|
cemux->setPort(\Y, ceY);
|
||||||
cemux->fixup_parameters();
|
cemux->fixup_parameters();
|
||||||
|
blacklist(cemux);
|
||||||
|
|
||||||
|
dff->setPort(\D, dffD);
|
||||||
|
dff->setPort(\Q, dffQ);
|
||||||
dff->fixup_parameters();
|
dff->fixup_parameters();
|
||||||
|
blacklist(dff);
|
||||||
|
|
||||||
log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(cemux), log_id(rstmux, "n/a"), count);
|
log("dffcemux pattern in %s: dff=%s, cemux=%s, rstmux=%s; removed %d constant bits.\n", log_id(module), log_id(dff), log_id(cemux), log_id(rstmux, "n/a"), count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,6 +362,7 @@ with open(outfile, "w") as f:
|
||||||
print(" Module *module;", file=f)
|
print(" Module *module;", file=f)
|
||||||
print(" SigMap sigmap;", file=f)
|
print(" SigMap sigmap;", file=f)
|
||||||
print(" std::function<void()> on_accept;", file=f)
|
print(" std::function<void()> on_accept;", file=f)
|
||||||
|
print(" bool setup_done;", file=f)
|
||||||
print(" bool generate_mode;", file=f)
|
print(" bool generate_mode;", file=f)
|
||||||
print(" int accept_cnt;", file=f)
|
print(" int accept_cnt;", file=f)
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
@ -477,7 +478,17 @@ with open(outfile, "w") as f:
|
||||||
print("", file=f)
|
print("", file=f)
|
||||||
|
|
||||||
print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f)
|
print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f)
|
||||||
print(" module(module), sigmap(module), generate_mode(false), rngseed(12345678) {", file=f)
|
print(" module(module), sigmap(module), setup_done(false), generate_mode(false), rngseed(12345678) {", file=f)
|
||||||
|
print(" setup(cells);", file=f)
|
||||||
|
print(" }", file=f)
|
||||||
|
print("", file=f)
|
||||||
|
|
||||||
|
print(" {}_pm(Module *module) :".format(prefix), file=f)
|
||||||
|
print(" module(module), sigmap(module), setup_done(false), generate_mode(false), rngseed(12345678) {", file=f)
|
||||||
|
print(" }", file=f)
|
||||||
|
print("", file=f)
|
||||||
|
|
||||||
|
print(" void setup(const vector<Cell*> &cells) {", file=f)
|
||||||
for current_pattern in sorted(patterns.keys()):
|
for current_pattern in sorted(patterns.keys()):
|
||||||
for s, t in sorted(udata_types[current_pattern].items()):
|
for s, t in sorted(udata_types[current_pattern].items()):
|
||||||
if t.endswith("*"):
|
if t.endswith("*"):
|
||||||
|
@ -485,6 +496,8 @@ with open(outfile, "w") as f:
|
||||||
else:
|
else:
|
||||||
print(" ud_{}.{} = {}();".format(current_pattern, s, t), file=f)
|
print(" ud_{}.{} = {}();".format(current_pattern, s, t), file=f)
|
||||||
current_pattern = None
|
current_pattern = None
|
||||||
|
print(" log_assert(!setup_done);", file=f)
|
||||||
|
print(" setup_done = true;", file=f)
|
||||||
print(" for (auto port : module->ports)", file=f)
|
print(" for (auto port : module->ports)", file=f)
|
||||||
print(" add_siguser(module->wire(port), nullptr);", file=f)
|
print(" add_siguser(module->wire(port), nullptr);", file=f)
|
||||||
print(" for (auto cell : module->cells())", file=f)
|
print(" for (auto cell : module->cells())", file=f)
|
||||||
|
@ -539,6 +552,7 @@ with open(outfile, "w") as f:
|
||||||
|
|
||||||
for current_pattern in sorted(patterns.keys()):
|
for current_pattern in sorted(patterns.keys()):
|
||||||
print(" int run_{}(std::function<void()> on_accept_f) {{".format(current_pattern), file=f)
|
print(" int run_{}(std::function<void()> on_accept_f) {{".format(current_pattern), file=f)
|
||||||
|
print(" log_assert(setup_done);", file=f)
|
||||||
print(" accept_cnt = 0;", file=f)
|
print(" accept_cnt = 0;", file=f)
|
||||||
print(" on_accept = on_accept_f;", file=f)
|
print(" on_accept = on_accept_f;", file=f)
|
||||||
print(" rollback = 0;", file=f)
|
print(" rollback = 0;", file=f)
|
||||||
|
|
|
@ -23,13 +23,11 @@
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
// for peepopt_pm
|
|
||||||
bool did_something;
|
|
||||||
|
|
||||||
#include "passes/pmgen/test_pmgen_pm.h"
|
#include "passes/pmgen/test_pmgen_pm.h"
|
||||||
#include "passes/pmgen/ice40_dsp_pm.h"
|
#include "passes/pmgen/ice40_dsp_pm.h"
|
||||||
#include "passes/pmgen/xilinx_srl_pm.h"
|
#include "passes/pmgen/xilinx_srl_pm.h"
|
||||||
#include "passes/pmgen/peepopt_pm.h"
|
|
||||||
|
#include "generate.h"
|
||||||
|
|
||||||
void reduce_chain(test_pmgen_pm &pm)
|
void reduce_chain(test_pmgen_pm &pm)
|
||||||
{
|
{
|
||||||
|
@ -118,123 +116,6 @@ void opt_eqpmux(test_pmgen_pm &pm)
|
||||||
log(" -> %s (%s)\n", log_id(c), log_id(c->type));
|
log(" -> %s (%s)\n", log_id(c), log_id(c->type));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GENERATE_PATTERN(pmclass, pattern) \
|
|
||||||
generate_pattern<pmclass>([](pmclass &pm, std::function<void()> f){ return pm.run_ ## pattern(f); }, #pmclass, #pattern, design)
|
|
||||||
|
|
||||||
void pmtest_addports(Module *module)
|
|
||||||
{
|
|
||||||
pool<SigBit> driven_bits, used_bits;
|
|
||||||
SigMap sigmap(module);
|
|
||||||
int icnt = 0, ocnt = 0;
|
|
||||||
|
|
||||||
for (auto cell : module->cells())
|
|
||||||
for (auto conn : cell->connections())
|
|
||||||
{
|
|
||||||
if (cell->input(conn.first))
|
|
||||||
for (auto bit : sigmap(conn.second))
|
|
||||||
used_bits.insert(bit);
|
|
||||||
if (cell->output(conn.first))
|
|
||||||
for (auto bit : sigmap(conn.second))
|
|
||||||
driven_bits.insert(bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto wire : vector<Wire*>(module->wires()))
|
|
||||||
{
|
|
||||||
SigSpec ibits, obits;
|
|
||||||
for (auto bit : sigmap(wire)) {
|
|
||||||
if (!used_bits.count(bit))
|
|
||||||
obits.append(bit);
|
|
||||||
if (!driven_bits.count(bit))
|
|
||||||
ibits.append(bit);
|
|
||||||
}
|
|
||||||
if (!ibits.empty()) {
|
|
||||||
Wire *w = module->addWire(stringf("\\i%d", icnt++), GetSize(ibits));
|
|
||||||
w->port_input = true;
|
|
||||||
module->connect(ibits, w);
|
|
||||||
}
|
|
||||||
if (!obits.empty()) {
|
|
||||||
Wire *w = module->addWire(stringf("\\o%d", ocnt++), GetSize(obits));
|
|
||||||
w->port_output = true;
|
|
||||||
module->connect(w, obits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module->fixup_ports();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class pm>
|
|
||||||
void generate_pattern(std::function<void(pm&,std::function<void()>)> run, const char *pmclass, const char *pattern, Design *design)
|
|
||||||
{
|
|
||||||
log("Generating \"%s\" patterns for pattern matcher \"%s\".\n", pattern, pmclass);
|
|
||||||
|
|
||||||
int modcnt = 0;
|
|
||||||
int maxmodcnt = 100;
|
|
||||||
int maxsubcnt = 4;
|
|
||||||
int timeout = 0;
|
|
||||||
vector<Module*> mods;
|
|
||||||
|
|
||||||
while (modcnt < maxmodcnt)
|
|
||||||
{
|
|
||||||
int submodcnt = 0, itercnt = 0, cellcnt = 0;
|
|
||||||
Module *mod = design->addModule(NEW_ID);
|
|
||||||
|
|
||||||
while (modcnt < maxmodcnt && submodcnt < maxsubcnt && itercnt++ < 1000)
|
|
||||||
{
|
|
||||||
if (timeout++ > 10000)
|
|
||||||
log_error("pmgen generator is stuck: 10000 iterations with no matching module generated.\n");
|
|
||||||
|
|
||||||
pm matcher(mod, mod->cells());
|
|
||||||
|
|
||||||
matcher.rng(1);
|
|
||||||
matcher.rngseed += modcnt;
|
|
||||||
matcher.rng(1);
|
|
||||||
matcher.rngseed += submodcnt;
|
|
||||||
matcher.rng(1);
|
|
||||||
matcher.rngseed += itercnt;
|
|
||||||
matcher.rng(1);
|
|
||||||
matcher.rngseed += cellcnt;
|
|
||||||
matcher.rng(1);
|
|
||||||
|
|
||||||
if (GetSize(mod->cells()) != cellcnt)
|
|
||||||
{
|
|
||||||
bool found_match = false;
|
|
||||||
run(matcher, [&](){ found_match = true; });
|
|
||||||
cellcnt = GetSize(mod->cells());
|
|
||||||
|
|
||||||
if (found_match) {
|
|
||||||
Module *m = design->addModule(stringf("\\pmtest_%s_%s_%05d",
|
|
||||||
pmclass, pattern, modcnt++));
|
|
||||||
log("Creating module %s with %d cells.\n", log_id(m), cellcnt);
|
|
||||||
mod->cloneInto(m);
|
|
||||||
pmtest_addports(m);
|
|
||||||
mods.push_back(m);
|
|
||||||
submodcnt++;
|
|
||||||
timeout = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
matcher.generate_mode = true;
|
|
||||||
run(matcher, [](){});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submodcnt && maxsubcnt < (1 << 16))
|
|
||||||
maxsubcnt *= 2;
|
|
||||||
|
|
||||||
design->remove(mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
Module *m = design->addModule(stringf("\\pmtest_%s_%s", pmclass, pattern));
|
|
||||||
log("Creating module %s with %d cells.\n", log_id(m), GetSize(mods));
|
|
||||||
for (auto mod : mods) {
|
|
||||||
Cell *c = m->addCell(mod->name, mod->name);
|
|
||||||
for (auto port : mod->ports) {
|
|
||||||
Wire *w = m->addWire(NEW_ID, GetSize(mod->wire(port)));
|
|
||||||
c->setPort(port, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pmtest_addports(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TestPmgenPass : public Pass {
|
struct TestPmgenPass : public Pass {
|
||||||
TestPmgenPass() : Pass("test_pmgen", "test pass for pmgen") { }
|
TestPmgenPass() : Pass("test_pmgen", "test pass for pmgen") { }
|
||||||
void help() YS_OVERRIDE
|
void help() YS_OVERRIDE
|
||||||
|
@ -355,12 +236,6 @@ struct TestPmgenPass : public Pass {
|
||||||
if (pattern == "xilinx_srl.variable")
|
if (pattern == "xilinx_srl.variable")
|
||||||
return GENERATE_PATTERN(xilinx_srl_pm, variable);
|
return GENERATE_PATTERN(xilinx_srl_pm, variable);
|
||||||
|
|
||||||
if (pattern == "peepopt-muldiv")
|
|
||||||
return GENERATE_PATTERN(peepopt_pm, muldiv);
|
|
||||||
|
|
||||||
if (pattern == "peepopt-shiftmul")
|
|
||||||
return GENERATE_PATTERN(peepopt_pm, shiftmul);
|
|
||||||
|
|
||||||
log_cmd_error("Unknown pattern: %s\n", pattern.c_str());
|
log_cmd_error("Unknown pattern: %s\n", pattern.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,16 +98,16 @@ code sigA sigB sigC sigD sigM clock
|
||||||
if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") {
|
if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") {
|
||||||
// Only care about those bits that are used
|
// Only care about those bits that are used
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < GetSize(P); i++) {
|
for (i = GetSize(P)-1; i >= 0; i--)
|
||||||
if (nusers(P[i]) <= 1)
|
if (nusers(P[i]) > 1)
|
||||||
break;
|
break;
|
||||||
sigM.append(P[i]);
|
i++;
|
||||||
}
|
|
||||||
log_assert(nusers(P.extract_end(i)) <= 1);
|
log_assert(nusers(P.extract_end(i)) <= 1);
|
||||||
// This sigM could have no users if downstream sinks (e.g. $add) is
|
// This sigM could have no users if downstream sinks (e.g. $add) is
|
||||||
// narrower than $mul result, for example
|
// narrower than $mul result, for example
|
||||||
if (sigM.empty())
|
if (i == 0)
|
||||||
reject;
|
reject;
|
||||||
|
sigM = P.extract(0, i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sigM = P;
|
sigM = P;
|
||||||
|
@ -460,6 +460,8 @@ arg argD argQ clock
|
||||||
|
|
||||||
code
|
code
|
||||||
dff = nullptr;
|
dff = nullptr;
|
||||||
|
if (GetSize(argQ) == 0)
|
||||||
|
reject;
|
||||||
for (const auto &c : argQ.chunks()) {
|
for (const auto &c : argQ.chunks()) {
|
||||||
// Abandon matches when 'Q' is a constant
|
// Abandon matches when 'Q' is a constant
|
||||||
if (!c.wire)
|
if (!c.wire)
|
||||||
|
|
|
@ -63,12 +63,12 @@ code sigC sigP clock
|
||||||
if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") {
|
if (param(dsp, \USE_MULT, Const("MULTIPLY")).decode_string() == "MULTIPLY") {
|
||||||
// Only care about those bits that are used
|
// Only care about those bits that are used
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < GetSize(P); i++) {
|
for (i = GetSize(P)-1; i >= 0; i--)
|
||||||
if (nusers(P[i]) <= 1)
|
if (nusers(P[i]) > 1)
|
||||||
break;
|
break;
|
||||||
sigP.append(P[i]);
|
i++;
|
||||||
}
|
|
||||||
log_assert(nusers(P.extract_end(i)) <= 1);
|
log_assert(nusers(P.extract_end(i)) <= 1);
|
||||||
|
sigP = P.extract(0, i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sigP = P;
|
sigP = P;
|
||||||
|
|
|
@ -262,10 +262,14 @@ struct ExtractFaWorker
|
||||||
pool<SigBit> new_leaves = leaves;
|
pool<SigBit> new_leaves = leaves;
|
||||||
|
|
||||||
new_leaves.erase(bit);
|
new_leaves.erase(bit);
|
||||||
if (cell->hasPort(ID::A)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::A))));
|
for (auto port : {ID::A, ID::B, ID(C), ID(D)}) {
|
||||||
if (cell->hasPort(ID::B)) new_leaves.insert(sigmap(SigBit(cell->getPort(ID::B))));
|
if (!cell->hasPort(port))
|
||||||
if (cell->hasPort(ID(C))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(C)))));
|
continue;
|
||||||
if (cell->hasPort(ID(D))) new_leaves.insert(sigmap(SigBit(cell->getPort(ID(D)))));
|
auto bit = sigmap(SigBit(cell->getPort(port)));
|
||||||
|
if (!bit.wire)
|
||||||
|
continue;
|
||||||
|
new_leaves.insert(bit);
|
||||||
|
}
|
||||||
|
|
||||||
if (GetSize(new_leaves) > maxbreadth)
|
if (GetSize(new_leaves) > maxbreadth)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -394,7 +394,7 @@ struct FlowGraph
|
||||||
|
|
||||||
pair<pool<RTLIL::SigBit>, pool<RTLIL::SigBit>> edge_cut()
|
pair<pool<RTLIL::SigBit>, pool<RTLIL::SigBit>> edge_cut()
|
||||||
{
|
{
|
||||||
pool<RTLIL::SigBit> x, xi;
|
pool<RTLIL::SigBit> x = {source}, xi; // X and X̅ in the paper
|
||||||
|
|
||||||
NodePrime source_prime = {source, true};
|
NodePrime source_prime = {source, true};
|
||||||
pool<NodePrime> visited;
|
pool<NodePrime> visited;
|
||||||
|
@ -437,6 +437,7 @@ struct FlowGraph
|
||||||
for (auto collapsed_node : collapsed[sink])
|
for (auto collapsed_node : collapsed[sink])
|
||||||
xi.insert(collapsed_node);
|
xi.insert(collapsed_node);
|
||||||
|
|
||||||
|
log_assert(x[source] && !xi[source]);
|
||||||
log_assert(!x[sink] && xi[sink]);
|
log_assert(!x[sink] && xi[sink]);
|
||||||
return {x, xi};
|
return {x, xi};
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1051,7 @@ struct FlowmapWorker
|
||||||
|
|
||||||
auto cut_inputs = cut_lut_at_gate(lut, lut_gate);
|
auto cut_inputs = cut_lut_at_gate(lut, lut_gate);
|
||||||
pool<RTLIL::SigBit> gate_inputs = cut_inputs.first, other_inputs = cut_inputs.second;
|
pool<RTLIL::SigBit> gate_inputs = cut_inputs.first, other_inputs = cut_inputs.second;
|
||||||
if (gate_inputs.empty() && (int)other_inputs.size() == order)
|
if (gate_inputs.empty() && (int)other_inputs.size() >= order)
|
||||||
{
|
{
|
||||||
if (debug_relax)
|
if (debug_relax)
|
||||||
log(" Breaking would result in a (k+1)-LUT.\n");
|
log(" Breaking would result in a (k+1)-LUT.\n");
|
||||||
|
|
|
@ -9,12 +9,12 @@ GENFILES += techlibs/common/simcells_help.inc
|
||||||
|
|
||||||
techlibs/common/simlib_help.inc: techlibs/common/cellhelp.py techlibs/common/simlib.v
|
techlibs/common/simlib_help.inc: techlibs/common/cellhelp.py techlibs/common/simlib.v
|
||||||
$(Q) mkdir -p techlibs/common
|
$(Q) mkdir -p techlibs/common
|
||||||
$(P) python3 $^ > $@.new
|
$(P) $(PYTHON_EXECUTABLE) $^ > $@.new
|
||||||
$(Q) mv $@.new $@
|
$(Q) mv $@.new $@
|
||||||
|
|
||||||
techlibs/common/simcells_help.inc: techlibs/common/cellhelp.py techlibs/common/simcells.v
|
techlibs/common/simcells_help.inc: techlibs/common/cellhelp.py techlibs/common/simcells.v
|
||||||
$(Q) mkdir -p techlibs/common
|
$(Q) mkdir -p techlibs/common
|
||||||
$(P) python3 $^ > $@.new
|
$(P) $(PYTHON_EXECUTABLE) $^ > $@.new
|
||||||
$(Q) mv $@.new $@
|
$(Q) mv $@.new $@
|
||||||
|
|
||||||
kernel/register.o: techlibs/common/simlib_help.inc techlibs/common/simcells_help.inc
|
kernel/register.o: techlibs/common/simlib_help.inc techlibs/common/simcells_help.inc
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// with n <= k inputs should be techmapped in this way, because this shortens the critical path
|
// with n <= k inputs should be techmapped in this way, because this shortens the critical path
|
||||||
// from n to 1 by avoiding carry chains.
|
// from n to 1 by avoiding carry chains.
|
||||||
|
|
||||||
(* techmap_celltype = "$eq $ne $lt $le $gt $ge" *)
|
(* techmap_celltype = "$lt $le $gt $ge" *)
|
||||||
module _90_lut_cmp_ (A, B, Y);
|
module _90_lut_cmp_ (A, B, Y);
|
||||||
|
|
||||||
parameter A_SIGNED = 0;
|
parameter A_SIGNED = 0;
|
||||||
|
|
|
@ -27,12 +27,12 @@ EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
|
||||||
|
|
||||||
techlibs/ecp5/brams_init.mk: techlibs/ecp5/brams_init.py
|
techlibs/ecp5/brams_init.mk: techlibs/ecp5/brams_init.py
|
||||||
$(Q) mkdir -p techlibs/ecp5
|
$(Q) mkdir -p techlibs/ecp5
|
||||||
$(P) python3 $<
|
$(P) $(PYTHON_EXECUTABLE) $<
|
||||||
$(Q) touch $@
|
$(Q) touch $@
|
||||||
|
|
||||||
techlibs/ecp5/brams_connect.mk: techlibs/ecp5/brams_connect.py
|
techlibs/ecp5/brams_connect.mk: techlibs/ecp5/brams_connect.py
|
||||||
$(Q) mkdir -p techlibs/ecp5
|
$(Q) mkdir -p techlibs/ecp5
|
||||||
$(P) python3 $<
|
$(P) $(PYTHON_EXECUTABLE) $<
|
||||||
$(Q) touch $@
|
$(Q) touch $@
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -333,6 +333,13 @@ module ECLKSYNCB(
|
||||||
);
|
);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
(* blackbox *)
|
||||||
|
module ECLKBRIDGECS(
|
||||||
|
input CLK0, CLK1, SEL,
|
||||||
|
output ECSOUT
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
(* blackbox *)
|
(* blackbox *)
|
||||||
module DCCA(
|
module DCCA(
|
||||||
input CLKI, CE,
|
input CLKI, CE,
|
||||||
|
|
|
@ -23,15 +23,15 @@ module FD1S3JX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLI
|
||||||
// module FL1S3AY(); endmodule
|
// module FL1S3AY(); endmodule
|
||||||
|
|
||||||
// Diamond I/O registers
|
// Diamond I/O registers
|
||||||
module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; 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 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"; 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 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"; 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 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"; 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 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"; 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 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"; 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 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"; 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 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"; 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 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
|
// TODO: Diamond I/O latches
|
||||||
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
|
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
|
||||||
|
|
|
@ -297,6 +297,7 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
run("simplemap");
|
run("simplemap");
|
||||||
run("ecp5_ffinit");
|
run("ecp5_ffinit");
|
||||||
run("ecp5_gsr");
|
run("ecp5_gsr");
|
||||||
|
run("attrmvcp -copy -attr syn_useioff");
|
||||||
run("opt_clean");
|
run("opt_clean");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,9 +314,9 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
if (abc9) {
|
if (abc9) {
|
||||||
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
|
run("read_verilog -icells -lib +/ecp5/abc9_model.v");
|
||||||
if (nowidelut)
|
if (nowidelut)
|
||||||
run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200");
|
run("abc9 -lut +/ecp5/abc9_5g_nowide.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
|
||||||
else
|
else
|
||||||
run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200");
|
run("abc9 -lut +/ecp5/abc9_5g.lut -box +/ecp5/abc9_5g.box -W 200 -nomfs");
|
||||||
run("techmap -map +/ecp5/abc9_unmap.v");
|
run("techmap -map +/ecp5/abc9_unmap.v");
|
||||||
} else {
|
} else {
|
||||||
if (nowidelut)
|
if (nowidelut)
|
||||||
|
@ -338,6 +339,7 @@ struct SynthEcp5Pass : public ScriptPass
|
||||||
|
|
||||||
if (check_label("check"))
|
if (check_label("check"))
|
||||||
{
|
{
|
||||||
|
run("autoname");
|
||||||
run("hierarchy -check");
|
run("hierarchy -check");
|
||||||
run("stat");
|
run("stat");
|
||||||
run("check -noinit");
|
run("check -noinit");
|
||||||
|
|
|
@ -17,6 +17,18 @@ module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE
|
||||||
module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
||||||
module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
`ifndef NO_LUT
|
`ifndef NO_LUT
|
||||||
module \$lut (A, Y);
|
module \$lut (A, Y);
|
||||||
parameter WIDTH = 0;
|
parameter WIDTH = 0;
|
||||||
|
|
|
@ -60,6 +60,8 @@ module EFX_FF(
|
||||||
assign sr = SR_POLARITY ? SR : ~SR;
|
assign sr = SR_POLARITY ? SR : ~SR;
|
||||||
assign d = D_POLARITY ? D : ~D;
|
assign d = D_POLARITY ? D : ~D;
|
||||||
|
|
||||||
|
initial Q = 1'b0;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (SR_SYNC == 1)
|
if (SR_SYNC == 1)
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -15,3 +15,13 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/dram.txt))
|
||||||
|
|
||||||
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_init3.vh))
|
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_init3.vh))
|
||||||
|
|
||||||
|
EXTRA_OBJS += techlibs/gowin/brams_init.mk
|
||||||
|
.SECONDARY: techlibs/gowin/brams_init.mk
|
||||||
|
|
||||||
|
techlibs/gowin/brams_init.mk: techlibs/gowin/brams_init.py
|
||||||
|
$(Q) mkdir -p techlibs/gowin
|
||||||
|
$(P) python3 $<
|
||||||
|
$(Q) touch $@
|
||||||
|
|
||||||
|
techlibs/gowin/bram_init_16.vh: techlibs/gowin/brams_init.mk
|
||||||
|
$(eval $(call add_gen_share_file,share/gowin,techlibs/gowin/bram_init_16.vh))
|
||||||
|
|
|
@ -40,15 +40,15 @@ module _80_gw1n_alu(A, B, CI, BI, X, Y, CO);
|
||||||
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||||
|
|
||||||
wire [Y_WIDTH-1:0] AA = A_buf;
|
wire [Y_WIDTH-1:0] AA = A_buf;
|
||||||
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
|
wire [Y_WIDTH-1:0] BB = B_buf;
|
||||||
wire [Y_WIDTH-1:0] C = {CO, CI};
|
wire [Y_WIDTH-1:0] C = {CO, CI};
|
||||||
|
|
||||||
genvar i;
|
genvar i;
|
||||||
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
|
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
|
||||||
ALU #(.ALU_MODE(32'b0))
|
ALU #(.ALU_MODE(2)) // ADDSUB I3 ? add : sub
|
||||||
alu(.I0(AA[i]),
|
alu(.I0(AA[i]),
|
||||||
.I1(BB[i]),
|
.I1(BB[i]),
|
||||||
.I3(1'b0),
|
.I3(~BI),
|
||||||
.CIN(C[i]),
|
.CIN(C[i]),
|
||||||
.COUT(CO[i]),
|
.COUT(CO[i]),
|
||||||
.SUM(Y[i])
|
.SUM(Y[i])
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
bram $__GW1NR_SDP
|
bram $__GW1NR_SDP
|
||||||
# uncomment when done
|
init 1
|
||||||
# init 1
|
abits 9 @a9d36
|
||||||
|
dbits 32 @a9d36
|
||||||
abits 10 @a10d18
|
abits 10 @a10d18
|
||||||
dbits 16 @a10d18
|
dbits 16 @a10d18
|
||||||
abits 11 @a11d9
|
abits 11 @a11d9
|
||||||
|
@ -14,7 +15,8 @@ bram $__GW1NR_SDP
|
||||||
groups 2
|
groups 2
|
||||||
ports 1 1
|
ports 1 1
|
||||||
wrmode 1 0
|
wrmode 1 0
|
||||||
enable 1 1 @a10d18
|
enable 4 1 @a9d36
|
||||||
|
enable 2 1 @a10d18
|
||||||
enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
|
enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
|
||||||
transp 0 0
|
transp 0 0
|
||||||
clocks 2 3
|
clocks 2 3
|
||||||
|
@ -24,6 +26,6 @@ endbram
|
||||||
match $__GW1NR_SDP
|
match $__GW1NR_SDP
|
||||||
min bits 2048
|
min bits 2048
|
||||||
min efficiency 5
|
min efficiency 5
|
||||||
shuffle_enable B
|
shuffle_enable A
|
||||||
make_transp
|
make_transp
|
||||||
endmatch
|
endmatch
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
with open("techlibs/gowin/bram_init_16.vh", "w") as f:
|
||||||
|
for i in range(0, 0x40):
|
||||||
|
low = i << 8
|
||||||
|
hi = ((i+1) << 8)-1
|
||||||
|
snippet = "INIT[%d:%d]" % (hi, low)
|
||||||
|
print(".INIT_RAM_%02X({%s})," % (i, snippet), file=f)
|
|
@ -8,8 +8,7 @@
|
||||||
module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
parameter CFG_ABITS = 10;
|
parameter CFG_ABITS = 10;
|
||||||
parameter CFG_DBITS = 16;
|
parameter CFG_DBITS = 16;
|
||||||
parameter CFG_ENABLE_A = 3;
|
parameter CFG_ENABLE_A = 1;
|
||||||
|
|
||||||
parameter [16383:0] INIT = 16384'hx;
|
parameter [16383:0] INIT = 16384'hx;
|
||||||
parameter CLKPOL2 = 1;
|
parameter CLKPOL2 = 1;
|
||||||
parameter CLKPOL3 = 1;
|
parameter CLKPOL3 = 1;
|
||||||
|
@ -25,9 +24,12 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
output [CFG_DBITS-1:0] B1DATA;
|
output [CFG_DBITS-1:0] B1DATA;
|
||||||
input B1EN;
|
input B1EN;
|
||||||
|
|
||||||
|
wire [31-CFG_DBITS:0] open;
|
||||||
|
|
||||||
|
|
||||||
generate if (CFG_DBITS == 1) begin
|
generate if (CFG_DBITS == 1) begin
|
||||||
SDP #(
|
SDP #(
|
||||||
|
`include "bram_init_16.vh"
|
||||||
.READ_MODE(0),
|
.READ_MODE(0),
|
||||||
.BIT_WIDTH_0(1),
|
.BIT_WIDTH_0(1),
|
||||||
.BIT_WIDTH_1(1),
|
.BIT_WIDTH_1(1),
|
||||||
|
@ -38,10 +40,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||||
.WREB(1'b0), .CEB(B1EN),
|
.WREB(1'b0), .CEB(B1EN),
|
||||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||||
|
.DO({open, B1DATA}),
|
||||||
|
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||||
|
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||||
);
|
);
|
||||||
end else if (CFG_DBITS == 2) begin
|
end else if (CFG_DBITS == 2) begin
|
||||||
SDP #(
|
SDP #(
|
||||||
|
`include "bram_init_16.vh"
|
||||||
.READ_MODE(0),
|
.READ_MODE(0),
|
||||||
.BIT_WIDTH_0(2),
|
.BIT_WIDTH_0(2),
|
||||||
.BIT_WIDTH_1(2),
|
.BIT_WIDTH_1(2),
|
||||||
|
@ -52,10 +58,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||||
.WREB(1'b0), .CEB(B1EN),
|
.WREB(1'b0), .CEB(B1EN),
|
||||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||||
|
.DO({open, B1DATA}),
|
||||||
|
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||||
|
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||||
);
|
);
|
||||||
end else if (CFG_DBITS <= 4) begin
|
end else if (CFG_DBITS <= 4) begin
|
||||||
SDP #(
|
SDP #(
|
||||||
|
`include "bram_init_16.vh"
|
||||||
.READ_MODE(0),
|
.READ_MODE(0),
|
||||||
.BIT_WIDTH_0(4),
|
.BIT_WIDTH_0(4),
|
||||||
.BIT_WIDTH_1(4),
|
.BIT_WIDTH_1(4),
|
||||||
|
@ -66,10 +76,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
.WREA(A1EN), .OCE(1'b0),
|
.WREA(A1EN), .OCE(1'b0),
|
||||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||||
|
.DO({open, B1DATA}),
|
||||||
|
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||||
|
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||||
);
|
);
|
||||||
end else if (CFG_DBITS <= 8) begin
|
end else if (CFG_DBITS <= 8) begin
|
||||||
SDP #(
|
SDP #(
|
||||||
|
`include "bram_init_16.vh"
|
||||||
.READ_MODE(0),
|
.READ_MODE(0),
|
||||||
.BIT_WIDTH_0(8),
|
.BIT_WIDTH_0(8),
|
||||||
.BIT_WIDTH_1(8),
|
.BIT_WIDTH_1(8),
|
||||||
|
@ -80,10 +94,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||||
.WREB(1'b0), .CEB(B1EN),
|
.WREB(1'b0), .CEB(B1EN),
|
||||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||||
|
.DO({open, B1DATA}),
|
||||||
|
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||||
|
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||||
);
|
);
|
||||||
end else if (CFG_DBITS <= 16) begin
|
end else if (CFG_DBITS <= 16) begin
|
||||||
SDP #(
|
SDP #(
|
||||||
|
`include "bram_init_16.vh"
|
||||||
.READ_MODE(0),
|
.READ_MODE(0),
|
||||||
.BIT_WIDTH_0(16),
|
.BIT_WIDTH_0(16),
|
||||||
.BIT_WIDTH_1(16),
|
.BIT_WIDTH_1(16),
|
||||||
|
@ -91,10 +109,31 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
.RESET_MODE("SYNC")
|
.RESET_MODE("SYNC")
|
||||||
) _TECHMAP_REPLACE_ (
|
) _TECHMAP_REPLACE_ (
|
||||||
.CLKA(CLK2), .CLKB(CLK3),
|
.CLKA(CLK2), .CLKB(CLK3),
|
||||||
.WREA(A1EN), .OCE(1'b0),
|
.WREA(|A1EN), .OCE(1'b0),
|
||||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||||
|
.DO({open, B1DATA}),
|
||||||
|
.ADA({A1ADDR, {(12-CFG_ABITS){1'b0}}, A1EN}),
|
||||||
|
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||||
|
);
|
||||||
|
end else if (CFG_DBITS <= 32) begin
|
||||||
|
SDP #(
|
||||||
|
`include "bram_init_16.vh"
|
||||||
|
.READ_MODE(0),
|
||||||
|
.BIT_WIDTH_0(32),
|
||||||
|
.BIT_WIDTH_1(32),
|
||||||
|
.BLK_SEL(3'b000),
|
||||||
|
.RESET_MODE("SYNC")
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.CLKA(CLK2), .CLKB(CLK3),
|
||||||
|
.WREA(|A1EN), .OCE(1'b0),
|
||||||
|
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||||
|
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||||
|
.DI(A1DATA),
|
||||||
|
.DO(B1DATA),
|
||||||
|
.ADA({A1ADDR, {(10-CFG_ABITS){1'b0}}, A1EN}),
|
||||||
|
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||||
);
|
);
|
||||||
end else begin
|
end else begin
|
||||||
wire TECHMAP_FAIL = 1'b1;
|
wire TECHMAP_FAIL = 1'b1;
|
||||||
|
|
|
@ -1,9 +1,83 @@
|
||||||
module \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
//All DFF* have INIT, but the hardware is always initialised to the reset
|
||||||
module \$_DFF_P_ #(parameter INIT = 1'b0) (input D, C, output Q); DFF #(.INIT(INIT)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
//value regardless. The parameter is ignored.
|
||||||
|
|
||||||
|
// DFFN D Flip-Flop with Negative-Edge Clock
|
||||||
|
module \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||||
|
// DFF D Flip-Flop
|
||||||
|
module \$_DFF_P_ (input D, C, output Q); DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||||
|
|
||||||
|
// DFFE D Flip-Flop with Clock Enable
|
||||||
|
module \$_DFFE_PP_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule
|
||||||
|
module \$_DFFE_PN_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule
|
||||||
|
|
||||||
|
// DFFNE D Flip-Flop with Negative-Edge Clock and Clock Enable
|
||||||
|
module \$_DFFE_NP_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule
|
||||||
|
module \$_DFFE_NN_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule
|
||||||
|
|
||||||
|
// DFFR D Flip-Flop with Synchronous Reset
|
||||||
module \$__DFFS_PN0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
|
module \$__DFFS_PN0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
|
||||||
module \$__DFFS_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
module \$__DFFS_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||||
module \$__DFFS_PP1_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
|
||||||
|
// DFFNR D Flip-Flop with Negative-Edge Clock and Synchronous Reset
|
||||||
|
module \$__DFFS_NN0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
|
||||||
|
module \$__DFFS_NP0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||||
|
|
||||||
|
// DFFRE D Flip-Flop with Clock Enable and Synchronous Reset
|
||||||
|
module \$__DFFSE_PN0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule
|
||||||
|
module \$__DFFSE_PP0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
// DFFNRE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset
|
||||||
|
module \$__DFFNSE_PN0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule
|
||||||
|
module \$__DFFNSE_PP0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
// DFFS D Flip-Flop with Synchronous Set
|
||||||
|
module \$__DFFS_PN1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule
|
||||||
|
module \$__DFFS_PP1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule
|
||||||
|
|
||||||
|
// DFFNS D Flip-Flop with Negative-Edge Clock and Synchronous Set
|
||||||
|
module \$__DFFS_NN1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule
|
||||||
|
module \$__DFFS_NP1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule
|
||||||
|
|
||||||
|
// DFFSE D Flip-Flop with Clock Enable and Synchronous Set
|
||||||
|
module \$__DFFSE_PN1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule
|
||||||
|
module \$__DFFSE_PP1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
// DFFNSE D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set
|
||||||
|
module \$__DFFSE_NN1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule
|
||||||
|
module \$__DFFSE_NP1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
// DFFP D Flip-Flop with Asynchronous Preset
|
||||||
|
module \$_DFF_PP1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule
|
||||||
|
module \$_DFF_PN1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule
|
||||||
|
|
||||||
|
// DFFNP D Flip-Flop with Negative-Edge Clock and Asynchronous Preset
|
||||||
|
module \$_DFF_NP1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule
|
||||||
|
module \$_DFF_NN1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule
|
||||||
|
|
||||||
|
// DFFC D Flip-Flop with Asynchronous Clear
|
||||||
|
module \$_DFF_PP0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule
|
||||||
|
module \$_DFF_PN0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule
|
||||||
|
|
||||||
|
// DFFNC D Flip-Flop with Negative-Edge Clock and Asynchronous Clear
|
||||||
|
module \$_DFF_NP0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule
|
||||||
|
module \$_DFF_NN0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule
|
||||||
|
|
||||||
|
// DFFPE D Flip-Flop with Clock Enable and Asynchronous Preset
|
||||||
|
module \$__DFFE_PP1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule
|
||||||
|
module \$__DFFE_PN1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
// DFFNPE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Asynchronous Preset
|
||||||
|
module \$__DFFE_NP1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule
|
||||||
|
module \$__DFFE_NN1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
// DFFCE D Flip-Flop with Clock Enable and Asynchronous Clear
|
||||||
|
module \$__DFFE_PP0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule
|
||||||
|
module \$__DFFE_PN0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
// DFFNCE D Flip-Flop with Negative-Edge Clock,Clock Enable and Asynchronous Clear
|
||||||
|
module \$__DFFE_NP0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule
|
||||||
|
module \$__DFFE_NN0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule
|
||||||
|
|
||||||
|
|
||||||
module \$lut (A, Y);
|
module \$lut (A, Y);
|
||||||
parameter WIDTH = 0;
|
parameter WIDTH = 0;
|
||||||
|
@ -28,6 +102,30 @@ module \$lut (A, Y);
|
||||||
if (WIDTH == 4) begin
|
if (WIDTH == 4) begin
|
||||||
LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y),
|
LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y),
|
||||||
.I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]));
|
.I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 5) begin
|
||||||
|
wire f0, f1;
|
||||||
|
\$lut #(.LUT(LUT[15: 0]), .WIDTH(4)) lut0 (.A(A[3:0]), .Y(f0));
|
||||||
|
\$lut #(.LUT(LUT[31:16]), .WIDTH(4)) lut1 (.A(A[3:0]), .Y(f1));
|
||||||
|
MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[4]), .O(Y));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 6) begin
|
||||||
|
wire f0, f1;
|
||||||
|
\$lut #(.LUT(LUT[31: 0]), .WIDTH(5)) lut0 (.A(A[4:0]), .Y(f0));
|
||||||
|
\$lut #(.LUT(LUT[63:32]), .WIDTH(5)) lut1 (.A(A[4:0]), .Y(f1));
|
||||||
|
MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[5]), .O(Y));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 7) begin
|
||||||
|
wire f0, f1;
|
||||||
|
\$lut #(.LUT(LUT[63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0));
|
||||||
|
\$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1));
|
||||||
|
MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[6]), .O(Y));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 8) begin
|
||||||
|
wire f0, f1;
|
||||||
|
\$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0));
|
||||||
|
\$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1));
|
||||||
|
MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[7]), .O(Y));
|
||||||
end else begin
|
end else begin
|
||||||
wire _TECHMAP_FAIL_ = 1;
|
wire _TECHMAP_FAIL_ = 1;
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,41 @@ module LUT4(output F, input I0, I1, I2, I3);
|
||||||
assign F = I0 ? s1[1] : s1[0];
|
assign F = I0 ? s1[1] : s1[0];
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
module MUX2 (O, I0, I1, S0);
|
||||||
|
input I0,I1;
|
||||||
|
input S0;
|
||||||
|
output O;
|
||||||
|
assign O = S0 ? I1 : I0;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module MUX2_LUT5 (O, I0, I1, S0);
|
||||||
|
input I0,I1;
|
||||||
|
input S0;
|
||||||
|
output O;
|
||||||
|
MUX2 mux2_lut5 (O, I0, I1, S0);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module MUX2_LUT6 (O, I0, I1, S0);
|
||||||
|
input I0,I1;
|
||||||
|
input S0;
|
||||||
|
output O;
|
||||||
|
MUX2 mux2_lut6 (O, I0, I1, S0);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module MUX2_LUT7 (O, I0, I1, S0);
|
||||||
|
input I0,I1;
|
||||||
|
input S0;
|
||||||
|
output O;
|
||||||
|
MUX2 mux2_lut7 (O, I0, I1, S0);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module MUX2_LUT8 (O, I0, I1, S0);
|
||||||
|
input I0,I1;
|
||||||
|
input S0;
|
||||||
|
output O;
|
||||||
|
MUX2 mux2_lut8 (O, I0, I1, S0);
|
||||||
|
endmodule
|
||||||
|
|
||||||
module DFF (output reg Q, input CLK, D);
|
module DFF (output reg Q, input CLK, D);
|
||||||
parameter [0:0] INIT = 1'b0;
|
parameter [0:0] INIT = 1'b0;
|
||||||
initial Q = INIT;
|
initial Q = INIT;
|
||||||
|
@ -31,12 +66,39 @@ module DFF (output reg Q, input CLK, D);
|
||||||
Q <= D;
|
Q <= D;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module DFFN (output reg Q, input CLK, D);
|
module DFFE (output reg Q, input D, CLK, CE);
|
||||||
parameter [0:0] INIT = 1'b0;
|
parameter [0:0] INIT = 1'b0;
|
||||||
initial Q = INIT;
|
initial Q = INIT;
|
||||||
always @(negedge CLK)
|
always @(posedge CLK) begin
|
||||||
|
if (CE)
|
||||||
Q <= D;
|
Q <= D;
|
||||||
endmodule
|
end
|
||||||
|
endmodule // DFFE (positive clock edge; clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFS (output reg Q, input D, CLK, SET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (SET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFS (positive clock edge; synchronous set)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFSE (output reg Q, input D, CLK, CE, SET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (SET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFSE (positive clock edge; synchronous set takes precedence over clock enable)
|
||||||
|
|
||||||
|
|
||||||
module DFFR (output reg Q, input D, CLK, RESET);
|
module DFFR (output reg Q, input D, CLK, RESET);
|
||||||
parameter [0:0] INIT = 1'b0;
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
@ -49,6 +111,181 @@ module DFFR (output reg Q, input D, CLK, RESET);
|
||||||
end
|
end
|
||||||
endmodule // DFFR (positive clock edge; synchronous reset)
|
endmodule // DFFR (positive clock edge; synchronous reset)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFRE (output reg Q, input D, CLK, CE, RESET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RESET)
|
||||||
|
Q <= 1'b0;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFRE (positive clock edge; synchronous reset takes precedence over clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFP (output reg Q, input D, CLK, PRESET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(posedge CLK or posedge PRESET) begin
|
||||||
|
if(PRESET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFP (positive clock edge; asynchronous preset)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFPE (output reg Q, input D, CLK, CE, PRESET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(posedge CLK or posedge PRESET) begin
|
||||||
|
if(PRESET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFPE (positive clock edge; asynchronous preset; clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFC (output reg Q, input D, CLK, CLEAR);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(posedge CLK or posedge CLEAR) begin
|
||||||
|
if(CLEAR)
|
||||||
|
Q <= 1'b0;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFC (positive clock edge; asynchronous clear)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFCE (output reg Q, input D, CLK, CE, CLEAR);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(posedge CLK or posedge CLEAR) begin
|
||||||
|
if(CLEAR)
|
||||||
|
Q <= 1'b0;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFCE (positive clock edge; asynchronous clear; clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFN (output reg Q, input CLK, D);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK)
|
||||||
|
Q <= D;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module DFFNE (output reg Q, input D, CLK, CE);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK) begin
|
||||||
|
if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNE (negative clock edge; clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNS (output reg Q, input D, CLK, SET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK) begin
|
||||||
|
if (SET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNS (negative clock edge; synchronous set)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNSE (output reg Q, input D, CLK, CE, SET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK) begin
|
||||||
|
if (SET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNSE (negative clock edge; synchronous set takes precedence over clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNR (output reg Q, input D, CLK, RESET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK) begin
|
||||||
|
if (RESET)
|
||||||
|
Q <= 1'b0;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNR (negative clock edge; synchronous reset)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNRE (output reg Q, input D, CLK, CE, RESET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK) begin
|
||||||
|
if (RESET)
|
||||||
|
Q <= 1'b0;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNRE (negative clock edge; synchronous reset takes precedence over clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNP (output reg Q, input D, CLK, PRESET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK or posedge PRESET) begin
|
||||||
|
if(PRESET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNP (negative clock edge; asynchronous preset)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNPE (output reg Q, input D, CLK, CE, PRESET);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK or posedge PRESET) begin
|
||||||
|
if(PRESET)
|
||||||
|
Q <= 1'b1;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNPE (negative clock edge; asynchronous preset; clock enable)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNC (output reg Q, input D, CLK, CLEAR);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK or posedge CLEAR) begin
|
||||||
|
if(CLEAR)
|
||||||
|
Q <= 1'b0;
|
||||||
|
else
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNC (negative clock edge; asynchronous clear)
|
||||||
|
|
||||||
|
|
||||||
|
module DFFNCE (output reg Q, input D, CLK, CE, CLEAR);
|
||||||
|
parameter [0:0] INIT = 1'b0;
|
||||||
|
initial Q = INIT;
|
||||||
|
always @(negedge CLK or posedge CLEAR) begin
|
||||||
|
if(CLEAR)
|
||||||
|
Q <= 1'b0;
|
||||||
|
else if (CE)
|
||||||
|
Q <= D;
|
||||||
|
end
|
||||||
|
endmodule // DFFNCE (negative clock edge; asynchronous clear; clock enable)
|
||||||
|
|
||||||
|
// TODO add more DFF sim cells
|
||||||
|
|
||||||
module VCC(output V);
|
module VCC(output V);
|
||||||
assign V = 1;
|
assign V = 1;
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -65,14 +302,98 @@ module OBUF(output O, input I);
|
||||||
assign O = I;
|
assign O = I;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
module TBUF (O, I, OEN);
|
||||||
|
input I, OEN;
|
||||||
|
output O;
|
||||||
|
assign O = OEN ? I : 1'bz;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module IOBUF (O, IO, I, OEN);
|
||||||
|
input I,OEN;
|
||||||
|
output O;
|
||||||
|
inout IO;
|
||||||
|
assign IO = OEN ? I : 1'bz;
|
||||||
|
assign I = IO;
|
||||||
|
endmodule
|
||||||
|
|
||||||
module GSR (input GSRI);
|
module GSR (input GSRI);
|
||||||
wire GSRO = GSRI;
|
wire GSRO = GSRI;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module ALU (input I0, input I1, input I3, input CIN, output COUT, output SUM);
|
module ALU (SUM, COUT, I0, I1, I3, CIN);
|
||||||
parameter [3:0] ALU_MODE = 0; // default 0 = ADD
|
|
||||||
assign {COUT, SUM} = CIN + I1 + I0;
|
input I0;
|
||||||
endmodule // alu
|
input I1;
|
||||||
|
input I3;
|
||||||
|
input CIN;
|
||||||
|
output SUM;
|
||||||
|
output COUT;
|
||||||
|
|
||||||
|
localparam ADD = 0;
|
||||||
|
localparam SUB = 1;
|
||||||
|
localparam ADDSUB = 2;
|
||||||
|
localparam NE = 3;
|
||||||
|
localparam GE = 4;
|
||||||
|
localparam LE = 5;
|
||||||
|
localparam CUP = 6;
|
||||||
|
localparam CDN = 7;
|
||||||
|
localparam CUPCDN = 8;
|
||||||
|
localparam MULT = 9;
|
||||||
|
|
||||||
|
parameter ALU_MODE = 0;
|
||||||
|
|
||||||
|
reg S, C;
|
||||||
|
|
||||||
|
assign SUM = S ^ CIN;
|
||||||
|
assign COUT = S? CIN : C;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
case (ALU_MODE)
|
||||||
|
ADD: begin
|
||||||
|
S = I0 ^ I1;
|
||||||
|
C = I0;
|
||||||
|
end
|
||||||
|
SUB: begin
|
||||||
|
S = I0 ^ ~I1;
|
||||||
|
C = I0;
|
||||||
|
end
|
||||||
|
ADDSUB: begin
|
||||||
|
S = I3? I0 ^ I1 : I0 ^ ~I1;
|
||||||
|
C = I0;
|
||||||
|
end
|
||||||
|
NE: begin
|
||||||
|
S = I0 ^ ~I1;
|
||||||
|
C = 1'b1;
|
||||||
|
end
|
||||||
|
GE: begin
|
||||||
|
S = I0 ^ ~I1;
|
||||||
|
C = I0;
|
||||||
|
end
|
||||||
|
LE: begin
|
||||||
|
S = ~I0 ^ I1;
|
||||||
|
C = I1;
|
||||||
|
end
|
||||||
|
CUP: begin
|
||||||
|
S = I0;
|
||||||
|
C = 1'b0;
|
||||||
|
end
|
||||||
|
CDN: begin
|
||||||
|
S = ~I0;
|
||||||
|
C = 1'b1;
|
||||||
|
end
|
||||||
|
CUPCDN: begin
|
||||||
|
S = I3? I0 : ~I0;
|
||||||
|
C = I0;
|
||||||
|
end
|
||||||
|
MULT: begin
|
||||||
|
S = I0 & I1;
|
||||||
|
C = I0 & I1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
module RAM16S4 (DO, DI, AD, WRE, CLK);
|
module RAM16S4 (DO, DI, AD, WRE, CLK);
|
||||||
parameter WIDTH = 4;
|
parameter WIDTH = 4;
|
||||||
|
|
|
@ -64,6 +64,12 @@ struct SynthGowinPass : public ScriptPass
|
||||||
log(" -retime\n");
|
log(" -retime\n");
|
||||||
log(" run 'abc' with -dff option\n");
|
log(" run 'abc' with -dff option\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -nowidelut\n");
|
||||||
|
log(" do not use muxes to implement LUTs larger than LUT4s\n");
|
||||||
|
log("\n");
|
||||||
|
log(" -abc9\n");
|
||||||
|
log(" use new ABC9 flow (EXPERIMENTAL)\n");
|
||||||
|
log("\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("The following commands are executed by this synthesis command:\n");
|
log("The following commands are executed by this synthesis command:\n");
|
||||||
help_script();
|
help_script();
|
||||||
|
@ -71,7 +77,7 @@ struct SynthGowinPass : public ScriptPass
|
||||||
}
|
}
|
||||||
|
|
||||||
string top_opt, vout_file;
|
string top_opt, vout_file;
|
||||||
bool retime, nobram, nodram, flatten, nodffe;
|
bool retime, nobram, nodram, flatten, nodffe, nowidelut, abc9;
|
||||||
|
|
||||||
void clear_flags() YS_OVERRIDE
|
void clear_flags() YS_OVERRIDE
|
||||||
{
|
{
|
||||||
|
@ -82,6 +88,8 @@ struct SynthGowinPass : public ScriptPass
|
||||||
nobram = false;
|
nobram = false;
|
||||||
nodffe = false;
|
nodffe = false;
|
||||||
nodram = false;
|
nodram = false;
|
||||||
|
nowidelut = false;
|
||||||
|
abc9 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
|
@ -128,6 +136,14 @@ struct SynthGowinPass : public ScriptPass
|
||||||
flatten = false;
|
flatten = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-nowidelut") {
|
||||||
|
nowidelut = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-abc9") {
|
||||||
|
abc9 = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
@ -186,6 +202,7 @@ struct SynthGowinPass : public ScriptPass
|
||||||
run("techmap -map +/techmap.v");
|
run("techmap -map +/techmap.v");
|
||||||
if (retime || help_mode)
|
if (retime || help_mode)
|
||||||
run("abc -dff", "(only if -retime)");
|
run("abc -dff", "(only if -retime)");
|
||||||
|
run("splitnets");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label("map_ffs"))
|
if (check_label("map_ffs"))
|
||||||
|
@ -202,16 +219,25 @@ struct SynthGowinPass : public ScriptPass
|
||||||
|
|
||||||
if (check_label("map_luts"))
|
if (check_label("map_luts"))
|
||||||
{
|
{
|
||||||
|
if (nowidelut && abc9) {
|
||||||
|
run("abc9 -lut 4");
|
||||||
|
} else if (nowidelut && !abc9) {
|
||||||
run("abc -lut 4");
|
run("abc -lut 4");
|
||||||
|
} else if (!nowidelut && abc9) {
|
||||||
|
run("abc9 -lut 4:8");
|
||||||
|
} else if (!nowidelut && !abc9) {
|
||||||
|
run("abc -lut 4:8");
|
||||||
|
}
|
||||||
run("clean");
|
run("clean");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label("map_cells"))
|
if (check_label("map_cells"))
|
||||||
{
|
{
|
||||||
run("techmap -map +/gowin/cells_map.v");
|
run("techmap -map +/gowin/cells_map.v");
|
||||||
run("hilomap -hicell VCC V -locell GND G");
|
run("setundef -undriven -params -zero");
|
||||||
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O", "(unless -noiopads)");
|
run("hilomap -singleton -hicell VCC V -locell GND G");
|
||||||
run("dffinit -ff DFF Q INIT");
|
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O "
|
||||||
|
"-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)");
|
||||||
run("clean");
|
run("clean");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -226,7 +252,7 @@ struct SynthGowinPass : public ScriptPass
|
||||||
if (check_label("vout"))
|
if (check_label("vout"))
|
||||||
{
|
{
|
||||||
if (!vout_file.empty() || help_mode)
|
if (!vout_file.empty() || help_mode)
|
||||||
run(stringf("write_verilog -nodec -attr2comment -defparam -renameprefix gen %s",
|
run(stringf("write_verilog -decimal -attr2comment -defparam -renameprefix gen %s",
|
||||||
help_mode ? "<file-name>" : vout_file.c_str()));
|
help_mode ? "<file-name>" : vout_file.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ EXTRA_OBJS += techlibs/ice40/brams_init.mk
|
||||||
|
|
||||||
techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py
|
techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py
|
||||||
$(Q) mkdir -p techlibs/ice40
|
$(Q) mkdir -p techlibs/ice40
|
||||||
$(P) python3 $<
|
$(P) $(PYTHON_EXECUTABLE) $<
|
||||||
$(Q) touch techlibs/ice40/brams_init.mk
|
$(Q) touch techlibs/ice40/brams_init.mk
|
||||||
|
|
||||||
techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk
|
techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
|
`timescale 1ps / 1ps
|
||||||
`define SB_DFF_REG reg Q = 0
|
`define SB_DFF_REG reg Q = 0
|
||||||
// `define SB_DFF_REG reg Q
|
// `define SB_DFF_REG reg Q
|
||||||
|
|
||||||
|
@ -81,6 +81,37 @@ module SB_IO (
|
||||||
if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
|
if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
|
||||||
endgenerate
|
endgenerate
|
||||||
`endif
|
`endif
|
||||||
|
`ifdef TIMING
|
||||||
|
specify
|
||||||
|
(INPUT_CLK => D_IN_0) = (0:0:0, 0:0:0);
|
||||||
|
(INPUT_CLK => D_IN_1) = (0:0:0, 0:0:0);
|
||||||
|
(PACKAGE_PIN => D_IN_0) = (0:0:0, 0:0:0);
|
||||||
|
(OUTPUT_CLK => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
||||||
|
(D_OUT_0 => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
||||||
|
(OUTPUT_ENABLE => PACKAGE_PIN) = (0:0:0, 0:0:0);
|
||||||
|
|
||||||
|
$setuphold(posedge OUTPUT_CLK, posedge D_OUT_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge OUTPUT_CLK, negedge D_OUT_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge OUTPUT_CLK, posedge D_OUT_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge OUTPUT_CLK, negedge D_OUT_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge OUTPUT_CLK, posedge D_OUT_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge OUTPUT_CLK, negedge D_OUT_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge OUTPUT_CLK, posedge D_OUT_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge OUTPUT_CLK, negedge D_OUT_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge INPUT_CLK, posedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge INPUT_CLK, negedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge OUTPUT_CLK, posedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge OUTPUT_CLK, negedge CLOCK_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge INPUT_CLK, posedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge INPUT_CLK, negedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge INPUT_CLK, posedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge INPUT_CLK, negedge PACKAGE_PIN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge OUTPUT_CLK, posedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge OUTPUT_CLK, negedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge OUTPUT_CLK, posedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge OUTPUT_CLK, negedge OUTPUT_ENABLE, 0:0:0, 0:0:0);
|
||||||
|
endspecify
|
||||||
|
`endif
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module SB_GB_IO (
|
module SB_GB_IO (
|
||||||
|
@ -127,6 +158,11 @@ module SB_GB (
|
||||||
output GLOBAL_BUFFER_OUTPUT
|
output GLOBAL_BUFFER_OUTPUT
|
||||||
);
|
);
|
||||||
assign GLOBAL_BUFFER_OUTPUT = USER_SIGNAL_TO_GLOBAL_BUFFER;
|
assign GLOBAL_BUFFER_OUTPUT = USER_SIGNAL_TO_GLOBAL_BUFFER;
|
||||||
|
`ifdef TIMING
|
||||||
|
specify
|
||||||
|
(USER_SIGNAL_TO_GLOBAL_BUFFER => GLOBAL_BUFFER_OUTPUT) = (0:0:0, 0:0:0);
|
||||||
|
endspecify
|
||||||
|
`endif
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
// SiliconBlue Logic Cells
|
// SiliconBlue Logic Cells
|
||||||
|
@ -830,33 +866,81 @@ module ICESTORM_LC (
|
||||||
parameter [0:0] CIN_CONST = 0;
|
parameter [0:0] CIN_CONST = 0;
|
||||||
parameter [0:0] CIN_SET = 0;
|
parameter [0:0] CIN_SET = 0;
|
||||||
|
|
||||||
|
wire I0_pd = (I0 === 1'bz) ? 1'b0 : I0;
|
||||||
|
wire I1_pd = (I1 === 1'bz) ? 1'b0 : I1;
|
||||||
|
wire I2_pd = (I2 === 1'bz) ? 1'b0 : I2;
|
||||||
|
wire I3_pd = (I3 === 1'bz) ? 1'b0 : I3;
|
||||||
|
wire SR_pd = (SR === 1'bz) ? 1'b0 : SR;
|
||||||
|
wire CEN_pu = (CEN === 1'bz) ? 1'b1 : CEN;
|
||||||
|
|
||||||
wire mux_cin = CIN_CONST ? CIN_SET : CIN;
|
wire mux_cin = CIN_CONST ? CIN_SET : CIN;
|
||||||
|
|
||||||
assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
|
assign COUT = CARRY_ENABLE ? (I1_pd && I2_pd) || ((I1_pd || I2_pd) && mux_cin) : 1'bx;
|
||||||
|
|
||||||
wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
|
wire [7:0] lut_s3 = I3_pd ? LUT_INIT[15:8] : LUT_INIT[7:0];
|
||||||
wire [3:0] lut_s2 = I2 ? lut_s3[ 7:4] : lut_s3[3:0];
|
wire [3:0] lut_s2 = I2_pd ? lut_s3[ 7:4] : lut_s3[3:0];
|
||||||
wire [1:0] lut_s1 = I1 ? lut_s2[ 3:2] : lut_s2[1:0];
|
wire [1:0] lut_s1 = I1_pd ? lut_s2[ 3:2] : lut_s2[1:0];
|
||||||
wire lut_o = I0 ? lut_s1[ 1] : lut_s1[ 0];
|
wire lut_o = I0_pd ? lut_s1[ 1] : lut_s1[ 0];
|
||||||
|
|
||||||
assign LO = lut_o;
|
assign LO = lut_o;
|
||||||
|
|
||||||
wire polarized_clk;
|
wire polarized_clk;
|
||||||
assign polarized_clk = CLK ^ NEG_CLK;
|
assign polarized_clk = CLK ^ NEG_CLK;
|
||||||
|
|
||||||
reg o_reg;
|
reg o_reg = 1'b0;
|
||||||
always @(posedge polarized_clk)
|
always @(posedge polarized_clk)
|
||||||
if (CEN)
|
if (CEN_pu)
|
||||||
o_reg <= SR ? SET_NORESET : lut_o;
|
o_reg <= SR_pd ? SET_NORESET : lut_o;
|
||||||
|
|
||||||
reg o_reg_async;
|
reg o_reg_async = 1'b0;
|
||||||
always @(posedge polarized_clk, posedge SR)
|
always @(posedge polarized_clk, posedge SR)
|
||||||
if (SR)
|
if (SR_pd)
|
||||||
o_reg <= SET_NORESET;
|
o_reg_async <= SET_NORESET;
|
||||||
else if (CEN)
|
else if (CEN_pu)
|
||||||
o_reg <= lut_o;
|
o_reg_async <= lut_o;
|
||||||
|
|
||||||
assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
|
assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
|
||||||
|
`ifdef TIMING
|
||||||
|
specify
|
||||||
|
(I0 => O) = (0:0:0, 0:0:0);
|
||||||
|
(I1 => O) = (0:0:0, 0:0:0);
|
||||||
|
(I2 => O) = (0:0:0, 0:0:0);
|
||||||
|
(I3 => O) = (0:0:0, 0:0:0);
|
||||||
|
(I0 => LO) = (0:0:0, 0:0:0);
|
||||||
|
(I1 => LO) = (0:0:0, 0:0:0);
|
||||||
|
(I2 => LO) = (0:0:0, 0:0:0);
|
||||||
|
(I3 => LO) = (0:0:0, 0:0:0);
|
||||||
|
(I1 => COUT) = (0:0:0, 0:0:0);
|
||||||
|
(I2 => COUT) = (0:0:0, 0:0:0);
|
||||||
|
(CIN => COUT) = (0:0:0, 0:0:0);
|
||||||
|
(CLK => O) = (0:0:0, 0:0:0);
|
||||||
|
(SR => O) = (0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, posedge I0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, negedge I0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, posedge I0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, negedge I0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, posedge I1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, negedge I1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, posedge I1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, negedge I1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, posedge I2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, negedge I2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, posedge I2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, negedge I2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, posedge I3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, negedge I3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, posedge I3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, negedge I3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, posedge CEN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, negedge CEN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, posedge CEN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, negedge CEN, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, posedge SR, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge CLK, negedge SR, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, posedge SR, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge CLK, negedge SR, 0:0:0, 0:0:0);
|
||||||
|
endspecify
|
||||||
|
`endif
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
// SiliconBlue PLL Cells
|
// SiliconBlue PLL Cells
|
||||||
|
@ -1576,3 +1660,341 @@ module SB_MAC16 (
|
||||||
assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
|
assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
|
||||||
assign O = {Oh, Ol};
|
assign O = {Oh, Ol};
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// Post-place-and-route RAM model
|
||||||
|
module ICESTORM_RAM(
|
||||||
|
output RDATA_15, RDATA_14, RDATA_13, RDATA_12, RDATA_11, RDATA_10, RDATA_9, RDATA_8, RDATA_7, RDATA_6, RDATA_5, RDATA_4, RDATA_3, RDATA_2, RDATA_1, RDATA_0,
|
||||||
|
input RCLK, RCLKE, RE,
|
||||||
|
input RADDR_10, RADDR_9, RADDR_8, RADDR_7, RADDR_6, RADDR_5, RADDR_4, RADDR_3, RADDR_2, RADDR_1, RADDR_0,
|
||||||
|
input WCLK, WCLKE, WE,
|
||||||
|
input WADDR_10, WADDR_9, WADDR_8, WADDR_7, WADDR_6, WADDR_5, WADDR_4, WADDR_3, WADDR_2, WADDR_1, WADDR_0,
|
||||||
|
input MASK_15, MASK_14, MASK_13, MASK_12, MASK_11, MASK_10, MASK_9, MASK_8, MASK_7, MASK_6, MASK_5, MASK_4, MASK_3, MASK_2, MASK_1, MASK_0,
|
||||||
|
input WDATA_15, WDATA_14, WDATA_13, WDATA_12, WDATA_11, WDATA_10, WDATA_9, WDATA_8, WDATA_7, WDATA_6, WDATA_5, WDATA_4, WDATA_3, WDATA_2, WDATA_1, WDATA_0
|
||||||
|
);
|
||||||
|
parameter WRITE_MODE = 0;
|
||||||
|
parameter READ_MODE = 0;
|
||||||
|
|
||||||
|
parameter NEG_CLK_R = 1'b0;
|
||||||
|
parameter NEG_CLK_W = 1'b0;
|
||||||
|
|
||||||
|
parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||||
|
|
||||||
|
// Pull-down and pull-up functions
|
||||||
|
function pd;
|
||||||
|
input x;
|
||||||
|
begin
|
||||||
|
pd = (x === 1'bz) ? 1'b0 : x;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function pu;
|
||||||
|
input x;
|
||||||
|
begin
|
||||||
|
pu = (x === 1'bz) ? 1'b1 : x;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
SB_RAM40_4K #(
|
||||||
|
.WRITE_MODE(WRITE_MODE),
|
||||||
|
.READ_MODE (READ_MODE ),
|
||||||
|
.INIT_0 (INIT_0 ),
|
||||||
|
.INIT_1 (INIT_1 ),
|
||||||
|
.INIT_2 (INIT_2 ),
|
||||||
|
.INIT_3 (INIT_3 ),
|
||||||
|
.INIT_4 (INIT_4 ),
|
||||||
|
.INIT_5 (INIT_5 ),
|
||||||
|
.INIT_6 (INIT_6 ),
|
||||||
|
.INIT_7 (INIT_7 ),
|
||||||
|
.INIT_8 (INIT_8 ),
|
||||||
|
.INIT_9 (INIT_9 ),
|
||||||
|
.INIT_A (INIT_A ),
|
||||||
|
.INIT_B (INIT_B ),
|
||||||
|
.INIT_C (INIT_C ),
|
||||||
|
.INIT_D (INIT_D ),
|
||||||
|
.INIT_E (INIT_E ),
|
||||||
|
.INIT_F (INIT_F )
|
||||||
|
) RAM (
|
||||||
|
.RDATA({RDATA_15, RDATA_14, RDATA_13, RDATA_12, RDATA_11, RDATA_10, RDATA_9, RDATA_8, RDATA_7, RDATA_6, RDATA_5, RDATA_4, RDATA_3, RDATA_2, RDATA_1, RDATA_0}),
|
||||||
|
.RCLK (pd(RCLK) ^ NEG_CLK_R),
|
||||||
|
.RCLKE(pu(RCLKE)),
|
||||||
|
.RE (pd(RE)),
|
||||||
|
.RADDR({pd(RADDR_10), pd(RADDR_9), pd(RADDR_8), pd(RADDR_7), pd(RADDR_6), pd(RADDR_5), pd(RADDR_4), pd(RADDR_3), pd(RADDR_2), pd(RADDR_1), pd(RADDR_0)}),
|
||||||
|
.WCLK (pd(WCLK) ^ NEG_CLK_W),
|
||||||
|
.WCLKE(pu(WCLKE)),
|
||||||
|
.WE (pd(WE)),
|
||||||
|
.WADDR({pd(WADDR_10), pd(WADDR_9), pd(WADDR_8), pd(WADDR_7), pd(WADDR_6), pd(WADDR_5), pd(WADDR_4), pd(WADDR_3), pd(WADDR_2), pd(WADDR_1), pd(WADDR_0)}),
|
||||||
|
.MASK ({pd(MASK_15), pd(MASK_14), pd(MASK_13), pd(MASK_12), pd(MASK_11), pd(MASK_10), pd(MASK_9), pd(MASK_8),
|
||||||
|
pd(MASK_7), pd(MASK_6), pd(MASK_5), pd(MASK_4), pd(MASK_3), pd(MASK_2), pd(MASK_1), pd(MASK_0)}),
|
||||||
|
.WDATA({pd(WDATA_15), pd(WDATA_14), pd(WDATA_13), pd(WDATA_12), pd(WDATA_11), pd(WDATA_10), pd(WDATA_9), pd(WDATA_8),
|
||||||
|
pd(WDATA_7), pd(WDATA_6), pd(WDATA_5), pd(WDATA_4), pd(WDATA_3), pd(WDATA_2), pd(WDATA_1), pd(WDATA_0)})
|
||||||
|
);
|
||||||
|
|
||||||
|
`ifdef TIMING
|
||||||
|
specify
|
||||||
|
(RCLK => RDATA_15) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_14) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_13) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_12) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_11) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_10) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_9) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_8) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_7) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_6) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_5) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_4) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_3) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_2) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_1) = (0:0:0, 0:0:0);
|
||||||
|
(RCLK => RDATA_0) = (0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, posedge RADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge RCLK, negedge RADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, posedge RADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge RCLK, negedge RADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WCLKE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WE, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WADDR_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge MASK_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge MASK_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge MASK_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge MASK_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_15, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_14, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_13, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_12, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_11, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_10, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_9, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_8, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_7, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_6, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_5, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_4, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_3, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_2, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_1, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, posedge WDATA_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(posedge WCLK, negedge WDATA_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, posedge WDATA_0, 0:0:0, 0:0:0);
|
||||||
|
$setuphold(negedge WCLK, negedge WDATA_0, 0:0:0, 0:0:0);
|
||||||
|
|
||||||
|
endspecify
|
||||||
|
`endif
|
||||||
|
endmodule
|
||||||
|
|
|
@ -273,6 +273,7 @@ struct SynthIce40Pass : public ScriptPass
|
||||||
run("opt_expr");
|
run("opt_expr");
|
||||||
run("opt_clean");
|
run("opt_clean");
|
||||||
if (help_mode || dsp) {
|
if (help_mode || dsp) {
|
||||||
|
run("memory_dff");
|
||||||
run("techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 "
|
run("techmap -map +/mul2dsp.v -map +/ice40/dsp_map.v -D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=16 "
|
||||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 "
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_Y_MINWIDTH=11 "
|
||||||
"-D DSP_NAME=$__MUL16X16", "(if -dsp)");
|
"-D DSP_NAME=$__MUL16X16", "(if -dsp)");
|
||||||
|
@ -379,6 +380,7 @@ struct SynthIce40Pass : public ScriptPass
|
||||||
|
|
||||||
if (check_label("check"))
|
if (check_label("check"))
|
||||||
{
|
{
|
||||||
|
run("autoname");
|
||||||
run("hierarchy -check");
|
run("hierarchy -check");
|
||||||
run("stat");
|
run("stat");
|
||||||
run("check -noinit");
|
run("check -noinit");
|
||||||
|
|
|
@ -13,7 +13,7 @@ EXTRA_OBJS += techlibs/xilinx/brams_init.mk
|
||||||
|
|
||||||
techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py
|
techlibs/xilinx/brams_init.mk: techlibs/xilinx/brams_init.py
|
||||||
$(Q) mkdir -p techlibs/xilinx
|
$(Q) mkdir -p techlibs/xilinx
|
||||||
$(P) python3 $<
|
$(P) $(PYTHON_EXECUTABLE) $<
|
||||||
$(Q) touch $@
|
$(Q) touch $@
|
||||||
|
|
||||||
techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk
|
techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk
|
||||||
|
@ -25,16 +25,14 @@ techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk
|
||||||
|
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_cells_xtra.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6v_cells_xtra.v))
|
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_cells_xtra.v))
|
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_cells_xtra.v))
|
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_bb.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_xcu_brams.txt))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams.txt))
|
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_brams_map.v))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams.txt))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcup_urams_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
|
||||||
|
@ -42,7 +40,13 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_ff_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_ff_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_ff_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/dsp_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3s_mult_map.v))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sda_dsp_map.v))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_dsp_map.v))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc4v_dsp_map.v))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc5v_dsp_map.v))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_dsp_map.v))
|
||||||
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_dsp_map.v))
|
||||||
|
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_map.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_map.v))
|
||||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_unmap.v))
|
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_unmap.v))
|
||||||
|
|
|
@ -38,6 +38,17 @@ module IBUF(
|
||||||
assign O = I;
|
assign O = I;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
module IBUFG(
|
||||||
|
output O,
|
||||||
|
(* iopad_external_pin *)
|
||||||
|
input I);
|
||||||
|
parameter CAPACITANCE = "DONT_CARE";
|
||||||
|
parameter IBUF_DELAY_VALUE = "0";
|
||||||
|
parameter IBUF_LOW_PWR = "TRUE";
|
||||||
|
parameter IOSTANDARD = "DEFAULT";
|
||||||
|
assign O = I;
|
||||||
|
endmodule
|
||||||
|
|
||||||
module OBUF(
|
module OBUF(
|
||||||
(* iopad_external_pin *)
|
(* iopad_external_pin *)
|
||||||
output O,
|
output O,
|
||||||
|
@ -578,6 +589,515 @@ module SRLC32E (
|
||||||
endgenerate
|
endgenerate
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// DSP
|
||||||
|
|
||||||
|
// Virtex 2, Virtex 2 Pro, Spartan 3.
|
||||||
|
|
||||||
|
// Asynchronous mode.
|
||||||
|
|
||||||
|
module MULT18X18 (
|
||||||
|
input signed [17:0] A,
|
||||||
|
input signed [17:0] B,
|
||||||
|
output signed [35:0] P
|
||||||
|
);
|
||||||
|
|
||||||
|
assign P = A * B;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Synchronous mode.
|
||||||
|
|
||||||
|
module MULT18X18S (
|
||||||
|
input signed [17:0] A,
|
||||||
|
input signed [17:0] B,
|
||||||
|
output reg signed [35:0] P,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input C,
|
||||||
|
input CE,
|
||||||
|
input R
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(posedge C)
|
||||||
|
if (R)
|
||||||
|
P <= 0;
|
||||||
|
else if (CE)
|
||||||
|
P <= A * B;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Spartan 3E, Spartan 3A.
|
||||||
|
|
||||||
|
module MULT18X18SIO (
|
||||||
|
input signed [17:0] A,
|
||||||
|
input signed [17:0] B,
|
||||||
|
output signed [35:0] P,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input CLK,
|
||||||
|
input CEA,
|
||||||
|
input CEB,
|
||||||
|
input CEP,
|
||||||
|
input RSTA,
|
||||||
|
input RSTB,
|
||||||
|
input RSTP,
|
||||||
|
input signed [17:0] BCIN,
|
||||||
|
output signed [17:0] BCOUT
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter integer AREG = 1;
|
||||||
|
parameter integer BREG = 1;
|
||||||
|
parameter B_INPUT = "DIRECT";
|
||||||
|
parameter integer PREG = 1;
|
||||||
|
|
||||||
|
// The multiplier.
|
||||||
|
wire signed [35:0] P_MULT;
|
||||||
|
assign P_MULT = A_MULT * B_MULT;
|
||||||
|
|
||||||
|
// The cascade output.
|
||||||
|
assign BCOUT = B_MULT;
|
||||||
|
|
||||||
|
// The B input multiplexer.
|
||||||
|
wire signed [17:0] B_MUX;
|
||||||
|
assign B_MUX = (B_INPUT == "DIRECT") ? B : BCIN;
|
||||||
|
|
||||||
|
// The registers.
|
||||||
|
reg signed [17:0] A_REG;
|
||||||
|
reg signed [17:0] B_REG;
|
||||||
|
reg signed [35:0] P_REG;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
A_REG = 0;
|
||||||
|
B_REG = 0;
|
||||||
|
P_REG = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTA)
|
||||||
|
A_REG <= 0;
|
||||||
|
else if (CEA)
|
||||||
|
A_REG <= A;
|
||||||
|
|
||||||
|
if (RSTB)
|
||||||
|
B_REG <= 0;
|
||||||
|
else if (CEB)
|
||||||
|
B_REG <= B_MUX;
|
||||||
|
|
||||||
|
if (RSTP)
|
||||||
|
P_REG <= 0;
|
||||||
|
else if (CEP)
|
||||||
|
P_REG <= P_MULT;
|
||||||
|
end
|
||||||
|
|
||||||
|
// The register enables.
|
||||||
|
wire signed [17:0] A_MULT;
|
||||||
|
wire signed [17:0] B_MULT;
|
||||||
|
assign A_MULT = (AREG == 1) ? A_REG : A;
|
||||||
|
assign B_MULT = (BREG == 1) ? B_REG : B_MUX;
|
||||||
|
assign P = (PREG == 1) ? P_REG : P_MULT;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Spartan 3A DSP.
|
||||||
|
|
||||||
|
module DSP48A (
|
||||||
|
input signed [17:0] A,
|
||||||
|
input signed [17:0] B,
|
||||||
|
input signed [47:0] C,
|
||||||
|
input signed [17:0] D,
|
||||||
|
input signed [47:0] PCIN,
|
||||||
|
input CARRYIN,
|
||||||
|
input [7:0] OPMODE,
|
||||||
|
output signed [47:0] P,
|
||||||
|
output signed [17:0] BCOUT,
|
||||||
|
output signed [47:0] PCOUT,
|
||||||
|
output CARRYOUT,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input CLK,
|
||||||
|
input CEA,
|
||||||
|
input CEB,
|
||||||
|
input CEC,
|
||||||
|
input CED,
|
||||||
|
input CEM,
|
||||||
|
input CECARRYIN,
|
||||||
|
input CEOPMODE,
|
||||||
|
input CEP,
|
||||||
|
input RSTA,
|
||||||
|
input RSTB,
|
||||||
|
input RSTC,
|
||||||
|
input RSTD,
|
||||||
|
input RSTM,
|
||||||
|
input RSTCARRYIN,
|
||||||
|
input RSTOPMODE,
|
||||||
|
input RSTP
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter integer A0REG = 0;
|
||||||
|
parameter integer A1REG = 1;
|
||||||
|
parameter integer B0REG = 0;
|
||||||
|
parameter integer B1REG = 1;
|
||||||
|
parameter integer CREG = 1;
|
||||||
|
parameter integer DREG = 1;
|
||||||
|
parameter integer MREG = 1;
|
||||||
|
parameter integer CARRYINREG = 1;
|
||||||
|
parameter integer OPMODEREG = 1;
|
||||||
|
parameter integer PREG = 1;
|
||||||
|
parameter CARRYINSEL = "CARRYIN";
|
||||||
|
parameter RSTTYPE = "SYNC";
|
||||||
|
|
||||||
|
// This is a strict subset of Spartan 6 -- reuse its model.
|
||||||
|
|
||||||
|
DSP48A1 #(
|
||||||
|
.A0REG(A0REG),
|
||||||
|
.A1REG(A1REG),
|
||||||
|
.B0REG(B0REG),
|
||||||
|
.B1REG(B1REG),
|
||||||
|
.CREG(CREG),
|
||||||
|
.DREG(DREG),
|
||||||
|
.MREG(MREG),
|
||||||
|
.CARRYINREG(CARRYINREG),
|
||||||
|
.CARRYOUTREG(0),
|
||||||
|
.OPMODEREG(OPMODEREG),
|
||||||
|
.PREG(PREG),
|
||||||
|
.CARRYINSEL(CARRYINSEL),
|
||||||
|
.RSTTYPE(RSTTYPE)
|
||||||
|
) upgrade (
|
||||||
|
.A(A),
|
||||||
|
.B(B),
|
||||||
|
.C(C),
|
||||||
|
.D(D),
|
||||||
|
.PCIN(PCIN),
|
||||||
|
.CARRYIN(CARRYIN),
|
||||||
|
.OPMODE(OPMODE),
|
||||||
|
// M unconnected
|
||||||
|
.P(P),
|
||||||
|
.BCOUT(BCOUT),
|
||||||
|
.PCOUT(PCOUT),
|
||||||
|
.CARRYOUT(CARRYOUT),
|
||||||
|
// CARRYOUTF unconnected
|
||||||
|
.CLK(CLK),
|
||||||
|
.CEA(CEA),
|
||||||
|
.CEB(CEB),
|
||||||
|
.CEC(CEC),
|
||||||
|
.CED(CED),
|
||||||
|
.CEM(CEM),
|
||||||
|
.CECARRYIN(CECARRYIN),
|
||||||
|
.CEOPMODE(CEOPMODE),
|
||||||
|
.CEP(CEP),
|
||||||
|
.RSTA(RSTA),
|
||||||
|
.RSTB(RSTB),
|
||||||
|
.RSTC(RSTC),
|
||||||
|
.RSTD(RSTD),
|
||||||
|
.RSTM(RSTM),
|
||||||
|
.RSTCARRYIN(RSTCARRYIN),
|
||||||
|
.RSTOPMODE(RSTOPMODE),
|
||||||
|
.RSTP(RSTP)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Spartan 6.
|
||||||
|
|
||||||
|
module DSP48A1 (
|
||||||
|
input signed [17:0] A,
|
||||||
|
input signed [17:0] B,
|
||||||
|
input signed [47:0] C,
|
||||||
|
input signed [17:0] D,
|
||||||
|
input signed [47:0] PCIN,
|
||||||
|
input CARRYIN,
|
||||||
|
input [7:0] OPMODE,
|
||||||
|
output signed [35:0] M,
|
||||||
|
output signed [47:0] P,
|
||||||
|
output signed [17:0] BCOUT,
|
||||||
|
output signed [47:0] PCOUT,
|
||||||
|
output CARRYOUT,
|
||||||
|
output CARRYOUTF,
|
||||||
|
(* clkbuf_sink *)
|
||||||
|
input CLK,
|
||||||
|
input CEA,
|
||||||
|
input CEB,
|
||||||
|
input CEC,
|
||||||
|
input CED,
|
||||||
|
input CEM,
|
||||||
|
input CECARRYIN,
|
||||||
|
input CEOPMODE,
|
||||||
|
input CEP,
|
||||||
|
input RSTA,
|
||||||
|
input RSTB,
|
||||||
|
input RSTC,
|
||||||
|
input RSTD,
|
||||||
|
input RSTM,
|
||||||
|
input RSTCARRYIN,
|
||||||
|
input RSTOPMODE,
|
||||||
|
input RSTP
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter integer A0REG = 0;
|
||||||
|
parameter integer A1REG = 1;
|
||||||
|
parameter integer B0REG = 0;
|
||||||
|
parameter integer B1REG = 1;
|
||||||
|
parameter integer CREG = 1;
|
||||||
|
parameter integer DREG = 1;
|
||||||
|
parameter integer MREG = 1;
|
||||||
|
parameter integer CARRYINREG = 1;
|
||||||
|
parameter integer CARRYOUTREG = 1;
|
||||||
|
parameter integer OPMODEREG = 1;
|
||||||
|
parameter integer PREG = 1;
|
||||||
|
parameter CARRYINSEL = "OPMODE5";
|
||||||
|
parameter RSTTYPE = "SYNC";
|
||||||
|
|
||||||
|
wire signed [35:0] M_MULT;
|
||||||
|
wire signed [47:0] P_IN;
|
||||||
|
wire signed [17:0] A0_OUT;
|
||||||
|
wire signed [17:0] B0_OUT;
|
||||||
|
wire signed [17:0] A1_OUT;
|
||||||
|
wire signed [17:0] B1_OUT;
|
||||||
|
wire signed [17:0] B1_IN;
|
||||||
|
wire signed [47:0] C_OUT;
|
||||||
|
wire signed [17:0] D_OUT;
|
||||||
|
wire signed [7:0] OPMODE_OUT;
|
||||||
|
wire CARRYIN_OUT;
|
||||||
|
wire CARRYOUT_IN;
|
||||||
|
wire CARRYIN_IN;
|
||||||
|
reg signed [47:0] XMUX;
|
||||||
|
reg signed [47:0] ZMUX;
|
||||||
|
|
||||||
|
// The registers.
|
||||||
|
reg signed [17:0] A0_REG;
|
||||||
|
reg signed [17:0] A1_REG;
|
||||||
|
reg signed [17:0] B0_REG;
|
||||||
|
reg signed [17:0] B1_REG;
|
||||||
|
reg signed [47:0] C_REG;
|
||||||
|
reg signed [17:0] D_REG;
|
||||||
|
reg signed [35:0] M_REG;
|
||||||
|
reg signed [47:0] P_REG;
|
||||||
|
reg [7:0] OPMODE_REG;
|
||||||
|
reg CARRYIN_REG;
|
||||||
|
reg CARRYOUT_REG;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
A0_REG = 0;
|
||||||
|
A1_REG = 0;
|
||||||
|
B0_REG = 0;
|
||||||
|
B1_REG = 0;
|
||||||
|
C_REG = 0;
|
||||||
|
D_REG = 0;
|
||||||
|
M_REG = 0;
|
||||||
|
P_REG = 0;
|
||||||
|
OPMODE_REG = 0;
|
||||||
|
CARRYIN_REG = 0;
|
||||||
|
CARRYOUT_REG = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
generate
|
||||||
|
|
||||||
|
if (RSTTYPE == "SYNC") begin
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTA) begin
|
||||||
|
A0_REG <= 0;
|
||||||
|
A1_REG <= 0;
|
||||||
|
end else if (CEA) begin
|
||||||
|
A0_REG <= A;
|
||||||
|
A1_REG <= A0_OUT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTB) begin
|
||||||
|
B0_REG <= 0;
|
||||||
|
B1_REG <= 0;
|
||||||
|
end else if (CEB) begin
|
||||||
|
B0_REG <= B;
|
||||||
|
B1_REG <= B1_IN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTC) begin
|
||||||
|
C_REG <= 0;
|
||||||
|
end else if (CEC) begin
|
||||||
|
C_REG <= C;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTD) begin
|
||||||
|
D_REG <= 0;
|
||||||
|
end else if (CED) begin
|
||||||
|
D_REG <= D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTM) begin
|
||||||
|
M_REG <= 0;
|
||||||
|
end else if (CEM) begin
|
||||||
|
M_REG <= M_MULT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTP) begin
|
||||||
|
P_REG <= 0;
|
||||||
|
end else if (CEP) begin
|
||||||
|
P_REG <= P_IN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTOPMODE) begin
|
||||||
|
OPMODE_REG <= 0;
|
||||||
|
end else if (CEOPMODE) begin
|
||||||
|
OPMODE_REG <= OPMODE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK) begin
|
||||||
|
if (RSTCARRYIN) begin
|
||||||
|
CARRYIN_REG <= 0;
|
||||||
|
CARRYOUT_REG <= 0;
|
||||||
|
end else if (CECARRYIN) begin
|
||||||
|
CARRYIN_REG <= CARRYIN_IN;
|
||||||
|
CARRYOUT_REG <= CARRYOUT_IN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
always @(posedge CLK, posedge RSTA) begin
|
||||||
|
if (RSTA) begin
|
||||||
|
A0_REG <= 0;
|
||||||
|
A1_REG <= 0;
|
||||||
|
end else if (CEA) begin
|
||||||
|
A0_REG <= A;
|
||||||
|
A1_REG <= A0_OUT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK, posedge RSTB) begin
|
||||||
|
if (RSTB) begin
|
||||||
|
B0_REG <= 0;
|
||||||
|
B1_REG <= 0;
|
||||||
|
end else if (CEB) begin
|
||||||
|
B0_REG <= B;
|
||||||
|
B1_REG <= B1_IN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK, posedge RSTC) begin
|
||||||
|
if (RSTC) begin
|
||||||
|
C_REG <= 0;
|
||||||
|
end else if (CEC) begin
|
||||||
|
C_REG <= C;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK, posedge RSTD) begin
|
||||||
|
if (RSTD) begin
|
||||||
|
D_REG <= 0;
|
||||||
|
end else if (CED) begin
|
||||||
|
D_REG <= D;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK, posedge RSTM) begin
|
||||||
|
if (RSTM) begin
|
||||||
|
M_REG <= 0;
|
||||||
|
end else if (CEM) begin
|
||||||
|
M_REG <= M_MULT;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK, posedge RSTP) begin
|
||||||
|
if (RSTP) begin
|
||||||
|
P_REG <= 0;
|
||||||
|
end else if (CEP) begin
|
||||||
|
P_REG <= P_IN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK, posedge RSTOPMODE) begin
|
||||||
|
if (RSTOPMODE) begin
|
||||||
|
OPMODE_REG <= 0;
|
||||||
|
end else if (CEOPMODE) begin
|
||||||
|
OPMODE_REG <= OPMODE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge CLK, posedge RSTCARRYIN) begin
|
||||||
|
if (RSTCARRYIN) begin
|
||||||
|
CARRYIN_REG <= 0;
|
||||||
|
CARRYOUT_REG <= 0;
|
||||||
|
end else if (CECARRYIN) begin
|
||||||
|
CARRYIN_REG <= CARRYIN_IN;
|
||||||
|
CARRYOUT_REG <= CARRYOUT_IN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// The register enables.
|
||||||
|
assign A0_OUT = (A0REG == 1) ? A0_REG : A;
|
||||||
|
assign A1_OUT = (A1REG == 1) ? A1_REG : A0_OUT;
|
||||||
|
assign B0_OUT = (B0REG == 1) ? B0_REG : B;
|
||||||
|
assign B1_OUT = (B1REG == 1) ? B1_REG : B1_IN;
|
||||||
|
assign C_OUT = (CREG == 1) ? C_REG : C;
|
||||||
|
assign D_OUT = (DREG == 1) ? D_REG : D;
|
||||||
|
assign M = (MREG == 1) ? M_REG : M_MULT;
|
||||||
|
assign P = (PREG == 1) ? P_REG : P_IN;
|
||||||
|
assign OPMODE_OUT = (OPMODEREG == 1) ? OPMODE_REG : OPMODE;
|
||||||
|
assign CARRYIN_OUT = (CARRYINREG == 1) ? CARRYIN_REG : CARRYIN_IN;
|
||||||
|
assign CARRYOUT = (CARRYOUTREG == 1) ? CARRYOUT_REG : CARRYOUT_IN;
|
||||||
|
assign CARRYOUTF = CARRYOUT;
|
||||||
|
|
||||||
|
// The pre-adder.
|
||||||
|
wire signed [17:0] PREADDER;
|
||||||
|
assign B1_IN = OPMODE_OUT[4] ? PREADDER : B0_OUT;
|
||||||
|
assign PREADDER = OPMODE_OUT[6] ? D_OUT - B0_OUT : D_OUT + B0_OUT;
|
||||||
|
|
||||||
|
// The multiplier.
|
||||||
|
assign M_MULT = A1_OUT * B1_OUT;
|
||||||
|
|
||||||
|
// The carry in selection.
|
||||||
|
assign CARRYIN_IN = (CARRYINSEL == "OPMODE5") ? OPMODE_OUT[5] : CARRYIN;
|
||||||
|
|
||||||
|
// The post-adder inputs.
|
||||||
|
always @* begin
|
||||||
|
case (OPMODE_OUT[1:0])
|
||||||
|
2'b00: XMUX <= 0;
|
||||||
|
2'b01: XMUX <= M;
|
||||||
|
2'b10: XMUX <= P;
|
||||||
|
2'b11: XMUX <= {D_OUT[11:0], B1_OUT, A1_OUT};
|
||||||
|
default: XMUX <= 48'hxxxxxxxxxxxx;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
case (OPMODE_OUT[3:2])
|
||||||
|
2'b00: ZMUX <= 0;
|
||||||
|
2'b01: ZMUX <= PCIN;
|
||||||
|
2'b10: ZMUX <= P;
|
||||||
|
2'b11: ZMUX <= C_OUT;
|
||||||
|
default: ZMUX <= 48'hxxxxxxxxxxxx;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// The post-adder.
|
||||||
|
wire signed [48:0] X_EXT;
|
||||||
|
wire signed [48:0] Z_EXT;
|
||||||
|
assign X_EXT = XMUX;
|
||||||
|
assign Z_EXT = ZMUX;
|
||||||
|
assign {CARRYOUT_IN, P_IN} = OPMODE_OUT[7] ? (Z_EXT - (X_EXT + CARRYIN_OUT)) : (Z_EXT + X_EXT + CARRYIN_OUT);
|
||||||
|
|
||||||
|
// Cascade outputs.
|
||||||
|
assign BCOUT = B1_OUT;
|
||||||
|
assign PCOUT = P;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// TODO: DSP48 (Virtex 4).
|
||||||
|
|
||||||
|
// TODO: DSP48E (Virtex 5).
|
||||||
|
|
||||||
|
// Virtex 6, Series 7.
|
||||||
|
|
||||||
module DSP48E1 (
|
module DSP48E1 (
|
||||||
output [29:0] ACOUT,
|
output [29:0] ACOUT,
|
||||||
output [17:0] BCOUT,
|
output [17:0] BCOUT,
|
||||||
|
@ -1040,3 +1560,5 @@ module DSP48E1 (
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// TODO: DSP48E2 (Ultrascale).
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -46,7 +46,7 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
log(" -top <module>\n");
|
log(" -top <module>\n");
|
||||||
log(" use the specified module as top module\n");
|
log(" use the specified module as top module\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -family {xcup|xcu|xc7|xc6v|xc6s}\n");
|
log(" -family {xcup|xcu|xc7|xc6v|xc5v|xc6s}\n");
|
||||||
log(" run synthesis for the specified Xilinx architecture\n");
|
log(" run synthesis for the specified Xilinx architecture\n");
|
||||||
log(" generate the synthesis netlist for the specified family.\n");
|
log(" generate the synthesis netlist for the specified family.\n");
|
||||||
log(" default: xc7\n");
|
log(" default: xc7\n");
|
||||||
|
@ -93,6 +93,9 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
log(" -noclkbuf\n");
|
log(" -noclkbuf\n");
|
||||||
log(" disable automatic clock buffer insertion\n");
|
log(" disable automatic clock buffer insertion\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -uram\n");
|
||||||
|
log(" infer URAM288s for large memories (xcup only)\n");
|
||||||
|
log("\n");
|
||||||
log(" -widemux <int>\n");
|
log(" -widemux <int>\n");
|
||||||
log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
|
log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
|
||||||
log(" above this number of inputs (minimum value 2, recommended value >= 5).\n");
|
log(" above this number of inputs (minimum value 2, recommended value >= 5).\n");
|
||||||
|
@ -119,7 +122,7 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string top_opt, edif_file, blif_file, family;
|
std::string top_opt, edif_file, blif_file, family;
|
||||||
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, abc9;
|
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram, abc9;
|
||||||
bool flatten_before_abc;
|
bool flatten_before_abc;
|
||||||
int widemux;
|
int widemux;
|
||||||
|
|
||||||
|
@ -143,6 +146,7 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
nocarry = false;
|
nocarry = false;
|
||||||
nowidelut = false;
|
nowidelut = false;
|
||||||
nodsp = false;
|
nodsp = false;
|
||||||
|
uram = false;
|
||||||
abc9 = false;
|
abc9 = false;
|
||||||
flatten_before_abc = false;
|
flatten_before_abc = false;
|
||||||
widemux = 0;
|
widemux = 0;
|
||||||
|
@ -248,11 +252,15 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
nodsp = true;
|
nodsp = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-uram") {
|
||||||
|
uram = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc6s")
|
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc5v" && family != "xc6s")
|
||||||
log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
|
log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
|
||||||
|
|
||||||
if (widemux != 0 && widemux < 2)
|
if (widemux != 0 && widemux < 2)
|
||||||
|
@ -289,24 +297,7 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
read_args += " -lib +/xilinx/cells_sim.v";
|
read_args += " -lib +/xilinx/cells_sim.v";
|
||||||
run("read_verilog" + read_args);
|
run("read_verilog" + read_args);
|
||||||
|
|
||||||
if (help_mode)
|
run("read_verilog -lib +/xilinx/cells_xtra.v");
|
||||||
run("read_verilog -lib +/xilinx/{family}_cells_xtra.v");
|
|
||||||
else if (family == "xc6s")
|
|
||||||
run("read_verilog -lib +/xilinx/xc6s_cells_xtra.v");
|
|
||||||
else if (family == "xc6v")
|
|
||||||
run("read_verilog -lib +/xilinx/xc6v_cells_xtra.v");
|
|
||||||
else if (family == "xc7")
|
|
||||||
run("read_verilog -lib +/xilinx/xc7_cells_xtra.v");
|
|
||||||
else if (family == "xcu" || family == "xcup")
|
|
||||||
run("read_verilog -lib +/xilinx/xcu_cells_xtra.v");
|
|
||||||
|
|
||||||
if (help_mode) {
|
|
||||||
run("read_verilog -lib +/xilinx/{family}_brams_bb.v");
|
|
||||||
} else if (family == "xc6s") {
|
|
||||||
run("read_verilog -lib +/xilinx/xc6s_brams_bb.v");
|
|
||||||
} else if (family == "xc6v" || family == "xc7") {
|
|
||||||
run("read_verilog -lib +/xilinx/xc7_brams_bb.v");
|
|
||||||
}
|
|
||||||
|
|
||||||
run(stringf("hierarchy -check %s", top_opt.c_str()));
|
run(stringf("hierarchy -check %s", top_opt.c_str()));
|
||||||
}
|
}
|
||||||
|
@ -342,15 +333,53 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
|
|
||||||
if (check_label("map_dsp", "(skip if '-nodsp')")) {
|
if (check_label("map_dsp", "(skip if '-nodsp')")) {
|
||||||
if (!nodsp || help_mode) {
|
if (!nodsp || help_mode) {
|
||||||
|
run("memory_dff"); // xilinx_dsp will merge registers, reserve memory port registers first
|
||||||
// NB: Xilinx multipliers are signed only
|
// NB: Xilinx multipliers are signed only
|
||||||
run("techmap -map +/mul2dsp.v -map +/xilinx/dsp_map.v -D DSP_A_MAXWIDTH=25 "
|
if (help_mode)
|
||||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 -D DSP_B_MAXWIDTH=18 " // Partial multipliers are intentionally
|
run("techmap -map +/mul2dsp.v -map +/xilinx/{family}_dsp_map.v {options}");
|
||||||
|
else if (family == "xc2v" || family == "xc3s" || family == "xc3se" || family == "xc3sa")
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/xilinx/xc3s_mult_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
|
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||||
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||||
|
else if (family == "xc3sda")
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/xilinx/xc3sda_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
|
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||||
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||||
|
else if (family == "xc6s")
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/xilinx/xc6s_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
|
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||||
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||||
|
else if (family == "xc4v")
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/xilinx/xc4v_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
|
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||||
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||||
|
else if (family == "xc5v")
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/xilinx/xc5v_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
|
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||||
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||||
|
else if (family == "xc6v" || family == "xc7")
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/xilinx/xc7_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||||
// limited to 18x18 in order to take
|
// limited to 18x18 in order to take
|
||||||
// advantage of the (PCOUT << 17) -> PCIN
|
// advantage of the (PCOUT << 17) -> PCIN
|
||||||
// dedicated cascade chain capability
|
// dedicated cascade chain capability
|
||||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||||
|
else if (family == "xcu" || family == "xcup")
|
||||||
|
run("techmap -map +/mul2dsp.v -map +/xilinx/xcu_dsp_map.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=18 "
|
||||||
|
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||||
|
// limited to 18x18 in order to take
|
||||||
|
// advantage of the (PCOUT << 17) -> PCIN
|
||||||
|
// dedicated cascade chain capability
|
||||||
|
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||||
|
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||||
|
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL27X18");
|
||||||
run("select a:mul2dsp");
|
run("select a:mul2dsp");
|
||||||
run("setattr -unset mul2dsp");
|
run("setattr -unset mul2dsp");
|
||||||
run("opt_expr -fine");
|
run("opt_expr -fine");
|
||||||
|
@ -371,6 +400,20 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
run("opt_clean");
|
run("opt_clean");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check_label("map_uram", "(only if '-uram')")) {
|
||||||
|
if (help_mode) {
|
||||||
|
run("memory_bram -rules +/xilinx/{family}_urams.txt");
|
||||||
|
run("techmap -map +/xilinx/{family}_urams_map.v");
|
||||||
|
} else if (uram) {
|
||||||
|
if (family == "xcup") {
|
||||||
|
run("memory_bram -rules +/xilinx/xcup_urams.txt");
|
||||||
|
run("techmap -map +/xilinx/xcup_urams_map.v");
|
||||||
|
} else {
|
||||||
|
log_warning("UltraRAM inference not supported for family %s.\n", family.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (check_label("map_bram", "(skip if '-nobram')")) {
|
if (check_label("map_bram", "(skip if '-nobram')")) {
|
||||||
if (help_mode) {
|
if (help_mode) {
|
||||||
run("memory_bram -rules +/xilinx/{family}_brams.txt");
|
run("memory_bram -rules +/xilinx/{family}_brams.txt");
|
||||||
|
@ -380,8 +423,11 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
run("memory_bram -rules +/xilinx/xc6s_brams.txt");
|
run("memory_bram -rules +/xilinx/xc6s_brams.txt");
|
||||||
run("techmap -map +/xilinx/xc6s_brams_map.v");
|
run("techmap -map +/xilinx/xc6s_brams_map.v");
|
||||||
} else if (family == "xc6v" || family == "xc7") {
|
} else if (family == "xc6v" || family == "xc7") {
|
||||||
run("memory_bram -rules +/xilinx/xc7_brams.txt");
|
run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
|
||||||
run("techmap -map +/xilinx/xc7_brams_map.v");
|
run("techmap -map +/xilinx/xc7_brams_map.v");
|
||||||
|
} else if (family == "xcu" || family == "xcup") {
|
||||||
|
run("memory_bram -rules +/xilinx/xc7_xcu_brams.txt");
|
||||||
|
run("techmap -map +/xilinx/xcu_brams_map.v");
|
||||||
} else {
|
} else {
|
||||||
log_warning("Block RAM inference not yet supported for family %s.\n", family.c_str());
|
log_warning("Block RAM inference not yet supported for family %s.\n", family.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
MULT18X18 _TECHMAP_REPLACE_ (
|
||||||
|
.A(A),
|
||||||
|
.B(B),
|
||||||
|
.P(Y)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [47:0] P_48;
|
||||||
|
DSP48A #(
|
||||||
|
// Disable all registers
|
||||||
|
.A0REG(0),
|
||||||
|
.A1REG(0),
|
||||||
|
.B0REG(0),
|
||||||
|
.B1REG(0),
|
||||||
|
.CARRYINREG(0),
|
||||||
|
.CARRYINSEL("OPMODE5"),
|
||||||
|
.CREG(0),
|
||||||
|
.DREG(0),
|
||||||
|
.MREG(0),
|
||||||
|
.OPMODEREG(0),
|
||||||
|
.PREG(0)
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
//Data path
|
||||||
|
.A(A),
|
||||||
|
.B(B),
|
||||||
|
.C(48'b0),
|
||||||
|
.D(18'b0),
|
||||||
|
.P(P_48),
|
||||||
|
|
||||||
|
.OPMODE(8'b0000010)
|
||||||
|
);
|
||||||
|
assign Y = P_48;
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [47:0] P_48;
|
||||||
|
DSP48 #(
|
||||||
|
// Disable all registers
|
||||||
|
.AREG(0),
|
||||||
|
.BREG(0),
|
||||||
|
.B_INPUT("DIRECT"),
|
||||||
|
.CARRYINREG(0),
|
||||||
|
.CARRYINSELREG(0),
|
||||||
|
.CREG(0),
|
||||||
|
.MREG(0),
|
||||||
|
.OPMODEREG(0),
|
||||||
|
.PREG(0),
|
||||||
|
.SUBTRACTREG(0),
|
||||||
|
.LEGACY_MODE("MULT18X18")
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
//Data path
|
||||||
|
.A(A),
|
||||||
|
.B(B),
|
||||||
|
.C(48'b0),
|
||||||
|
.P(P_48),
|
||||||
|
|
||||||
|
.SUBTRACT(1'b0),
|
||||||
|
.OPMODE(7'b000101),
|
||||||
|
.CARRYINSEL(2'b00),
|
||||||
|
|
||||||
|
.BCIN(18'b0),
|
||||||
|
.PCIN(48'b0),
|
||||||
|
.CARRYIN(1'b0)
|
||||||
|
);
|
||||||
|
assign Y = P_48;
|
||||||
|
endmodule
|
|
@ -0,0 +1,45 @@
|
||||||
|
module \$__MUL25X18 (input [24:0] A, input [17:0] B, output [42:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [47:0] P_48;
|
||||||
|
DSP48E #(
|
||||||
|
// Disable all registers
|
||||||
|
.ACASCREG(0),
|
||||||
|
.A_INPUT("DIRECT"),
|
||||||
|
.ALUMODEREG(0),
|
||||||
|
.AREG(0),
|
||||||
|
.BCASCREG(0),
|
||||||
|
.B_INPUT("DIRECT"),
|
||||||
|
.BREG(0),
|
||||||
|
.MULTCARRYINREG(0),
|
||||||
|
.CARRYINREG(0),
|
||||||
|
.CARRYINSELREG(0),
|
||||||
|
.CREG(0),
|
||||||
|
.MREG(0),
|
||||||
|
.OPMODEREG(0),
|
||||||
|
.PREG(0),
|
||||||
|
.USE_MULT("MULT"),
|
||||||
|
.USE_SIMD("ONE48")
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
//Data path
|
||||||
|
.A({{5{A[24]}}, A}),
|
||||||
|
.B(B),
|
||||||
|
.C(48'b0),
|
||||||
|
.P(P_48),
|
||||||
|
|
||||||
|
.ALUMODE(4'b0000),
|
||||||
|
.OPMODE(7'b000101),
|
||||||
|
.CARRYINSEL(3'b000),
|
||||||
|
|
||||||
|
.ACIN(30'b0),
|
||||||
|
.BCIN(18'b0),
|
||||||
|
.PCIN(48'b0),
|
||||||
|
.CARRYIN(1'b0)
|
||||||
|
);
|
||||||
|
assign Y = P_48;
|
||||||
|
endmodule
|
||||||
|
|
|
@ -1,223 +0,0 @@
|
||||||
module RAMB8BWER (
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
input CLKAWRCLK,
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
input CLKBRDCLK,
|
|
||||||
input ENAWREN,
|
|
||||||
input ENBRDEN,
|
|
||||||
input REGCEA,
|
|
||||||
input REGCEBREGCE,
|
|
||||||
input RSTA,
|
|
||||||
input RSTBRST,
|
|
||||||
|
|
||||||
input [12:0] ADDRAWRADDR,
|
|
||||||
input [12:0] ADDRBRDADDR,
|
|
||||||
input [15:0] DIADI,
|
|
||||||
input [15:0] DIBDI,
|
|
||||||
input [1:0] DIPADIP,
|
|
||||||
input [1:0] DIPBDIP,
|
|
||||||
input [1:0] WEAWEL,
|
|
||||||
input [1:0] WEBWEU,
|
|
||||||
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [15:0] DOADO,
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [15:0] DOBDO,
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [1:0] DOPADOP,
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [1:0] DOPBDOP
|
|
||||||
);
|
|
||||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter RAM_MODE = "TDP";
|
|
||||||
parameter integer DOA_REG = 0;
|
|
||||||
parameter integer DOB_REG = 0;
|
|
||||||
|
|
||||||
parameter integer DATA_WIDTH_A = 0;
|
|
||||||
parameter integer DATA_WIDTH_B = 0;
|
|
||||||
|
|
||||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
|
||||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
|
||||||
|
|
||||||
parameter EN_RSTRAM_A = "TRUE";
|
|
||||||
parameter EN_RSTRAM_B = "TRUE";
|
|
||||||
|
|
||||||
parameter INIT_A = 18'h000000000;
|
|
||||||
parameter INIT_B = 18'h000000000;
|
|
||||||
parameter SRVAL_A = 18'h000000000;
|
|
||||||
parameter SRVAL_B = 18'h000000000;
|
|
||||||
|
|
||||||
parameter RST_PRIORITY_A = "CE";
|
|
||||||
parameter RST_PRIORITY_B = "CE";
|
|
||||||
|
|
||||||
parameter RSTTYPE = "SYNC";
|
|
||||||
|
|
||||||
parameter SIM_COLLISION_CHECK = "ALL";
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
module RAMB16BWER (
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
input CLKA,
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
input CLKB,
|
|
||||||
input ENA,
|
|
||||||
input ENB,
|
|
||||||
input REGCEA,
|
|
||||||
input REGCEB,
|
|
||||||
input RSTA,
|
|
||||||
input RSTB,
|
|
||||||
|
|
||||||
input [13:0] ADDRA,
|
|
||||||
input [13:0] ADDRB,
|
|
||||||
input [31:0] DIA,
|
|
||||||
input [31:0] DIB,
|
|
||||||
input [3:0] DIPA,
|
|
||||||
input [3:0] DIPB,
|
|
||||||
input [3:0] WEA,
|
|
||||||
input [3:0] WEB,
|
|
||||||
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [31:0] DOA,
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [31:0] DOB,
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [3:0] DOPA,
|
|
||||||
/* (* abc9_arrival=<TODO> *) */
|
|
||||||
output [3:0] DOPB
|
|
||||||
);
|
|
||||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter integer DOA_REG = 0;
|
|
||||||
parameter integer DOB_REG = 0;
|
|
||||||
|
|
||||||
parameter integer DATA_WIDTH_A = 0;
|
|
||||||
parameter integer DATA_WIDTH_B = 0;
|
|
||||||
|
|
||||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
|
||||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
|
||||||
|
|
||||||
parameter EN_RSTRAM_A = "TRUE";
|
|
||||||
parameter EN_RSTRAM_B = "TRUE";
|
|
||||||
|
|
||||||
parameter INIT_A = 36'h000000000;
|
|
||||||
parameter INIT_B = 36'h000000000;
|
|
||||||
parameter SRVAL_A = 36'h000000000;
|
|
||||||
parameter SRVAL_B = 36'h000000000;
|
|
||||||
|
|
||||||
parameter RST_PRIORITY_A = "CE";
|
|
||||||
parameter RST_PRIORITY_B = "CE";
|
|
||||||
|
|
||||||
parameter RSTTYPE = "SYNC";
|
|
||||||
|
|
||||||
parameter SIM_COLLISION_CHECK = "ALL";
|
|
||||||
endmodule
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,35 @@
|
||||||
|
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [47:0] P_48;
|
||||||
|
DSP48A1 #(
|
||||||
|
// Disable all registers
|
||||||
|
.A0REG(0),
|
||||||
|
.A1REG(0),
|
||||||
|
.B0REG(0),
|
||||||
|
.B1REG(0),
|
||||||
|
.CARRYINREG(0),
|
||||||
|
.CARRYINSEL("OPMODE5"),
|
||||||
|
.CREG(0),
|
||||||
|
.DREG(0),
|
||||||
|
.MREG(0),
|
||||||
|
.OPMODEREG(0),
|
||||||
|
.PREG(0)
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
//Data path
|
||||||
|
.A(A),
|
||||||
|
.B(B),
|
||||||
|
.C(48'b0),
|
||||||
|
.D(18'b0),
|
||||||
|
.P(P_48),
|
||||||
|
|
||||||
|
.OPMODE(8'b0000010)
|
||||||
|
);
|
||||||
|
assign Y = P_48;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,349 +0,0 @@
|
||||||
// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/f8e0364116b2983ac72a3dc8c509ea1cc79e2e3d/artix7/timings/BRAM_L.sdf#L138-L147
|
|
||||||
|
|
||||||
module RAMB18E1 (
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
|
|
||||||
input CLKARDCLK,
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
|
|
||||||
input CLKBWRCLK,
|
|
||||||
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
|
|
||||||
input ENARDEN,
|
|
||||||
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
|
|
||||||
input ENBWREN,
|
|
||||||
input REGCEAREGCE,
|
|
||||||
input REGCEB,
|
|
||||||
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
|
|
||||||
input RSTRAMARSTRAM,
|
|
||||||
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
|
|
||||||
input RSTRAMB,
|
|
||||||
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
|
|
||||||
input RSTREGARSTREG,
|
|
||||||
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
|
|
||||||
input RSTREGB,
|
|
||||||
|
|
||||||
input [13:0] ADDRARDADDR,
|
|
||||||
input [13:0] ADDRBWRADDR,
|
|
||||||
input [15:0] DIADI,
|
|
||||||
input [15:0] DIBDI,
|
|
||||||
input [1:0] DIPADIP,
|
|
||||||
input [1:0] DIPBDIP,
|
|
||||||
input [1:0] WEA,
|
|
||||||
input [3:0] WEBWE,
|
|
||||||
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [15:0] DOADO,
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [15:0] DOBDO,
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [1:0] DOPADOP,
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [1:0] DOPBDOP
|
|
||||||
);
|
|
||||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter IS_CLKARDCLK_INVERTED = 1'b0;
|
|
||||||
parameter IS_CLKBWRCLK_INVERTED = 1'b0;
|
|
||||||
parameter IS_ENARDEN_INVERTED = 1'b0;
|
|
||||||
parameter IS_ENBWREN_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTRAMB_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTREGB_INVERTED = 1'b0;
|
|
||||||
|
|
||||||
parameter RAM_MODE = "TDP";
|
|
||||||
parameter integer DOA_REG = 0;
|
|
||||||
parameter integer DOB_REG = 0;
|
|
||||||
|
|
||||||
parameter integer READ_WIDTH_A = 0;
|
|
||||||
parameter integer READ_WIDTH_B = 0;
|
|
||||||
parameter integer WRITE_WIDTH_A = 0;
|
|
||||||
parameter integer WRITE_WIDTH_B = 0;
|
|
||||||
|
|
||||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
|
||||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
|
||||||
|
|
||||||
parameter SIM_DEVICE = "VIRTEX6";
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
module RAMB36E1 (
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
|
|
||||||
input CLKARDCLK,
|
|
||||||
(* clkbuf_sink *)
|
|
||||||
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
|
|
||||||
input CLKBWRCLK,
|
|
||||||
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
|
|
||||||
input ENARDEN,
|
|
||||||
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
|
|
||||||
input ENBWREN,
|
|
||||||
input REGCEAREGCE,
|
|
||||||
input REGCEB,
|
|
||||||
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
|
|
||||||
input RSTRAMARSTRAM,
|
|
||||||
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
|
|
||||||
input RSTRAMB,
|
|
||||||
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
|
|
||||||
input RSTREGARSTREG,
|
|
||||||
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
|
|
||||||
input RSTREGB,
|
|
||||||
|
|
||||||
input [15:0] ADDRARDADDR,
|
|
||||||
input [15:0] ADDRBWRADDR,
|
|
||||||
input [31:0] DIADI,
|
|
||||||
input [31:0] DIBDI,
|
|
||||||
input [3:0] DIPADIP,
|
|
||||||
input [3:0] DIPBDIP,
|
|
||||||
input [3:0] WEA,
|
|
||||||
input [7:0] WEBWE,
|
|
||||||
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [31:0] DOADO,
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [31:0] DOBDO,
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [3:0] DOPADOP,
|
|
||||||
(* abc9_arrival=2454 *)
|
|
||||||
output [3:0] DOPBDOP
|
|
||||||
);
|
|
||||||
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INITP_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_40 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_41 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_42 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_43 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_44 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_45 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_46 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_47 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_48 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_49 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_4A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_4B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_4C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_4D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_4E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_4F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_50 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_51 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_52 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_53 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_54 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_55 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_56 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_57 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_58 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_59 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_5A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_5B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_5C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_5D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_5E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_5F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_60 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_61 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_62 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_63 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_64 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_65 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_66 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_67 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_68 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_69 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_6A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_6B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_6C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_6D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_6E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_6F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_70 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_71 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_72 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_73 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_74 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_75 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_76 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_77 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_78 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_79 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_7A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_7B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_7C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_7D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_7E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
parameter INIT_7F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
|
||||||
|
|
||||||
parameter IS_CLKARDCLK_INVERTED = 1'b0;
|
|
||||||
parameter IS_CLKBWRCLK_INVERTED = 1'b0;
|
|
||||||
parameter IS_ENARDEN_INVERTED = 1'b0;
|
|
||||||
parameter IS_ENBWREN_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTRAMB_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
|
|
||||||
parameter IS_RSTREGB_INVERTED = 1'b0;
|
|
||||||
|
|
||||||
parameter RAM_MODE = "TDP";
|
|
||||||
parameter integer DOA_REG = 0;
|
|
||||||
parameter integer DOB_REG = 0;
|
|
||||||
|
|
||||||
parameter integer READ_WIDTH_A = 0;
|
|
||||||
parameter integer READ_WIDTH_B = 0;
|
|
||||||
parameter integer WRITE_WIDTH_A = 0;
|
|
||||||
parameter integer WRITE_WIDTH_B = 0;
|
|
||||||
|
|
||||||
parameter WRITE_MODE_A = "WRITE_FIRST";
|
|
||||||
parameter WRITE_MODE_B = "WRITE_FIRST";
|
|
||||||
|
|
||||||
parameter SIM_DEVICE = "VIRTEX6";
|
|
||||||
endmodule
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,384 @@
|
||||||
|
module \$__XILINX_RAMB36_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
|
parameter CLKPOL2 = 1;
|
||||||
|
parameter CLKPOL3 = 1;
|
||||||
|
parameter [36863:0] INIT = 36864'bx;
|
||||||
|
|
||||||
|
input CLK2;
|
||||||
|
input CLK3;
|
||||||
|
|
||||||
|
input [8:0] A1ADDR;
|
||||||
|
output [71:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
|
input [8:0] B1ADDR;
|
||||||
|
input [71:0] B1DATA;
|
||||||
|
input [7:0] B1EN;
|
||||||
|
|
||||||
|
wire [15:0] A1ADDR_16 = {A1ADDR, 6'b0};
|
||||||
|
wire [15:0] B1ADDR_16 = {B1ADDR, 6'b0};
|
||||||
|
|
||||||
|
wire [7:0] DIP, DOP;
|
||||||
|
wire [63:0] DI, DO;
|
||||||
|
|
||||||
|
assign A1DATA = { DOP[7], DO[63:56], DOP[6], DO[55:48], DOP[5], DO[47:40], DOP[4], DO[39:32],
|
||||||
|
DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||||
|
|
||||||
|
assign { DIP[7], DI[63:56], DIP[6], DI[55:48], DIP[5], DI[47:40], DIP[4], DI[39:32],
|
||||||
|
DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||||
|
|
||||||
|
RAMB36E2 #(
|
||||||
|
.READ_WIDTH_A(72),
|
||||||
|
.WRITE_WIDTH_B(72),
|
||||||
|
.WRITE_MODE_A("READ_FIRST"),
|
||||||
|
.WRITE_MODE_B("READ_FIRST"),
|
||||||
|
.DOA_REG(0),
|
||||||
|
.DOB_REG(0),
|
||||||
|
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||||
|
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||||
|
`include "brams_init_36.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.DOUTBDOUT(DO[63:32]),
|
||||||
|
.DOUTADOUT(DO[31:0]),
|
||||||
|
.DOUTPBDOUTP(DOP[7:4]),
|
||||||
|
.DOUTPADOUTP(DOP[3:0]),
|
||||||
|
.DINBDIN(DI[63:32]),
|
||||||
|
.DINADIN(DI[31:0]),
|
||||||
|
.DINPBDINP(DIP[7:4]),
|
||||||
|
.DINPADINP(DIP[3:0]),
|
||||||
|
|
||||||
|
.ADDRARDADDR(A1ADDR_16),
|
||||||
|
.CLKARDCLK(CLK2),
|
||||||
|
.ENARDEN(A1EN),
|
||||||
|
.ADDRENA(|1),
|
||||||
|
.REGCEAREGCE(|1),
|
||||||
|
.RSTRAMARSTRAM(|0),
|
||||||
|
.RSTREGARSTREG(|0),
|
||||||
|
.WEA(4'b0),
|
||||||
|
|
||||||
|
.ADDRBWRADDR(B1ADDR_16),
|
||||||
|
.CLKBWRCLK(CLK3),
|
||||||
|
.ENBWREN(|1),
|
||||||
|
.ADDRENB(|1),
|
||||||
|
.REGCEB(|1),
|
||||||
|
.RSTRAMB(|0),
|
||||||
|
.RSTREGB(|0),
|
||||||
|
.WEBWE(B1EN),
|
||||||
|
|
||||||
|
.SLEEP(|0)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module \$__XILINX_RAMB18_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
|
parameter CLKPOL2 = 1;
|
||||||
|
parameter CLKPOL3 = 1;
|
||||||
|
parameter [18431:0] INIT = 18432'bx;
|
||||||
|
|
||||||
|
input CLK2;
|
||||||
|
input CLK3;
|
||||||
|
|
||||||
|
input [8:0] A1ADDR;
|
||||||
|
output [35:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
|
input [8:0] B1ADDR;
|
||||||
|
input [35:0] B1DATA;
|
||||||
|
input [3:0] B1EN;
|
||||||
|
|
||||||
|
wire [13:0] A1ADDR_14 = {A1ADDR, 5'b0};
|
||||||
|
wire [13:0] B1ADDR_14 = {B1ADDR, 5'b0};
|
||||||
|
|
||||||
|
wire [3:0] DIP, DOP;
|
||||||
|
wire [31:0] DI, DO;
|
||||||
|
|
||||||
|
assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||||
|
assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||||
|
|
||||||
|
RAMB18E2 #(
|
||||||
|
.READ_WIDTH_A(36),
|
||||||
|
.WRITE_WIDTH_B(36),
|
||||||
|
.WRITE_MODE_A("READ_FIRST"),
|
||||||
|
.WRITE_MODE_B("READ_FIRST"),
|
||||||
|
.DOA_REG(0),
|
||||||
|
.DOB_REG(0),
|
||||||
|
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||||
|
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||||
|
`include "brams_init_18.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.DOUTBDOUT(DO[31:16]),
|
||||||
|
.DOUTADOUT(DO[15:0]),
|
||||||
|
.DOUTPBDOUTP(DOP[3:2]),
|
||||||
|
.DOUTPADOUTP(DOP[1:0]),
|
||||||
|
.DINBDIN(DI[31:16]),
|
||||||
|
.DINADIN(DI[15:0]),
|
||||||
|
.DINPBDINP(DIP[3:2]),
|
||||||
|
.DINPADINP(DIP[1:0]),
|
||||||
|
|
||||||
|
.ADDRARDADDR(A1ADDR_14),
|
||||||
|
.CLKARDCLK(CLK2),
|
||||||
|
.ENARDEN(A1EN),
|
||||||
|
.ADDRENA(|1),
|
||||||
|
.REGCEAREGCE(|1),
|
||||||
|
.RSTRAMARSTRAM(|0),
|
||||||
|
.RSTREGARSTREG(|0),
|
||||||
|
.WEA(2'b0),
|
||||||
|
|
||||||
|
.ADDRBWRADDR(B1ADDR_14),
|
||||||
|
.CLKBWRCLK(CLK3),
|
||||||
|
.ENBWREN(|1),
|
||||||
|
.ADDRENB(|1),
|
||||||
|
.REGCEB(|1),
|
||||||
|
.RSTRAMB(|0),
|
||||||
|
.RSTREGB(|0),
|
||||||
|
.WEBWE(B1EN),
|
||||||
|
|
||||||
|
.SLEEP(|0)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module \$__XILINX_RAMB36_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
|
parameter CFG_ABITS = 10;
|
||||||
|
parameter CFG_DBITS = 36;
|
||||||
|
parameter CFG_ENABLE_B = 4;
|
||||||
|
|
||||||
|
parameter CLKPOL2 = 1;
|
||||||
|
parameter CLKPOL3 = 1;
|
||||||
|
parameter [36863:0] INIT = 36864'bx;
|
||||||
|
|
||||||
|
input CLK2;
|
||||||
|
input CLK3;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] A1ADDR;
|
||||||
|
output [CFG_DBITS-1:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] B1ADDR;
|
||||||
|
input [CFG_DBITS-1:0] B1DATA;
|
||||||
|
input [CFG_ENABLE_B-1:0] B1EN;
|
||||||
|
|
||||||
|
wire [15:0] A1ADDR_16 = A1ADDR << (15 - CFG_ABITS);
|
||||||
|
wire [15:0] B1ADDR_16 = B1ADDR << (15 - CFG_ABITS);
|
||||||
|
wire [7:0] B1EN_8 = B1EN;
|
||||||
|
|
||||||
|
wire [3:0] DIP, DOP;
|
||||||
|
wire [31:0] DI, DO;
|
||||||
|
|
||||||
|
wire [31:0] DOBDO;
|
||||||
|
wire [3:0] DOPBDOP;
|
||||||
|
|
||||||
|
assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||||
|
assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||||
|
|
||||||
|
generate if (CFG_DBITS > 8) begin
|
||||||
|
RAMB36E2 #(
|
||||||
|
.READ_WIDTH_A(CFG_DBITS),
|
||||||
|
.READ_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_A(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_MODE_A("READ_FIRST"),
|
||||||
|
.WRITE_MODE_B("READ_FIRST"),
|
||||||
|
.DOA_REG(0),
|
||||||
|
.DOB_REG(0),
|
||||||
|
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||||
|
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||||
|
`include "brams_init_36.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.DINADIN(32'hFFFFFFFF),
|
||||||
|
.DINPADINP(4'hF),
|
||||||
|
.DOUTADOUT(DO[31:0]),
|
||||||
|
.DOUTPADOUTP(DOP[3:0]),
|
||||||
|
.ADDRARDADDR(A1ADDR_16),
|
||||||
|
.CLKARDCLK(CLK2),
|
||||||
|
.ENARDEN(A1EN),
|
||||||
|
.ADDRENA(|1),
|
||||||
|
.REGCEAREGCE(|1),
|
||||||
|
.RSTRAMARSTRAM(|0),
|
||||||
|
.RSTREGARSTREG(|0),
|
||||||
|
.WEA(4'b0),
|
||||||
|
|
||||||
|
.DINBDIN(DI),
|
||||||
|
.DINPBDINP(DIP),
|
||||||
|
.DOUTBDOUT(DOBDO),
|
||||||
|
.DOUTPBDOUTP(DOPBDOP),
|
||||||
|
.ADDRBWRADDR(B1ADDR_16),
|
||||||
|
.CLKBWRCLK(CLK3),
|
||||||
|
.ENBWREN(|1),
|
||||||
|
.ADDRENB(|1),
|
||||||
|
.REGCEB(|0),
|
||||||
|
.RSTRAMB(|0),
|
||||||
|
.RSTREGB(|0),
|
||||||
|
.WEBWE(B1EN_8),
|
||||||
|
|
||||||
|
.SLEEP(|0)
|
||||||
|
);
|
||||||
|
end else begin
|
||||||
|
RAMB36E2 #(
|
||||||
|
.READ_WIDTH_A(CFG_DBITS),
|
||||||
|
.READ_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_A(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_MODE_A("READ_FIRST"),
|
||||||
|
.WRITE_MODE_B("READ_FIRST"),
|
||||||
|
.DOA_REG(0),
|
||||||
|
.DOB_REG(0),
|
||||||
|
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||||
|
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||||
|
`include "brams_init_32.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.DINADIN(32'hFFFFFFFF),
|
||||||
|
.DINPADINP(4'hF),
|
||||||
|
.DOUTADOUT(DO[31:0]),
|
||||||
|
.DOUTPADOUTP(DOP[3:0]),
|
||||||
|
.ADDRARDADDR(A1ADDR_16),
|
||||||
|
.CLKARDCLK(CLK2),
|
||||||
|
.ENARDEN(A1EN),
|
||||||
|
.ADDRENA(|1),
|
||||||
|
.REGCEAREGCE(|1),
|
||||||
|
.RSTRAMARSTRAM(|0),
|
||||||
|
.RSTREGARSTREG(|0),
|
||||||
|
.WEA(4'b0),
|
||||||
|
|
||||||
|
.DINBDIN(DI),
|
||||||
|
.DINPBDINP(DIP),
|
||||||
|
.DOUTBDOUT(DOBDO),
|
||||||
|
.DOUTPBDOUTP(DOPBDOP),
|
||||||
|
.ADDRBWRADDR(B1ADDR_16),
|
||||||
|
.CLKBWRCLK(CLK3),
|
||||||
|
.ENBWREN(|1),
|
||||||
|
.ADDRENB(|1),
|
||||||
|
.REGCEB(|0),
|
||||||
|
.RSTRAMB(|0),
|
||||||
|
.RSTREGB(|0),
|
||||||
|
.WEBWE(B1EN_8),
|
||||||
|
|
||||||
|
.SLEEP(|0)
|
||||||
|
);
|
||||||
|
end endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module \$__XILINX_RAMB18_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
|
parameter CFG_ABITS = 10;
|
||||||
|
parameter CFG_DBITS = 18;
|
||||||
|
parameter CFG_ENABLE_B = 2;
|
||||||
|
|
||||||
|
parameter CLKPOL2 = 1;
|
||||||
|
parameter CLKPOL3 = 1;
|
||||||
|
parameter [18431:0] INIT = 18432'bx;
|
||||||
|
|
||||||
|
input CLK2;
|
||||||
|
input CLK3;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] A1ADDR;
|
||||||
|
output [CFG_DBITS-1:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] B1ADDR;
|
||||||
|
input [CFG_DBITS-1:0] B1DATA;
|
||||||
|
input [CFG_ENABLE_B-1:0] B1EN;
|
||||||
|
|
||||||
|
wire [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS);
|
||||||
|
wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS);
|
||||||
|
wire [3:0] B1EN_4 = B1EN;
|
||||||
|
|
||||||
|
wire [1:0] DIP, DOP;
|
||||||
|
wire [15:0] DI, DO;
|
||||||
|
|
||||||
|
wire [15:0] DOBDO;
|
||||||
|
wire [1:0] DOPBDOP;
|
||||||
|
|
||||||
|
assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
|
||||||
|
assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
|
||||||
|
|
||||||
|
generate if (CFG_DBITS > 8) begin
|
||||||
|
RAMB18E2 #(
|
||||||
|
.READ_WIDTH_A(CFG_DBITS),
|
||||||
|
.READ_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_A(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_MODE_A("READ_FIRST"),
|
||||||
|
.WRITE_MODE_B("READ_FIRST"),
|
||||||
|
.DOA_REG(0),
|
||||||
|
.DOB_REG(0),
|
||||||
|
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||||
|
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||||
|
`include "brams_init_18.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.DINADIN(16'hFFFF),
|
||||||
|
.DINPADINP(2'b11),
|
||||||
|
.DOUTADOUT(DO),
|
||||||
|
.DOUTPADOUTP(DOP),
|
||||||
|
.ADDRARDADDR(A1ADDR_14),
|
||||||
|
.CLKARDCLK(CLK2),
|
||||||
|
.ENARDEN(A1EN),
|
||||||
|
.ADDRENA(|1),
|
||||||
|
.REGCEAREGCE(|1),
|
||||||
|
.RSTRAMARSTRAM(|0),
|
||||||
|
.RSTREGARSTREG(|0),
|
||||||
|
.WEA(2'b0),
|
||||||
|
|
||||||
|
.DINBDIN(DI),
|
||||||
|
.DINPBDINP(DIP),
|
||||||
|
.DOUTBDOUT(DOBDO),
|
||||||
|
.DOUTPBDOUTP(DOPBDOP),
|
||||||
|
.ADDRBWRADDR(B1ADDR_14),
|
||||||
|
.CLKBWRCLK(CLK3),
|
||||||
|
.ENBWREN(|1),
|
||||||
|
.ADDRENB(|1),
|
||||||
|
.REGCEB(|0),
|
||||||
|
.RSTRAMB(|0),
|
||||||
|
.RSTREGB(|0),
|
||||||
|
.WEBWE(B1EN_4),
|
||||||
|
|
||||||
|
.SLEEP(|0)
|
||||||
|
);
|
||||||
|
end else begin
|
||||||
|
RAMB18E2 #(
|
||||||
|
//.RAM_MODE("TDP"),
|
||||||
|
.READ_WIDTH_A(CFG_DBITS),
|
||||||
|
.READ_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_A(CFG_DBITS),
|
||||||
|
.WRITE_WIDTH_B(CFG_DBITS),
|
||||||
|
.WRITE_MODE_A("READ_FIRST"),
|
||||||
|
.WRITE_MODE_B("READ_FIRST"),
|
||||||
|
.DOA_REG(0),
|
||||||
|
.DOB_REG(0),
|
||||||
|
.IS_CLKARDCLK_INVERTED(!CLKPOL2),
|
||||||
|
.IS_CLKBWRCLK_INVERTED(!CLKPOL3),
|
||||||
|
`include "brams_init_16.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.DINADIN(16'hFFFF),
|
||||||
|
.DINPADINP(2'b11),
|
||||||
|
.DOUTADOUT(DO),
|
||||||
|
.DOUTPADOUTP(DOP),
|
||||||
|
.ADDRARDADDR(A1ADDR_14),
|
||||||
|
.CLKARDCLK(CLK2),
|
||||||
|
.ENARDEN(A1EN),
|
||||||
|
.ADDRENA(|1),
|
||||||
|
.REGCEAREGCE(|1),
|
||||||
|
.RSTRAMARSTRAM(|0),
|
||||||
|
.RSTREGARSTREG(|0),
|
||||||
|
.WEA(2'b0),
|
||||||
|
|
||||||
|
.DINBDIN(DI),
|
||||||
|
.DINPBDINP(DIP),
|
||||||
|
.DOUTBDOUT(DOBDO),
|
||||||
|
.DOUTPBDOUTP(DOPBDOP),
|
||||||
|
.ADDRBWRADDR(B1ADDR_14),
|
||||||
|
.CLKBWRCLK(CLK3),
|
||||||
|
.ENBWREN(|1),
|
||||||
|
.ADDRENB(|1),
|
||||||
|
.REGCEB(|0),
|
||||||
|
.RSTRAMB(|0),
|
||||||
|
.RSTREGB(|0),
|
||||||
|
.WEBWE(B1EN_4),
|
||||||
|
|
||||||
|
.SLEEP(|0)
|
||||||
|
);
|
||||||
|
end endgenerate
|
||||||
|
endmodule
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,51 @@
|
||||||
|
module \$__MUL27X18 (input [26:0] A, input [17:0] B, output [44:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [47:0] P_48;
|
||||||
|
DSP48E2 #(
|
||||||
|
// Disable all registers
|
||||||
|
.ACASCREG(0),
|
||||||
|
.ADREG(0),
|
||||||
|
.A_INPUT("DIRECT"),
|
||||||
|
.ALUMODEREG(0),
|
||||||
|
.AREG(0),
|
||||||
|
.BCASCREG(0),
|
||||||
|
.B_INPUT("DIRECT"),
|
||||||
|
.BREG(0),
|
||||||
|
.CARRYINREG(0),
|
||||||
|
.CARRYINSELREG(0),
|
||||||
|
.CREG(0),
|
||||||
|
.DREG(0),
|
||||||
|
.INMODEREG(0),
|
||||||
|
.MREG(0),
|
||||||
|
.OPMODEREG(0),
|
||||||
|
.PREG(0),
|
||||||
|
.USE_MULT("MULTIPLY"),
|
||||||
|
.USE_SIMD("ONE48"),
|
||||||
|
.AMULTSEL("A"),
|
||||||
|
.BMULTSEL("B")
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
//Data path
|
||||||
|
.A({{3{A[26]}}, A}),
|
||||||
|
.B(B),
|
||||||
|
.C(48'b0),
|
||||||
|
.D(27'b0),
|
||||||
|
.P(P_48),
|
||||||
|
|
||||||
|
.INMODE(5'b00000),
|
||||||
|
.ALUMODE(4'b0000),
|
||||||
|
.OPMODE(9'b00000101),
|
||||||
|
.CARRYINSEL(3'b000),
|
||||||
|
|
||||||
|
.ACIN(30'b0),
|
||||||
|
.BCIN(18'b0),
|
||||||
|
.PCIN(48'b0),
|
||||||
|
.CARRYIN(1'b0)
|
||||||
|
);
|
||||||
|
assign Y = P_48;
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
bram $__XILINX_URAM288
|
||||||
|
init 0
|
||||||
|
abits 12
|
||||||
|
dbits 72
|
||||||
|
groups 2
|
||||||
|
ports 1 1
|
||||||
|
wrmode 0 1
|
||||||
|
enable 1 9
|
||||||
|
transp 0 0
|
||||||
|
clocks 2 2
|
||||||
|
clkpol 2 2
|
||||||
|
endbram
|
||||||
|
|
||||||
|
match $__XILINX_URAM288
|
||||||
|
min bits 131072
|
||||||
|
min efficiency 15
|
||||||
|
shuffle_enable B
|
||||||
|
make_transp
|
||||||
|
endmatch
|
|
@ -0,0 +1,47 @@
|
||||||
|
module \$__XILINX_URAM288 (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
|
parameter CLKPOL2 = 1;
|
||||||
|
|
||||||
|
input CLK2;
|
||||||
|
|
||||||
|
input [11:0] A1ADDR;
|
||||||
|
output [71:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
|
input [11:0] B1ADDR;
|
||||||
|
input [71:0] B1DATA;
|
||||||
|
input [8:0] B1EN;
|
||||||
|
|
||||||
|
|
||||||
|
URAM288 #(
|
||||||
|
.BWE_MODE_A("PARITY_INDEPENDENT"),
|
||||||
|
.BWE_MODE_B("PARITY_INDEPENDENT"),
|
||||||
|
.EN_AUTO_SLEEP_MODE("FALSE"),
|
||||||
|
.IREG_PRE_A("FALSE"),
|
||||||
|
.IREG_PRE_B("FALSE"),
|
||||||
|
.IS_CLK_INVERTED(!CLKPOL2),
|
||||||
|
.OREG_A("FALSE"),
|
||||||
|
.OREG_B("FALSE")
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.ADDR_A({11'b0, A1ADDR}),
|
||||||
|
.BWE_A(9'b0),
|
||||||
|
.DIN_A(72'b0),
|
||||||
|
.EN_A(A1EN),
|
||||||
|
.RDB_WR_A(1'b0),
|
||||||
|
.INJECT_DBITERR_A(1'b0),
|
||||||
|
.INJECT_SBITERR_A(1'b0),
|
||||||
|
.RST_A(1'b0),
|
||||||
|
.DOUT_A(A1DATA),
|
||||||
|
|
||||||
|
.ADDR_B({11'b0, B1ADDR}),
|
||||||
|
.BWE_B(B1EN),
|
||||||
|
.DIN_B(B1DATA),
|
||||||
|
.EN_B(|B1EN),
|
||||||
|
.RDB_WR_B(1'b1),
|
||||||
|
.INJECT_DBITERR_B(1'b0),
|
||||||
|
.INJECT_SBITERR_B(1'b0),
|
||||||
|
.RST_B(1'b0),
|
||||||
|
|
||||||
|
.CLK(CLK2),
|
||||||
|
.SLEEP(1'b0)
|
||||||
|
);
|
||||||
|
endmodule
|
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog ../common/add_sub.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # 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:AL_MAP_ADDER
|
||||||
|
select -assert-count 4 t:AL_MAP_LUT1
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT1 t:AL_MAP_ADDER %% t:* %D
|
|
@ -0,0 +1,11 @@
|
||||||
|
read_verilog ../common/counter.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
flatten
|
||||||
|
equiv_opt -map +/anlogic/cells_sim.v synth_anlogic # 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:AL_MAP_ADDER
|
||||||
|
select -assert-count 8 t:AL_MAP_SEQ
|
||||||
|
select -assert-none t:AL_MAP_SEQ t:AL_MAP_ADDER %% t:* %D
|
|
@ -0,0 +1,20 @@
|
||||||
|
read_verilog ../common/dffs.v
|
||||||
|
design -save read
|
||||||
|
|
||||||
|
hierarchy -top dff
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # 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:AL_MAP_SEQ
|
||||||
|
select -assert-none t:AL_MAP_SEQ %% t:* %D
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top dffe
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd dffe # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT3
|
||||||
|
select -assert-count 1 t:AL_MAP_SEQ
|
||||||
|
select -assert-none t:AL_MAP_LUT3 t:AL_MAP_SEQ %% t:* %D
|
|
@ -0,0 +1,18 @@
|
||||||
|
read_verilog ../common/fsm.v
|
||||||
|
hierarchy -top fsm
|
||||||
|
proc
|
||||||
|
flatten
|
||||||
|
|
||||||
|
equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
|
||||||
|
miter -equiv -make_assert -flatten gold gate miter
|
||||||
|
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
|
||||||
|
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd fsm # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT2
|
||||||
|
select -assert-count 5 t:AL_MAP_LUT5
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT6
|
||||||
|
select -assert-count 6 t:AL_MAP_SEQ
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT5 t:AL_MAP_LUT6 t:AL_MAP_SEQ %% t:* %D
|
|
@ -0,0 +1,33 @@
|
||||||
|
read_verilog ../common/latches.v
|
||||||
|
design -save read
|
||||||
|
|
||||||
|
hierarchy -top latchp
|
||||||
|
proc
|
||||||
|
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||||
|
synth_anlogic
|
||||||
|
cd latchp # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT3
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT3 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top latchn
|
||||||
|
proc
|
||||||
|
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||||
|
synth_anlogic
|
||||||
|
cd latchn # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT3
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT3 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top latchsr
|
||||||
|
proc
|
||||||
|
# Can't run any sort of equivalence check because latches are blown to LUTs
|
||||||
|
synth_anlogic
|
||||||
|
cd latchsr # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT5
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT5 %% t:* %D
|
|
@ -0,0 +1,11 @@
|
||||||
|
read_verilog ../common/logic.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd top # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT1
|
||||||
|
select -assert-count 6 t:AL_MAP_LUT2
|
||||||
|
select -assert-count 2 t:AL_MAP_LUT4
|
||||||
|
select -assert-none t:AL_MAP_LUT1 t:AL_MAP_LUT2 t:AL_MAP_LUT4 %% t:* %D
|
|
@ -0,0 +1,21 @@
|
||||||
|
read_verilog ../common/memory.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
#ERROR: Failed to import cell gate.mem.0.0.0 (type EG_LOGIC_DRAM16X4) to SAT database.
|
||||||
|
#sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd top
|
||||||
|
|
||||||
|
select -assert-count 8 t:AL_MAP_LUT2
|
||||||
|
select -assert-count 8 t:AL_MAP_LUT4
|
||||||
|
select -assert-count 8 t:AL_MAP_LUT5
|
||||||
|
select -assert-count 36 t:AL_MAP_SEQ
|
||||||
|
select -assert-count 8 t:EG_LOGIC_DRAM16X4 #Why not AL_LOGIC_BRAM?
|
||||||
|
select -assert-none t:AL_MAP_LUT2 t:AL_MAP_LUT4 t:AL_MAP_LUT5 t:AL_MAP_SEQ t:EG_LOGIC_DRAM16X4 %% t:* %D
|
|
@ -0,0 +1,42 @@
|
||||||
|
read_verilog ../common/mux.v
|
||||||
|
design -save read
|
||||||
|
|
||||||
|
hierarchy -top mux2
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # 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:AL_MAP_LUT3
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT3 %% t:* %D
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top mux4
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd mux4 # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT6
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT6 %% t:* %D
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top mux8
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # 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 3 t:AL_MAP_LUT4
|
||||||
|
select -assert-count 1 t:AL_MAP_LUT6
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT4 t:AL_MAP_LUT6 %% t:* %D
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top mux16
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd mux16 # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 5 t:AL_MAP_LUT6
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_LUT6 %% t:* %D
|
|
@ -6,7 +6,7 @@ for x in *.ys; do
|
||||||
echo "all:: run-$x"
|
echo "all:: run-$x"
|
||||||
echo "run-$x:"
|
echo "run-$x:"
|
||||||
echo " @echo 'Running $x..'"
|
echo " @echo 'Running $x..'"
|
||||||
echo " @../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x"
|
echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x"
|
||||||
done
|
done
|
||||||
for s in *.sh; do
|
for s in *.sh; do
|
||||||
if [ "$s" != "run-test.sh" ]; then
|
if [ "$s" != "run-test.sh" ]; then
|
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog ../common/shifter.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
flatten
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd top # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 8 t:AL_MAP_SEQ
|
||||||
|
|
||||||
|
select -assert-none t:AL_MAP_SEQ %% t:* %D
|
|
@ -0,0 +1,9 @@
|
||||||
|
read_verilog ../common/tribuf.v
|
||||||
|
hierarchy -top tristate
|
||||||
|
proc
|
||||||
|
flatten
|
||||||
|
equiv_opt -assert -map +/anlogic/cells_sim.v -map +/simcells.v synth_anlogic # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd tristate # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:$_TBUF_
|
||||||
|
select -assert-none t:$_TBUF_ %% t:* %D
|
|
@ -0,0 +1,12 @@
|
||||||
|
module top
|
||||||
|
(
|
||||||
|
input [3:0] x,
|
||||||
|
input [3:0] y,
|
||||||
|
|
||||||
|
output [3:0] A,
|
||||||
|
output [3:0] B
|
||||||
|
);
|
||||||
|
|
||||||
|
assign A = x + y;
|
||||||
|
assign B = x - y;
|
||||||
|
endmodule
|
|
@ -0,0 +1,43 @@
|
||||||
|
module adff( input d, clk, clr, output reg q );
|
||||||
|
initial begin
|
||||||
|
q = 0;
|
||||||
|
end
|
||||||
|
always @( posedge clk, posedge clr )
|
||||||
|
if ( clr )
|
||||||
|
q <= 1'b0;
|
||||||
|
else
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module adffn( input d, clk, clr, output reg q );
|
||||||
|
initial begin
|
||||||
|
q = 0;
|
||||||
|
end
|
||||||
|
always @( posedge clk, negedge clr )
|
||||||
|
if ( !clr )
|
||||||
|
q <= 1'b0;
|
||||||
|
else
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module dffs( input d, clk, pre, clr, output reg q );
|
||||||
|
initial begin
|
||||||
|
q = 0;
|
||||||
|
end
|
||||||
|
always @( posedge clk )
|
||||||
|
if ( pre )
|
||||||
|
q <= 1'b1;
|
||||||
|
else
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module ndffnr( input d, clk, pre, clr, output reg q );
|
||||||
|
initial begin
|
||||||
|
q = 0;
|
||||||
|
end
|
||||||
|
always @( negedge clk )
|
||||||
|
if ( !clr )
|
||||||
|
q <= 1'b0;
|
||||||
|
else
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
|
@ -0,0 +1,11 @@
|
||||||
|
module top ( out, clk, reset );
|
||||||
|
output [7:0] out;
|
||||||
|
input clk, reset;
|
||||||
|
reg [7:0] out;
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset)
|
||||||
|
if (reset)
|
||||||
|
out <= 8'b0;
|
||||||
|
else
|
||||||
|
out <= out + 1;
|
||||||
|
endmodule
|
|
@ -0,0 +1,13 @@
|
||||||
|
module dff ( input d, clk, output reg q );
|
||||||
|
always @( posedge clk )
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module dffe( input d, clk, en, output reg q );
|
||||||
|
initial begin
|
||||||
|
q = 0;
|
||||||
|
end
|
||||||
|
always @( posedge clk )
|
||||||
|
if ( en )
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
|
@ -0,0 +1,51 @@
|
||||||
|
module fsm ( clock, reset, req_0, req_1, gnt_0, gnt_1 );
|
||||||
|
input clock,reset,req_0,req_1;
|
||||||
|
output gnt_0,gnt_1;
|
||||||
|
wire clock,reset,req_0,req_1;
|
||||||
|
reg gnt_0,gnt_1;
|
||||||
|
|
||||||
|
parameter SIZE = 3;
|
||||||
|
parameter IDLE = 3'b001;
|
||||||
|
parameter GNT0 = 3'b010;
|
||||||
|
parameter GNT1 = 3'b100;
|
||||||
|
parameter GNT2 = 3'b101;
|
||||||
|
|
||||||
|
reg [SIZE-1:0] state;
|
||||||
|
reg [SIZE-1:0] next_state;
|
||||||
|
|
||||||
|
always @ (posedge clock)
|
||||||
|
begin : FSM
|
||||||
|
if (reset == 1'b1) begin
|
||||||
|
state <= #1 IDLE;
|
||||||
|
gnt_0 <= 0;
|
||||||
|
gnt_1 <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
case(state)
|
||||||
|
IDLE : if (req_0 == 1'b1) begin
|
||||||
|
state <= #1 GNT0;
|
||||||
|
gnt_0 <= 1;
|
||||||
|
end else if (req_1 == 1'b1) begin
|
||||||
|
gnt_1 <= 1;
|
||||||
|
state <= #1 GNT0;
|
||||||
|
end else begin
|
||||||
|
state <= #1 IDLE;
|
||||||
|
end
|
||||||
|
GNT0 : if (req_0 == 1'b1) begin
|
||||||
|
state <= #1 GNT0;
|
||||||
|
end else begin
|
||||||
|
gnt_0 <= 0;
|
||||||
|
state <= #1 IDLE;
|
||||||
|
end
|
||||||
|
GNT1 : if (req_1 == 1'b1) begin
|
||||||
|
state <= #1 GNT2;
|
||||||
|
gnt_1 <= req_0;
|
||||||
|
end
|
||||||
|
GNT2 : if (req_0 == 1'b1) begin
|
||||||
|
state <= #1 GNT1;
|
||||||
|
gnt_1 <= req_1;
|
||||||
|
end
|
||||||
|
default : state <= #1 IDLE;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,21 @@
|
||||||
|
module latchp ( input d, clk, en, output reg q );
|
||||||
|
always @*
|
||||||
|
if ( en )
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module latchn ( input d, clk, en, output reg q );
|
||||||
|
always @*
|
||||||
|
if ( !en )
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module latchsr ( input d, clk, en, clr, pre, output reg q );
|
||||||
|
always @*
|
||||||
|
if ( clr )
|
||||||
|
q <= 1'b0;
|
||||||
|
else if ( pre )
|
||||||
|
q <= 1'b1;
|
||||||
|
else if ( en )
|
||||||
|
q <= d;
|
||||||
|
endmodule
|
|
@ -0,0 +1,16 @@
|
||||||
|
module top
|
||||||
|
(
|
||||||
|
input [0:7] in,
|
||||||
|
output B1,B2,B3,B4,B5,B6,B7,B8,B9,B10
|
||||||
|
);
|
||||||
|
assign B1 = in[0] & in[1];
|
||||||
|
assign B2 = in[0] | in[1];
|
||||||
|
assign B3 = in[0] ~& in[1];
|
||||||
|
assign B4 = in[0] ~| in[1];
|
||||||
|
assign B5 = in[0] ^ in[1];
|
||||||
|
assign B6 = in[0] ~^ in[1];
|
||||||
|
assign B7 = ~in[0];
|
||||||
|
assign B8 = in[0];
|
||||||
|
assign B9 = in[0:1] && in [2:3];
|
||||||
|
assign B10 = in[0:1] || in [2:3];
|
||||||
|
endmodule
|
|
@ -0,0 +1,9 @@
|
||||||
|
module top
|
||||||
|
(
|
||||||
|
input [5:0] x,
|
||||||
|
input [5:0] y,
|
||||||
|
|
||||||
|
output [11:0] A,
|
||||||
|
);
|
||||||
|
assign A = x * y;
|
||||||
|
endmodule
|
|
@ -0,0 +1,60 @@
|
||||||
|
module mux2 (S,A,B,Y);
|
||||||
|
input S;
|
||||||
|
input A,B;
|
||||||
|
output reg Y;
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
Y = (S)? B : A;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux4 ( S, D, Y );
|
||||||
|
input[1:0] S;
|
||||||
|
input[3:0] D;
|
||||||
|
output Y;
|
||||||
|
|
||||||
|
reg Y;
|
||||||
|
wire[1:0] S;
|
||||||
|
wire[3:0] D;
|
||||||
|
|
||||||
|
always @*
|
||||||
|
begin
|
||||||
|
case( S )
|
||||||
|
0 : Y = D[0];
|
||||||
|
1 : Y = D[1];
|
||||||
|
2 : Y = D[2];
|
||||||
|
3 : Y = D[3];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux8 ( S, D, Y );
|
||||||
|
input[2:0] S;
|
||||||
|
input[7:0] D;
|
||||||
|
output Y;
|
||||||
|
|
||||||
|
reg Y;
|
||||||
|
wire[2:0] S;
|
||||||
|
wire[7:0] D;
|
||||||
|
|
||||||
|
always @*
|
||||||
|
begin
|
||||||
|
case( S )
|
||||||
|
0 : Y = D[0];
|
||||||
|
1 : Y = D[1];
|
||||||
|
2 : Y = D[2];
|
||||||
|
3 : Y = D[3];
|
||||||
|
4 : Y = D[4];
|
||||||
|
5 : Y = D[5];
|
||||||
|
6 : Y = D[6];
|
||||||
|
7 : Y = D[7];
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module mux16 (D, S, Y);
|
||||||
|
input [15:0] D;
|
||||||
|
input [3:0] S;
|
||||||
|
output Y;
|
||||||
|
|
||||||
|
assign Y = D[S];
|
||||||
|
endmodule
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue