mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
4cce7f6967
|
@ -169,7 +169,6 @@ struct FirrtlWorker
|
|||
return *str == '\\' ? str + 1 : str;
|
||||
}
|
||||
|
||||
|
||||
std::string cellname(RTLIL::Cell *cell)
|
||||
{
|
||||
return fid(cell->name).c_str();
|
||||
|
@ -219,29 +218,42 @@ struct FirrtlWorker
|
|||
if (it->second.size() > 0) {
|
||||
const SigSpec &secondSig = it->second;
|
||||
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.
|
||||
FDirection dir = getPortFDirection(it->first, instModule);
|
||||
std::string source, sink;
|
||||
std::string sourceExpr, sinkExpr;
|
||||
const SigSpec *sinkSig = nullptr;
|
||||
switch (dir) {
|
||||
case FD_INOUT:
|
||||
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
|
||||
case FD_OUT:
|
||||
source = firstName;
|
||||
sink = secondName;
|
||||
sourceExpr = firstName;
|
||||
sinkExpr = secondExpr;
|
||||
sinkSig = &secondSig;
|
||||
break;
|
||||
case FD_NODIRECTION:
|
||||
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
|
||||
/* FALL_THROUGH */
|
||||
case FD_IN:
|
||||
source = secondName;
|
||||
sink = firstName;
|
||||
sourceExpr = secondExpr;
|
||||
sinkExpr = firstName;
|
||||
break;
|
||||
default:
|
||||
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir);
|
||||
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"));
|
||||
|
|
|
@ -48,7 +48,7 @@ struct ProtobufDesignSerializer
|
|||
|
||||
ProtobufDesignSerializer(bool use_selection, bool aig_mode) :
|
||||
aig_mode_(aig_mode), use_selection_(use_selection) { }
|
||||
|
||||
|
||||
string get_name(IdString name)
|
||||
{
|
||||
return RTLIL::unescape_id(name);
|
||||
|
@ -60,7 +60,7 @@ struct ProtobufDesignSerializer
|
|||
{
|
||||
for (auto ¶m : parameters) {
|
||||
std::string key = get_name(param.first);
|
||||
|
||||
|
||||
|
||||
yosys::pb::Parameter pb_param;
|
||||
|
||||
|
@ -207,7 +207,7 @@ struct ProtobufDesignSerializer
|
|||
(*models)[aig.name] = pb_model;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void serialize_design(yosys::pb::Design *pb, Design *design)
|
||||
{
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
|
|
@ -1103,20 +1103,27 @@ struct Smt2Worker
|
|||
break;
|
||||
|
||||
Const initword = init_data.extract(i*width, width, State::Sx);
|
||||
Const initmask = initword;
|
||||
bool gen_init_constr = false;
|
||||
|
||||
for (auto bit : initword.bits)
|
||||
if (bit == State::S0 || bit == State::S1)
|
||||
for (int k = 0; k < GetSize(initword); k++) {
|
||||
if (initword[k] == State::S0 || initword[k] == State::S1) {
|
||||
gen_init_constr = true;
|
||||
initmask[k] = State::S1;
|
||||
} else {
|
||||
initmask[k] = State::S0;
|
||||
initword[k] = State::S0;
|
||||
}
|
||||
}
|
||||
|
||||
if (gen_init_constr)
|
||||
{
|
||||
if (statebv)
|
||||
/* FIXME */;
|
||||
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(),
|
||||
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
|
||||
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;
|
||||
std::map<RTLIL::IdString, int> auto_name_map;
|
||||
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;
|
||||
dump_reg_init(ss, cell->getPort("\\Q"));
|
||||
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(" expressions.\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(" 32-bit constant values are by default dumped as decimal numbers,\n");
|
||||
log(" not bit pattern. This option deactivates this feature and instead\n");
|
||||
|
@ -1663,6 +1667,7 @@ struct VerilogBackend : public Backend {
|
|||
nostr = false;
|
||||
defparam = false;
|
||||
decimal = false;
|
||||
siminit = false;
|
||||
auto_prefix = "";
|
||||
|
||||
bool blackboxes = false;
|
||||
|
@ -1739,6 +1744,10 @@ struct VerilogBackend : public Backend {
|
|||
decimal = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-siminit") {
|
||||
siminit = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-blackboxes") {
|
||||
blackboxes = true;
|
||||
continue;
|
||||
|
|
|
@ -2316,7 +2316,7 @@ struct ReadPass : public Pass {
|
|||
}
|
||||
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");
|
||||
|
||||
if (args.size() < 3)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
//
|
||||
// yosys -- Yosys Open SYnthesis Suite
|
||||
//
|
||||
//
|
||||
// Copyright (C) 2018 Serge Bazanski <q3k@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
|
||||
|
@ -73,7 +73,7 @@ message Module {
|
|||
BitVector bits = 2;
|
||||
}
|
||||
map<string, Port> port = 2;
|
||||
|
||||
|
||||
// Named cells in this module.
|
||||
message Cell {
|
||||
// Set to true when the name of this cell is automatically created and
|
||||
|
@ -129,7 +129,7 @@ message Model {
|
|||
TYPE_FALSE = 6;
|
||||
};
|
||||
Type type = 1;
|
||||
|
||||
|
||||
message Port {
|
||||
// Name of port.
|
||||
string portname = 1;
|
||||
|
@ -148,7 +148,7 @@ message Model {
|
|||
// Set for AND, NAND.
|
||||
Gate gate = 3;
|
||||
}
|
||||
|
||||
|
||||
// Set when the node drives given output port(s).
|
||||
message OutPort {
|
||||
// Name of port.
|
||||
|
|
|
@ -53,6 +53,7 @@ struct WreduceWorker
|
|||
std::set<Cell*, IdString::compare_ptr_by_name<Cell>> work_queue_cells;
|
||||
std::set<SigBit> work_queue_bits;
|
||||
pool<SigBit> keep_bits;
|
||||
dict<SigBit, State> init_bits;
|
||||
|
||||
WreduceWorker(WreduceConfig *config, Module *module) :
|
||||
config(config), module(module), mi(module) { }
|
||||
|
@ -141,6 +142,7 @@ struct WreduceWorker
|
|||
|
||||
SigSpec sig_d = mi.sigmap(cell->getPort("\\D"));
|
||||
SigSpec sig_q = mi.sigmap(cell->getPort("\\Q"));
|
||||
Const initval;
|
||||
|
||||
int width_before = GetSize(sig_q);
|
||||
|
||||
|
@ -150,16 +152,24 @@ struct WreduceWorker
|
|||
bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0;
|
||||
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--)
|
||||
{
|
||||
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);
|
||||
sig_d.remove(i);
|
||||
sig_q.remove(i);
|
||||
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]);
|
||||
sig_d.remove(i);
|
||||
sig_q.remove(i);
|
||||
|
@ -167,7 +177,7 @@ struct WreduceWorker
|
|||
}
|
||||
|
||||
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_q.remove(i);
|
||||
zero_ext = false;
|
||||
|
@ -183,10 +193,11 @@ struct WreduceWorker
|
|||
|
||||
if (GetSize(sig_q) == 0) {
|
||||
log("Removed cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type));
|
||||
module->remove(cell);
|
||||
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));
|
||||
|
||||
for (auto bit : sig_d)
|
||||
|
@ -376,10 +387,18 @@ struct WreduceWorker
|
|||
|
||||
void run()
|
||||
{
|
||||
for (auto w : module->wires())
|
||||
for (auto w : module->wires()) {
|
||||
if (w->get_bool_attribute("\\keep"))
|
||||
for (auto bit : mi.sigmap(w))
|
||||
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())
|
||||
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
|
||||
.SECONDARY: passes/pmgen/ice40_dsp_pm.h
|
||||
|
||||
passes/pmgen/ice40_dsp_pm.h: passes/pmgen/ice40_dsp.pmg passes/pmgen/pmgen.py
|
||||
$(P) cd passes/pmgen && python3 pmgen.py ice40_dsp
|
||||
passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg
|
||||
$(P) mkdir -p passes/pmgen && python3 $^
|
||||
|
|
|
@ -6,7 +6,10 @@ import pprint
|
|||
|
||||
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()
|
||||
udata_types = dict()
|
||||
|
@ -73,7 +76,7 @@ def rewrite_cpp(s):
|
|||
|
||||
return "".join(t)
|
||||
|
||||
with open("%s.pmg" % prefix, "r") as f:
|
||||
with open(pmgfile, "r") as f:
|
||||
while True:
|
||||
line = f.readline()
|
||||
if line == "": break
|
||||
|
@ -82,7 +85,7 @@ with open("%s.pmg" % prefix, "r") as f:
|
|||
cmd = line.split()
|
||||
if len(cmd) == 0 or cmd[0].startswith("//"): continue
|
||||
cmd = cmd[0]
|
||||
|
||||
|
||||
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)
|
||||
assert m
|
||||
|
@ -187,10 +190,10 @@ with open("%s_pm.h" % prefix, "w") as f:
|
|||
print("YOSYS_NAMESPACE_BEGIN", 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(" 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)
|
||||
|
||||
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(" {}_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)
|
||||
for s, t in sorted(udata_types.items()):
|
||||
if t.endswith("*"):
|
||||
|
@ -318,7 +321,7 @@ with open("%s_pm.h" % prefix, "w") as 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(" module->remove(cell);", 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(" 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(" }", file=f)
|
||||
print("", file=f)
|
||||
|
|
|
@ -8,4 +8,5 @@ OBJS += passes/sat/expose.o
|
|||
OBJS += passes/sat/assertpmux.o
|
||||
OBJS += passes/sat/clk2fflogic.o
|
||||
OBJS += passes/sat/async2sync.o
|
||||
OBJS += passes/sat/supercover.o
|
||||
|
||||
|
|
|
@ -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_PP1_", "$_DFF_P_");
|
||||
|
||||
log(" final dff cell mappings:\n");
|
||||
logmap_all();
|
||||
log(" final dff cell mappings:\n");
|
||||
logmap_all();
|
||||
|
||||
for (auto &it : design->modules_)
|
||||
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> inputs, pool<RTLIL::SigBit> outputs,
|
||||
std::function<GraphStyle(RTLIL::SigBit)> node_style =
|
||||
[](RTLIL::SigBit) { return GraphStyle{}; },
|
||||
[](RTLIL::SigBit) { return GraphStyle{}; },
|
||||
std::function<GraphStyle(RTLIL::SigBit, RTLIL::SigBit)> edge_style =
|
||||
[](RTLIL::SigBit, RTLIL::SigBit) { return GraphStyle{}; },
|
||||
[](RTLIL::SigBit, RTLIL::SigBit) { return GraphStyle{}; },
|
||||
string name = "")
|
||||
{
|
||||
FILE *f = fopen(filename.c_str(), "w");
|
||||
|
|
|
@ -30,7 +30,7 @@ endmodule
|
|||
module PADOUT (output padout, input padin, input oe);
|
||||
assign padout = padin;
|
||||
assign oe = oe;
|
||||
endmodule
|
||||
endmodule
|
||||
|
||||
module LUT4 (output dout,
|
||||
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);
|
||||
end
|
||||
assign dout = combout_rt & 1'b1;
|
||||
endmodule
|
||||
endmodule
|
||||
|
||||
module DFF (output q,
|
||||
input d, ck);
|
||||
reg q;
|
||||
always @(posedge ck)
|
||||
q <= d;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
|
@ -52,13 +52,13 @@ struct AnlogicEqnPass : public Pass {
|
|||
eqn += names[j];
|
||||
else
|
||||
eqn += std::string("~") + names[j];
|
||||
|
||||
|
||||
if (j!=(inputs-1)) eqn += "*";
|
||||
}
|
||||
eqn += ")+";
|
||||
}
|
||||
}
|
||||
if (eqn.empty()) return Const("0");
|
||||
if (eqn.empty()) return Const("0");
|
||||
eqn = eqn.substr(0, eqn.length()-1);
|
||||
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_sim.v))
|
||||
|
|
|
@ -33,7 +33,7 @@ module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
|
|||
input CI, BI;
|
||||
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;
|
||||
\$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;
|
||||
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 *)
|
||||
module IDDRX1F(
|
||||
input D, SCLK, RST,
|
||||
|
@ -164,6 +199,31 @@ module IDDRX1F(
|
|||
parameter GSR = "ENABLED";
|
||||
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 *)
|
||||
module ODDRX1F(
|
||||
input SCLK, RST, D0, D1,
|
||||
|
@ -172,6 +232,91 @@ module ODDRX1F(
|
|||
parameter GSR = "ENABLED";
|
||||
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 *)
|
||||
module CLKDIVF(
|
||||
input CLKI, RST, ALIGNWD,
|
||||
|
@ -181,6 +326,13 @@ module CLKDIVF(
|
|||
parameter DIV = "2.0";
|
||||
endmodule
|
||||
|
||||
(* blackbox *)
|
||||
module ECLKSYNCB(
|
||||
input ECLKI, STOP,
|
||||
output ECLKO
|
||||
);
|
||||
endmodule
|
||||
|
||||
(* blackbox *)
|
||||
module DCCA(
|
||||
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_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
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
|
|
|
@ -57,7 +57,7 @@ module TRELLIS_RAM16X2 (
|
|||
input RAD0, RAD1, RAD2, RAD3,
|
||||
output DO0, DO1
|
||||
);
|
||||
parameter WCKMUX = "WCK";
|
||||
parameter WCKMUX = "WCK";
|
||||
parameter WREMUX = "WRE";
|
||||
parameter INITVAL_0 = 16'h0000;
|
||||
parameter INITVAL_1 = 16'h0000;
|
||||
|
@ -104,7 +104,7 @@ module TRELLIS_DPR16X4 (
|
|||
input [3:0] RAD,
|
||||
output [3:0] DO
|
||||
);
|
||||
parameter WCKMUX = "WCK";
|
||||
parameter WCKMUX = "WCK";
|
||||
parameter WREMUX = "WRE";
|
||||
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 [127:0] CEMUX = "1";
|
||||
parameter CLKMUX = "CLK";
|
||||
parameter LSRMUX = "LSR";
|
||||
parameter SRMODE = "LSR_OVER_CE";
|
||||
parameter REGSET = "RESET";
|
||||
parameter [127:0] LSRMODE = "LSR";
|
||||
|
||||
reg muxce;
|
||||
always @(*)
|
||||
|
@ -222,8 +223,12 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, output reg Q);
|
|||
|
||||
wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
|
||||
wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
|
||||
|
||||
localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0;
|
||||
generate
|
||||
if (LSRMODE == "PRLD")
|
||||
wire srval = M;
|
||||
else
|
||||
localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0;
|
||||
endgenerate
|
||||
|
||||
initial Q = srval;
|
||||
|
||||
|
@ -339,6 +344,8 @@ module TRELLIS_SLICE(
|
|||
parameter REG1_SD = "0";
|
||||
parameter REG0_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_1 = "NO";
|
||||
parameter WREMUX = "WRE";
|
||||
|
@ -428,10 +435,11 @@ module TRELLIS_SLICE(
|
|||
.CLKMUX(CLKMUX),
|
||||
.LSRMUX(LSRMUX),
|
||||
.SRMODE(SRMODE),
|
||||
.REGSET(REG0_REGSET)
|
||||
.REGSET(REG0_REGSET),
|
||||
.LSRMODE(REG0_LSRMODE)
|
||||
) ff_0 (
|
||||
.CLK(CLK), .LSR(LSR), .CE(CE),
|
||||
.DI(muxdi0),
|
||||
.DI(muxdi0), .M(M0),
|
||||
.Q(Q0)
|
||||
);
|
||||
TRELLIS_FF #(
|
||||
|
@ -440,10 +448,11 @@ module TRELLIS_SLICE(
|
|||
.CLKMUX(CLKMUX),
|
||||
.LSRMUX(LSRMUX),
|
||||
.SRMODE(SRMODE),
|
||||
.REGSET(REG1_REGSET)
|
||||
.REGSET(REG1_REGSET),
|
||||
.LSRMODE(REG1_LSRMODE)
|
||||
) ff_1 (
|
||||
.CLK(CLK), .LSR(LSR), .CE(CE),
|
||||
.DI(muxdi1),
|
||||
.DI(muxdi1), .M(M1),
|
||||
.Q(Q1)
|
||||
);
|
||||
endmodule
|
||||
|
@ -547,3 +556,20 @@ module DP16KD(
|
|||
parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
|
||||
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
|
||||
|
|
|
@ -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("opt_expr -mux_undef");
|
||||
run("simplemap");
|
||||
// TODO
|
||||
#if 0
|
||||
run("ecp5_ffinit");
|
||||
#endif
|
||||
}
|
||||
|
||||
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 B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
|
||||
input [A_WIDTH-1:0] A;
|
||||
input [B_WIDTH-1:0] B;
|
||||
output [Y_WIDTH-1:0] X, Y;
|
||||
|
||||
|
||||
input CI, BI;
|
||||
output [Y_WIDTH-1:0] CO;
|
||||
|
||||
|
||||
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
|
||||
|
||||
|
||||
wire [Y_WIDTH-1:0] A_buf, B_buf;
|
||||
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
|
||||
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||
|
||||
|
||||
wire [Y_WIDTH-1:0] AA = A_buf;
|
||||
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
|
||||
wire [Y_WIDTH-1:0] C = {CO, CI};
|
||||
|
||||
|
||||
genvar i;
|
||||
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
|
||||
ALU #(.ALU_MODE(32'b0))
|
||||
|
|
|
@ -111,7 +111,7 @@ struct SynthGowinPass : public ScriptPass
|
|||
if (args[argidx] == "-noflatten") {
|
||||
flatten = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
|
|
@ -112,14 +112,14 @@ module GP_OBUFT(input IN, input OE, output OUT);
|
|||
endmodule
|
||||
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
parameter LUT = 0;
|
||||
parameter WIDTH = 0;
|
||||
parameter LUT = 0;
|
||||
|
||||
input [WIDTH-1:0] A;
|
||||
output Y;
|
||||
input [WIDTH-1:0] A;
|
||||
output Y;
|
||||
|
||||
generate
|
||||
if (WIDTH == 1) begin
|
||||
generate
|
||||
if (WIDTH == 1) begin
|
||||
if(LUT == 2'b01) begin
|
||||
GP_INV _TECHMAP_REPLACE_ (.OUT(Y), .IN(A[0]) );
|
||||
end
|
||||
|
@ -127,22 +127,22 @@ module \$lut (A, Y);
|
|||
GP_2LUT #(.INIT({2'b00, LUT})) _TECHMAP_REPLACE_ (.OUT(Y),
|
||||
.IN0(A[0]), .IN1(1'b0));
|
||||
end
|
||||
end else
|
||||
if (WIDTH == 2) begin
|
||||
GP_2LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
|
||||
.IN0(A[0]), .IN1(A[1]));
|
||||
end else
|
||||
if (WIDTH == 3) begin
|
||||
GP_3LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
|
||||
.IN0(A[0]), .IN1(A[1]), .IN2(A[2]));
|
||||
end else
|
||||
if (WIDTH == 4) begin
|
||||
GP_4LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
|
||||
.IN0(A[0]), .IN1(A[1]), .IN2(A[2]), .IN3(A[3]));
|
||||
end else begin
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
endgenerate
|
||||
end else
|
||||
if (WIDTH == 2) begin
|
||||
GP_2LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
|
||||
.IN0(A[0]), .IN1(A[1]));
|
||||
end else
|
||||
if (WIDTH == 3) begin
|
||||
GP_3LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
|
||||
.IN0(A[0]), .IN1(A[1]), .IN2(A[2]));
|
||||
end else
|
||||
if (WIDTH == 4) begin
|
||||
GP_4LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y),
|
||||
.IN0(A[0]), .IN1(A[1]), .IN2(A[2]), .IN3(A[3]));
|
||||
end else begin
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP);
|
||||
|
|
|
@ -7,8 +7,8 @@ module \$__ICE40_RAM4K (
|
|||
input [10:0] WADDR,
|
||||
input [15:0] MASK, WDATA
|
||||
);
|
||||
parameter integer READ_MODE = 0;
|
||||
parameter integer WRITE_MODE = 0;
|
||||
parameter [1:0] READ_MODE = 0;
|
||||
parameter [1:0] WRITE_MODE = 0;
|
||||
parameter [0:0] NEGCLK_R = 0;
|
||||
parameter [0:0] NEGCLK_W = 0;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ module fa
|
|||
wire VCC;
|
||||
|
||||
assign VCC = 1'b1;
|
||||
|
||||
|
||||
cycloneiv_lcell_comb gen_sum_0 (.combout(sum_x),
|
||||
.dataa(a_c),
|
||||
.datab(b_c),
|
||||
|
@ -40,7 +40,7 @@ module fa
|
|||
.datad(VCC));
|
||||
defparam syn__05_.lut_mask = 16'b1001011010010110;
|
||||
defparam syn__05_.sum_lutc_input = "datac";
|
||||
|
||||
|
||||
cycloneiv_lcell_comb gen_cout_0 (.combout(cout_t),
|
||||
.dataa(cin_c),
|
||||
.datab(b_c),
|
||||
|
@ -48,11 +48,11 @@ module fa
|
|||
.datad(VCC));
|
||||
defparam syn__06_.lut_mask = 16'b1110000011100000;
|
||||
defparam syn__06_.sum_lutc_input = "datac";
|
||||
|
||||
|
||||
endmodule // fa
|
||||
|
||||
module f_stage();
|
||||
|
||||
|
||||
endmodule // f_stage
|
||||
|
||||
module f_end();
|
||||
|
@ -88,7 +88,7 @@ module _80_cycloneive_alu (A, B, CI, BI, X, Y, CO);
|
|||
.cin_c(C[0]),
|
||||
.cout_t(C0[1]),
|
||||
.sum_x(Y[0]));
|
||||
|
||||
|
||||
genvar i;
|
||||
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]));
|
||||
|
|
|
@ -76,7 +76,7 @@ module \$lut (A, Y);
|
|||
wire VCC;
|
||||
wire GND;
|
||||
assign {VCC,GND} = {1'b1,1'b0};
|
||||
|
||||
|
||||
generate
|
||||
if (WIDTH == 1) begin
|
||||
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:
|
||||
**Extended LUT Mode**
|
||||
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).
|
||||
end*/
|
||||
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_tff_async_reset.v $adff
|
||||
code_hdl_models_uart.v $adff
|
||||
code_specman_switch_fabric.v subfield assignment (bits() <= ...)
|
||||
code_tidbits_asyn_reset.v $adff
|
||||
code_tidbits_reg_seq_example.v $adff
|
||||
code_verilog_tutorial_always_example.v empty module
|
||||
|
|
|
@ -12,7 +12,6 @@ multiplier.v inst id[0] of
|
|||
muxtree.v drops modules
|
||||
omsp_dbg_uart.v $adff
|
||||
operators.v $pow
|
||||
paramods.v subfield assignment (bits() <= ...)
|
||||
partsel.v drops modules
|
||||
process.v drops modules
|
||||
realexpr.v drops modules
|
||||
|
|
|
@ -8,7 +8,7 @@ verbose=false
|
|||
keeprunning=false
|
||||
makejmode=false
|
||||
frontend="verilog"
|
||||
backend_opts="-noattr -noexpr"
|
||||
backend_opts="-noattr -noexpr -siminit"
|
||||
autotb_opts=""
|
||||
include_opts=""
|
||||
xinclude_opts=""
|
||||
|
@ -49,7 +49,7 @@ while getopts xmGl:wkjvref:s:p:n:S:I:-: opt; do
|
|||
r)
|
||||
backend_opts="$backend_opts -norename" ;;
|
||||
e)
|
||||
backend_opts="$( echo " $backend_opts " | sed 's, -noexpr ,,; s,^ ,,; s, $,,;'; )" ;;
|
||||
backend_opts="$( echo " $backend_opts " | sed 's, -noexpr , ,; s,^ ,,; s, $,,;'; )" ;;
|
||||
f)
|
||||
frontend="$OPTARG" ;;
|
||||
s)
|
||||
|
@ -175,7 +175,7 @@ do
|
|||
if [ -n "$firrtl2verilog" ]; 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
|
||||
$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
|
||||
fi
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue