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:
commit
4cce7f6967
31 changed files with 622 additions and 105 deletions
|
@ -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"));
|
||||||
|
|
|
@ -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 ¶m : parameters) {
|
for (auto ¶m : 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;
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 $^
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
92
passes/sat/supercover.cc
Normal 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
|
|
@ -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"))
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
198
techlibs/ecp5/ecp5_ffinit.cc
Normal file
198
techlibs/ecp5/ecp5_ffinit.cc
Normal 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
|
|
@ -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"))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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]));
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue