Merge remote-tracking branch 'origin/master' into xaig_dff

This commit is contained in:
Eddie Hung 2019-10-03 10:55:23 -07:00
commit 549d6ea467
20 changed files with 374 additions and 86 deletions

View File

@ -50,6 +50,7 @@ Yosys 0.9 .. Yosys 0.9-dev
- "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental) - "synth_ecp5" to now infer DSP blocks (-nodsp to disable, experimental)
- "synth_ice40 -dsp" to infer DSP blocks - "synth_ice40 -dsp" to infer DSP blocks
- Added latch support to synth_xilinx - Added latch support to synth_xilinx
- Added "check -mapped"
Yosys 0.8 .. Yosys 0.9 Yosys 0.8 .. Yosys 0.9
---------------------- ----------------------

View File

@ -115,7 +115,7 @@ LDFLAGS += -rdynamic
LDLIBS += -lrt LDLIBS += -lrt
endif endif
YOSYS_VER := 0.9+899 YOSYS_VER := 0.9+932
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
OBJS = kernel/version_$(GIT_REV).o OBJS = kernel/version_$(GIT_REV).o
@ -128,7 +128,7 @@ bumpversion:
# is just a symlink to your actual ABC working directory, as 'make mrproper' # is just a symlink to your actual ABC working directory, as 'make mrproper'
# will remove the 'abc' directory and you do not want to accidentally # will remove the 'abc' directory and you do not want to accidentally
# delete your work on ABC.. # delete your work on ABC..
ABCREV = 5776ad0 ABCREV = 623b5e8
ABCPULL = 1 ABCPULL = 1
ABCURL ?= https://github.com/berkeley-abc/abc ABCURL ?= https://github.com/berkeley-abc/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1

View File

@ -569,7 +569,7 @@ struct BtorWorker
int nid_init_val = -1; int nid_init_val = -1;
if (!initval.is_fully_undef()) if (!initval.is_fully_undef())
nid_init_val = get_sig_nid(initval); nid_init_val = get_sig_nid(initval, -1, false, true);
int sid = get_bv_sid(GetSize(sig_q)); int sid = get_bv_sid(GetSize(sig_q));
int nid = next_nid++; int nid = next_nid++;
@ -681,7 +681,7 @@ struct BtorWorker
{ {
if (verbose) if (verbose)
btorf("; initval = %s\n", log_signal(firstword)); btorf("; initval = %s\n", log_signal(firstword));
nid_init_val = get_sig_nid(firstword); nid_init_val = get_sig_nid(firstword, -1, false, true);
} }
else else
{ {
@ -693,8 +693,8 @@ struct BtorWorker
if (thisword.is_fully_undef()) if (thisword.is_fully_undef())
continue; continue;
Const thisaddr(i, abits); Const thisaddr(i, abits);
int nid_thisword = get_sig_nid(thisword); int nid_thisword = get_sig_nid(thisword, -1, false, true);
int nid_thisaddr = get_sig_nid(thisaddr); int nid_thisaddr = get_sig_nid(thisaddr, -1, false, true);
int last_nid_init_val = nid_init_val; int last_nid_init_val = nid_init_val;
nid_init_val = next_nid++; nid_init_val = next_nid++;
if (verbose) if (verbose)
@ -792,7 +792,7 @@ struct BtorWorker
cell_recursion_guard.erase(cell); cell_recursion_guard.erase(cell);
} }
int get_sig_nid(SigSpec sig, int to_width = -1, bool is_signed = false) int get_sig_nid(SigSpec sig, int to_width = -1, bool is_signed = false, bool is_init = false)
{ {
int nid = -1; int nid = -1;
sigmap.apply(sig); sigmap.apply(sig);
@ -823,6 +823,9 @@ struct BtorWorker
int sid = get_bv_sid(GetSize(sig)); int sid = get_bv_sid(GetSize(sig));
int nid_input = next_nid++; int nid_input = next_nid++;
if (is_init)
btorf("%d state %d\n", nid_input, sid);
else
btorf("%d input %d\n", nid_input, sid); btorf("%d input %d\n", nid_input, sid);
int nid_masked_input; int nid_masked_input;

View File

@ -1256,7 +1256,7 @@ def smt_check_sat():
return smt.check_sat() return smt.check_sat()
if tempind: if tempind:
retstatus = False retstatus = "FAILED"
skip_counter = step_size skip_counter = step_size
for step in range(num_steps, -1, -1): for step in range(num_steps, -1, -1):
if smt.forall: if smt.forall:
@ -1303,7 +1303,7 @@ if tempind:
else: else:
print_msg("Temporal induction successful.") print_msg("Temporal induction successful.")
retstatus = True retstatus = "PASSED"
break break
elif covermode: elif covermode:
@ -1321,7 +1321,7 @@ elif covermode:
smt.write("(define-fun covers_0 ((state |%s_s|)) (_ BitVec %d) %s)" % (topmod, len(cover_desc), cover_expr)) smt.write("(define-fun covers_0 ((state |%s_s|)) (_ BitVec %d) %s)" % (topmod, len(cover_desc), cover_expr))
step = 0 step = 0
retstatus = False retstatus = "FAILED"
found_failed_assert = False found_failed_assert = False
assert step_size == 1 assert step_size == 1
@ -1365,7 +1365,7 @@ elif covermode:
if smt_check_sat() == "unsat": if smt_check_sat() == "unsat":
print("%s Cannot appended steps without violating assumptions!" % smt.timestamp()) print("%s Cannot appended steps without violating assumptions!" % smt.timestamp())
found_failed_assert = True found_failed_assert = True
retstatus = False retstatus = "FAILED"
break break
reached_covers = smt.bv2bin(smt.get("(covers_%d s%d)" % (coveridx, step))) reached_covers = smt.bv2bin(smt.get("(covers_%d s%d)" % (coveridx, step)))
@ -1400,7 +1400,7 @@ elif covermode:
break break
if "1" not in cover_mask: if "1" not in cover_mask:
retstatus = True retstatus = "PASSED"
break break
step += 1 step += 1
@ -1412,7 +1412,7 @@ elif covermode:
else: # not tempind, covermode else: # not tempind, covermode
step = 0 step = 0
retstatus = True retstatus = "PASSED"
while step < num_steps: while step < num_steps:
smt_state(step) smt_state(step)
smt_assert_consequent("(|%s_u| s%d)" % (topmod, step)) smt_assert_consequent("(|%s_u| s%d)" % (topmod, step))
@ -1459,8 +1459,8 @@ else: # not tempind, covermode
print_msg("Checking assumptions in steps %d to %d.." % (step, last_check_step)) print_msg("Checking assumptions in steps %d to %d.." % (step, last_check_step))
if smt_check_sat() == "unsat": if smt_check_sat() == "unsat":
print("%s Warmup failed!" % smt.timestamp()) print("%s Assumptions are unsatisfiable!" % smt.timestamp())
retstatus = False retstatus = "PREUNSAT"
break break
if not final_only: if not final_only:
@ -1487,13 +1487,13 @@ else: # not tempind, covermode
print_msg("Re-solving with appended steps..") print_msg("Re-solving with appended steps..")
if smt_check_sat() == "unsat": if smt_check_sat() == "unsat":
print("%s Cannot appended steps without violating assumptions!" % smt.timestamp()) print("%s Cannot appended steps without violating assumptions!" % smt.timestamp())
retstatus = False retstatus = "FAILED"
break break
print_anyconsts(step) print_anyconsts(step)
for i in range(step, last_check_step+1): for i in range(step, last_check_step+1):
print_failed_asserts(i) print_failed_asserts(i)
write_trace(0, last_check_step+1+append_steps, '%') write_trace(0, last_check_step+1+append_steps, '%')
retstatus = False retstatus = "FAILED"
break break
smt_pop() smt_pop()
@ -1519,7 +1519,7 @@ else: # not tempind, covermode
print_anyconsts(i) print_anyconsts(i)
print_failed_asserts(i, final=True) print_failed_asserts(i, final=True)
write_trace(0, i+1, '%') write_trace(0, i+1, '%')
retstatus = False retstatus = "FAILED"
break break
smt_pop() smt_pop()
@ -1534,7 +1534,7 @@ else: # not tempind, covermode
print_msg("Solving for step %d.." % (last_check_step)) print_msg("Solving for step %d.." % (last_check_step))
if smt_check_sat() != "sat": if smt_check_sat() != "sat":
print("%s No solution found!" % smt.timestamp()) print("%s No solution found!" % smt.timestamp())
retstatus = False retstatus = "FAILED"
break break
elif dumpall: elif dumpall:
@ -1551,5 +1551,5 @@ else: # not tempind, covermode
smt.write("(exit)") smt.write("(exit)")
smt.wait() smt.wait()
print_msg("Status: %s" % ("PASSED" if retstatus else "FAILED (!)")) print_msg("Status: %s" % retstatus)
sys.exit(0 if retstatus else 1) sys.exit(0 if retstatus == "PASSED" else 1)

View File

@ -1382,10 +1382,10 @@ void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RT
// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces // create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
// This method is used to explode the interface when the interface is a port of the module (not instantiated inside) // This method is used to explode the interface when the interface is a port of the module (not instantiated inside)
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool /*mayfail*/)
{ {
AstNode *new_ast = NULL; AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast, mayfail); std::string modname = derive_common(design, parameters, &new_ast);
// Since interfaces themselves may be instantiated with different parameters, // Since interfaces themselves may be instantiated with different parameters,
// "modname" must also take those into account, so that unique modules // "modname" must also take those into account, so that unique modules
@ -1398,11 +1398,17 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
has_interfaces = true; has_interfaces = true;
} }
std::string new_modname = modname;
if (has_interfaces) if (has_interfaces)
modname += "$interfaces$" + interf_info; new_modname += "$interfaces$" + interf_info;
if (!design->has(modname)) { if (!design->has(new_modname)) {
if (!new_ast) {
auto mod = dynamic_cast<AstModule*>(design->module(modname));
new_ast = mod->ast->clone();
}
modname = new_modname;
new_ast->str = modname; new_ast->str = modname;
// Iterate over all interfaces which are ports in this module: // Iterate over all interfaces which are ports in this module:
@ -1455,10 +1461,10 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
} }
// create a new parametric module (when needed) and return the name of the generated module - without support for interfaces // create a new parametric module (when needed) and return the name of the generated module - without support for interfaces
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool /*mayfail*/)
{ {
AstNode *new_ast = NULL; AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast, mayfail); std::string modname = derive_common(design, parameters, &new_ast);
if (!design->has(modname)) { if (!design->has(modname)) {
new_ast->str = modname; new_ast->str = modname;
@ -1473,31 +1479,66 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, R
} }
// create a new parametric module (when needed) and return the name of the generated module // create a new parametric module (when needed) and return the name of the generated module
std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool) std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out)
{ {
std::string stripped_name = name.str(); std::string stripped_name = name.str();
if (stripped_name.compare(0, 9, "$abstract") == 0) if (stripped_name.compare(0, 9, "$abstract") == 0)
stripped_name = stripped_name.substr(9); stripped_name = stripped_name.substr(9);
log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
loadconfig();
std::string para_info; std::string para_info;
AstNode *new_ast = ast->clone();
int para_counter = 0; int para_counter = 0;
int orig_parameters_n = parameters.size(); for (const auto child : ast->children) {
for (auto it = new_ast->children.begin(); it != new_ast->children.end(); it++) {
AstNode *child = *it;
if (child->type != AST_PARAMETER) if (child->type != AST_PARAMETER)
continue; continue;
para_counter++; para_counter++;
std::string para_id = child->str; std::string para_id = child->str;
if (parameters.count(para_id) > 0) { if (parameters.count(para_id) > 0) {
log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str]))); log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
rewrite_parameter:
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id]))); para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
continue;
}
para_id = stringf("$%d", para_counter);
if (parameters.count(para_id) > 0) {
log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
continue;
}
}
std::string modname;
if (parameters.size() == 0)
modname = stripped_name;
else if (para_info.size() > 60)
modname = "$paramod$" + sha1(para_info) + stripped_name;
else
modname = "$paramod" + stripped_name + para_info;
if (design->has(modname))
return modname;
log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());
loadconfig();
AstNode *new_ast = ast->clone();
para_counter = 0;
for (auto child : new_ast->children) {
if (child->type != AST_PARAMETER)
continue;
para_counter++;
std::string para_id = child->str;
if (parameters.count(para_id) > 0) {
log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
goto rewrite_parameter;
}
para_id = stringf("$%d", para_counter);
if (parameters.count(para_id) > 0) {
log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
goto rewrite_parameter;
}
continue;
rewrite_parameter:
delete child->children.at(0); delete child->children.at(0);
if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) { if ((parameters[para_id].flags & RTLIL::CONST_FLAG_REAL) != 0) {
child->children[0] = new AstNode(AST_REALVALUE); child->children[0] = new AstNode(AST_REALVALUE);
@ -1507,13 +1548,6 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
else else
child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0); child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0);
parameters.erase(para_id); parameters.erase(para_id);
continue;
}
para_id = stringf("$%d", para_counter);
if (parameters.count(para_id) > 0) {
log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
goto rewrite_parameter;
}
} }
for (auto param : parameters) { for (auto param : parameters) {
@ -1526,16 +1560,6 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
new_ast->children.push_back(defparam); new_ast->children.push_back(defparam);
} }
std::string modname;
if (orig_parameters_n == 0)
modname = stripped_name;
else if (para_info.size() > 60)
modname = "$paramod$" + sha1(para_info) + stripped_name;
else
modname = "$paramod" + stripped_name + para_info;
(*new_ast_out) = new_ast; (*new_ast_out) = new_ast;
return modname; return modname;
} }

View File

@ -296,7 +296,7 @@ namespace AST
~AstModule() YS_OVERRIDE; ~AstModule() YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail) YS_OVERRIDE;
RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE; RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE;
std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool mayfail); std::string derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out);
void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE; void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces) YS_OVERRIDE;
RTLIL::Module *clone() const YS_OVERRIDE; RTLIL::Module *clone() const YS_OVERRIDE;
void loadconfig() const; void loadconfig() const;

View File

@ -34,6 +34,8 @@
#include "libs/sha1/sha1.h" #include "libs/sha1/sha1.h"
#include "kernel/yosys.h" #include "kernel/yosys.h"
extern char **environ;
YOSYS_NAMESPACE_BEGIN YOSYS_NAMESPACE_BEGIN
#if defined(_WIN32) #if defined(_WIN32)

View File

@ -551,6 +551,10 @@ void log_dump_val_worker(RTLIL::SigSpec v) {
log("%s", log_signal(v)); log("%s", log_signal(v));
} }
void log_dump_val_worker(RTLIL::State v) {
log("%s", log_signal(v));
}
const char *log_signal(const RTLIL::SigSpec &sig, bool autoint) const char *log_signal(const RTLIL::SigSpec &sig, bool autoint)
{ {
std::stringstream buf; std::stringstream buf;

View File

@ -292,6 +292,7 @@ static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p
static inline void log_dump_args_worker(const char *p YS_ATTRIBUTE(unused)) { log_assert(*p == 0); } static inline void log_dump_args_worker(const char *p YS_ATTRIBUTE(unused)) { log_assert(*p == 0); }
void log_dump_val_worker(RTLIL::IdString v); void log_dump_val_worker(RTLIL::IdString v);
void log_dump_val_worker(RTLIL::SigSpec v); void log_dump_val_worker(RTLIL::SigSpec v);
void log_dump_val_worker(RTLIL::State v);
template<typename K, typename T, typename OPS> template<typename K, typename T, typename OPS>
static inline void log_dump_val_worker(dict<K, T, OPS> &v) { static inline void log_dump_val_worker(dict<K, T, OPS> &v) {

View File

@ -210,6 +210,7 @@ namespace RTLIL {
struct Module; struct Module;
struct Design; struct Design;
struct Monitor; struct Monitor;
enum State : unsigned char;
} }
namespace AST { namespace AST {

View File

@ -41,14 +41,24 @@ struct CheckPass : public Pass {
log("\n"); log("\n");
log(" - used wires that do not have a driver\n"); log(" - used wires that do not have a driver\n");
log("\n"); log("\n");
log("When called with -noinit then this command also checks for wires which have\n"); log("Options:\n");
log("the 'init' attribute set.\n");
log("\n"); log("\n");
log("When called with -initdrv then this command also checks for wires which have\n"); log(" -noinit\n");
log("the 'init' attribute set and aren't driven by a FF cell type.\n"); log(" Also check for wires which have the 'init' attribute set.\n");
log("\n"); log("\n");
log("When called with -assert then the command will produce an error if any\n"); log(" -initdrv\n");
log("problems are found in the current design.\n"); log(" Also check for wires that have the 'init' attribute set and are not\n");
log(" driven by an FF cell type.\n");
log("\n");
log(" -mapped\n");
log(" Also check for internal cells that have not been mapped to cells of the\n");
log(" target architecture.\n");
log("\n");
log(" -allow-tbuf\n");
log(" Modify the -mapped behavior to still allow $_TBUF_ cells.\n");
log("\n");
log(" -assert\n");
log(" Produce a runtime error if any problems are found in the current design.\n");
log("\n"); log("\n");
} }
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@ -56,6 +66,8 @@ struct CheckPass : public Pass {
int counter = 0; int counter = 0;
bool noinit = false; bool noinit = false;
bool initdrv = false; bool initdrv = false;
bool mapped = false;
bool allow_tbuf = false;
bool assert_mode = false; bool assert_mode = false;
size_t argidx; size_t argidx;
@ -68,6 +80,14 @@ struct CheckPass : public Pass {
initdrv = true; initdrv = true;
continue; continue;
} }
if (args[argidx] == "-mapped") {
mapped = true;
continue;
}
if (args[argidx] == "-allow-tbuf") {
allow_tbuf = true;
continue;
}
if (args[argidx] == "-assert") { if (args[argidx] == "-assert") {
assert_mode = true; assert_mode = true;
continue; continue;
@ -135,6 +155,13 @@ struct CheckPass : public Pass {
TopoSort<string> topo; TopoSort<string> topo;
for (auto cell : module->cells()) for (auto cell : module->cells())
{
if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) {
if (allow_tbuf && cell->type == ID($_TBUF_)) goto cell_allowed;
log_warning("Cell %s.%s is an unmapped internal cell of type %s.\n", log_id(module), log_id(cell), log_id(cell->type));
counter++;
cell_allowed:;
}
for (auto &conn : cell->connections()) { for (auto &conn : cell->connections()) {
SigSpec sig = sigmap(conn.second); SigSpec sig = sigmap(conn.second);
bool logic_cell = yosys_celltypes.cell_evaluable(cell->type); bool logic_cell = yosys_celltypes.cell_evaluable(cell->type);
@ -159,6 +186,7 @@ struct CheckPass : public Pass {
for (auto bit : sig) for (auto bit : sig)
if (bit.wire) wire_drivers_count[bit]++; if (bit.wire) wire_drivers_count[bit]++;
} }
}
pool<SigBit> init_bits; pool<SigBit> init_bits;

View File

@ -265,6 +265,12 @@ struct TechmapWorker
} }
design->select(module, w); design->select(module, w);
if (it.second->name.begins_with("\\_TECHMAP_REPLACE_.")) {
IdString replace_name = stringf("%s%s", orig_cell_name.c_str(), it.second->name.c_str() + strlen("\\_TECHMAP_REPLACE_"));
Wire *replace_w = module->addWire(replace_name, it.second);
module->connect(replace_w, w);
}
} }
SigMap tpl_sigmap(tpl); SigMap tpl_sigmap(tpl);
@ -386,6 +392,8 @@ struct TechmapWorker
if (techmap_replace_cell) if (techmap_replace_cell)
c_name = orig_cell_name; c_name = orig_cell_name;
else if (it.second->name.begins_with("\\_TECHMAP_REPLACE_."))
c_name = stringf("%s%s", orig_cell_name.c_str(), c_name.c_str() + strlen("\\_TECHMAP_REPLACE_"));
else else
apply_prefix(cell->name, c_name); apply_prefix(cell->name, c_name);
@ -1206,6 +1214,12 @@ struct TechmapPass : public Pass {
log("\n"); log("\n");
log("A cell with the name _TECHMAP_REPLACE_ in the map file will inherit the name\n"); log("A cell with the name _TECHMAP_REPLACE_ in the map file will inherit the name\n");
log("and attributes of the cell that is being replaced.\n"); log("and attributes of the cell that is being replaced.\n");
log("A cell with a name of the form `_TECHMAP_REPLACE_.<suffix>` in the map file will\n");
log("be named thus but with the `_TECHMAP_REPLACE_' prefix substituted with the name\n");
log("of the cell being replaced.\n");
log("Similarly, a wire named in the form `_TECHMAP_REPLACE_.<suffix>` will cause a\n");
log("new wire alias to be created and named as above but with the `_TECHMAP_REPLACE_'\n");
log("prefix also substituted.\n");
log("\n"); log("\n");
log("See 'help extract' for a pass that does the opposite thing.\n"); log("See 'help extract' for a pass that does the opposite thing.\n");
log("\n"); log("\n");

View File

@ -6,4 +6,5 @@ bram_conn_2.vh
bram_conn_4.vh bram_conn_4.vh
bram_conn_9.vh bram_conn_9.vh
bram_conn_18.vh bram_conn_18.vh
bram_conn_36.vh
brams_connect.mk brams_connect.mk

View File

@ -44,6 +44,7 @@ techlibs/ecp5/bram_conn_2.vh: techlibs/ecp5/brams_connect.mk
techlibs/ecp5/bram_conn_4.vh: techlibs/ecp5/brams_connect.mk techlibs/ecp5/bram_conn_4.vh: techlibs/ecp5/brams_connect.mk
techlibs/ecp5/bram_conn_9.vh: techlibs/ecp5/brams_connect.mk techlibs/ecp5/bram_conn_9.vh: techlibs/ecp5/brams_connect.mk
techlibs/ecp5/bram_conn_18.vh: techlibs/ecp5/brams_connect.mk techlibs/ecp5/bram_conn_18.vh: techlibs/ecp5/brams_connect.mk
techlibs/ecp5/bram_conn_36.vh: techlibs/ecp5/brams_connect.mk
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_1_2_4.vh)) $(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_1_2_4.vh))
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_9_18_36.vh)) $(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_init_9_18_36.vh))
@ -53,3 +54,4 @@ $(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_2.vh))
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_4.vh)) $(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_4.vh))
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_9.vh)) $(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_9.vh))
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_18.vh)) $(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_18.vh))
$(eval $(call add_gen_share_file,share/ecp5,techlibs/ecp5/bram_conn_36.vh))

View File

@ -1,3 +1,18 @@
bram $__ECP5_PDPW16KD
init 1
abits 9
dbits 36
groups 2
ports 1 1
wrmode 1 0
enable 4 1
transp 0 0
clocks 2 3
clkpol 2 3
endbram
bram $__ECP5_DP16KD bram $__ECP5_DP16KD
init 1 init 1
@ -22,8 +37,16 @@ bram $__ECP5_DP16KD
clkpol 2 3 clkpol 2 3
endbram endbram
match $__ECP5_PDPW16KD
min bits 2048
min efficiency 5
shuffle_enable A
make_transp
or_next_if_better
endmatch
match $__ECP5_DP16KD match $__ECP5_DP16KD
min bits 2048 min bits 2048
min efficiency 5 min efficiency 5
shuffle_enable B shuffle_enable A
endmatch endmatch

View File

@ -10,6 +10,18 @@ def write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits):
print(" %s," % ", ".join(dia_conn), file=f) print(" %s," % ", ".join(dia_conn), file=f)
print(" %s," % ", ".join(dob_conn), file=f) print(" %s," % ", ".join(dob_conn), file=f)
def write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits):
adw_conn = [".ADW%d(%s)" % (i, adw_bits[i]) for i in range(len(adw_bits))]
adr_conn = [".ADR%d(%s)" % (i, adr_bits[i]) for i in range(len(adr_bits))]
di_conn = [".DI%d(%s)" % (i, di_bits[i]) for i in range(len(di_bits))]
do_conn = [".DO%d(%s)" % (i, do_bits[i]) for i in range(len(do_bits))]
be_conn = [".BE%d(%s)" % (i, be_bits[i]) for i in range(len(be_bits))]
print(" %s," % ", ".join(adw_conn), file=f)
print(" %s," % ", ".join(adr_conn), file=f)
print(" %s," % ", ".join(di_conn), file=f)
print(" %s," % ", ".join(do_conn), file=f)
print(" %s," % ", ".join(be_conn), file=f)
with open("techlibs/ecp5/bram_conn_1.vh", "w") as f: with open("techlibs/ecp5/bram_conn_1.vh", "w") as f:
ada_bits = ["A1ADDR[%d]" % i for i in range(14)] ada_bits = ["A1ADDR[%d]" % i for i in range(14)]
adb_bits = ["B1ADDR[%d]" % i for i in range(14)] adb_bits = ["B1ADDR[%d]" % i for i in range(14)]
@ -44,3 +56,11 @@ with open("techlibs/ecp5/bram_conn_18.vh", "w") as f:
dia_bits = ["A1DATA[%d]" % i for i in range(18)] dia_bits = ["A1DATA[%d]" % i for i in range(18)]
dob_bits = ["B1DATA[%d]" % i for i in range(18)] dob_bits = ["B1DATA[%d]" % i for i in range(18)]
write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits) write_bus_ports(f, ada_bits, adb_bits, dia_bits, dob_bits)
with open("techlibs/ecp5/bram_conn_36.vh", "w") as f:
adw_bits = ["A1ADDR[%d]" % i for i in range(9)]
adr_bits = ["1'b0", "1'b0", "1'b0", "1'b0", "1'b0"] + ["B1ADDR[%d]" % i for i in range(9)]
di_bits = ["A1DATA[%d]" % i for i in range(36)]
do_bits = ["B1DATA[%d]" % (i + 18) for i in range(18)] + ["B1DATA[%d]" % i for i in range(18)]
be_bits = ["A1EN[%d]" % i for i in range(4)]
write_bus_ports_pdp(f, adw_bits, adr_bits, di_bits, do_bits, be_bits)

View File

@ -113,3 +113,45 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
wire TECHMAP_FAIL = 1'b1; wire TECHMAP_FAIL = 1'b1;
end endgenerate end endgenerate
endmodule endmodule
module \$__ECP5_PDPW16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CFG_ABITS = 9;
parameter CFG_DBITS = 36;
parameter CFG_ENABLE_A = 4;
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
parameter [18431:0] INIT = 18432'bx;
input CLK2;
input CLK3;
input [CFG_ABITS-1:0] A1ADDR;
input [CFG_DBITS-1:0] A1DATA;
input [CFG_ENABLE_A-1:0] A1EN;
input [CFG_ABITS-1:0] B1ADDR;
output [CFG_DBITS-1:0] B1DATA;
input B1EN;
localparam CLKWMUX = CLKPOL2 ? "CLKA" : "INV";
localparam CLKRMUX = CLKPOL3 ? "CLKB" : "INV";
localparam WRITEMODE_A = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE";
PDPW16KD #(
`include "bram_init_9_18_36.vh"
.DATA_WIDTH_W(36),
.DATA_WIDTH_R(36),
.CLKWMUX(CLKWMUX),
.CLKRMUX(CLKRMUX),
.GSR("AUTO")
) _TECHMAP_REPLACE_ (
`include "bram_conn_36.vh"
.CLKW(CLK2), .CLKR(CLK3),
.CEW(1'b1),
.CER(B1EN), .OCER(1'b1),
.RST(1'b0)
);
endmodule

View File

@ -684,3 +684,97 @@ module SGSR (
input GSR, CLK input GSR, CLK
); );
endmodule endmodule
(* blackbox *)
module PDPW16KD (
input DI35, DI34, DI33, DI32, DI31, DI30, DI29, DI28, DI27, DI26, DI25, DI24, DI23, DI22, DI21, DI20, DI19, DI18,
input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0,
input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0,
input BE3, BE2, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0,
input ADR13, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0,
input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST,
output DO35, DO34, DO33, DO32, DO31, DO30, DO29, DO28, DO27, DO26, DO25, DO24, DO23, DO22, DO21, DO20, DO19, DO18,
output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0
);
parameter DATA_WIDTH_W = 36;
parameter DATA_WIDTH_R = 36;
parameter GSR = "ENABLED";
parameter REGMODE = "NOREG";
parameter RESETMODE = "SYNC";
parameter ASYNC_RESET_RELEASE = "SYNC";
parameter CSDECODE_W = "0b000";
parameter CSDECODE_R = "0b000";
parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_DATA = "STATIC";
parameter CLKWMUX = "CLKW";
parameter CLKRMUX = "CLKR";
endmodule

10
tests/techmap/aigmap.ys Normal file
View File

@ -0,0 +1,10 @@
read_verilog <<EOT
module top(input i, j, s, output o, p);
assign o = s ? j : i;
assign p = ~i;
endmodule
EOT
select t:$mux
aigmap -select
select -assert-any %

View File

@ -0,0 +1,18 @@
read_verilog <<EOT
module sub(input i, output o, input j);
foobar _TECHMAP_REPLACE_(i, o, j);
wire _TECHMAP_REPLACE_.asdf = i ;
barfoo _TECHMAP_REPLACE_.blah (i, o, j);
endmodule
EOT
design -stash techmap
read_verilog <<EOT
module top(input i, output o);
sub s0(i, o);
endmodule
EOT
techmap -map %techmap
select -assert-any w:s0.asdf
select -assert-any c:s0.blah