mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'origin/master' into eddie/xilinx_srl
This commit is contained in:
commit
ba5d81c7f1
|
@ -26,6 +26,11 @@ Yosys 0.9 .. Yosys 0.9-dev
|
|||
- Added automatic gzip compression (based on filename extension) for backends
|
||||
- Improve attribute and parameter encoding in JSON to avoid ambiguities between
|
||||
bit vectors and strings containing [01xz]*
|
||||
- Added "clkbufmap" pass
|
||||
- Added "synth_xilinx -family xc6s" for Spartan 6 support (experimental)
|
||||
- Added "synth_xilinx -ise" (experimental)
|
||||
- Added "synth_xilinx -iopad"
|
||||
- "synth_xilinx" now automatically inserts clock buffers (add -noclkbuf to disable)
|
||||
- Improvements in pmgen: subpattern and recursive matches
|
||||
- Added "opt_share" pass, run as part of "opt -full"
|
||||
- Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping
|
||||
|
|
|
@ -390,6 +390,7 @@ Finally run all tests with "make config-{clang,gcc,gcc-4.8}":
|
|||
Release:
|
||||
|
||||
- set YOSYS_VER to x.y.z in Makefile
|
||||
- remove "bumpversion" target from Makefile
|
||||
- update version string in CHANGELOG
|
||||
git commit -am "Yosys x.y.z"
|
||||
|
||||
|
|
3
Makefile
3
Makefile
|
@ -119,6 +119,9 @@ YOSYS_VER := 0.9+1
|
|||
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
|
||||
OBJS = kernel/version_$(GIT_REV).o
|
||||
|
||||
bumpversion:
|
||||
sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 8a4c6e6.. | wc -l`/;" Makefile
|
||||
|
||||
# set 'ABCREV = default' to use abc/ as it is
|
||||
#
|
||||
# Note: If you do ABC development, make sure that 'abc' in this directory
|
||||
|
|
15
README.md
15
README.md
|
@ -332,6 +332,21 @@ Verilog Attributes and non-standard features
|
|||
that represent module parameters or localparams (when the HDL front-end
|
||||
is run in -pwires mode).
|
||||
|
||||
- The ``clkbuf_driver`` attribute can be set on an output port of a blackbox
|
||||
module to mark it as a clock buffer output, and thus prevent ``clkbufmap``
|
||||
from inserting another clock buffer on a net driven by such output.
|
||||
|
||||
- The ``clkbuf_sink`` attribute can be set on an input port of a module to
|
||||
request clock buffer insertion by the ``clkbufmap`` pass.
|
||||
|
||||
- The ``clkbuf_inhibit`` is the default attribute to set on a wire to prevent
|
||||
automatic clock buffer insertion by ``clkbufmap``. This behaviour can be
|
||||
overridden by providing a custom selection to ``clkbufmap``.
|
||||
|
||||
- The ``iopad_external_pin`` attribute on a blackbox module's port marks
|
||||
it as the external-facing pin of an I/O pad, and prevents ``iopadmap``
|
||||
from inserting another pad cell on it.
|
||||
|
||||
- In addition to the ``(* ... *)`` attribute syntax, Yosys supports
|
||||
the non-standard ``{* ... *}`` attribute syntax to set default attributes
|
||||
for everything that comes after the ``{* ... *}`` statement. (Reset
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
read_verilog example.v
|
||||
synth_xilinx -top example -family xc6s
|
||||
iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I
|
||||
synth_xilinx -top example -family xc6s -ise
|
||||
write_edif -pvector bra example.edif
|
||||
|
|
|
@ -268,7 +268,7 @@ struct SatHelper
|
|||
RTLIL::SigSpec removed_bits;
|
||||
for (int i = 0; i < lhs.size(); i++) {
|
||||
RTLIL::SigSpec bit = lhs.extract(i, 1);
|
||||
if (!satgen.initial_state.check_all(bit)) {
|
||||
if (rhs[i] == State::Sx || !satgen.initial_state.check_all(bit)) {
|
||||
removed_bits.append(bit);
|
||||
lhs.remove(i, 1);
|
||||
rhs.remove(i, 1);
|
||||
|
|
|
@ -16,6 +16,7 @@ endif
|
|||
|
||||
ifneq ($(SMALL),1)
|
||||
OBJS += passes/techmap/iopadmap.o
|
||||
OBJS += passes/techmap/clkbufmap.o
|
||||
OBJS += passes/techmap/hilomap.o
|
||||
OBJS += passes/techmap/extract.o
|
||||
OBJS += passes/techmap/extract_fa.o
|
||||
|
|
|
@ -143,6 +143,82 @@ void attrmap_apply(string objname, vector<std::unique_ptr<AttrmapAction>> &actio
|
|||
attributes.swap(new_attributes);
|
||||
}
|
||||
|
||||
void log_attrmap_paramap_options()
|
||||
{
|
||||
log(" -tocase <name>\n");
|
||||
log(" Match attribute names case-insensitively and set it to the specified\n");
|
||||
log(" name.\n");
|
||||
log("\n");
|
||||
log(" -rename <old_name> <new_name>\n");
|
||||
log(" Rename attributes as specified\n");
|
||||
log("\n");
|
||||
log(" -map <old_name>=<old_value> <new_name>=<new_value>\n");
|
||||
log(" Map key/value pairs as indicated.\n");
|
||||
log("\n");
|
||||
log(" -imap <old_name>=<old_value> <new_name>=<new_value>\n");
|
||||
log(" Like -map, but use case-insensitive match for <old_value> when\n");
|
||||
log(" it is a string value.\n");
|
||||
log("\n");
|
||||
log(" -remove <name>=<value>\n");
|
||||
log(" Remove attributes matching this pattern.\n");
|
||||
}
|
||||
|
||||
bool parse_attrmap_paramap_options(size_t &argidx, std::vector<std::string> &args, vector<std::unique_ptr<AttrmapAction>> &actions)
|
||||
{
|
||||
std::string arg = args[argidx];
|
||||
if (arg == "-tocase" && argidx+1 < args.size()) {
|
||||
auto action = new AttrmapTocase;
|
||||
action->name = args[++argidx];
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
return true;
|
||||
}
|
||||
if (arg == "-rename" && argidx+2 < args.size()) {
|
||||
auto action = new AttrmapRename;
|
||||
action->old_name = args[++argidx];
|
||||
action->new_name = args[++argidx];
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
return true;
|
||||
}
|
||||
if ((arg == "-map" || arg == "-imap") && argidx+2 < args.size()) {
|
||||
string arg1 = args[++argidx];
|
||||
string arg2 = args[++argidx];
|
||||
string val1, val2;
|
||||
size_t p = arg1.find("=");
|
||||
if (p != string::npos) {
|
||||
val1 = arg1.substr(p+1);
|
||||
arg1 = arg1.substr(0, p);
|
||||
}
|
||||
p = arg2.find("=");
|
||||
if (p != string::npos) {
|
||||
val2 = arg2.substr(p+1);
|
||||
arg2 = arg2.substr(0, p);
|
||||
}
|
||||
auto action = new AttrmapMap;
|
||||
action->imap = (arg == "-map");
|
||||
action->old_name = arg1;
|
||||
action->new_name = arg2;
|
||||
action->old_value = val1;
|
||||
action->new_value = val2;
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
return true;
|
||||
}
|
||||
if (arg == "-remove" && argidx+1 < args.size()) {
|
||||
string arg1 = args[++argidx], val1;
|
||||
size_t p = arg1.find("=");
|
||||
if (p != string::npos) {
|
||||
val1 = arg1.substr(p+1);
|
||||
arg1 = arg1.substr(0, p);
|
||||
}
|
||||
auto action = new AttrmapRemove;
|
||||
action->name = arg1;
|
||||
action->has_value = (p != string::npos);
|
||||
action->value = val1;
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct AttrmapPass : public Pass {
|
||||
AttrmapPass() : Pass("attrmap", "renaming attributes") { }
|
||||
void help() YS_OVERRIDE
|
||||
|
@ -151,25 +227,10 @@ struct AttrmapPass : public Pass {
|
|||
log("\n");
|
||||
log(" attrmap [options] [selection]\n");
|
||||
log("\n");
|
||||
log("This command renames attributes and/or mapps key/value pairs to\n");
|
||||
log("This command renames attributes and/or maps key/value pairs to\n");
|
||||
log("other key/value pairs.\n");
|
||||
log("\n");
|
||||
log(" -tocase <name>\n");
|
||||
log(" Match attribute names case-insensitively and set it to the specified\n");
|
||||
log(" name.\n");
|
||||
log("\n");
|
||||
log(" -rename <old_name> <new_name>\n");
|
||||
log(" Rename attributes as specified\n");
|
||||
log("\n");
|
||||
log(" -map <old_name>=<old_value> <new_name>=<new_value>\n");
|
||||
log(" Map key/value pairs as indicated.\n");
|
||||
log("\n");
|
||||
log(" -imap <old_name>=<old_value> <new_name>=<new_value>\n");
|
||||
log(" Like -map, but use case-insensitive match for <old_value> when\n");
|
||||
log(" it is a string value.\n");
|
||||
log("\n");
|
||||
log(" -remove <name>=<value>\n");
|
||||
log(" Remove attributes matching this pattern.\n");
|
||||
log_attrmap_paramap_options();
|
||||
log("\n");
|
||||
log(" -modattr\n");
|
||||
log(" Operate on module attributes instead of attributes on wires and cells.\n");
|
||||
|
@ -190,58 +251,9 @@ struct AttrmapPass : public Pass {
|
|||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
std::string arg = args[argidx];
|
||||
if (arg == "-tocase" && argidx+1 < args.size()) {
|
||||
auto action = new AttrmapTocase;
|
||||
action->name = args[++argidx];
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
if (parse_attrmap_paramap_options(argidx, args, actions))
|
||||
continue;
|
||||
}
|
||||
if (arg == "-rename" && argidx+2 < args.size()) {
|
||||
auto action = new AttrmapRename;
|
||||
action->old_name = args[++argidx];
|
||||
action->new_name = args[++argidx];
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
continue;
|
||||
}
|
||||
if ((arg == "-map" || arg == "-imap") && argidx+2 < args.size()) {
|
||||
string arg1 = args[++argidx];
|
||||
string arg2 = args[++argidx];
|
||||
string val1, val2;
|
||||
size_t p = arg1.find("=");
|
||||
if (p != string::npos) {
|
||||
val1 = arg1.substr(p+1);
|
||||
arg1 = arg1.substr(0, p);
|
||||
}
|
||||
p = arg2.find("=");
|
||||
if (p != string::npos) {
|
||||
val2 = arg2.substr(p+1);
|
||||
arg2 = arg2.substr(0, p);
|
||||
}
|
||||
auto action = new AttrmapMap;
|
||||
action->imap = (arg == "-map");
|
||||
action->old_name = arg1;
|
||||
action->new_name = arg2;
|
||||
action->old_value = val1;
|
||||
action->new_value = val2;
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
continue;
|
||||
}
|
||||
if (arg == "-remove" && argidx+1 < args.size()) {
|
||||
string arg1 = args[++argidx], val1;
|
||||
size_t p = arg1.find("=");
|
||||
if (p != string::npos) {
|
||||
val1 = arg1.substr(p+1);
|
||||
arg1 = arg1.substr(0, p);
|
||||
}
|
||||
auto action = new AttrmapRemove;
|
||||
action->name = arg1;
|
||||
action->has_value = (p != string::npos);
|
||||
action->value = val1;
|
||||
actions.push_back(std::unique_ptr<AttrmapAction>(action));
|
||||
continue;
|
||||
}
|
||||
if (arg == "-modattr") {
|
||||
if (args[argidx] == "-modattr") {
|
||||
modattr_mode = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -287,4 +299,43 @@ struct AttrmapPass : public Pass {
|
|||
}
|
||||
} AttrmapPass;
|
||||
|
||||
struct ParamapPass : public Pass {
|
||||
ParamapPass() : Pass("paramap", "renaming cell parameters") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" paramap [options] [selection]\n");
|
||||
log("\n");
|
||||
log("This command renames cell parameters and/or maps key/value pairs to\n");
|
||||
log("other key/value pairs.\n");
|
||||
log("\n");
|
||||
log_attrmap_paramap_options();
|
||||
log("\n");
|
||||
log("For example, mapping Diamond-style ECP5 \"init\" attributes to Yosys-style:\n");
|
||||
log("\n");
|
||||
log(" paramap -tocase INIT t:LUT4\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
{
|
||||
log_header(design, "Executing PARAMAP pass (move or copy cell parameters).\n");
|
||||
|
||||
vector<std::unique_ptr<AttrmapAction>> actions;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
if (parse_attrmap_paramap_options(argidx, args, actions))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
for (auto cell : module->selected_cells())
|
||||
attrmap_apply(stringf("%s.%s", log_id(module), log_id(cell)), actions, cell->parameters);
|
||||
}
|
||||
} ParamapPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
||||
|
|
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
* Copyright (C) 2019 Marcin Kościelnicki <mwk@0x04.net>
|
||||
*
|
||||
* 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"
|
||||
#include "kernel/sigtools.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
void split_portname_pair(std::string &port1, std::string &port2)
|
||||
{
|
||||
size_t pos = port1.find_first_of(':');
|
||||
if (pos != std::string::npos) {
|
||||
port2 = port1.substr(pos+1);
|
||||
port1 = port1.substr(0, pos);
|
||||
}
|
||||
}
|
||||
|
||||
struct ClkbufmapPass : public Pass {
|
||||
ClkbufmapPass() : Pass("clkbufmap", "insert global buffers on clock networks") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" clkbufmap [options] [selection]\n");
|
||||
log("\n");
|
||||
log("Inserts global buffers between nets connected to clock inputs and their drivers.\n");
|
||||
log("\n");
|
||||
log("In the absence of any selection, all wires without the 'clkbuf_inhibit'\n");
|
||||
log("attribute will be considered for global buffer insertion.\n");
|
||||
log("Alternatively, to consider all wires without the 'buffer_type' attribute set to\n");
|
||||
log("'none' or 'bufr' one would specify:\n");
|
||||
log(" 'w:* a:buffer_type=none a:buffer_type=bufr %%u %%d'\n");
|
||||
log("as the selection.\n");
|
||||
log("\n");
|
||||
log(" -buf <celltype> <portname_out>:<portname_in>\n");
|
||||
log(" Specifies the cell type to use for the global buffers\n");
|
||||
log(" and its port names. The first port will be connected to\n");
|
||||
log(" the clock network sinks, and the second will be connected\n");
|
||||
log(" to the actual clock source. This option is required.\n");
|
||||
log("\n");
|
||||
log(" -inpad <celltype> <portname_out>:<portname_in>\n");
|
||||
log(" If specified, a PAD cell of the given type is inserted on\n");
|
||||
log(" clock nets that are also top module's inputs (in addition\n");
|
||||
log(" to the global buffer).\n");
|
||||
log("\n");
|
||||
}
|
||||
|
||||
void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) {
|
||||
if (modules_processed.count(module))
|
||||
return;
|
||||
for (auto cell : module->cells()) {
|
||||
Module *submodule = design->module(cell->type);
|
||||
if (!submodule)
|
||||
continue;
|
||||
module_queue(design, submodule, modules_sorted, modules_processed);
|
||||
}
|
||||
modules_sorted.push_back(module);
|
||||
modules_processed.insert(module);
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
{
|
||||
log_header(design, "Executing CLKBUFMAP pass (inserting global clock buffers).\n");
|
||||
|
||||
std::string buf_celltype, buf_portname, buf_portname2;
|
||||
std::string inpad_celltype, inpad_portname, inpad_portname2;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
std::string arg = args[argidx];
|
||||
if (arg == "-buf" && argidx+2 < args.size()) {
|
||||
buf_celltype = args[++argidx];
|
||||
buf_portname = args[++argidx];
|
||||
split_portname_pair(buf_portname, buf_portname2);
|
||||
continue;
|
||||
}
|
||||
if (arg == "-inpad" && argidx+2 < args.size()) {
|
||||
inpad_celltype = args[++argidx];
|
||||
inpad_portname = args[++argidx];
|
||||
split_portname_pair(inpad_portname, inpad_portname2);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bool select = false;
|
||||
if (argidx < args.size()) {
|
||||
if (args[argidx].compare(0, 1, "-") != 0)
|
||||
select = true;
|
||||
extra_args(args, argidx, design);
|
||||
}
|
||||
|
||||
if (buf_celltype.empty())
|
||||
log_error("The -buf option is required.\n");
|
||||
|
||||
// Cell type, port name, bit index.
|
||||
pool<pair<IdString, pair<IdString, int>>> sink_ports;
|
||||
pool<pair<IdString, pair<IdString, int>>> buf_ports;
|
||||
|
||||
// Process submodules before module using them.
|
||||
std::vector<Module *> modules_sorted;
|
||||
pool<Module *> modules_processed;
|
||||
for (auto module : design->selected_modules())
|
||||
module_queue(design, module, modules_sorted, modules_processed);
|
||||
|
||||
for (auto module : modules_sorted)
|
||||
{
|
||||
if (module->get_blackbox_attribute()) {
|
||||
for (auto port : module->ports) {
|
||||
auto wire = module->wire(port);
|
||||
if (wire->get_bool_attribute("\\clkbuf_driver"))
|
||||
for (int i = 0; i < GetSize(wire); i++)
|
||||
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
|
||||
if (wire->get_bool_attribute("\\clkbuf_sink"))
|
||||
for (int i = 0; i < GetSize(wire); i++)
|
||||
sink_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pool<SigBit> sink_wire_bits;
|
||||
pool<SigBit> buf_wire_bits;
|
||||
pool<SigBit> driven_wire_bits;
|
||||
SigMap sigmap(module);
|
||||
// bit -> (buffer, buffer's input)
|
||||
dict<SigBit, pair<Cell *, Wire *>> buffered_bits;
|
||||
|
||||
// First, collect nets that could use a clock buffer.
|
||||
for (auto cell : module->cells())
|
||||
for (auto port : cell->connections())
|
||||
for (int i = 0; i < port.second.size(); i++)
|
||||
if (sink_ports.count(make_pair(cell->type, make_pair(port.first, i))))
|
||||
sink_wire_bits.insert(sigmap(port.second[i]));
|
||||
|
||||
// Second, collect ones that already have a clock buffer.
|
||||
for (auto cell : module->cells())
|
||||
for (auto port : cell->connections())
|
||||
for (int i = 0; i < port.second.size(); i++)
|
||||
if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i))))
|
||||
buf_wire_bits.insert(sigmap(port.second[i]));
|
||||
|
||||
// Collect all driven bits.
|
||||
for (auto cell : module->cells())
|
||||
for (auto port : cell->connections())
|
||||
if (cell->output(port.first))
|
||||
for (int i = 0; i < port.second.size(); i++)
|
||||
driven_wire_bits.insert(port.second[i]);
|
||||
|
||||
// Insert buffers.
|
||||
std::vector<pair<Wire *, Wire *>> input_queue;
|
||||
// Copy current wire list, as we will be adding new ones during iteration.
|
||||
std::vector<Wire *> wires(module->wires());
|
||||
for (auto wire : wires)
|
||||
{
|
||||
// Should not happen.
|
||||
if (wire->port_input && wire->port_output)
|
||||
continue;
|
||||
bool process_wire = module->selected(wire);
|
||||
if (!select && wire->get_bool_attribute("\\clkbuf_inhibit"))
|
||||
process_wire = false;
|
||||
if (!process_wire) {
|
||||
// This wire is supposed to be bypassed, so make sure we don't buffer it in
|
||||
// some buffer higher up in the hierarchy.
|
||||
if (wire->port_output)
|
||||
for (int i = 0; i < GetSize(wire); i++)
|
||||
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
|
||||
continue;
|
||||
}
|
||||
|
||||
pool<int> input_bits;
|
||||
|
||||
for (int i = 0; i < GetSize(wire); i++)
|
||||
{
|
||||
SigBit wire_bit(wire, i);
|
||||
SigBit mapped_wire_bit = sigmap(wire_bit);
|
||||
if (buf_wire_bits.count(mapped_wire_bit)) {
|
||||
// Already buffered downstream. If this is an output, mark it.
|
||||
if (wire->port_output)
|
||||
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
|
||||
} else if (!sink_wire_bits.count(mapped_wire_bit)) {
|
||||
// Nothing to do.
|
||||
} else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute("\\top"))) {
|
||||
// Clock network not yet buffered, driven by one of
|
||||
// our cells or a top-level input -- buffer it.
|
||||
|
||||
log("Inserting %s on %s.%s[%d].\n", buf_celltype.c_str(), log_id(module), log_id(wire), i);
|
||||
RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(buf_celltype));
|
||||
Wire *iwire = module->addWire(NEW_ID);
|
||||
cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit);
|
||||
cell->setPort(RTLIL::escape_id(buf_portname2), iwire);
|
||||
if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute("\\top")) {
|
||||
log("Inserting %s on %s.%s[%d].\n", inpad_celltype.c_str(), log_id(module), log_id(wire), i);
|
||||
RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype));
|
||||
cell2->setPort(RTLIL::escape_id(inpad_portname), iwire);
|
||||
iwire = module->addWire(NEW_ID);
|
||||
cell2->setPort(RTLIL::escape_id(inpad_portname2), iwire);
|
||||
}
|
||||
buffered_bits[mapped_wire_bit] = make_pair(cell, iwire);
|
||||
|
||||
if (wire->port_input) {
|
||||
input_bits.insert(i);
|
||||
}
|
||||
} else if (wire->port_input) {
|
||||
// A clock input in a submodule -- mark it, let higher level
|
||||
// worry about it.
|
||||
if (wire->port_input)
|
||||
sink_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
|
||||
}
|
||||
}
|
||||
if (!input_bits.empty()) {
|
||||
// This is an input port and some buffers were inserted -- we need
|
||||
// to create a new input wire and transfer attributes.
|
||||
Wire *new_wire = module->addWire(NEW_ID, wire);
|
||||
|
||||
for (int i = 0; i < wire->width; i++) {
|
||||
SigBit wire_bit(wire, i);
|
||||
SigBit mapped_wire_bit = sigmap(wire_bit);
|
||||
auto it = buffered_bits.find(mapped_wire_bit);
|
||||
if (it != buffered_bits.end()) {
|
||||
|
||||
module->connect(it->second.second, SigSpec(new_wire, i));
|
||||
} else {
|
||||
module->connect(SigSpec(wire, i), SigSpec(new_wire, i));
|
||||
}
|
||||
}
|
||||
input_queue.push_back(make_pair(wire, new_wire));
|
||||
}
|
||||
}
|
||||
|
||||
// Mark any newly-buffered output ports as such.
|
||||
for (auto wire : module->selected_wires()) {
|
||||
if (wire->port_input || !wire->port_output)
|
||||
continue;
|
||||
for (int i = 0; i < GetSize(wire); i++)
|
||||
{
|
||||
SigBit wire_bit(wire, i);
|
||||
SigBit mapped_wire_bit = sigmap(wire_bit);
|
||||
if (buffered_bits.count(mapped_wire_bit))
|
||||
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
|
||||
}
|
||||
}
|
||||
|
||||
// Reconnect the drivers to buffer inputs.
|
||||
for (auto cell : module->cells())
|
||||
for (auto port : cell->connections()) {
|
||||
if (!cell->output(port.first))
|
||||
continue;
|
||||
SigSpec sig = port.second;
|
||||
bool newsig = false;
|
||||
for (auto &bit : sig) {
|
||||
const auto it = buffered_bits.find(sigmap(bit));
|
||||
if (it == buffered_bits.end())
|
||||
continue;
|
||||
// Avoid substituting buffer's own output pin.
|
||||
if (cell == it->second.first)
|
||||
continue;
|
||||
bit = it->second.second;
|
||||
newsig = true;
|
||||
}
|
||||
if (newsig)
|
||||
cell->setPort(port.first, sig);
|
||||
}
|
||||
|
||||
// This has to be done last, to avoid upsetting sigmap before the port reconnections.
|
||||
for (auto &it : input_queue) {
|
||||
Wire *wire = it.first;
|
||||
Wire *new_wire = it.second;
|
||||
module->swap_names(new_wire, wire);
|
||||
wire->attributes.clear();
|
||||
wire->port_id = 0;
|
||||
wire->port_input = false;
|
||||
wire->port_output = false;
|
||||
}
|
||||
|
||||
module->fixup_ports();
|
||||
}
|
||||
}
|
||||
} ClkbufmapPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
|
@ -64,6 +64,11 @@ struct IopadmapPass : public Pass {
|
|||
log(" of the tristate driver and the 2nd portname is the internal output\n");
|
||||
log(" buffering the external signal.\n");
|
||||
log("\n");
|
||||
log(" -ignore <celltype> <portname>[:<portname>]*\n");
|
||||
log(" Skips mapping inputs/outputs that are already connected to given\n");
|
||||
log(" ports of the given cell. Can be used multiple times. This is in\n");
|
||||
log(" addition to the cells specified as mapping targets.\n");
|
||||
log("\n");
|
||||
log(" -widthparam <param_name>\n");
|
||||
log(" Use the specified parameter name to set the port width.\n");
|
||||
log("\n");
|
||||
|
@ -88,6 +93,7 @@ struct IopadmapPass : public Pass {
|
|||
std::string toutpad_celltype, toutpad_portname, toutpad_portname2, toutpad_portname3;
|
||||
std::string tinoutpad_celltype, tinoutpad_portname, tinoutpad_portname2, tinoutpad_portname3, tinoutpad_portname4;
|
||||
std::string widthparam, nameparam;
|
||||
pool<pair<IdString, IdString>> ignore;
|
||||
bool flag_bits = false;
|
||||
|
||||
size_t argidx;
|
||||
|
@ -127,6 +133,18 @@ struct IopadmapPass : public Pass {
|
|||
split_portname_pair(tinoutpad_portname3, tinoutpad_portname4);
|
||||
continue;
|
||||
}
|
||||
if (arg == "-ignore" && argidx+2 < args.size()) {
|
||||
std::string ignore_celltype = args[++argidx];
|
||||
std::string ignore_portname = args[++argidx];
|
||||
std::string ignore_portname2;
|
||||
while (!ignore_portname.empty()) {
|
||||
split_portname_pair(ignore_portname, ignore_portname2);
|
||||
ignore.insert(make_pair(RTLIL::escape_id(ignore_celltype), RTLIL::escape_id(ignore_portname)));
|
||||
|
||||
ignore_portname = ignore_portname2;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (arg == "-widthparam" && argidx+1 < args.size()) {
|
||||
widthparam = args[++argidx];
|
||||
continue;
|
||||
|
@ -143,6 +161,23 @@ struct IopadmapPass : public Pass {
|
|||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (!inpad_portname2.empty())
|
||||
ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname2)));
|
||||
if (!outpad_portname2.empty())
|
||||
ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname2)));
|
||||
if (!inoutpad_portname2.empty())
|
||||
ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname2)));
|
||||
if (!toutpad_portname3.empty())
|
||||
ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname3)));
|
||||
if (!tinoutpad_portname4.empty())
|
||||
ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname4)));
|
||||
|
||||
for (auto module : design->modules())
|
||||
if (module->get_blackbox_attribute())
|
||||
for (auto wire : module->wires())
|
||||
if (wire->get_bool_attribute("\\iopad_external_pin"))
|
||||
ignore.insert(make_pair(module->name, wire->name));
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
{
|
||||
dict<IdString, pool<int>> skip_wires;
|
||||
|
@ -150,28 +185,11 @@ struct IopadmapPass : public Pass {
|
|||
SigMap sigmap(module);
|
||||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type == RTLIL::escape_id(inpad_celltype) && cell->hasPort(RTLIL::escape_id(inpad_portname2)))
|
||||
for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(inpad_portname2))))
|
||||
for (auto port : cell->connections())
|
||||
if (ignore.count(make_pair(cell->type, port.first)))
|
||||
for (auto bit : sigmap(port.second))
|
||||
skip_wire_bits.insert(bit);
|
||||
|
||||
if (cell->type == RTLIL::escape_id(outpad_celltype) && cell->hasPort(RTLIL::escape_id(outpad_portname2)))
|
||||
for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(outpad_portname2))))
|
||||
skip_wire_bits.insert(bit);
|
||||
|
||||
if (cell->type == RTLIL::escape_id(inoutpad_celltype) && cell->hasPort(RTLIL::escape_id(inoutpad_portname2)))
|
||||
for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(inoutpad_portname2))))
|
||||
skip_wire_bits.insert(bit);
|
||||
|
||||
if (cell->type == RTLIL::escape_id(toutpad_celltype) && cell->hasPort(RTLIL::escape_id(toutpad_portname3)))
|
||||
for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(toutpad_portname3))))
|
||||
skip_wire_bits.insert(bit);
|
||||
|
||||
if (cell->type == RTLIL::escape_id(tinoutpad_celltype) && cell->hasPort(RTLIL::escape_id(tinoutpad_portname4)))
|
||||
for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(tinoutpad_portname4))))
|
||||
skip_wire_bits.insert(bit);
|
||||
}
|
||||
|
||||
if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty())
|
||||
{
|
||||
dict<SigBit, pair<IdString, pool<IdString>>> tbuf_bits;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o
|
||||
OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o \
|
||||
techlibs/ecp5/ecp5_gsr.o
|
||||
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v))
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v))
|
||||
|
|
|
@ -33,7 +33,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.CLKBMUX(CLKBMUX),
|
||||
.WRITEMODE_A(WRITEMODE_A),
|
||||
.WRITEMODE_B("READBEFOREWRITE"),
|
||||
.GSR("DISABLED")
|
||||
.GSR("AUTO")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`include "bram_conn_1.vh"
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
|
@ -50,7 +50,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.CLKBMUX(CLKBMUX),
|
||||
.WRITEMODE_A(WRITEMODE_A),
|
||||
.WRITEMODE_B("READBEFOREWRITE"),
|
||||
.GSR("DISABLED")
|
||||
.GSR("AUTO")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`include "bram_conn_2.vh"
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
|
@ -67,7 +67,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.CLKBMUX(CLKBMUX),
|
||||
.WRITEMODE_A(WRITEMODE_A),
|
||||
.WRITEMODE_B("READBEFOREWRITE"),
|
||||
.GSR("DISABLED")
|
||||
.GSR("AUTO")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`include "bram_conn_4.vh"
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
|
@ -84,7 +84,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.CLKBMUX(CLKBMUX),
|
||||
.WRITEMODE_A(WRITEMODE_A),
|
||||
.WRITEMODE_B("READBEFOREWRITE"),
|
||||
.GSR("DISABLED")
|
||||
.GSR("AUTO")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`include "bram_conn_9.vh"
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
|
@ -101,7 +101,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.CLKBMUX(CLKBMUX),
|
||||
.WRITEMODE_A(WRITEMODE_A),
|
||||
.WRITEMODE_B("READBEFOREWRITE"),
|
||||
.GSR("DISABLED")
|
||||
.GSR("AUTO")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`include "bram_conn_18.vh"
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
|
|
|
@ -664,3 +664,23 @@ module PCSCLKDIV (
|
|||
);
|
||||
parameter GSR = "DISABLED";
|
||||
endmodule
|
||||
|
||||
// Note: this module is not marked keep as we want it swept away in synth (sim use only)
|
||||
(* blackbox *)
|
||||
module PUR (
|
||||
input PUR
|
||||
);
|
||||
parameter RST_PULSE = 1;
|
||||
endmodule
|
||||
|
||||
(* blackbox, keep *)
|
||||
module GSR (
|
||||
input GSR
|
||||
);
|
||||
endmodule
|
||||
|
||||
(* blackbox, keep *)
|
||||
module SGSR (
|
||||
input GSR, CLK
|
||||
);
|
||||
endmodule
|
|
@ -1,51 +1,51 @@
|
|||
module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
module \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
|
||||
|
||||
// TODO: Diamond flip-flops
|
||||
// module FD1P3AX(); endmodule
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
|
||||
* Copyright (C) 2019 David Shah <david@symbioticeda.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kernel/yosys.h"
|
||||
#include "kernel/sigtools.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct Ecp5GsrPass : public Pass {
|
||||
Ecp5GsrPass() : Pass("ecp5_gsr", "ECP5: handle GSR") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" ecp5_gsr [options] [selection]\n");
|
||||
log("\n");
|
||||
log("Trim active low async resets connected to GSR and resolve GSR parameter,\n");
|
||||
log("if a GSR or SGSR primitive is used in the design.\n");
|
||||
log("\n");
|
||||
log("If any cell has the GSR parameter set to \"AUTO\", this will be resolved\n");
|
||||
log("to \"ENABLED\" if a GSR primitive is present and the (* nogsr *) attribute\n");
|
||||
log("is not set, otherwise it will be resolved to \"DISABLED\".\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
{
|
||||
log_header(design, "Executing ECP5_GSR pass (implement FF init values).\n");
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
{
|
||||
// if (args[argidx] == "-singleton") {
|
||||
// singleton_mode = true;
|
||||
// continue;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
{
|
||||
log("Handling GSR in %s.\n", log_id(module));
|
||||
|
||||
SigMap sigmap(module);
|
||||
|
||||
SigBit gsr;
|
||||
bool found_gsr = false;
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (cell->type != ID(GSR) && cell->type != ID(SGSR))
|
||||
continue;
|
||||
if (found_gsr)
|
||||
log_error("Found more than one GSR or SGSR cell in module %s.\n", log_id(module));
|
||||
found_gsr = true;
|
||||
SigSpec sig_gsr = cell->getPort(ID(GSR));
|
||||
if (GetSize(sig_gsr) < 1)
|
||||
log_error("GSR cell %s has disconnected GSR input.\n", log_id(cell));
|
||||
gsr = sigmap(sig_gsr[0]);
|
||||
}
|
||||
|
||||
// Resolve GSR parameter
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (!cell->hasParam(ID(GSR)) || cell->getParam(ID(GSR)).decode_string() != "AUTO")
|
||||
continue;
|
||||
|
||||
bool gsren = found_gsr;
|
||||
if (cell->get_bool_attribute("\\nogsr"))
|
||||
gsren = false;
|
||||
cell->setParam(ID(GSR), gsren ? Const("ENABLED") : Const("DISABLED"));
|
||||
|
||||
}
|
||||
|
||||
if (!found_gsr)
|
||||
continue;
|
||||
|
||||
// For finding active low FF inputs
|
||||
pool<SigBit> inverted_gsr;
|
||||
|
||||
log_debug("GSR net in module %s is %s.\n", log_id(module), log_signal(gsr));
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (cell->type != ID($_NOT_))
|
||||
continue;
|
||||
SigSpec sig_a = cell->getPort(ID(A)), sig_y = cell->getPort(ID(Y));
|
||||
if (GetSize(sig_a) < 1 || GetSize(sig_y) < 1)
|
||||
continue;
|
||||
SigBit a = sigmap(sig_a[0]);
|
||||
if (a == gsr)
|
||||
inverted_gsr.insert(sigmap(sig_y[0]));
|
||||
}
|
||||
|
||||
for (auto cell : module->selected_cells())
|
||||
{
|
||||
if (cell->type != ID(TRELLIS_FF))
|
||||
continue;
|
||||
if (!cell->hasParam(ID(GSR)) || cell->getParam(ID(GSR)).decode_string() != "ENABLED")
|
||||
continue;
|
||||
if (!cell->hasParam(ID(SRMODE)) || cell->getParam(ID(SRMODE)).decode_string() != "ASYNC")
|
||||
continue;
|
||||
SigSpec sig_lsr = cell->getPort(ID(LSR));
|
||||
if (GetSize(sig_lsr) < 1)
|
||||
continue;
|
||||
SigBit lsr = sigmap(sig_lsr[0]);
|
||||
if (!inverted_gsr.count(lsr))
|
||||
continue;
|
||||
cell->setParam(ID(SRMODE), Const("SYNC"));
|
||||
cell->unsetPort(ID(LSR));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} Ecp5GsrPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
|
@ -271,6 +271,8 @@ struct SynthEcp5Pass : public ScriptPass
|
|||
run("opt_expr -undriven -mux_undef");
|
||||
run("simplemap");
|
||||
run("ecp5_ffinit");
|
||||
run("ecp5_gsr");
|
||||
run("opt_clean");
|
||||
}
|
||||
|
||||
if (check_label("map_luts"))
|
||||
|
|
|
@ -29,24 +29,35 @@ module GND(output G);
|
|||
assign G = 0;
|
||||
endmodule
|
||||
|
||||
module IBUF(output O, input I);
|
||||
module IBUF(
|
||||
output O,
|
||||
(* iopad_external_pin *)
|
||||
input I);
|
||||
parameter IOSTANDARD = "default";
|
||||
parameter IBUF_LOW_PWR = 0;
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module OBUF(output O, input I);
|
||||
module OBUF(
|
||||
(* iopad_external_pin *)
|
||||
output O,
|
||||
input I);
|
||||
parameter IOSTANDARD = "default";
|
||||
parameter DRIVE = 12;
|
||||
parameter SLEW = "SLOW";
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module BUFG(output O, input I);
|
||||
module BUFG(
|
||||
(* clkbuf_driver *)
|
||||
output O,
|
||||
input I);
|
||||
|
||||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module BUFGCTRL(
|
||||
(* clkbuf_driver *)
|
||||
output O,
|
||||
input I0, input I1,
|
||||
input S0, input S1,
|
||||
|
@ -72,7 +83,11 @@ assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT);
|
|||
|
||||
endmodule
|
||||
|
||||
module BUFHCE(output O, input I, input CE);
|
||||
module BUFHCE(
|
||||
(* clkbuf_driver *)
|
||||
output O,
|
||||
input I,
|
||||
input CE);
|
||||
|
||||
parameter [0:0] INIT_OUT = 1'b0;
|
||||
parameter CE_TYPE = "SYNC";
|
||||
|
@ -221,7 +236,7 @@ endmodule
|
|||
|
||||
`endif
|
||||
|
||||
module FDRE (output reg Q, input C, CE, D, R);
|
||||
module FDRE (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -233,7 +248,7 @@ module FDRE (output reg Q, input C, CE, D, R);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDSE (output reg Q, input C, CE, D, S);
|
||||
module FDSE (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -245,7 +260,7 @@ module FDSE (output reg Q, input C, CE, D, S);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDCE (output reg Q, input C, CE, D, CLR);
|
||||
module FDCE (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -259,7 +274,7 @@ module FDCE (output reg Q, input C, CE, D, CLR);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDPE (output reg Q, input C, CE, D, PRE);
|
||||
module FDPE (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
parameter [0:0] IS_C_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_D_INVERTED = 1'b0;
|
||||
|
@ -273,25 +288,25 @@ module FDPE (output reg Q, input C, CE, D, PRE);
|
|||
endcase endgenerate
|
||||
endmodule
|
||||
|
||||
module FDRE_1 (output reg Q, input C, CE, D, R);
|
||||
module FDRE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, R);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
module FDSE_1 (output reg Q, input C, CE, D, S);
|
||||
module FDSE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, S);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
module FDCE_1 (output reg Q, input C, CE, D, CLR);
|
||||
module FDCE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
|
||||
endmodule
|
||||
|
||||
module FDPE_1 (output reg Q, input C, CE, D, PRE);
|
||||
module FDPE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE);
|
||||
parameter [0:0] INIT = 1'b1;
|
||||
initial Q <= INIT;
|
||||
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
|
||||
|
@ -302,6 +317,7 @@ module RAM32X1D (
|
|||
output DPO, SPO,
|
||||
(* abc_scc_break *)
|
||||
input D,
|
||||
(* clkbuf_sink *)
|
||||
input WCLK,
|
||||
(* abc_scc_break *)
|
||||
input WE,
|
||||
|
@ -324,6 +340,7 @@ module RAM64X1D (
|
|||
output DPO, SPO,
|
||||
(* abc_scc_break *)
|
||||
input D,
|
||||
(* clkbuf_sink *)
|
||||
input WCLK,
|
||||
(* abc_scc_break *)
|
||||
input WE,
|
||||
|
@ -346,6 +363,7 @@ module RAM128X1D (
|
|||
output DPO, SPO,
|
||||
(* abc_scc_break *)
|
||||
input D,
|
||||
(* clkbuf_sink *)
|
||||
input WCLK,
|
||||
(* abc_scc_break *)
|
||||
input WE,
|
||||
|
@ -362,7 +380,9 @@ endmodule
|
|||
|
||||
module SRL16E (
|
||||
output Q,
|
||||
input A0, A1, A2, A3, CE, CLK, D
|
||||
(* clkbuf_sink *)
|
||||
input CLK,
|
||||
input A0, A1, A2, A3, CE, D
|
||||
);
|
||||
parameter [15:0] INIT = 16'h0000;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
|
@ -374,7 +394,27 @@ module SRL16E (
|
|||
always @(negedge CLK) if (CE) r <= { r[14:0], D };
|
||||
end
|
||||
else
|
||||
always @(posedge CLK) if (CE) r <= { r[14:0], D };
|
||||
always @(posedge CLK) if (CE) r <= { r[14:0], D };
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module SRLC16E (
|
||||
output Q,
|
||||
output Q15,
|
||||
input A0, A1, A2, A3, CE, CLK, D
|
||||
);
|
||||
parameter [15:0] INIT = 16'h0000;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
|
||||
reg [15:0] r = INIT;
|
||||
assign Q15 = r[15];
|
||||
assign Q = r[{A3,A2,A1,A0}];
|
||||
generate
|
||||
if (IS_CLK_INVERTED) begin
|
||||
always @(negedge CLK) if (CE) r <= { r[14:0], D };
|
||||
end
|
||||
else
|
||||
always @(posedge CLK) if (CE) r <= { r[14:0], D };
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
|
@ -382,7 +422,9 @@ module SRLC32E (
|
|||
output Q,
|
||||
output Q31,
|
||||
input [4:0] A,
|
||||
input CE, CLK, D
|
||||
(* clkbuf_sink *)
|
||||
input CLK,
|
||||
input CE, D
|
||||
);
|
||||
parameter [31:0] INIT = 32'h00000000;
|
||||
parameter [0:0] IS_CLK_INVERTED = 1'b0;
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from io import StringIO
|
||||
from enum import Enum, auto
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
|
||||
class Cell:
|
||||
def __init__(self, name, keep=False, port_attrs={}):
|
||||
self.name = name
|
||||
self.keep = keep
|
||||
self.port_attrs = port_attrs
|
||||
|
||||
|
||||
CELLS = [
|
||||
# Design elements types listed in Xilinx UG953
|
||||
Cell('BSCANE2', keep=True),
|
||||
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
#Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
|
||||
#Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFMR', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFMRCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('CAPTUREE2', keep=True),
|
||||
# Cell('CARRY4'),
|
||||
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('DCIRESET', keep=True),
|
||||
Cell('DNA_PORT'),
|
||||
Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('EFUSE_USR'),
|
||||
# Cell('FDCE'),
|
||||
# Cell('FDPE'),
|
||||
# Cell('FDRE'),
|
||||
# Cell('FDSE'),
|
||||
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FRAME_ECCE2'),
|
||||
Cell('GTHE2_CHANNEL'),
|
||||
Cell('GTHE2_COMMON'),
|
||||
Cell('GTPE2_CHANNEL'),
|
||||
Cell('GTPE2_COMMON'),
|
||||
Cell('GTXE2_CHANNEL'),
|
||||
Cell('GTXE2_COMMON'),
|
||||
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_GTE2', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('ICAPE2', keep=True),
|
||||
Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
|
||||
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
|
||||
Cell('IDELAYE2', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IN_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('ISERDESE2', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLKB': ['clkbuf_sink'],
|
||||
'OCLK': ['clkbuf_sink'],
|
||||
'OCLKB': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
'CLKDIVP': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('KEEPER'),
|
||||
Cell('LDCE'),
|
||||
Cell('LDPE'),
|
||||
# Cell('LUT1'),
|
||||
# Cell('LUT2'),
|
||||
# Cell('LUT3'),
|
||||
# Cell('LUT4'),
|
||||
# Cell('LUT5'),
|
||||
# Cell('LUT6'),
|
||||
#Cell('LUT6_2'),
|
||||
Cell('MMCME2_ADV'),
|
||||
Cell('MMCME2_BASE'),
|
||||
# Cell('MUXF7'),
|
||||
# Cell('MUXF8'),
|
||||
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ODELAYE2', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('OSERDESE2', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
Cell('OUT_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('PHASER_IN'),
|
||||
Cell('PHASER_IN_PHY'),
|
||||
Cell('PHASER_OUT'),
|
||||
Cell('PHASER_OUT_PHY'),
|
||||
Cell('PHASER_REF'),
|
||||
Cell('PHY_CONTROL'),
|
||||
Cell('PLLE2_ADV'),
|
||||
Cell('PLLE2_BASE'),
|
||||
Cell('PS7', keep=True),
|
||||
Cell('PULLDOWN'),
|
||||
Cell('PULLUP'),
|
||||
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
|
||||
Cell('ROM128X1'),
|
||||
Cell('ROM256X1'),
|
||||
Cell('ROM32X1'),
|
||||
Cell('ROM64X1'),
|
||||
#Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
#Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('STARTUPE2', keep=True),
|
||||
Cell('USR_ACCESSE2'),
|
||||
Cell('XADC'),
|
||||
]
|
||||
|
||||
class State(Enum):
|
||||
OUTSIDE = auto()
|
||||
IN_MODULE = auto()
|
||||
IN_OTHER_MODULE = auto()
|
||||
IN_FUNCTION = auto()
|
||||
IN_TASK = auto()
|
||||
|
||||
def xtract_cell_decl(cell, dirs, outf):
|
||||
for dir in dirs:
|
||||
fname = os.path.join(dir, cell.name + '.v')
|
||||
try:
|
||||
with open(fname) as f:
|
||||
state = State.OUTSIDE
|
||||
found = False
|
||||
# Probably the most horrible Verilog "parser" ever written.
|
||||
for l in f:
|
||||
l = l.partition('//')[0]
|
||||
l = l.strip()
|
||||
if l == 'module {}'.format(cell.name) or l.startswith('module {} '.format(cell.name)):
|
||||
if found:
|
||||
print('Multiple modules in {}.'.format(fname))
|
||||
sys.exit(1)
|
||||
elif state != State.OUTSIDE:
|
||||
print('Nested modules in {}.'.format(fname))
|
||||
sys.exit(1)
|
||||
found = True
|
||||
state = State.IN_MODULE
|
||||
if cell.keep:
|
||||
outf.write('(* keep *)\n')
|
||||
outf.write('module {} (...);\n'.format(cell.name))
|
||||
elif l.startswith('module '):
|
||||
if state != State.OUTSIDE:
|
||||
print('Nested modules in {}.'.format(fname))
|
||||
sys.exit(1)
|
||||
state = State.IN_OTHER_MODULE
|
||||
elif l.startswith('task '):
|
||||
if state == State.IN_MODULE:
|
||||
state = State.IN_TASK
|
||||
elif l.startswith('function '):
|
||||
if state == State.IN_MODULE:
|
||||
state = State.IN_FUNCTION
|
||||
elif l == 'endtask':
|
||||
if state == State.IN_TASK:
|
||||
state = State.IN_MODULE
|
||||
elif l == 'endfunction':
|
||||
if state == State.IN_FUNCTION:
|
||||
state = State.IN_MODULE
|
||||
elif l == 'endmodule':
|
||||
if state == State.IN_MODULE:
|
||||
outf.write(l + '\n')
|
||||
outf.write('\n')
|
||||
elif state != State.IN_OTHER_MODULE:
|
||||
print('endmodule in weird place in {}.'.format(cell.name, fname))
|
||||
sys.exit(1)
|
||||
state = State.OUTSIDE
|
||||
elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE:
|
||||
if l.endswith((';', ',')):
|
||||
l = l[:-1]
|
||||
if ';' in l:
|
||||
print('Weird port line in {} [{}].'.format(fname, l))
|
||||
sys.exit(1)
|
||||
kind, _, ports = l.partition(' ')
|
||||
for port in ports.split(','):
|
||||
port = port.strip()
|
||||
for attr in cell.port_attrs.get(port, []):
|
||||
outf.write(' (* {} *)\n'.format(attr))
|
||||
outf.write(' {} {};\n'.format(kind, port))
|
||||
elif l.startswith('parameter ') and state == State.IN_MODULE:
|
||||
if 'UNPLACED' in l:
|
||||
continue
|
||||
if l.endswith((';', ',')):
|
||||
l = l[:-1]
|
||||
while ' ' in l:
|
||||
l = l.replace(' ', ' ')
|
||||
if ';' in l:
|
||||
print('Weird parameter line in {} [{}].'.format(fname, l))
|
||||
sys.exit(1)
|
||||
outf.write(' {};\n'.format(l))
|
||||
if state != State.OUTSIDE:
|
||||
print('endmodule not found in {}.'.format(fname))
|
||||
sys.exit(1)
|
||||
if not found:
|
||||
print('Cannot find module {} in {}.'.format(cell.name, fname))
|
||||
sys.exit(1)
|
||||
return
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
print('Cannot find {}.'.format(cell.name))
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='Extract Xilinx blackbox cell definitions from Vivado.')
|
||||
parser.add_argument('vivado_dir', nargs='?', default='/opt/Xilinx/Vivado/2018.1')
|
||||
args = parser.parse_args()
|
||||
|
||||
dirs = [
|
||||
os.path.join(args.vivado_dir, 'data/verilog/src/xeclib'),
|
||||
os.path.join(args.vivado_dir, 'data/verilog/src/retarget'),
|
||||
]
|
||||
for dir in dirs:
|
||||
if not os.path.isdir(dir):
|
||||
print('{} is not a directory'.format(dir))
|
||||
|
||||
out = StringIO()
|
||||
for cell in CELLS:
|
||||
xtract_cell_decl(cell, dirs, out)
|
||||
|
||||
with open('cells_xtra.v', 'w') as f:
|
||||
f.write('// Created by cells_xtra.py from Xilinx models\n')
|
||||
f.write('\n')
|
||||
f.write(out.getvalue())
|
|
@ -1,147 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
libdir="/opt/Xilinx/Vivado/2018.1/data/verilog/src"
|
||||
|
||||
function xtract_cell_decl()
|
||||
{
|
||||
for dir in $libdir/xeclib $libdir/retarget; do
|
||||
[ -f $dir/$1.v ] || continue
|
||||
[ -z "$2" ] || echo $2
|
||||
egrep '^\s*((end)?module|parameter|input|inout|output|(end)?function|(end)?task)' $dir/$1.v |
|
||||
sed -re '/UNPLACED/ d; /^\s*function/,/endfunction/ d; /^\s*task/,/endtask/ d;
|
||||
s,//.*,,; s/#?\(.*/(...);/; s/^(input|output|parameter)/ \1/;
|
||||
s/\s+$//; s/,$/;/; /input|output|parameter/ s/[^;]$/&;/; s/\s+/ /g;
|
||||
s/^ ((end)?module)/\1/; s/^ / /; /module.*_bb/,/endmodule/ d;'
|
||||
echo; return
|
||||
done
|
||||
echo "Can't find $1."
|
||||
exit 1
|
||||
}
|
||||
|
||||
{
|
||||
echo "// Created by cells_xtra.sh from Xilinx models"
|
||||
echo
|
||||
|
||||
# Design elements types listed in Xilinx UG953
|
||||
xtract_cell_decl BSCANE2
|
||||
# xtract_cell_decl BUFG
|
||||
xtract_cell_decl BUFGCE
|
||||
xtract_cell_decl BUFGCE_1
|
||||
#xtract_cell_decl BUFGCTRL
|
||||
xtract_cell_decl BUFGMUX
|
||||
xtract_cell_decl BUFGMUX_1
|
||||
xtract_cell_decl BUFGMUX_CTRL
|
||||
xtract_cell_decl BUFH
|
||||
#xtract_cell_decl BUFHCE
|
||||
xtract_cell_decl BUFIO
|
||||
xtract_cell_decl BUFMR
|
||||
xtract_cell_decl BUFMRCE
|
||||
xtract_cell_decl BUFR
|
||||
xtract_cell_decl CAPTUREE2 "(* keep *)"
|
||||
# xtract_cell_decl CARRY4
|
||||
xtract_cell_decl CFGLUT5
|
||||
xtract_cell_decl DCIRESET "(* keep *)"
|
||||
xtract_cell_decl DNA_PORT
|
||||
xtract_cell_decl DSP48E1
|
||||
xtract_cell_decl EFUSE_USR
|
||||
# xtract_cell_decl FDCE
|
||||
# xtract_cell_decl FDPE
|
||||
# xtract_cell_decl FDRE
|
||||
# xtract_cell_decl FDSE
|
||||
xtract_cell_decl FIFO18E1
|
||||
xtract_cell_decl FIFO36E1
|
||||
xtract_cell_decl FRAME_ECCE2
|
||||
xtract_cell_decl GTHE2_CHANNEL
|
||||
xtract_cell_decl GTHE2_COMMON
|
||||
xtract_cell_decl GTPE2_CHANNEL
|
||||
xtract_cell_decl GTPE2_COMMON
|
||||
xtract_cell_decl GTXE2_CHANNEL
|
||||
xtract_cell_decl GTXE2_COMMON
|
||||
# xtract_cell_decl IBUF
|
||||
xtract_cell_decl IBUF_IBUFDISABLE
|
||||
xtract_cell_decl IBUF_INTERMDISABLE
|
||||
xtract_cell_decl IBUFDS
|
||||
xtract_cell_decl IBUFDS_DIFF_OUT
|
||||
xtract_cell_decl IBUFDS_DIFF_OUT_IBUFDISABLE
|
||||
xtract_cell_decl IBUFDS_DIFF_OUT_INTERMDISABLE
|
||||
xtract_cell_decl IBUFDS_GTE2
|
||||
xtract_cell_decl IBUFDS_IBUFDISABLE
|
||||
xtract_cell_decl IBUFDS_INTERMDISABLE
|
||||
xtract_cell_decl ICAPE2 "(* keep *)"
|
||||
xtract_cell_decl IDDR
|
||||
xtract_cell_decl IDDR_2CLK
|
||||
xtract_cell_decl IDELAYCTRL "(* keep *)"
|
||||
xtract_cell_decl IDELAYE2
|
||||
xtract_cell_decl IN_FIFO
|
||||
xtract_cell_decl IOBUF
|
||||
xtract_cell_decl IOBUF_DCIEN
|
||||
xtract_cell_decl IOBUF_INTERMDISABLE
|
||||
xtract_cell_decl IOBUFDS
|
||||
xtract_cell_decl IOBUFDS_DCIEN
|
||||
xtract_cell_decl IOBUFDS_DIFF_OUT
|
||||
xtract_cell_decl IOBUFDS_DIFF_OUT_DCIEN
|
||||
xtract_cell_decl IOBUFDS_DIFF_OUT_INTERMDISABLE
|
||||
xtract_cell_decl ISERDESE2
|
||||
xtract_cell_decl KEEPER
|
||||
xtract_cell_decl LDCE
|
||||
xtract_cell_decl LDPE
|
||||
# xtract_cell_decl LUT1
|
||||
# xtract_cell_decl LUT2
|
||||
# xtract_cell_decl LUT3
|
||||
# xtract_cell_decl LUT4
|
||||
# xtract_cell_decl LUT5
|
||||
# xtract_cell_decl LUT6
|
||||
#xtract_cell_decl LUT6_2
|
||||
xtract_cell_decl MMCME2_ADV
|
||||
xtract_cell_decl MMCME2_BASE
|
||||
# xtract_cell_decl MUXF7
|
||||
# xtract_cell_decl MUXF8
|
||||
# xtract_cell_decl OBUF
|
||||
xtract_cell_decl OBUFDS
|
||||
xtract_cell_decl OBUFT
|
||||
xtract_cell_decl OBUFTDS
|
||||
xtract_cell_decl ODDR
|
||||
xtract_cell_decl ODELAYE2
|
||||
xtract_cell_decl OSERDESE2
|
||||
xtract_cell_decl OUT_FIFO
|
||||
xtract_cell_decl PHASER_IN
|
||||
xtract_cell_decl PHASER_IN_PHY
|
||||
xtract_cell_decl PHASER_OUT
|
||||
xtract_cell_decl PHASER_OUT_PHY
|
||||
xtract_cell_decl PHASER_REF
|
||||
xtract_cell_decl PHY_CONTROL
|
||||
xtract_cell_decl PLLE2_ADV
|
||||
xtract_cell_decl PLLE2_BASE
|
||||
xtract_cell_decl PS7 "(* keep *)"
|
||||
xtract_cell_decl PULLDOWN
|
||||
xtract_cell_decl PULLUP
|
||||
#xtract_cell_decl RAM128X1D
|
||||
xtract_cell_decl RAM128X1S
|
||||
xtract_cell_decl RAM256X1S
|
||||
xtract_cell_decl RAM32M
|
||||
#xtract_cell_decl RAM32X1D
|
||||
xtract_cell_decl RAM32X1S
|
||||
xtract_cell_decl RAM32X1S_1
|
||||
xtract_cell_decl RAM32X2S
|
||||
xtract_cell_decl RAM64M
|
||||
#xtract_cell_decl RAM64X1D
|
||||
xtract_cell_decl RAM64X1S
|
||||
xtract_cell_decl RAM64X1S_1
|
||||
xtract_cell_decl RAM64X2S
|
||||
# xtract_cell_decl RAMB18E1
|
||||
# xtract_cell_decl RAMB36E1
|
||||
xtract_cell_decl ROM128X1
|
||||
xtract_cell_decl ROM256X1
|
||||
xtract_cell_decl ROM32X1
|
||||
xtract_cell_decl ROM64X1
|
||||
#xtract_cell_decl SRL16E
|
||||
#xtract_cell_decl SRLC32E
|
||||
xtract_cell_decl STARTUPE2 "(* keep *)"
|
||||
xtract_cell_decl USR_ACCESSE2
|
||||
xtract_cell_decl XADC
|
||||
} > cells_xtra.new
|
||||
|
||||
mv cells_xtra.new cells_xtra.v
|
||||
exit 0
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
// Created by cells_xtra.sh from Xilinx models
|
||||
// Created by cells_xtra.py from Xilinx models
|
||||
|
||||
(* keep *)
|
||||
module BSCANE2 (...);
|
||||
parameter DISABLE_JTAG = "FALSE";
|
||||
parameter integer JTAG_CHAIN = 1;
|
||||
|
@ -20,29 +21,39 @@ module BUFGCE (...);
|
|||
parameter CE_TYPE = "SYNC";
|
||||
parameter [0:0] IS_CE_INVERTED = 1'b0;
|
||||
parameter [0:0] IS_I_INVERTED = 1'b0;
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input CE;
|
||||
input I;
|
||||
endmodule
|
||||
|
||||
module BUFGCE_1 (...);
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input CE, I;
|
||||
input CE;
|
||||
input I;
|
||||
endmodule
|
||||
|
||||
module BUFGMUX (...);
|
||||
parameter CLK_SEL_TYPE = "SYNC";
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input I0, I1, S;
|
||||
input I0;
|
||||
input I1;
|
||||
input S;
|
||||
endmodule
|
||||
|
||||
module BUFGMUX_1 (...);
|
||||
parameter CLK_SEL_TYPE = "SYNC";
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input I0, I1, S;
|
||||
input I0;
|
||||
input I1;
|
||||
input S;
|
||||
endmodule
|
||||
|
||||
module BUFGMUX_CTRL (...);
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input I0;
|
||||
input I1;
|
||||
|
@ -50,16 +61,19 @@ module BUFGMUX_CTRL (...);
|
|||
endmodule
|
||||
|
||||
module BUFH (...);
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input I;
|
||||
endmodule
|
||||
|
||||
module BUFIO (...);
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input I;
|
||||
endmodule
|
||||
|
||||
module BUFMR (...);
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input I;
|
||||
endmodule
|
||||
|
@ -68,12 +82,14 @@ module BUFMRCE (...);
|
|||
parameter CE_TYPE = "SYNC";
|
||||
parameter integer INIT_OUT = 0;
|
||||
parameter [0:0] IS_CE_INVERTED = 1'b0;
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input CE;
|
||||
input I;
|
||||
endmodule
|
||||
|
||||
module BUFR (...);
|
||||
(* clkbuf_driver *)
|
||||
output O;
|
||||
input CE;
|
||||
input CLR;
|
||||
|
@ -95,8 +111,15 @@ module CFGLUT5 (...);
|
|||
output CDO;
|
||||
output O5;
|
||||
output O6;
|
||||
input I4, I3, I2, I1, I0;
|
||||
input CDI, CE, CLK;
|
||||
input I4;
|
||||
input I3;
|
||||
input I2;
|
||||
input I1;
|
||||
input I0;
|
||||
input CDI;
|
||||
input CE;
|
||||
(* clkbuf_sink *)
|
||||
input CLK;
|
||||
endmodule
|
||||
|
||||
(* keep *)
|
||||
|
@ -108,7 +131,10 @@ endmodule
|
|||
module DNA_PORT (...);
|
||||
parameter [56:0] SIM_DNA_VALUE = 57'h0;
|
||||
output DOUT;
|
||||
input CLK, DIN, READ, SHIFT;
|
||||
input CLK;
|
||||
input DIN;
|
||||
input READ;
|
||||
input SHIFT;
|
||||
endmodule
|
||||
|
||||
module DSP48E1 (...);
|
||||
|
@ -175,6 +201,7 @@ module DSP48E1 (...);
|
|||
input CEINMODE;
|
||||
input CEM;
|
||||
input CEP;
|
||||
(* clkbuf_sink *)
|
||||
input CLK;
|
||||
input [24:0] D;
|
||||
input [4:0] INMODE;
|
||||
|
@ -227,11 +254,13 @@ module FIFO18E1 (...);
|
|||
output WRERR;
|
||||
input [31:0] DI;
|
||||
input [3:0] DIP;
|
||||
(* clkbuf_sink *)
|
||||
input RDCLK;
|
||||
input RDEN;
|
||||
input REGCE;
|
||||
input RST;
|
||||
input RSTREG;
|
||||
(* clkbuf_sink *)
|
||||
input WRCLK;
|
||||
input WREN;
|
||||
endmodule
|
||||
|
@ -272,11 +301,13 @@ module FIFO36E1 (...);
|
|||
input [7:0] DIP;
|
||||
input INJECTDBITERR;
|
||||
input INJECTSBITERR;
|
||||
(* clkbuf_sink *)
|
||||
input RDCLK;
|
||||
input RDEN;
|
||||
input REGCE;
|
||||
input RST;
|
||||
input RSTREG;
|
||||
(* clkbuf_sink *)
|
||||
input WRCLK;
|
||||
input WREN;
|
||||
endmodule
|
||||
|
@ -1969,6 +2000,7 @@ module IBUF_IBUFDISABLE (...);
|
|||
parameter SIM_DEVICE = "7SERIES";
|
||||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
input IBUFDISABLE;
|
||||
endmodule
|
||||
|
@ -1979,6 +2011,7 @@ module IBUF_INTERMDISABLE (...);
|
|||
parameter SIM_DEVICE = "7SERIES";
|
||||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
input IBUFDISABLE;
|
||||
input INTERMDISABLE;
|
||||
|
@ -1993,7 +2026,10 @@ module IBUFDS (...);
|
|||
parameter IFD_DELAY_VALUE = "AUTO";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
output O;
|
||||
input I, IB;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
endmodule
|
||||
|
||||
module IBUFDS_DIFF_OUT (...);
|
||||
|
@ -2001,8 +2037,12 @@ module IBUFDS_DIFF_OUT (...);
|
|||
parameter DQS_BIAS = "FALSE";
|
||||
parameter IBUF_LOW_PWR = "TRUE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
output O, OB;
|
||||
input I, IB;
|
||||
output O;
|
||||
output OB;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
endmodule
|
||||
|
||||
module IBUFDS_DIFF_OUT_IBUFDISABLE (...);
|
||||
|
@ -2014,7 +2054,9 @@ module IBUFDS_DIFF_OUT_IBUFDISABLE (...);
|
|||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
output OB;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
input IBUFDISABLE;
|
||||
endmodule
|
||||
|
@ -2028,7 +2070,9 @@ module IBUFDS_DIFF_OUT_INTERMDISABLE (...);
|
|||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
output OB;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
input IBUFDISABLE;
|
||||
input INTERMDISABLE;
|
||||
|
@ -2041,7 +2085,9 @@ module IBUFDS_GTE2 (...);
|
|||
output O;
|
||||
output ODIV2;
|
||||
input CEB;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
endmodule
|
||||
|
||||
|
@ -2053,7 +2099,9 @@ module IBUFDS_IBUFDISABLE (...);
|
|||
parameter SIM_DEVICE = "7SERIES";
|
||||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
input IBUFDISABLE;
|
||||
endmodule
|
||||
|
@ -2066,12 +2114,50 @@ module IBUFDS_INTERMDISABLE (...);
|
|||
parameter SIM_DEVICE = "7SERIES";
|
||||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
input IBUFDISABLE;
|
||||
input INTERMDISABLE;
|
||||
endmodule
|
||||
|
||||
module IBUFG (...);
|
||||
parameter CAPACITANCE = "DONT_CARE";
|
||||
parameter IBUF_DELAY_VALUE = "0";
|
||||
parameter IBUF_LOW_PWR = "TRUE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
endmodule
|
||||
|
||||
module IBUFGDS (...);
|
||||
parameter CAPACITANCE = "DONT_CARE";
|
||||
parameter DIFF_TERM = "FALSE";
|
||||
parameter IBUF_DELAY_VALUE = "0";
|
||||
parameter IBUF_LOW_PWR = "TRUE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
endmodule
|
||||
|
||||
module IBUFGDS_DIFF_OUT (...);
|
||||
parameter DIFF_TERM = "FALSE";
|
||||
parameter DQS_BIAS = "FALSE";
|
||||
parameter IBUF_LOW_PWR = "TRUE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
output O;
|
||||
output OB;
|
||||
(* iopad_external_pin *)
|
||||
input I;
|
||||
(* iopad_external_pin *)
|
||||
input IB;
|
||||
endmodule
|
||||
|
||||
(* keep *)
|
||||
module ICAPE2 (...);
|
||||
parameter [31:0] DEVICE_ID = 32'h04244093;
|
||||
|
@ -2095,6 +2181,7 @@ module IDDR (...);
|
|||
parameter XON = "TRUE";
|
||||
output Q1;
|
||||
output Q2;
|
||||
(* clkbuf_sink *)
|
||||
input C;
|
||||
input CE;
|
||||
input D;
|
||||
|
@ -2112,7 +2199,9 @@ module IDDR_2CLK (...);
|
|||
parameter SRTYPE = "SYNC";
|
||||
output Q1;
|
||||
output Q2;
|
||||
(* clkbuf_sink *)
|
||||
input C;
|
||||
(* clkbuf_sink *)
|
||||
input CB;
|
||||
input CE;
|
||||
input D;
|
||||
|
@ -2124,6 +2213,7 @@ endmodule
|
|||
module IDELAYCTRL (...);
|
||||
parameter SIM_DEVICE = "7SERIES";
|
||||
output RDY;
|
||||
(* clkbuf_sink *)
|
||||
input REFCLK;
|
||||
input RST;
|
||||
endmodule
|
||||
|
@ -2143,6 +2233,7 @@ module IDELAYE2 (...);
|
|||
parameter integer SIM_DELAY_D = 0;
|
||||
output [4:0] CNTVALUEOUT;
|
||||
output DATAOUT;
|
||||
(* clkbuf_sink *)
|
||||
input C;
|
||||
input CE;
|
||||
input CINVCTRL;
|
||||
|
@ -2174,9 +2265,11 @@ module IN_FIFO (...);
|
|||
output [7:0] Q7;
|
||||
output [7:0] Q8;
|
||||
output [7:0] Q9;
|
||||
(* clkbuf_sink *)
|
||||
input RDCLK;
|
||||
input RDEN;
|
||||
input RESET;
|
||||
(* clkbuf_sink *)
|
||||
input WRCLK;
|
||||
input WREN;
|
||||
input [3:0] D0;
|
||||
|
@ -2197,8 +2290,10 @@ module IOBUF (...);
|
|||
parameter IOSTANDARD = "DEFAULT";
|
||||
parameter SLEW = "SLOW";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
input I, T;
|
||||
input I;
|
||||
input T;
|
||||
endmodule
|
||||
|
||||
module IOBUF_DCIEN (...);
|
||||
|
@ -2209,6 +2304,7 @@ module IOBUF_DCIEN (...);
|
|||
parameter SLEW = "SLOW";
|
||||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
input DCITERMDISABLE;
|
||||
input I;
|
||||
|
@ -2224,6 +2320,7 @@ module IOBUF_INTERMDISABLE (...);
|
|||
parameter SLEW = "SLOW";
|
||||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
input I;
|
||||
input IBUFDISABLE;
|
||||
|
@ -2238,8 +2335,11 @@ module IOBUFDS (...);
|
|||
parameter IOSTANDARD = "DEFAULT";
|
||||
parameter SLEW = "SLOW";
|
||||
output O;
|
||||
inout IO, IOB;
|
||||
input I, T;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
inout IOB;
|
||||
input I;
|
||||
input T;
|
||||
endmodule
|
||||
|
||||
module IOBUFDS_DCIEN (...);
|
||||
|
@ -2251,7 +2351,9 @@ module IOBUFDS_DCIEN (...);
|
|||
parameter SLEW = "SLOW";
|
||||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
(* iopad_external_pin *)
|
||||
inout IOB;
|
||||
input DCITERMDISABLE;
|
||||
input I;
|
||||
|
@ -2266,7 +2368,9 @@ module IOBUFDS_DIFF_OUT (...);
|
|||
parameter IOSTANDARD = "DEFAULT";
|
||||
output O;
|
||||
output OB;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
(* iopad_external_pin *)
|
||||
inout IOB;
|
||||
input I;
|
||||
input TM;
|
||||
|
@ -2282,7 +2386,9 @@ module IOBUFDS_DIFF_OUT_DCIEN (...);
|
|||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
output OB;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
(* iopad_external_pin *)
|
||||
inout IOB;
|
||||
input DCITERMDISABLE;
|
||||
input I;
|
||||
|
@ -2300,7 +2406,9 @@ module IOBUFDS_DIFF_OUT_INTERMDISABLE (...);
|
|||
parameter USE_IBUFDISABLE = "TRUE";
|
||||
output O;
|
||||
output OB;
|
||||
(* iopad_external_pin *)
|
||||
inout IO;
|
||||
(* iopad_external_pin *)
|
||||
inout IOB;
|
||||
input I;
|
||||
input IBUFDISABLE;
|
||||
|
@ -2348,15 +2456,21 @@ module ISERDESE2 (...);
|
|||
input BITSLIP;
|
||||
input CE1;
|
||||
input CE2;
|
||||
(* clkbuf_sink *)
|
||||
input CLK;
|
||||
(* clkbuf_sink *)
|
||||
input CLKB;
|
||||
(* clkbuf_sink *)
|
||||
input CLKDIV;
|
||||
(* clkbuf_sink *)
|
||||
input CLKDIVP;
|
||||
input D;
|
||||
input DDLY;
|
||||
input DYNCLKDIVSEL;
|
||||
input DYNCLKSEL;
|
||||
(* clkbuf_sink *)
|
||||
input OCLK;
|
||||
(* clkbuf_sink *)
|
||||
input OCLKB;
|
||||
input OFB;
|
||||
input RST;
|
||||
|
@ -2375,7 +2489,10 @@ module LDCE (...);
|
|||
parameter MSGON = "TRUE";
|
||||
parameter XON = "TRUE";
|
||||
output Q;
|
||||
input CLR, D, G, GE;
|
||||
input CLR;
|
||||
input D;
|
||||
input G;
|
||||
input GE;
|
||||
endmodule
|
||||
|
||||
module LDPE (...);
|
||||
|
@ -2385,7 +2502,10 @@ module LDPE (...);
|
|||
parameter MSGON = "TRUE";
|
||||
parameter XON = "TRUE";
|
||||
output Q;
|
||||
input D, G, GE, PRE;
|
||||
input D;
|
||||
input G;
|
||||
input GE;
|
||||
input PRE;
|
||||
endmodule
|
||||
|
||||
module MMCME2_ADV (...);
|
||||
|
@ -2533,7 +2653,10 @@ module OBUFDS (...);
|
|||
parameter CAPACITANCE = "DONT_CARE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
parameter SLEW = "SLOW";
|
||||
output O, OB;
|
||||
(* iopad_external_pin *)
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
output OB;
|
||||
input I;
|
||||
endmodule
|
||||
|
||||
|
@ -2542,20 +2665,27 @@ module OBUFT (...);
|
|||
parameter integer DRIVE = 12;
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
parameter SLEW = "SLOW";
|
||||
(* iopad_external_pin *)
|
||||
output O;
|
||||
input I, T;
|
||||
input I;
|
||||
input T;
|
||||
endmodule
|
||||
|
||||
module OBUFTDS (...);
|
||||
parameter CAPACITANCE = "DONT_CARE";
|
||||
parameter IOSTANDARD = "DEFAULT";
|
||||
parameter SLEW = "SLOW";
|
||||
output O, OB;
|
||||
input I, T;
|
||||
(* iopad_external_pin *)
|
||||
output O;
|
||||
(* iopad_external_pin *)
|
||||
output OB;
|
||||
input I;
|
||||
input T;
|
||||
endmodule
|
||||
|
||||
module ODDR (...);
|
||||
output Q;
|
||||
(* clkbuf_sink *)
|
||||
input C;
|
||||
input CE;
|
||||
input D1;
|
||||
|
@ -2586,6 +2716,7 @@ module ODELAYE2 (...);
|
|||
parameter integer SIM_DELAY_D = 0;
|
||||
output [4:0] CNTVALUEOUT;
|
||||
output DATAOUT;
|
||||
(* clkbuf_sink *)
|
||||
input C;
|
||||
input CE;
|
||||
input CINVCTRL;
|
||||
|
@ -2631,7 +2762,9 @@ module OSERDESE2 (...);
|
|||
output TBYTEOUT;
|
||||
output TFB;
|
||||
output TQ;
|
||||
(* clkbuf_sink *)
|
||||
input CLK;
|
||||
(* clkbuf_sink *)
|
||||
input CLKDIV;
|
||||
input D1;
|
||||
input D2;
|
||||
|
@ -2673,9 +2806,11 @@ module OUT_FIFO (...);
|
|||
output [3:0] Q9;
|
||||
output [7:0] Q5;
|
||||
output [7:0] Q6;
|
||||
(* clkbuf_sink *)
|
||||
input RDCLK;
|
||||
input RDEN;
|
||||
input RESET;
|
||||
(* clkbuf_sink *)
|
||||
input WRCLK;
|
||||
input WREN;
|
||||
input [7:0] D0;
|
||||
|
@ -3659,7 +3794,17 @@ module RAM128X1S (...);
|
|||
parameter [127:0] INIT = 128'h00000000000000000000000000000000;
|
||||
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, A5, A6, D, WCLK, WE;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input A5;
|
||||
input A6;
|
||||
input D;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
||||
module RAM256X1S (...);
|
||||
|
@ -3668,6 +3813,7 @@ module RAM256X1S (...);
|
|||
output O;
|
||||
input [7:0] A;
|
||||
input D;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
@ -3690,6 +3836,7 @@ module RAM32M (...);
|
|||
input [1:0] DIB;
|
||||
input [1:0] DIC;
|
||||
input [1:0] DID;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
@ -3698,22 +3845,48 @@ module RAM32X1S (...);
|
|||
parameter [31:0] INIT = 32'h00000000;
|
||||
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, D, WCLK, WE;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input D;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
||||
module RAM32X1S_1 (...);
|
||||
parameter [31:0] INIT = 32'h00000000;
|
||||
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, D, WCLK, WE;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input D;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
||||
module RAM32X2S (...);
|
||||
parameter [31:0] INIT_00 = 32'h00000000;
|
||||
parameter [31:0] INIT_01 = 32'h00000000;
|
||||
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
|
||||
output O0, O1;
|
||||
input A0, A1, A2, A3, A4, D0, D1, WCLK, WE;
|
||||
output O0;
|
||||
output O1;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input D0;
|
||||
input D1;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
||||
module RAM64M (...);
|
||||
|
@ -3734,6 +3907,7 @@ module RAM64M (...);
|
|||
input DIB;
|
||||
input DIC;
|
||||
input DID;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
@ -3742,46 +3916,97 @@ module RAM64X1S (...);
|
|||
parameter [63:0] INIT = 64'h0000000000000000;
|
||||
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, A5, D, WCLK, WE;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input A5;
|
||||
input D;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
||||
module RAM64X1S_1 (...);
|
||||
parameter [63:0] INIT = 64'h0000000000000000;
|
||||
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, A5, D, WCLK, WE;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input A5;
|
||||
input D;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
||||
module RAM64X2S (...);
|
||||
parameter [63:0] INIT_00 = 64'h0000000000000000;
|
||||
parameter [63:0] INIT_01 = 64'h0000000000000000;
|
||||
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
|
||||
output O0, O1;
|
||||
input A0, A1, A2, A3, A4, A5, D0, D1, WCLK, WE;
|
||||
output O0;
|
||||
output O1;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input A5;
|
||||
input D0;
|
||||
input D1;
|
||||
(* clkbuf_sink *)
|
||||
input WCLK;
|
||||
input WE;
|
||||
endmodule
|
||||
|
||||
module ROM128X1 (...);
|
||||
parameter [127:0] INIT = 128'h00000000000000000000000000000000;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, A5, A6;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input A5;
|
||||
input A6;
|
||||
endmodule
|
||||
|
||||
module ROM256X1 (...);
|
||||
parameter [255:0] INIT = 256'h0000000000000000000000000000000000000000000000000000000000000000;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, A5, A6, A7;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input A5;
|
||||
input A6;
|
||||
input A7;
|
||||
endmodule
|
||||
|
||||
module ROM32X1 (...);
|
||||
parameter [31:0] INIT = 32'h00000000;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
endmodule
|
||||
|
||||
module ROM64X1 (...);
|
||||
parameter [63:0] INIT = 64'h0000000000000000;
|
||||
output O;
|
||||
input A0, A1, A2, A3, A4, A5;
|
||||
input A0;
|
||||
input A1;
|
||||
input A2;
|
||||
input A3;
|
||||
input A4;
|
||||
input A5;
|
||||
endmodule
|
||||
|
||||
(* keep *)
|
||||
|
|
|
@ -63,6 +63,9 @@ struct SynthXilinxPass : public ScriptPass
|
|||
log(" generate an output netlist (and BLIF file) suitable for VPR\n");
|
||||
log(" (this feature is experimental and incomplete)\n");
|
||||
log("\n");
|
||||
log(" -ise\n");
|
||||
log(" generate an output netlist suitable for ISE (enables -iopad)\n");
|
||||
log("\n");
|
||||
log(" -nobram\n");
|
||||
log(" do not use block RAM cells in output netlist\n");
|
||||
log("\n");
|
||||
|
@ -78,6 +81,15 @@ struct SynthXilinxPass : public ScriptPass
|
|||
log(" -nowidelut\n");
|
||||
log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
|
||||
log("\n");
|
||||
log(" -iopad\n");
|
||||
log(" enable I/O buffer insertion (selected automatically by -ise)\n");
|
||||
log("\n");
|
||||
log(" -noiopad\n");
|
||||
log(" disable I/O buffer insertion (only useful with -ise)\n");
|
||||
log("\n");
|
||||
log(" -noclkbuf\n");
|
||||
log(" disable automatic clock buffer insertion\n");
|
||||
log("\n");
|
||||
log(" -widemux <int>\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");
|
||||
|
@ -104,7 +116,7 @@ struct SynthXilinxPass : public ScriptPass
|
|||
}
|
||||
|
||||
std::string top_opt, edif_file, blif_file, family;
|
||||
bool flatten, retime, vpr, nobram, nolutram, nosrl, nocarry, nowidelut, abc9;
|
||||
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, abc9;
|
||||
bool flatten_before_abc;
|
||||
int widemux;
|
||||
|
||||
|
@ -117,6 +129,10 @@ struct SynthXilinxPass : public ScriptPass
|
|||
flatten = false;
|
||||
retime = false;
|
||||
vpr = false;
|
||||
ise = false;
|
||||
iopad = false;
|
||||
noiopad = false;
|
||||
noclkbuf = false;
|
||||
nocarry = false;
|
||||
nobram = false;
|
||||
nolutram = false;
|
||||
|
@ -184,6 +200,22 @@ struct SynthXilinxPass : public ScriptPass
|
|||
vpr = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-ise") {
|
||||
ise = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-iopad") {
|
||||
iopad = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noiopad") {
|
||||
noiopad = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noclkbuf") {
|
||||
noclkbuf = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nocarry") {
|
||||
nocarry = true;
|
||||
continue;
|
||||
|
@ -430,6 +462,18 @@ struct SynthXilinxPass : public ScriptPass
|
|||
run("clean");
|
||||
}
|
||||
|
||||
if (check_label("finalize")) {
|
||||
bool do_iopad = iopad || (ise && !noiopad);
|
||||
if (help_mode || !noclkbuf) {
|
||||
if (help_mode || do_iopad)
|
||||
run("clkbufmap -buf BUFG O:I -inpad IBUFG O:I", "(skip if '-noclkbuf', '-inpad' passed if '-iopad' or '-ise' and not '-noiopad')");
|
||||
else
|
||||
run("clkbufmap -buf BUFG O:I");
|
||||
}
|
||||
if (do_iopad)
|
||||
run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
|
||||
}
|
||||
|
||||
if (check_label("check")) {
|
||||
run("hierarchy -check");
|
||||
run("stat -tech xilinx");
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
module RAMB8BWER (
|
||||
(* clkbuf_sink *)
|
||||
input CLKAWRCLK,
|
||||
(* clkbuf_sink *)
|
||||
input CLKBRDCLK,
|
||||
input ENAWREN,
|
||||
input ENBRDEN,
|
||||
|
@ -87,7 +89,9 @@ module RAMB8BWER (
|
|||
endmodule
|
||||
|
||||
module RAMB16BWER (
|
||||
(* clkbuf_sink *)
|
||||
input CLKA,
|
||||
(* clkbuf_sink *)
|
||||
input CLKB,
|
||||
input ENA,
|
||||
input ENB,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
module RAMB18E1 (
|
||||
(* clkbuf_sink *)
|
||||
input CLKARDCLK,
|
||||
(* clkbuf_sink *)
|
||||
input CLKBWRCLK,
|
||||
input ENARDEN,
|
||||
input ENBWREN,
|
||||
|
@ -123,7 +125,9 @@ module RAMB18E1 (
|
|||
endmodule
|
||||
|
||||
module RAMB36E1 (
|
||||
(* clkbuf_sink *)
|
||||
input CLKARDCLK,
|
||||
(* clkbuf_sink *)
|
||||
input CLKBWRCLK,
|
||||
input ENARDEN,
|
||||
input ENBWREN,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module test(input clk, input [3:0] bar, output [3:0] foo);
|
||||
module test(input clk, input [3:0] bar, output [3:0] foo, asdf);
|
||||
reg [3:0] foo = 0;
|
||||
reg [3:0] last_bar = 0;
|
||||
reg [3:0] asdf = 4'b1xxx;
|
||||
|
||||
always @*
|
||||
foo[1:0] <= bar[1:0];
|
||||
|
@ -11,5 +12,10 @@ module test(input clk, input [3:0] bar, output [3:0] foo);
|
|||
always @(posedge clk)
|
||||
last_bar <= bar;
|
||||
|
||||
always @(posedge clk)
|
||||
asdf[3] <= bar[3];
|
||||
always @*
|
||||
asdf[2:0] = 3'b111;
|
||||
|
||||
assert property (foo == {last_bar[3:2], bar[1:0]});
|
||||
endmodule
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
*.log
|
||||
/*.mk
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
read_verilog <<EOT
|
||||
module clkbuf (input i, (* clkbuf_driver *) output o); endmodule
|
||||
module dff ((* clkbuf_sink *) input clk, input d, output q); endmodule
|
||||
module dffe ((* clkbuf_sink *) input c, input d, e, output q); endmodule
|
||||
module latch (input e, d, output q); endmodule
|
||||
module clkgen (output o); endmodule
|
||||
|
||||
module top(input clk1, clk2, clk3, d, e, output [4:0] q);
|
||||
wire clk4, clk5, clk6;
|
||||
dff s0 (.clk(clk1), .d(d), .q(q[0]));
|
||||
dffe s1 (.c(clk2), .d(d), .e(e), .q(q[1]));
|
||||
latch s2 (.e(clk3), .d(d), .q(q[2]));
|
||||
sub s3 (.sclk4(clk4), .sclk5(clk5), .sclk6(clk6), .sd(d), .sq(q[3]));
|
||||
dff s4 (.clk(clk4), .d(d), .q(q[4]));
|
||||
dff s5 (.clk(clk5), .d(d), .q(q[4]));
|
||||
dff s6 (.clk(clk6), .d(d), .q(q[4]));
|
||||
endmodule
|
||||
|
||||
module sub(output sclk4, output sclk5, output sclk6, input sd, output sq);
|
||||
wire tmp;
|
||||
clkgen s7(.o(sclk4));
|
||||
clkgen s8(.o(sclk5));
|
||||
clkgen s9(.o(tmp));
|
||||
clkbuf s10(.i(tmp), .o(sclk6));
|
||||
dff s11(.clk(sclk4), .d(sd), .q(sq));
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -auto-top
|
||||
design -save ref
|
||||
|
||||
# ----------------------
|
||||
|
||||
design -load ref
|
||||
clkbufmap -buf clkbuf o:i
|
||||
select -assert-count 3 top/t:clkbuf
|
||||
select -assert-count 2 sub/t:clkbuf
|
||||
select -set clk1 w:clk1 %a %co t:clkbuf %i # Find 'clk1' fanouts that are 'clkbuf'
|
||||
select -assert-count 1 @clk1 # Check there is one such fanout
|
||||
select -assert-count 1 @clk1 %x:+[o] %co c:s* %i # Check that the 'o' of that clkbuf drives one fanout
|
||||
select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i # And that one fanout is 's0'
|
||||
select -set clk2 w:clk2 %a %co t:clkbuf %i
|
||||
select -assert-count 1 @clk2
|
||||
select -assert-count 1 @clk2 %x:+[o] %co c:s* %i
|
||||
select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i
|
||||
select -set clk5 w:clk5 %a %ci t:clkbuf %i
|
||||
select -assert-count 1 @clk5
|
||||
select -assert-count 1 @clk5 %x:+[o] %co c:s5 %i
|
||||
select -assert-count 1 @clk5 %x:+[i] %ci c:s3 %i
|
||||
select -set sclk4 w:sclk4 %a %ci t:clkbuf %i
|
||||
select -assert-count 1 @sclk4
|
||||
select -assert-count 1 @sclk4 %x:+[o] %co c:s11 %i
|
||||
select -assert-count 1 @sclk4 %x:+[i] %ci c:s7 %i
|
||||
|
||||
# ----------------------
|
||||
|
||||
design -load ref
|
||||
setattr -set clkbuf_inhibit 0 w:clk1
|
||||
setattr -set clkbuf_inhibit 1 w:clk2
|
||||
clkbufmap -buf clkbuf o:i
|
||||
select -assert-count 2 top/t:clkbuf
|
||||
select -set clk1 w:clk1 %a %co t:clkbuf %i # Find 'clk1' fanouts that are 'clkbuf'
|
||||
select -assert-count 1 @clk1 # Check there is one such fanout
|
||||
select -assert-count 1 @clk1 %x:+[o] %co c:s* %i # Check that the 'o' of that clkbuf drives one fanout
|
||||
select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i # And that one fanout is 's0'
|
||||
select -assert-count 0 w:clk2 %a %co t:clkbuf %i
|
||||
|
||||
# ----------------------
|
||||
|
||||
design -load ref
|
||||
setattr -set clkbuf_inhibit 1 w:clk1
|
||||
setattr -set buffer_type "bufg" w:clk2
|
||||
clkbufmap -buf clkbuf o:i w:* a:buffer_type=none a:buffer_type=bufr %u %d
|
||||
select -assert-count 3 top/t:clkbuf
|
||||
select -assert-count 2 sub/t:clkbuf
|
||||
select -set clk1 w:clk1 %a %co t:clkbuf %i # Find 'clk1' fanouts that are 'clkbuf'
|
||||
select -assert-count 1 @clk1 # Check there is one such fanout
|
||||
select -assert-count 1 @clk1 %x:+[o] %co c:s* %i # Check that the 'o' of that clkbuf drives one fanout
|
||||
select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i # And that one fanout is 's0'
|
||||
select -set clk2 w:clk2 %a %co t:clkbuf %i # Find 'clk1' fanouts that are 'clkbuf'
|
||||
select -assert-count 1 @clk2 # Check there is one such fanout
|
||||
select -assert-count 1 @clk2 %x:+[o] %co c:s* %i # Check that the 'o' of that clkbuf drives one fanout
|
||||
select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i # And that one fanout is 's0'
|
||||
|
||||
# ----------------------
|
||||
|
||||
design -load ref
|
||||
setattr -set buffer_type "none" w:clk1
|
||||
setattr -set buffer_type "bufr" w:clk2
|
||||
setattr -set buffer_type "bufr" w:sclk4
|
||||
setattr -set buffer_type "bufr" w:sclk5
|
||||
clkbufmap -buf clkbuf o:i w:* a:buffer_type=none a:buffer_type=bufr %u %d
|
||||
select -assert-count 0 w:clk1 %a %co t:clkbuf %i
|
||||
select -assert-count 0 w:clk2 %a %co t:clkbuf %i
|
||||
select -assert-count 0 top/t:clkbuf
|
||||
select -assert-count 1 sub/t:clkbuf
|
|
@ -1,10 +1,20 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
for x in *_runtest.sh; do
|
||||
echo "Running $x.."
|
||||
if ! bash $x &> ${x%.sh}.log; then
|
||||
tail ${x%.sh}.log
|
||||
echo ERROR
|
||||
exit 1
|
||||
{
|
||||
echo "all::"
|
||||
for x in *.ys; do
|
||||
echo "all:: run-$x"
|
||||
echo "run-$x:"
|
||||
echo " @echo 'Running $x..'"
|
||||
echo " @../../yosys -ql ${x%.ys}.log $x"
|
||||
done
|
||||
for s in *.sh; do
|
||||
if [ "$s" != "run-test.sh" ]; then
|
||||
echo "all:: run-$s"
|
||||
echo "run-$s:"
|
||||
echo " @echo 'Running $s..'"
|
||||
echo " @bash $s > ${s%.sh}.log 2>&1"
|
||||
fi
|
||||
done
|
||||
} > run-test.mk
|
||||
exec ${MAKE:-make} -f run-test.mk
|
||||
|
|
Loading…
Reference in New Issue