3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-22 13:53:40 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jim Lawson 2019-03-01 10:31:26 -08:00
commit 4cce7f6967
31 changed files with 622 additions and 105 deletions

View file

@ -169,7 +169,6 @@ struct FirrtlWorker
return *str == '\\' ? str + 1 : str; return *str == '\\' ? str + 1 : str;
} }
std::string cellname(RTLIL::Cell *cell) std::string cellname(RTLIL::Cell *cell)
{ {
return fid(cell->name).c_str(); return fid(cell->name).c_str();
@ -219,29 +218,42 @@ struct FirrtlWorker
if (it->second.size() > 0) { if (it->second.size() > 0) {
const SigSpec &secondSig = it->second; const SigSpec &secondSig = it->second;
const std::string firstName = cell_name + "." + make_id(it->first); const std::string firstName = cell_name + "." + make_id(it->first);
const std::string secondName = make_expr(secondSig); const std::string secondExpr = make_expr(secondSig);
// Find the direction for this port. // Find the direction for this port.
FDirection dir = getPortFDirection(it->first, instModule); FDirection dir = getPortFDirection(it->first, instModule);
std::string source, sink; std::string sourceExpr, sinkExpr;
const SigSpec *sinkSig = nullptr;
switch (dir) { switch (dir) {
case FD_INOUT: case FD_INOUT:
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second)); log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
case FD_OUT: case FD_OUT:
source = firstName; sourceExpr = firstName;
sink = secondName; sinkExpr = secondExpr;
sinkSig = &secondSig;
break; break;
case FD_NODIRECTION: case FD_NODIRECTION:
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second)); log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
/* FALL_THROUGH */ /* FALL_THROUGH */
case FD_IN: case FD_IN:
source = secondName; sourceExpr = secondExpr;
sink = firstName; sinkExpr = firstName;
break; break;
default: default:
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir); log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir);
break; break;
} }
wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sink.c_str(), source.c_str())); // Check for subfield assignment.
std::string bitsString = "bits(";
if (sinkExpr.substr(0, bitsString.length()) == bitsString ) {
if (sinkSig == nullptr)
log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str());
// Don't generate the assignment here.
// Add the source and sink to the "reverse_wire_map" and we'll output the assignment
// as part of the coalesced subfield assignments for this wire.
register_reverse_wire_map(sourceExpr, *sinkSig);
} else {
wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sinkExpr.c_str(), sourceExpr.c_str()));
}
} }
} }
wire_exprs.push_back(stringf("\n")); wire_exprs.push_back(stringf("\n"));

View file

@ -48,7 +48,7 @@ struct ProtobufDesignSerializer
ProtobufDesignSerializer(bool use_selection, bool aig_mode) : ProtobufDesignSerializer(bool use_selection, bool aig_mode) :
aig_mode_(aig_mode), use_selection_(use_selection) { } aig_mode_(aig_mode), use_selection_(use_selection) { }
string get_name(IdString name) string get_name(IdString name)
{ {
return RTLIL::unescape_id(name); return RTLIL::unescape_id(name);
@ -60,7 +60,7 @@ struct ProtobufDesignSerializer
{ {
for (auto &param : parameters) { for (auto &param : parameters) {
std::string key = get_name(param.first); std::string key = get_name(param.first);
yosys::pb::Parameter pb_param; yosys::pb::Parameter pb_param;
@ -207,7 +207,7 @@ struct ProtobufDesignSerializer
(*models)[aig.name] = pb_model; (*models)[aig.name] = pb_model;
} }
} }
void serialize_design(yosys::pb::Design *pb, Design *design) void serialize_design(yosys::pb::Design *pb, Design *design)
{ {
GOOGLE_PROTOBUF_VERIFY_VERSION; GOOGLE_PROTOBUF_VERIFY_VERSION;

View file

@ -1103,20 +1103,27 @@ struct Smt2Worker
break; break;
Const initword = init_data.extract(i*width, width, State::Sx); Const initword = init_data.extract(i*width, width, State::Sx);
Const initmask = initword;
bool gen_init_constr = false; bool gen_init_constr = false;
for (auto bit : initword.bits) for (int k = 0; k < GetSize(initword); k++) {
if (bit == State::S0 || bit == State::S1) if (initword[k] == State::S0 || initword[k] == State::S1) {
gen_init_constr = true; gen_init_constr = true;
initmask[k] = State::S1;
} else {
initmask[k] = State::S0;
initword[k] = State::S0;
}
}
if (gen_init_constr) if (gen_init_constr)
{ {
if (statebv) if (statebv)
/* FIXME */; /* FIXME */;
else else
init_list.push_back(stringf("(= (select (|%s#%d#0| state) #b%s) #b%s) ; %s[%d]", init_list.push_back(stringf("(= (bvand (select (|%s#%d#0| state) #b%s) #b%s) #b%s) ; %s[%d]",
get_id(module), arrayid, Const(i, abits).as_string().c_str(), get_id(module), arrayid, Const(i, abits).as_string().c_str(),
initword.as_string().c_str(), get_id(cell), i)); initmask.as_string().c_str(), initword.as_string().c_str(), get_id(cell), i));
} }
} }
} }

View file

@ -33,7 +33,7 @@
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, defparam, decimal; bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, defparam, decimal, siminit;
int auto_name_counter, auto_name_offset, auto_name_digits; int auto_name_counter, auto_name_offset, auto_name_digits;
std::map<RTLIL::IdString, int> auto_name_map; std::map<RTLIL::IdString, int> auto_name_map;
std::set<RTLIL::IdString> reg_wires, reg_ct; std::set<RTLIL::IdString> reg_wires, reg_ct;
@ -1310,7 +1310,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
} }
} }
if (reg_ct.count(cell->type) && cell->hasPort("\\Q")) { if (siminit && reg_ct.count(cell->type) && cell->hasPort("\\Q")) {
std::stringstream ss; std::stringstream ss;
dump_reg_init(ss, cell->getPort("\\Q")); dump_reg_init(ss, cell->getPort("\\Q"));
if (!ss.str().empty()) { if (!ss.str().empty()) {
@ -1607,6 +1607,10 @@ struct VerilogBackend : public Backend {
log(" without this option all internal cells are converted to Verilog\n"); log(" without this option all internal cells are converted to Verilog\n");
log(" expressions.\n"); log(" expressions.\n");
log("\n"); log("\n");
log(" -siminit\n");
log(" add initial statements with hierarchical refs to initialize FFs when\n");
log(" in -noexpr mode.\n");
log("\n");
log(" -nodec\n"); log(" -nodec\n");
log(" 32-bit constant values are by default dumped as decimal numbers,\n"); log(" 32-bit constant values are by default dumped as decimal numbers,\n");
log(" not bit pattern. This option deactivates this feature and instead\n"); log(" not bit pattern. This option deactivates this feature and instead\n");
@ -1663,6 +1667,7 @@ struct VerilogBackend : public Backend {
nostr = false; nostr = false;
defparam = false; defparam = false;
decimal = false; decimal = false;
siminit = false;
auto_prefix = ""; auto_prefix = "";
bool blackboxes = false; bool blackboxes = false;
@ -1739,6 +1744,10 @@ struct VerilogBackend : public Backend {
decimal = true; decimal = true;
continue; continue;
} }
if (arg == "-siminit") {
siminit = true;
continue;
}
if (arg == "-blackboxes") { if (arg == "-blackboxes") {
blackboxes = true; blackboxes = true;
continue; continue;

View file

@ -2316,7 +2316,7 @@ struct ReadPass : public Pass {
} }
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{ {
if (args.size() < 2) if (args.size() < 2 || args[1][0] != '-')
log_cmd_error("Missing mode parameter.\n"); log_cmd_error("Missing mode parameter.\n");
if (args.size() < 3) if (args.size() < 3)

View file

@ -1,12 +1,12 @@
// //
// yosys -- Yosys Open SYnthesis Suite // yosys -- Yosys Open SYnthesis Suite
// //
// Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com> // Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com>
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies. // copyright notice and this permission notice appear in all copies.
// //
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
@ -73,7 +73,7 @@ message Module {
BitVector bits = 2; BitVector bits = 2;
} }
map<string, Port> port = 2; map<string, Port> port = 2;
// Named cells in this module. // Named cells in this module.
message Cell { message Cell {
// Set to true when the name of this cell is automatically created and // Set to true when the name of this cell is automatically created and
@ -129,7 +129,7 @@ message Model {
TYPE_FALSE = 6; TYPE_FALSE = 6;
}; };
Type type = 1; Type type = 1;
message Port { message Port {
// Name of port. // Name of port.
string portname = 1; string portname = 1;
@ -148,7 +148,7 @@ message Model {
// Set for AND, NAND. // Set for AND, NAND.
Gate gate = 3; Gate gate = 3;
} }
// Set when the node drives given output port(s). // Set when the node drives given output port(s).
message OutPort { message OutPort {
// Name of port. // Name of port.

View file

@ -53,6 +53,7 @@ struct WreduceWorker
std::set<Cell*, IdString::compare_ptr_by_name<Cell>> work_queue_cells; std::set<Cell*, IdString::compare_ptr_by_name<Cell>> work_queue_cells;
std::set<SigBit> work_queue_bits; std::set<SigBit> work_queue_bits;
pool<SigBit> keep_bits; pool<SigBit> keep_bits;
dict<SigBit, State> init_bits;
WreduceWorker(WreduceConfig *config, Module *module) : WreduceWorker(WreduceConfig *config, Module *module) :
config(config), module(module), mi(module) { } config(config), module(module), mi(module) { }
@ -141,6 +142,7 @@ struct WreduceWorker
SigSpec sig_d = mi.sigmap(cell->getPort("\\D")); SigSpec sig_d = mi.sigmap(cell->getPort("\\D"));
SigSpec sig_q = mi.sigmap(cell->getPort("\\Q")); SigSpec sig_q = mi.sigmap(cell->getPort("\\Q"));
Const initval;
int width_before = GetSize(sig_q); int width_before = GetSize(sig_q);
@ -150,16 +152,24 @@ struct WreduceWorker
bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0; bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0;
bool sign_ext = !zero_ext; bool sign_ext = !zero_ext;
for (int i = 0; i < GetSize(sig_q); i++) {
SigBit bit = sig_q[i];
if (init_bits.count(bit))
initval.bits.push_back(init_bits.at(bit));
else
initval.bits.push_back(State::Sx);
}
for (int i = GetSize(sig_q)-1; i >= 0; i--) for (int i = GetSize(sig_q)-1; i >= 0; i--)
{ {
if (zero_ext && sig_d[i] == State::S0) { if (zero_ext && sig_d[i] == State::S0 && (initval[i] == State::S0 || initval[i] == State::Sx)) {
module->connect(sig_q[i], State::S0); module->connect(sig_q[i], State::S0);
sig_d.remove(i); sig_d.remove(i);
sig_q.remove(i); sig_q.remove(i);
continue; continue;
} }
if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1]) { if (sign_ext && i > 0 && sig_d[i] == sig_d[i-1] && initval[i] == initval[i-1]) {
module->connect(sig_q[i], sig_q[i-1]); module->connect(sig_q[i], sig_q[i-1]);
sig_d.remove(i); sig_d.remove(i);
sig_q.remove(i); sig_q.remove(i);
@ -167,7 +177,7 @@ struct WreduceWorker
} }
auto info = mi.query(sig_q[i]); auto info = mi.query(sig_q[i]);
if (!info->is_output && GetSize(info->ports) <= 1 && !keep_bits.count(mi.sigmap(sig_q[i]))) { if (!info->is_output && GetSize(info->ports) == 1 && !keep_bits.count(mi.sigmap(sig_q[i]))) {
sig_d.remove(i); sig_d.remove(i);
sig_q.remove(i); sig_q.remove(i);
zero_ext = false; zero_ext = false;
@ -183,10 +193,11 @@ struct WreduceWorker
if (GetSize(sig_q) == 0) { if (GetSize(sig_q) == 0) {
log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type)); log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type));
module->remove(cell);
return; return;
} }
log("Removed top %d bits (of %d) from mux cell %s.%s (%s).\n", width_before - GetSize(sig_q), width_before, log("Removed top %d bits (of %d) from FF cell %s.%s (%s).\n", width_before - GetSize(sig_q), width_before,
log_id(module), log_id(cell), log_id(cell->type)); log_id(module), log_id(cell), log_id(cell->type));
for (auto bit : sig_d) for (auto bit : sig_d)
@ -376,10 +387,18 @@ struct WreduceWorker
void run() void run()
{ {
for (auto w : module->wires()) for (auto w : module->wires()) {
if (w->get_bool_attribute("\\keep")) if (w->get_bool_attribute("\\keep"))
for (auto bit : mi.sigmap(w)) for (auto bit : mi.sigmap(w))
keep_bits.insert(bit); keep_bits.insert(bit);
if (w->attributes.count("\\init")) {
Const initval = w->attributes.at("\\init");
SigSpec initsig = mi.sigmap(w);
int width = std::min(GetSize(initval), GetSize(initsig));
for (int i = 0; i < width; i++)
init_bits[initsig[i]] = initval[i];
}
}
for (auto c : module->selected_cells()) for (auto c : module->selected_cells())
work_queue_cells.insert(c); work_queue_cells.insert(c);

View file

@ -4,5 +4,5 @@ passes/pmgen/ice40_dsp.o: passes/pmgen/ice40_dsp_pm.h
EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h
.SECONDARY: passes/pmgen/ice40_dsp_pm.h .SECONDARY: passes/pmgen/ice40_dsp_pm.h
passes/pmgen/ice40_dsp_pm.h: passes/pmgen/ice40_dsp.pmg passes/pmgen/pmgen.py passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg
$(P) cd passes/pmgen && python3 pmgen.py ice40_dsp $(P) mkdir -p passes/pmgen && python3 $^

View file

@ -6,7 +6,10 @@ import pprint
pp = pprint.PrettyPrinter(indent=4) pp = pprint.PrettyPrinter(indent=4)
prefix = sys.argv[1] pmgfile = sys.argv[1]
assert pmgfile.endswith(".pmg")
prefix = pmgfile[0:-4]
pmname = prefix.split('/')[-1]
state_types = dict() state_types = dict()
udata_types = dict() udata_types = dict()
@ -73,7 +76,7 @@ def rewrite_cpp(s):
return "".join(t) return "".join(t)
with open("%s.pmg" % prefix, "r") as f: with open(pmgfile, "r") as f:
while True: while True:
line = f.readline() line = f.readline()
if line == "": break if line == "": break
@ -82,7 +85,7 @@ with open("%s.pmg" % prefix, "r") as f:
cmd = line.split() cmd = line.split()
if len(cmd) == 0 or cmd[0].startswith("//"): continue if len(cmd) == 0 or cmd[0].startswith("//"): continue
cmd = cmd[0] cmd = cmd[0]
if cmd == "state": if cmd == "state":
m = re.match(r"^state\s+<(.*?)>\s+(([A-Za-z_][A-Za-z_0-9]*\s+)*[A-Za-z_][A-Za-z_0-9]*)\s*$", line) m = re.match(r"^state\s+<(.*?)>\s+(([A-Za-z_][A-Za-z_0-9]*\s+)*[A-Za-z_][A-Za-z_0-9]*)\s*$", line)
assert m assert m
@ -187,10 +190,10 @@ with open("%s_pm.h" % prefix, "w") as f:
print("YOSYS_NAMESPACE_BEGIN", file=f) print("YOSYS_NAMESPACE_BEGIN", file=f)
print("", file=f) print("", file=f)
print("struct {}_pm {{".format(prefix), file=f) print("struct {}_pm {{".format(pmname), file=f)
print(" Module *module;", file=f) print(" Module *module;", file=f)
print(" SigMap sigmap;", file=f) print(" SigMap sigmap;", file=f)
print(" std::function<void()> on_accept;".format(prefix), file=f) print(" std::function<void()> on_accept;".format(pmname), file=f)
print("", file=f) print("", file=f)
for index in range(len(blocks)): for index in range(len(blocks)):
@ -288,7 +291,7 @@ with open("%s_pm.h" % prefix, "w") as f:
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f) print(" {}_pm(Module *module, const vector<Cell*> &cells) :".format(pmname), file=f)
print(" module(module), sigmap(module) {", file=f) print(" module(module), sigmap(module) {", file=f)
for s, t in sorted(udata_types.items()): for s, t in sorted(udata_types.items()):
if t.endswith("*"): if t.endswith("*"):
@ -318,7 +321,7 @@ with open("%s_pm.h" % prefix, "w") as f:
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
print(" ~{}_pm() {{".format(prefix), file=f) print(" ~{}_pm() {{".format(pmname), file=f)
print(" for (auto cell : autoremove_cells)", file=f) print(" for (auto cell : autoremove_cells)", file=f)
print(" module->remove(cell);", file=f) print(" module->remove(cell);", file=f)
print(" }", file=f) print(" }", file=f)
@ -337,7 +340,7 @@ with open("%s_pm.h" % prefix, "w") as f:
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)
print(" void run(std::function<void({}_pm&)> on_accept_f) {{".format(prefix), file=f) print(" void run(std::function<void({}_pm&)> on_accept_f) {{".format(pmname), file=f)
print(" run([&](){on_accept_f(*this);});", file=f) print(" run([&](){on_accept_f(*this);});", file=f)
print(" }", file=f) print(" }", file=f)
print("", file=f) print("", file=f)

View file

@ -8,4 +8,5 @@ OBJS += passes/sat/expose.o
OBJS += passes/sat/assertpmux.o OBJS += passes/sat/assertpmux.o
OBJS += passes/sat/clk2fflogic.o OBJS += passes/sat/clk2fflogic.o
OBJS += passes/sat/async2sync.o OBJS += passes/sat/async2sync.o
OBJS += passes/sat/supercover.o

92
passes/sat/supercover.cc Normal file
View file

@ -0,0 +1,92 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SupercoverPass : public Pass {
SupercoverPass() : Pass("supercover", "add hi/lo cover cells for each wire bit") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" supercover [options] [selection]\n");
log("\n");
log("This command adds two cover cells for each bit of each selected wire, one\n");
log("checking for a hi signal level and one checking for lo level.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
// bool flag_noinit = false;
log_header(design, "Executing SUPERCOVER pass.\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
// if (args[argidx] == "-noinit") {
// flag_noinit = true;
// continue;
// }
break;
}
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
{
SigMap sigmap(module);
pool<SigBit> handled_bits;
int cnt_wire = 0, cnt_bits = 0;
log("Adding cover cells to module %s.\n", log_id(module));
for (auto wire : module->selected_wires())
{
bool counted_wire = false;
std::string src = wire->get_src_attribute();
for (auto bit : sigmap(SigSpec(wire)))
{
if (bit.wire == nullptr)
continue;
if (handled_bits.count(bit))
continue;
SigSpec inv = module->Not(NEW_ID, bit);
module->addCover(NEW_ID, bit, State::S1, src);
module->addCover(NEW_ID, inv, State::S1, src);
handled_bits.insert(bit);
if (!counted_wire) {
counted_wire = false;
cnt_wire++;
}
cnt_bits++;
}
}
log(" added cover cells to %d wires, %d bits.\n", cnt_wire, cnt_bits);
}
}
} SupercoverPass;
PRIVATE_NAMESPACE_END

View file

@ -660,8 +660,8 @@ struct DfflibmapPass : public Pass {
map_adff_to_dff("$_DFF_PP0_", "$_DFF_P_"); map_adff_to_dff("$_DFF_PP0_", "$_DFF_P_");
map_adff_to_dff("$_DFF_PP1_", "$_DFF_P_"); map_adff_to_dff("$_DFF_PP1_", "$_DFF_P_");
log(" final dff cell mappings:\n"); log(" final dff cell mappings:\n");
logmap_all(); logmap_all();
for (auto &it : design->modules_) for (auto &it : design->modules_)
if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox")) if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox"))

View file

@ -132,9 +132,9 @@ static void dump_dot_graph(string filename,
pool<RTLIL::SigBit> nodes, dict<RTLIL::SigBit, pool<RTLIL::SigBit>> edges, pool<RTLIL::SigBit> nodes, dict<RTLIL::SigBit, pool<RTLIL::SigBit>> edges,
pool<RTLIL::SigBit> inputs, pool<RTLIL::SigBit> outputs, pool<RTLIL::SigBit> inputs, pool<RTLIL::SigBit> outputs,
std::function<GraphStyle(RTLIL::SigBit)> node_style = std::function<GraphStyle(RTLIL::SigBit)> node_style =
[](RTLIL::SigBit) { return GraphStyle{}; }, [](RTLIL::SigBit) { return GraphStyle{}; },
std::function<GraphStyle(RTLIL::SigBit, RTLIL::SigBit)> edge_style = std::function<GraphStyle(RTLIL::SigBit, RTLIL::SigBit)> edge_style =
[](RTLIL::SigBit, RTLIL::SigBit) { return GraphStyle{}; }, [](RTLIL::SigBit, RTLIL::SigBit) { return GraphStyle{}; },
string name = "") string name = "")
{ {
FILE *f = fopen(filename.c_str(), "w"); FILE *f = fopen(filename.c_str(), "w");

View file

@ -30,7 +30,7 @@ endmodule
module PADOUT (output padout, input padin, input oe); module PADOUT (output padout, input padin, input oe);
assign padout = padin; assign padout = padin;
assign oe = oe; assign oe = oe;
endmodule endmodule
module LUT4 (output dout, module LUT4 (output dout,
input din0, din1, din2, din3); input din0, din1, din2, din3);
@ -66,14 +66,14 @@ always @(dataa_w or datab_w or datac_w or datad_w) begin
datac_w, datad_w); datac_w, datad_w);
end end
assign dout = combout_rt & 1'b1; assign dout = combout_rt & 1'b1;
endmodule endmodule
module DFF (output q, module DFF (output q,
input d, ck); input d, ck);
reg q; reg q;
always @(posedge ck) always @(posedge ck)
q <= d; q <= d;
endmodule endmodule

View file

@ -52,13 +52,13 @@ struct AnlogicEqnPass : public Pass {
eqn += names[j]; eqn += names[j];
else else
eqn += std::string("~") + names[j]; eqn += std::string("~") + names[j];
if (j!=(inputs-1)) eqn += "*"; if (j!=(inputs-1)) eqn += "*";
} }
eqn += ")+"; eqn += ")+";
} }
} }
if (eqn.empty()) return Const("0"); if (eqn.empty()) return Const("0");
eqn = eqn.substr(0, eqn.length()-1); eqn = eqn.substr(0, eqn.length()-1);
return Const(eqn); return Const(eqn);
} }

View file

@ -1,5 +1,5 @@
OBJS += techlibs/ecp5/synth_ecp5.o OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v))

View file

@ -33,7 +33,7 @@ module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
input CI, BI; input CI, BI;
output [Y_WIDTH-1:0] CO; output [Y_WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; wire _TECHMAP_FAIL_ = Y_WIDTH <= 4;
wire [Y_WIDTH-1:0] A_buf, B_buf; wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));

View file

@ -156,6 +156,41 @@ module OSCG(
parameter DIV = 128; parameter DIV = 128;
endmodule endmodule
(* blackbox *) (* keep *)
module USRMCLK(
input USRMCLKI, USRMCLKTS,
output USRMCLKO
);
endmodule
(* blackbox *) (* keep *)
module JTAGG(
input TCK, TMS, TDI, JTDO2, JTDO1,
output TDO, JTDI, JTCK, JRTI2, JRTI1,
output JSHIFT, JUPDATE, JRSTN, JCE2, JCE1
);
parameter ER1 = "ENABLED";
parameter ER2 = "ENABLED";
endmodule
(* blackbox *)
module DELAYF(
input A, LOADN, MOVE, DIRECTION,
output Z, CFLAG
);
parameter DEL_MODE = "USER_DEFINED";
parameter DEL_VALUE = 0;
endmodule
(* blackbox *)
module DELAYG(
input A,
output Z
);
parameter DEL_MODE = "USER_DEFINED";
parameter DEL_VALUE = 0;
endmodule
(* blackbox *) (* blackbox *)
module IDDRX1F( module IDDRX1F(
input D, SCLK, RST, input D, SCLK, RST,
@ -164,6 +199,31 @@ module IDDRX1F(
parameter GSR = "ENABLED"; parameter GSR = "ENABLED";
endmodule endmodule
(* blackbox *)
module IDDRX2F(
input D, SCLK, ECLK, RST,
output Q0, Q1, Q2, Q3
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module IDDR71B(
input D, SCLK, ECLK, RST, ALIGNWD,
output Q0, Q1, Q2, Q3, Q4, Q5, Q6
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module IDDRX2DQA(
input D, DQSR90, ECLK, SCLK, RST,
input RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0,
output Q0, Q1, Q2, Q3, QWL
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *) (* blackbox *)
module ODDRX1F( module ODDRX1F(
input SCLK, RST, D0, D1, input SCLK, RST, D0, D1,
@ -172,6 +232,91 @@ module ODDRX1F(
parameter GSR = "ENABLED"; parameter GSR = "ENABLED";
endmodule endmodule
(* blackbox *)
module ODDRX2F(
input SCLK, ECLK, RST, D0, D1, D2, D3,
output Q
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module ODDR71B(
input SCLK, ECLK, RST, D0, D1, D2, D3, D4, D5, D6,
output Q
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module OSHX2A(
input D0, D1, RST, ECLK, SCLK,
output Q
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module ODDRX2DQA(
input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW270,
output Q
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module ODDRX2DQSB(
input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW,
output Q
);
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module TSHX2DQA(
input T0, T1, SCLK, ECLK, DQSW270, RST,
output Q
);
parameter GSR = "ENABLED";
parameter REGSET = "SET";
endmodule
(* blackbox *)
module TSHX2DQSA(
input T0, T1, SCLK, ECLK, DQSW, RST,
output Q
);
parameter GSR = "ENABLED";
parameter REGSET = "SET";
endmodule
(* blackbox *)
module DQSBUFM(
input DQSI, READ1, READ0, READCLKSEL2, READCLKSEL1, READCLKSEL0, DDRDEL,
input ECLK, SCLK,
input DYNDELAY7, DYNDELAY6, DYNDELAY5, DYNDELAY4,
input DYNDELAY3, DYNDELAY2, DYNDELAY1, DYNDELAY0,
input RST, RDLOADN, RDMOVE, RDDIRECTION, WRLOADN, WRMOVE, WRDIRECTION, PAUSE,
output DQSR90, DQSW, DQSW270,
output RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0,
output DATAVALID, BURSTDET, RDCFLAG, WRCFLAG
);
parameter DQS_LI_DEL_ADJ = "FACTORYONLY";
parameter DQS_LI_DEL_VAL = 0;
parameter DQS_LO_DEL_ADJ = "FACTORYONLY";
parameter DQS_LO_DEL_VAL = 0;
parameter GSR = "ENABLED";
endmodule
(* blackbox *)
module DDRDLLA(
input CLK, RST, UDDCNTLN, FREEZE,
output LOCK, DDRDEL, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1, DCNTL0
);
parameter FORCE_MAX_DELAY = "NO";
parameter GSR = "ENABLED";
endmodule
(* blackbox *) (* blackbox *)
module CLKDIVF( module CLKDIVF(
input CLKI, RST, ALIGNWD, input CLKI, RST, ALIGNWD,
@ -181,6 +326,13 @@ module CLKDIVF(
parameter DIV = "2.0"; parameter DIV = "2.0";
endmodule endmodule
(* blackbox *)
module ECLKSYNCB(
input ECLKI, STOP,
output ECLKO
);
endmodule
(* blackbox *) (* blackbox *)
module DCCA( module DCCA(
input CLKI, CE, input CLKI, CE,

View file

@ -47,6 +47,9 @@ module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"
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_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_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
// For Diamond compatibility, FIXME: add all Diamond flipflop mappings
module FD1S3BX(input PD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule
`ifndef NO_LUT `ifndef NO_LUT
module \$lut (A, Y); module \$lut (A, Y);
parameter WIDTH = 0; parameter WIDTH = 0;

View file

@ -57,7 +57,7 @@ module TRELLIS_RAM16X2 (
input RAD0, RAD1, RAD2, RAD3, input RAD0, RAD1, RAD2, RAD3,
output DO0, DO1 output DO0, DO1
); );
parameter WCKMUX = "WCK"; parameter WCKMUX = "WCK";
parameter WREMUX = "WRE"; parameter WREMUX = "WRE";
parameter INITVAL_0 = 16'h0000; parameter INITVAL_0 = 16'h0000;
parameter INITVAL_1 = 16'h0000; parameter INITVAL_1 = 16'h0000;
@ -104,7 +104,7 @@ module TRELLIS_DPR16X4 (
input [3:0] RAD, input [3:0] RAD,
output [3:0] DO output [3:0] DO
); );
parameter WCKMUX = "WCK"; parameter WCKMUX = "WCK";
parameter WREMUX = "WRE"; parameter WREMUX = "WRE";
parameter [63:0] INITVAL = 64'h0000000000000000; parameter [63:0] INITVAL = 64'h0000000000000000;
@ -203,13 +203,14 @@ endmodule
// --------------------------------------- // ---------------------------------------
module TRELLIS_FF(input CLK, LSR, CE, DI, output reg Q); module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q);
parameter GSR = "ENABLED"; parameter GSR = "ENABLED";
parameter [127:0] CEMUX = "1"; parameter [127:0] CEMUX = "1";
parameter CLKMUX = "CLK"; parameter CLKMUX = "CLK";
parameter LSRMUX = "LSR"; parameter LSRMUX = "LSR";
parameter SRMODE = "LSR_OVER_CE"; parameter SRMODE = "LSR_OVER_CE";
parameter REGSET = "RESET"; parameter REGSET = "RESET";
parameter [127:0] LSRMODE = "LSR";
reg muxce; reg muxce;
always @(*) always @(*)
@ -222,8 +223,12 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, output reg Q);
wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
generate
localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0; if (LSRMODE == "PRLD")
wire srval = M;
else
localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0;
endgenerate
initial Q = srval; initial Q = srval;
@ -339,6 +344,8 @@ module TRELLIS_SLICE(
parameter REG1_SD = "0"; parameter REG1_SD = "0";
parameter REG0_REGSET = "RESET"; parameter REG0_REGSET = "RESET";
parameter REG1_REGSET = "RESET"; parameter REG1_REGSET = "RESET";
parameter REG0_LSRMODE = "LSR";
parameter REG1_LSRMODE = "LSR";
parameter [127:0] CCU2_INJECT1_0 = "NO"; parameter [127:0] CCU2_INJECT1_0 = "NO";
parameter [127:0] CCU2_INJECT1_1 = "NO"; parameter [127:0] CCU2_INJECT1_1 = "NO";
parameter WREMUX = "WRE"; parameter WREMUX = "WRE";
@ -428,10 +435,11 @@ module TRELLIS_SLICE(
.CLKMUX(CLKMUX), .CLKMUX(CLKMUX),
.LSRMUX(LSRMUX), .LSRMUX(LSRMUX),
.SRMODE(SRMODE), .SRMODE(SRMODE),
.REGSET(REG0_REGSET) .REGSET(REG0_REGSET),
.LSRMODE(REG0_LSRMODE)
) ff_0 ( ) ff_0 (
.CLK(CLK), .LSR(LSR), .CE(CE), .CLK(CLK), .LSR(LSR), .CE(CE),
.DI(muxdi0), .DI(muxdi0), .M(M0),
.Q(Q0) .Q(Q0)
); );
TRELLIS_FF #( TRELLIS_FF #(
@ -440,10 +448,11 @@ module TRELLIS_SLICE(
.CLKMUX(CLKMUX), .CLKMUX(CLKMUX),
.LSRMUX(LSRMUX), .LSRMUX(LSRMUX),
.SRMODE(SRMODE), .SRMODE(SRMODE),
.REGSET(REG1_REGSET) .REGSET(REG1_REGSET),
.LSRMODE(REG1_LSRMODE)
) ff_1 ( ) ff_1 (
.CLK(CLK), .LSR(LSR), .CE(CE), .CLK(CLK), .LSR(LSR), .CE(CE),
.DI(muxdi1), .DI(muxdi1), .M(M1),
.Q(Q1) .Q(Q1)
); );
endmodule endmodule
@ -547,3 +556,20 @@ module DP16KD(
parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
endmodule endmodule
// For Diamond compatibility, FIXME: add all Diamond flipflop mappings
module FD1S3BX(input PD, D, CK, output Q);
TRELLIS_FF #(
.GSR("DISABLED"),
.CEMUX("1"),
.CLKMUX("CLK"),
.LSRMUX("LSR"),
.REGSET("SET"),
.SRMODE("ASYNC")
) tff_i (
.CLK(CK),
.LSR(PD),
.DI(D),
.Q(Q)
);
endmodule

View file

@ -0,0 +1,198 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
* Copyright (C) 2018-19 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 Ecp5FfinitPass : public Pass {
Ecp5FfinitPass() : Pass("ecp5_ffinit", "ECP5: handle FF init values") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" ecp5_ffinit [options] [selection]\n");
log("\n");
log("Remove init values for FF output signals when equal to reset value.\n");
log("If reset is not used, set the reset value to the init value, otherwise\n");
log("unmap out the reset (if not an async reset).\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing ECP5_FFINIT 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 FF init values in %s.\n", log_id(module));
SigMap sigmap(module);
pool<Wire*> init_wires;
dict<SigBit, State> initbits;
dict<SigBit, SigBit> initbit_to_wire;
pool<SigBit> handled_initbits;
for (auto wire : module->selected_wires())
{
if (wire->attributes.count("\\init") == 0)
continue;
SigSpec wirebits = sigmap(wire);
Const initval = wire->attributes.at("\\init");
init_wires.insert(wire);
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++)
{
SigBit bit = wirebits[i];
State val = initval[i];
if (val != State::S0 && val != State::S1)
continue;
if (initbits.count(bit)) {
if (initbits.at(bit) != val)
log_error("Conflicting init values for signal %s (%s = %s, %s = %s).\n",
log_signal(bit), log_signal(SigBit(wire, i)), log_signal(val),
log_signal(initbit_to_wire[bit]), log_signal(initbits.at(bit)));
continue;
}
initbits[bit] = val;
initbit_to_wire[bit] = SigBit(wire, i);
}
}
for (auto cell : module->selected_cells())
{
if (cell->type != "\\TRELLIS_FF")
continue;
SigSpec sig_d = cell->getPort("\\DI");
SigSpec sig_q = cell->getPort("\\Q");
SigSpec sig_lsr = cell->getPort("\\LSR");
if (GetSize(sig_d) < 1 || GetSize(sig_q) < 1)
continue;
SigBit bit_d = sigmap(sig_d[0]);
SigBit bit_q = sigmap(sig_q[0]);
std::string regset = "RESET";
if (cell->hasParam("\\REGSET"))
regset = cell->getParam("\\REGSET").decode_string();
State resetState;
if (regset == "SET")
resetState = State::S1;
else if (regset == "RESET")
resetState = State::S0;
else
log_error("FF cell %s has illegal REGSET value %s.\n",
log_id(cell), regset.c_str());
if (!initbits.count(bit_q))
continue;
State val = initbits.at(bit_q);
log("FF init value for cell %s (%s): %s = %c\n", log_id(cell), log_id(cell->type),
log_signal(bit_q), val != State::S0 ? '1' : '0');
// Initval is the same as the reset state. Matches hardware, nowt more to do
if (val == resetState) {
handled_initbits.insert(bit_q);
continue;
}
if (GetSize(sig_lsr) >= 1 && sig_lsr[0] != State::S0) {
std::string srmode = "LSR_OVER_CE";
if (cell->hasParam("\\SRMODE"))
srmode = cell->getParam("\\SRMODE").decode_string();
if (srmode == "ASYNC") {
log("Async reset value %c for FF cell %s inconsistent with init value %c.\n",
resetState != State::S0 ? '1' : '0', log_id(cell), val != State::S0 ? '1' : '0');
} else {
SigBit bit_lsr = sigmap(sig_lsr[0]);
Wire *new_bit_d = module->addWire(NEW_ID);
if (resetState == State::S0) {
module->addAndnotGate(NEW_ID, bit_d, bit_lsr, new_bit_d);
} else {
module->addOrGate(NEW_ID, bit_d, bit_lsr, new_bit_d);
}
cell->setPort("\\DI", new_bit_d);
cell->setPort("\\LSR", State::S0);
if(cell->hasPort("\\CE")) {
std::string cemux = "CE";
if (cell->hasParam("\\CEMUX"))
cemux = cell->getParam("\\CEMUX").decode_string();
SigSpec sig_ce = cell->getPort("\\CE");
if (GetSize(sig_ce) >= 1) {
SigBit bit_ce = sigmap(sig_ce[0]);
Wire *new_bit_ce = module->addWire(NEW_ID);
if (cemux == "INV")
module->addAndnotGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce);
else
module->addOrGate(NEW_ID, bit_ce, bit_lsr, new_bit_ce);
cell->setPort("\\CE", new_bit_ce);
}
}
cell->setParam("\\REGSET", val != State::S0 ? Const("SET") : Const("RESET"));
handled_initbits.insert(bit_q);
}
} else {
cell->setParam("\\REGSET", val != State::S0 ? Const("SET") : Const("RESET"));
handled_initbits.insert(bit_q);
}
}
for (auto wire : init_wires)
{
if (wire->attributes.count("\\init") == 0)
continue;
SigSpec wirebits = sigmap(wire);
Const &initval = wire->attributes.at("\\init");
bool remove_attribute = true;
for (int i = 0; i < GetSize(wirebits) && i < GetSize(initval); i++) {
if (handled_initbits.count(wirebits[i]))
initval[i] = State::Sx;
else if (initval[i] != State::Sx)
remove_attribute = false;
}
if (remove_attribute)
wire->attributes.erase("\\init");
}
}
}
} Ecp5FfinitPass;
PRIVATE_NAMESPACE_END

View file

@ -255,10 +255,7 @@ struct SynthEcp5Pass : public ScriptPass
run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
run("opt_expr -mux_undef"); run("opt_expr -mux_undef");
run("simplemap"); run("simplemap");
// TODO
#if 0
run("ecp5_ffinit"); run("ecp5_ffinit");
#endif
} }
if (check_label("map_luts")) if (check_label("map_luts"))

View file

@ -25,24 +25,24 @@ module _80_gw1n_alu(A, B, CI, BI, X, Y, CO);
parameter A_WIDTH = 1; parameter A_WIDTH = 1;
parameter B_WIDTH = 1; parameter B_WIDTH = 1;
parameter Y_WIDTH = 1; parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A; input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B; input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] X, Y; output [Y_WIDTH-1:0] X, Y;
input CI, BI; input CI, BI;
output [Y_WIDTH-1:0] CO; output [Y_WIDTH-1:0] CO;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
wire [Y_WIDTH-1:0] A_buf, B_buf; wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] AA = A_buf;
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
wire [Y_WIDTH-1:0] C = {CO, CI}; wire [Y_WIDTH-1:0] C = {CO, CI};
genvar i; genvar i;
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
ALU #(.ALU_MODE(32'b0)) ALU #(.ALU_MODE(32'b0))

View file

@ -111,7 +111,7 @@ struct SynthGowinPass : public ScriptPass
if (args[argidx] == "-noflatten") { if (args[argidx] == "-noflatten") {
flatten = false; flatten = false;
continue; continue;
} }
break; break;
} }
extra_args(args, argidx, design); extra_args(args, argidx, design);

View file

@ -112,14 +112,14 @@ module GP_OBUFT(input IN, input OE, output OUT);
endmodule endmodule
module \$lut (A, Y); module \$lut (A, Y);
parameter WIDTH = 0; parameter WIDTH = 0;
parameter LUT = 0; parameter LUT = 0;
input [WIDTH-1:0] A; input [WIDTH-1:0] A;
output Y; output Y;
generate generate
if (WIDTH == 1) begin if (WIDTH == 1) begin
if(LUT == 2'b01) begin if(LUT == 2'b01) begin
GP_INV _TECHMAP_REPLACE_ (.OUT(Y), .IN(A[0]) ); GP_INV _TECHMAP_REPLACE_ (.OUT(Y), .IN(A[0]) );
end end
@ -127,22 +127,22 @@ module \$lut (A, Y);
GP_2LUT #(.INIT({2'b00, LUT})) _TECHMAP_REPLACE_ (.OUT(Y), GP_2LUT #(.INIT({2'b00, LUT})) _TECHMAP_REPLACE_ (.OUT(Y),
.IN0(A[0]), .IN1(1'b0)); .IN0(A[0]), .IN1(1'b0));
end end
end else end else
if (WIDTH == 2) begin if (WIDTH == 2) begin
GP_2LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), GP_2LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
.IN0(A[0]), .IN1(A[1])); .IN0(A[0]), .IN1(A[1]));
end else end else
if (WIDTH == 3) begin if (WIDTH == 3) begin
GP_3LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), GP_3LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
.IN0(A[0]), .IN1(A[1]), .IN2(A[2])); .IN0(A[0]), .IN1(A[1]), .IN2(A[2]));
end else end else
if (WIDTH == 4) begin if (WIDTH == 4) begin
GP_4LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), GP_4LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
.IN0(A[0]), .IN1(A[1]), .IN2(A[2]), .IN3(A[3])); .IN0(A[0]), .IN1(A[1]), .IN2(A[2]), .IN3(A[3]));
end else begin end else begin
wire _TECHMAP_FAIL_ = 1; wire _TECHMAP_FAIL_ = 1;
end end
endgenerate endgenerate
endmodule endmodule
module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP); module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP);

View file

@ -7,8 +7,8 @@ module \$__ICE40_RAM4K (
input [10:0] WADDR, input [10:0] WADDR,
input [15:0] MASK, WDATA input [15:0] MASK, WDATA
); );
parameter integer READ_MODE = 0; parameter [1:0] READ_MODE = 0;
parameter integer WRITE_MODE = 0; parameter [1:0] WRITE_MODE = 0;
parameter [0:0] NEGCLK_R = 0; parameter [0:0] NEGCLK_R = 0;
parameter [0:0] NEGCLK_W = 0; parameter [0:0] NEGCLK_W = 0;

View file

@ -32,7 +32,7 @@ module fa
wire VCC; wire VCC;
assign VCC = 1'b1; assign VCC = 1'b1;
cycloneiv_lcell_comb gen_sum_0 (.combout(sum_x), cycloneiv_lcell_comb gen_sum_0 (.combout(sum_x),
.dataa(a_c), .dataa(a_c),
.datab(b_c), .datab(b_c),
@ -40,7 +40,7 @@ module fa
.datad(VCC)); .datad(VCC));
defparam syn__05_.lut_mask = 16'b1001011010010110; defparam syn__05_.lut_mask = 16'b1001011010010110;
defparam syn__05_.sum_lutc_input = "datac"; defparam syn__05_.sum_lutc_input = "datac";
cycloneiv_lcell_comb gen_cout_0 (.combout(cout_t), cycloneiv_lcell_comb gen_cout_0 (.combout(cout_t),
.dataa(cin_c), .dataa(cin_c),
.datab(b_c), .datab(b_c),
@ -48,11 +48,11 @@ module fa
.datad(VCC)); .datad(VCC));
defparam syn__06_.lut_mask = 16'b1110000011100000; defparam syn__06_.lut_mask = 16'b1110000011100000;
defparam syn__06_.sum_lutc_input = "datac"; defparam syn__06_.sum_lutc_input = "datac";
endmodule // fa endmodule // fa
module f_stage(); module f_stage();
endmodule // f_stage endmodule // f_stage
module f_end(); module f_end();
@ -88,7 +88,7 @@ module _80_cycloneive_alu (A, B, CI, BI, X, Y, CO);
.cin_c(C[0]), .cin_c(C[0]),
.cout_t(C0[1]), .cout_t(C0[1]),
.sum_x(Y[0])); .sum_x(Y[0]));
genvar i; genvar i;
generate for (i = 1; i < Y_WIDTH; i = i + 1) begin:slice generate for (i = 1; i < Y_WIDTH; i = i + 1) begin:slice
cycloneive_lcell_comb #(.lut_mask(16'b0101_1010_0101_0000), .sum_lutc_input("cin")) arith_cell (.combout(Y[i]), .cout(CO[i]), .dataa(BB[i]), .datab(1'b1), .datac(1'b1), .datad(1'b1), .cin(C[i])); cycloneive_lcell_comb #(.lut_mask(16'b0101_1010_0101_0000), .sum_lutc_input("cin")) arith_cell (.combout(Y[i]), .cout(CO[i]), .dataa(BB[i]), .datab(1'b1), .datac(1'b1), .datad(1'b1), .cin(C[i]));

View file

@ -76,7 +76,7 @@ module \$lut (A, Y);
wire VCC; wire VCC;
wire GND; wire GND;
assign {VCC,GND} = {1'b1,1'b0}; assign {VCC,GND} = {1'b1,1'b0};
generate generate
if (WIDTH == 1) begin if (WIDTH == 1) begin
assign Y = ~A[0]; // Not need to spend 1 logic cell for such an easy function assign Y = ~A[0]; // Not need to spend 1 logic cell for such an easy function
@ -151,7 +151,7 @@ module \$lut (A, Y);
TODO: There's not a just 7-input function on Cyclone V, see the following note: TODO: There's not a just 7-input function on Cyclone V, see the following note:
**Extended LUT Mode** **Extended LUT Mode**
Use extended LUT mode to implement a specific set of 7-input functions. The set must Use extended LUT mode to implement a specific set of 7-input functions. The set must
be a 2-to-1 multiplexer fed by two arbitrary 5-input functions sharing four inputs. be a 2-to-1 multiplexer fed by two arbitrary 5-input functions sharing four inputs.
[source](Device Interfaces and Integration Basics for Cyclone V Devices). [source](Device Interfaces and Integration Basics for Cyclone V Devices).
end*/ end*/
else else

View file

@ -6,7 +6,6 @@ code_hdl_models_d_latch_gates.v combinational loop
code_hdl_models_dff_async_reset.v $adff code_hdl_models_dff_async_reset.v $adff
code_hdl_models_tff_async_reset.v $adff code_hdl_models_tff_async_reset.v $adff
code_hdl_models_uart.v $adff code_hdl_models_uart.v $adff
code_specman_switch_fabric.v subfield assignment (bits() <= ...)
code_tidbits_asyn_reset.v $adff code_tidbits_asyn_reset.v $adff
code_tidbits_reg_seq_example.v $adff code_tidbits_reg_seq_example.v $adff
code_verilog_tutorial_always_example.v empty module code_verilog_tutorial_always_example.v empty module

View file

@ -12,7 +12,6 @@ multiplier.v inst id[0] of
muxtree.v drops modules muxtree.v drops modules
omsp_dbg_uart.v $adff omsp_dbg_uart.v $adff
operators.v $pow operators.v $pow
paramods.v subfield assignment (bits() <= ...)
partsel.v drops modules partsel.v drops modules
process.v drops modules process.v drops modules
realexpr.v drops modules realexpr.v drops modules

View file

@ -8,7 +8,7 @@ verbose=false
keeprunning=false keeprunning=false
makejmode=false makejmode=false
frontend="verilog" frontend="verilog"
backend_opts="-noattr -noexpr" backend_opts="-noattr -noexpr -siminit"
autotb_opts="" autotb_opts=""
include_opts="" include_opts=""
xinclude_opts="" xinclude_opts=""
@ -49,7 +49,7 @@ while getopts xmGl:wkjvref:s:p:n:S:I:-: opt; do
r) r)
backend_opts="$backend_opts -norename" ;; backend_opts="$backend_opts -norename" ;;
e) e)
backend_opts="$( echo " $backend_opts " | sed 's, -noexpr ,,; s,^ ,,; s, $,,;'; )" ;; backend_opts="$( echo " $backend_opts " | sed 's, -noexpr , ,; s,^ ,,; s, $,,;'; )" ;;
f) f)
frontend="$OPTARG" ;; frontend="$OPTARG" ;;
s) s)
@ -175,7 +175,7 @@ do
if [ -n "$firrtl2verilog" ]; then if [ -n "$firrtl2verilog" ]; then
if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then
"$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt; memory; opt; fsm; opt -full -fine; pmuxtree" ${bn}_ref.v "$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt; memory; opt; fsm; opt -full -fine; pmuxtree" ${bn}_ref.v
$firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v -X verilog $firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v
test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.fir.v test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.fir.v
fi fi
fi fi