mirror of https://github.com/YosysHQ/yosys.git
Merge remote-tracking branch 'origin/master' into xc7mux
This commit is contained in:
commit
f374e0ab7e
|
@ -18,11 +18,12 @@ Yosys 0.8 .. Yosys 0.8-dev
|
|||
- Added "equiv_opt" pass
|
||||
- Added "read_aiger" frontend
|
||||
- Added "shregmap -tech xilinx"
|
||||
- "synth_xilinx" to now infer hard shift registers (-nosrl to disable)
|
||||
- Added "abc9" pass for timing-aware techmapping (experimental, FPGA only, no FFs)
|
||||
- Added "synth_xilinx -abc9" (experimental)
|
||||
- Added "synth_ice40 -abc9" (experimental)
|
||||
- Extended "muxcover -mux{4,8,16}=<cost>"
|
||||
- Added "synth -abc9" (experimental)
|
||||
- "synth_xilinx" to now infer hard shift registers (-nosrl to disable)
|
||||
- "synth_xilinx" to now infer wide multiplexers (-nomux to disable)
|
||||
|
||||
|
||||
|
|
|
@ -350,6 +350,14 @@ Verilog Attributes and non-standard features
|
|||
through the synthesis. When entities are combined, a new |-separated
|
||||
string is created that contains all the string from the original entities.
|
||||
|
||||
- The ``defaultvalue`` attribute is used to store default values for
|
||||
module inputs. The attribute is attached to the input wire by the HDL
|
||||
front-end when the input is declared with a default value.
|
||||
|
||||
- The ``parameter`` and ``localparam`` attributes are used to mark wires
|
||||
that represent module parameters or localparams (when the HDL front-end
|
||||
is run in -pwires mode).
|
||||
|
||||
- In addition to the ``(* ... *)`` attribute syntax, Yosys supports
|
||||
the non-standard ``{* ... *}`` attribute syntax to set default attributes
|
||||
for everything that comes after the ``{* ... *}`` statement. (Reset
|
||||
|
|
|
@ -776,6 +776,7 @@ struct AigerBackend : public Backend {
|
|||
writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode);
|
||||
|
||||
if (!map_filename.empty()) {
|
||||
rewrite_filename(filename);
|
||||
std::ofstream mapf;
|
||||
mapf.open(map_filename.c_str(), std::ofstream::trunc);
|
||||
if (mapf.fail())
|
||||
|
|
|
@ -483,6 +483,7 @@ struct DumpPass : public Pass {
|
|||
std::stringstream buf;
|
||||
|
||||
if (!filename.empty()) {
|
||||
rewrite_filename(filename);
|
||||
std::ofstream *ff = new std::ofstream;
|
||||
ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc);
|
||||
if (ff->fail()) {
|
||||
|
|
|
@ -525,6 +525,7 @@ struct JsonPass : public Pass {
|
|||
std::stringstream buf;
|
||||
|
||||
if (!filename.empty()) {
|
||||
rewrite_filename(filename);
|
||||
std::ofstream *ff = new std::ofstream;
|
||||
ff->open(filename.c_str(), std::ofstream::trunc);
|
||||
if (ff->fail()) {
|
||||
|
|
|
@ -336,6 +336,7 @@ struct ProtobufPass : public Pass {
|
|||
std::stringstream buf;
|
||||
|
||||
if (!filename.empty()) {
|
||||
rewrite_filename(filename);
|
||||
std::ofstream *ff = new std::ofstream;
|
||||
ff->open(filename.c_str(), std::ofstream::trunc);
|
||||
if (ff->fail()) {
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace AST {
|
|||
// instantiate global variables (private API)
|
||||
namespace AST_INTERNAL {
|
||||
bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches, flag_nomeminit;
|
||||
bool flag_nomem2reg, flag_mem2reg, flag_noblackbox, flag_lib, flag_nowb, flag_noopt, flag_icells, flag_autowire;
|
||||
bool flag_nomem2reg, flag_mem2reg, flag_noblackbox, flag_lib, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_autowire;
|
||||
AstNode *current_ast, *current_ast_mod;
|
||||
std::map<std::string, AstNode*> current_scope;
|
||||
const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL;
|
||||
|
@ -1112,6 +1112,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
|
|||
current_module->nowb = flag_nowb;
|
||||
current_module->noopt = flag_noopt;
|
||||
current_module->icells = flag_icells;
|
||||
current_module->pwires = flag_pwires;
|
||||
current_module->autowire = flag_autowire;
|
||||
current_module->fixup_ports();
|
||||
|
||||
|
@ -1126,7 +1127,7 @@ static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast
|
|||
|
||||
// create AstModule instances for all modules in the AST tree and add them to 'design'
|
||||
void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil,
|
||||
bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire)
|
||||
bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire)
|
||||
{
|
||||
current_ast = ast;
|
||||
flag_dump_ast1 = dump_ast1;
|
||||
|
@ -1144,6 +1145,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
|
|||
flag_nowb = nowb;
|
||||
flag_noopt = noopt;
|
||||
flag_icells = icells;
|
||||
flag_pwires = pwires;
|
||||
flag_autowire = autowire;
|
||||
|
||||
log_assert(current_ast->type == AST_DESIGN);
|
||||
|
@ -1480,6 +1482,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString
|
|||
flag_nowb = nowb;
|
||||
flag_noopt = noopt;
|
||||
flag_icells = icells;
|
||||
flag_pwires = pwires;
|
||||
flag_autowire = autowire;
|
||||
use_internal_line_num();
|
||||
|
||||
|
@ -1551,6 +1554,7 @@ RTLIL::Module *AstModule::clone() const
|
|||
new_mod->lib = lib;
|
||||
new_mod->noopt = noopt;
|
||||
new_mod->icells = icells;
|
||||
new_mod->pwires = pwires;
|
||||
new_mod->autowire = autowire;
|
||||
|
||||
return new_mod;
|
||||
|
|
|
@ -286,13 +286,13 @@ namespace AST
|
|||
|
||||
// process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code
|
||||
void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog1, bool dump_vlog2, bool dump_rtlil, bool nolatches, bool nomeminit,
|
||||
bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire);
|
||||
bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire);
|
||||
|
||||
// parametric modules are supported directly by the AST library
|
||||
// therefore we need our own derivate of RTLIL::Module with overloaded virtual functions
|
||||
struct AstModule : RTLIL::Module {
|
||||
AstNode *ast;
|
||||
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, autowire;
|
||||
bool nolatches, nomeminit, nomem2reg, mem2reg, noblackbox, lib, nowb, noopt, icells, pwires, autowire;
|
||||
~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, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail) YS_OVERRIDE;
|
||||
|
@ -325,7 +325,7 @@ namespace AST_INTERNAL
|
|||
{
|
||||
// internal state variables
|
||||
extern bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_rtlil, flag_nolatches, flag_nomeminit;
|
||||
extern bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;
|
||||
extern bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_pwires, flag_autowire;
|
||||
extern AST::AstNode *current_ast, *current_ast_mod;
|
||||
extern std::map<std::string, AST::AstNode*> current_scope;
|
||||
extern const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr;
|
||||
|
|
|
@ -853,7 +853,6 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
case AST_FUNCTION:
|
||||
case AST_DPI_FUNCTION:
|
||||
case AST_AUTOWIRE:
|
||||
case AST_LOCALPARAM:
|
||||
case AST_DEFPARAM:
|
||||
case AST_GENVAR:
|
||||
case AST_GENFOR:
|
||||
|
@ -895,6 +894,26 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
|||
// remember the parameter, needed for example in techmap
|
||||
case AST_PARAMETER:
|
||||
current_module->avail_parameters.insert(str);
|
||||
/* fall through */
|
||||
case AST_LOCALPARAM:
|
||||
if (flag_pwires)
|
||||
{
|
||||
if (GetSize(children) < 1 || children[0]->type != AST_CONSTANT)
|
||||
log_file_error(filename, linenum, "Parameter `%s' with non-constant value!\n", str.c_str());
|
||||
|
||||
RTLIL::Const val = children[0]->bitsAsConst();
|
||||
RTLIL::Wire *wire = current_module->addWire(str, GetSize(val));
|
||||
current_module->connect(wire, val);
|
||||
|
||||
wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
|
||||
wire->attributes[type == AST_PARAMETER ? "\\parameter" : "\\localparam"] = 1;
|
||||
|
||||
for (auto &attr : attributes) {
|
||||
if (attr.second->type != AST_CONSTANT)
|
||||
log_file_error(filename, linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
|
||||
wire->attributes[attr.first] = attr.second->asAttrConst();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// create an RTLIL::Wire for an AST_WIRE node
|
||||
|
|
|
@ -168,6 +168,9 @@ struct VerilogFrontend : public Frontend {
|
|||
log(" -icells\n");
|
||||
log(" interpret cell types starting with '$' as internal cell types\n");
|
||||
log("\n");
|
||||
log(" -pwires\n");
|
||||
log(" add a wire for each module parameter\n");
|
||||
log("\n");
|
||||
log(" -nooverwrite\n");
|
||||
log(" ignore re-definitions of modules. (the default behavior is to\n");
|
||||
log(" create an error message if the existing module is not a black box\n");
|
||||
|
@ -228,6 +231,7 @@ struct VerilogFrontend : public Frontend {
|
|||
bool flag_nodpi = false;
|
||||
bool flag_noopt = false;
|
||||
bool flag_icells = false;
|
||||
bool flag_pwires = false;
|
||||
bool flag_nooverwrite = false;
|
||||
bool flag_overwrite = false;
|
||||
bool flag_defer = false;
|
||||
|
@ -368,6 +372,10 @@ struct VerilogFrontend : public Frontend {
|
|||
flag_icells = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-pwires") {
|
||||
flag_pwires = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-ignore_redef" || arg == "-nooverwrite") {
|
||||
flag_nooverwrite = true;
|
||||
flag_overwrite = false;
|
||||
|
@ -458,7 +466,7 @@ struct VerilogFrontend : public Frontend {
|
|||
error_on_dpi_function(current_ast);
|
||||
|
||||
AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches,
|
||||
flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
|
||||
flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
|
||||
|
||||
if (!flag_nopp)
|
||||
delete lexin;
|
||||
|
|
|
@ -319,15 +319,17 @@ module_para_list:
|
|||
|
||||
single_module_para:
|
||||
/* empty */ |
|
||||
TOK_PARAMETER {
|
||||
attr TOK_PARAMETER {
|
||||
if (astbuf1) delete astbuf1;
|
||||
astbuf1 = new AstNode(AST_PARAMETER);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_range single_param_decl |
|
||||
TOK_LOCALPARAM {
|
||||
attr TOK_LOCALPARAM {
|
||||
if (astbuf1) delete astbuf1;
|
||||
astbuf1 = new AstNode(AST_LOCALPARAM);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_range single_param_decl |
|
||||
single_param_decl;
|
||||
|
||||
|
@ -345,7 +347,13 @@ module_arg_opt_assignment:
|
|||
if (ast_stack.back()->children.size() > 0 && ast_stack.back()->children.back()->type == AST_WIRE) {
|
||||
AstNode *wire = new AstNode(AST_IDENTIFIER);
|
||||
wire->str = ast_stack.back()->children.back()->str;
|
||||
if (ast_stack.back()->children.back()->is_reg)
|
||||
if (ast_stack.back()->children.back()->is_input) {
|
||||
AstNode *n = ast_stack.back()->children.back();
|
||||
if (n->attributes.count("\\defaultvalue"))
|
||||
delete n->attributes.at("\\defaultvalue");
|
||||
n->attributes["\\defaultvalue"] = $2;
|
||||
} else
|
||||
if (ast_stack.back()->children.back()->is_reg || ast_stack.back()->children.back()->is_logic)
|
||||
ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $2))));
|
||||
else
|
||||
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $2));
|
||||
|
@ -1211,6 +1219,7 @@ param_decl:
|
|||
attr TOK_PARAMETER {
|
||||
astbuf1 = new AstNode(AST_PARAMETER);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_real param_range param_decl_list ';' {
|
||||
delete astbuf1;
|
||||
};
|
||||
|
@ -1219,6 +1228,7 @@ localparam_decl:
|
|||
attr TOK_LOCALPARAM {
|
||||
astbuf1 = new AstNode(AST_LOCALPARAM);
|
||||
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
|
||||
append_attr(astbuf1, $1);
|
||||
} param_signed param_integer param_real param_range param_decl_list ';' {
|
||||
delete astbuf1;
|
||||
};
|
||||
|
@ -1360,7 +1370,12 @@ wire_name_and_opt_assign:
|
|||
wire_name '=' expr {
|
||||
AstNode *wire = new AstNode(AST_IDENTIFIER);
|
||||
wire->str = ast_stack.back()->children.back()->str;
|
||||
if (astbuf1->is_reg)
|
||||
if (astbuf1->is_input) {
|
||||
if (astbuf1->attributes.count("\\defaultvalue"))
|
||||
delete astbuf1->attributes.at("\\defaultvalue");
|
||||
astbuf1->attributes["\\defaultvalue"] = $3;
|
||||
} else
|
||||
if (astbuf1->is_reg || astbuf1->is_logic)
|
||||
ast_stack.back()->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, wire, $3))));
|
||||
else
|
||||
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, wire, $3));
|
||||
|
@ -1385,7 +1400,13 @@ wire_name:
|
|||
node->children.push_back(rng);
|
||||
}
|
||||
node->type = AST_MEMORY;
|
||||
node->children.push_back($2);
|
||||
auto *rangeNode = $2;
|
||||
if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
|
||||
// SV array size [n], rewrite as [n-1:0]
|
||||
rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
|
||||
rangeNode->children.push_back(AstNode::mkconst_int(0, false));
|
||||
}
|
||||
node->children.push_back(rangeNode);
|
||||
}
|
||||
if (current_function_or_task == NULL) {
|
||||
if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) {
|
||||
|
|
|
@ -1381,7 +1381,34 @@ void RTLIL::Module::check()
|
|||
for (auto &it : processes) {
|
||||
log_assert(it.first == it.second->name);
|
||||
log_assert(!it.first.empty());
|
||||
// FIXME: More checks here..
|
||||
log_assert(it.second->root_case.compare.empty());
|
||||
std::vector<CaseRule*> all_cases = {&it.second->root_case};
|
||||
for (size_t i = 0; i < all_cases.size(); i++) {
|
||||
for (auto &switch_it : all_cases[i]->switches) {
|
||||
for (auto &case_it : switch_it->cases) {
|
||||
for (auto &compare_it : case_it->compare) {
|
||||
log_assert(switch_it->signal.size() == compare_it.size());
|
||||
}
|
||||
all_cases.push_back(case_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto &sync_it : it.second->syncs) {
|
||||
switch (sync_it->type) {
|
||||
case SyncType::ST0:
|
||||
case SyncType::ST1:
|
||||
case SyncType::STp:
|
||||
case SyncType::STn:
|
||||
case SyncType::STe:
|
||||
log_assert(!sync_it->signal.empty());
|
||||
break;
|
||||
case SyncType::STa:
|
||||
case SyncType::STg:
|
||||
case SyncType::STi:
|
||||
log_assert(sync_it->signal.empty());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &it : connections_) {
|
||||
|
|
|
@ -651,6 +651,10 @@ void rewrite_filename(std::string &filename)
|
|||
filename = filename.substr(1, GetSize(filename)-2);
|
||||
if (filename.substr(0, 2) == "+/")
|
||||
filename = proc_share_dirname() + filename.substr(2);
|
||||
#ifndef _WIN32
|
||||
if (filename.substr(0, 2) == "~/")
|
||||
filename = filename.replace(0, 1, getenv("HOME"));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef YOSYS_ENABLE_TCL
|
||||
|
|
|
@ -350,6 +350,18 @@ and this bit is a one (the second ``1'').} for {\tt \textbackslash{}reset == 1}
|
|||
sets {\tt \$0\textbackslash{}q[0:0]} to the value of {\tt \textbackslash{}d} if {\tt
|
||||
\textbackslash{}enable} is active (lines $6 \dots 11$).
|
||||
|
||||
A case can specify zero or more compare values that will determine whether it matches. Each of the compare values
|
||||
must be the exact same width as the control signal. When more than one compare value is specified, the case matches
|
||||
if any of them matches the control signal; when zero compare values are specified, the case always matches (i.e.
|
||||
it is the default case).
|
||||
|
||||
A switch prioritizes cases from first to last: multiple cases can match, but only the first matched case becomes
|
||||
active. This normally synthesizes to a priority encoder. The {\tt parallel\_case} attribute allows passes to assume
|
||||
that no more than one case will match, and {\tt full\_case} attribute allows passes to assume that exactly one
|
||||
case will match; if these invariants are ever dynamically violated, the behavior is undefined. These attributes
|
||||
are useful when an invariant invisible to the synthesizer causes the control signal to never take certain
|
||||
bit patterns.
|
||||
|
||||
The lines $13 \dots 16$ then cause {\tt \textbackslash{}q} to be updated whenever there is
|
||||
a positive clock edge on {\tt \textbackslash{}clock} or {\tt \textbackslash{}reset}.
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ USING_YOSYS_NAMESPACE
|
|||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct BlackboxPass : public Pass {
|
||||
BlackboxPass() : Pass("blackbox", "change type of cells in the design") { }
|
||||
BlackboxPass() : Pass("blackbox", "convert modules into blackbox modules") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
|
|
|
@ -285,8 +285,8 @@ struct StatPass : public Pass {
|
|||
log(" use cell area information from the provided liberty file\n");
|
||||
log("\n");
|
||||
log(" -tech <technology>\n");
|
||||
log(" print area estemate for the specified technology. Corrently supported\n");
|
||||
log(" calues for <technology>: xilinx\n");
|
||||
log(" print area estemate for the specified technology. Currently supported\n");
|
||||
log(" values for <technology>: xilinx\n");
|
||||
log("\n");
|
||||
log(" -width\n");
|
||||
log(" annotate internal cell types with their word width.\n");
|
||||
|
|
|
@ -62,7 +62,7 @@ struct WriteFileFrontend : public Frontend {
|
|||
if (argidx < args.size() && args[argidx].rfind("-", 0) != 0)
|
||||
output_filename = args[argidx++];
|
||||
else
|
||||
log_cmd_error("Missing putput filename.\n");
|
||||
log_cmd_error("Missing output filename.\n");
|
||||
|
||||
extra_args(f, filename, args, argidx);
|
||||
|
||||
|
|
|
@ -591,6 +591,9 @@ struct HierarchyPass : public Pass {
|
|||
log(" module instances when the width does not match the module port. This\n");
|
||||
log(" option disables this behavior.\n");
|
||||
log("\n");
|
||||
log(" -nodefaults\n");
|
||||
log(" do not resolve input port default values\n");
|
||||
log("\n");
|
||||
log(" -nokeep_asserts\n");
|
||||
log(" per default this pass sets the \"keep\" attribute on all modules\n");
|
||||
log(" that directly or indirectly contain one or more formal properties.\n");
|
||||
|
@ -645,6 +648,7 @@ struct HierarchyPass : public Pass {
|
|||
bool generate_mode = false;
|
||||
bool keep_positionals = false;
|
||||
bool keep_portwidths = false;
|
||||
bool nodefaults = false;
|
||||
bool nokeep_asserts = false;
|
||||
std::vector<std::string> generate_cells;
|
||||
std::vector<generate_port_decl_t> generate_ports;
|
||||
|
@ -712,6 +716,10 @@ struct HierarchyPass : public Pass {
|
|||
keep_portwidths = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodefaults") {
|
||||
nodefaults = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nokeep_asserts") {
|
||||
nokeep_asserts = true;
|
||||
continue;
|
||||
|
@ -940,6 +948,36 @@ struct HierarchyPass : public Pass {
|
|||
}
|
||||
}
|
||||
|
||||
if (!nodefaults)
|
||||
{
|
||||
dict<IdString, dict<IdString, Const>> defaults_db;
|
||||
|
||||
for (auto module : design->modules())
|
||||
for (auto wire : module->wires())
|
||||
if (wire->port_input && wire->attributes.count("\\defaultvalue"))
|
||||
defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");
|
||||
|
||||
for (auto module : design->modules())
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (defaults_db.count(cell->type) == 0)
|
||||
continue;
|
||||
|
||||
if (keep_positionals) {
|
||||
bool found_positionals = false;
|
||||
for (auto &conn : cell->connections())
|
||||
if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9')
|
||||
found_positionals = true;
|
||||
if (found_positionals)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &it : defaults_db.at(cell->type))
|
||||
if (!cell->hasPort(it.first))
|
||||
cell->setPort(it.first, it.second);
|
||||
}
|
||||
}
|
||||
|
||||
std::set<Module*> blackbox_derivatives;
|
||||
std::vector<Module*> design_modules = design->modules();
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ struct AssertpmuxWorker
|
|||
};
|
||||
|
||||
struct AssertpmuxPass : public Pass {
|
||||
AssertpmuxPass() : Pass("assertpmux", "convert internal signals to module ports") { }
|
||||
AssertpmuxPass() : Pass("assertpmux", "adds asserts for parallel muxes") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
|
@ -195,8 +195,8 @@ struct AssertpmuxPass : public Pass {
|
|||
log("\n");
|
||||
log(" -always\n");
|
||||
log(" usually the $pmux condition is only checked when the $pmux output\n");
|
||||
log(" is used be the mux tree it drives. this option will deactivate this\n");
|
||||
log(" additional constrained and check the $pmux condition always.\n");
|
||||
log(" is used by the mux tree it drives. this option will deactivate this\n");
|
||||
log(" additional constraint and check the $pmux condition always.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
|
|
|
@ -24,7 +24,7 @@ USING_YOSYS_NAMESPACE
|
|||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct CutpointPass : public Pass {
|
||||
CutpointPass() : Pass("cutpoint", "add hi/lo cover cells for each wire bit") { }
|
||||
CutpointPass() : Pass("cutpoint", "adds formal cut points to the design") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
|
|
|
@ -610,7 +610,7 @@ struct MuxcoverPass : public Pass {
|
|||
use_mux4 = true;
|
||||
if (arg.size() > 5) {
|
||||
if (arg[5] != '=') break;
|
||||
cost_mux4 = atoi(arg.substr(5).c_str());
|
||||
cost_mux4 = atoi(arg.substr(6).c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ struct MuxcoverPass : public Pass {
|
|||
use_mux8 = true;
|
||||
if (arg.size() > 5) {
|
||||
if (arg[5] != '=') break;
|
||||
cost_mux8 = atoi(arg.substr(5).c_str());
|
||||
cost_mux8 = atoi(arg.substr(6).c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ struct MuxcoverPass : public Pass {
|
|||
use_mux16 = true;
|
||||
if (arg.size() > 6) {
|
||||
if (arg[6] != '=') break;
|
||||
cost_mux16 = atoi(arg.substr(6).c_str());
|
||||
cost_mux16 = atoi(arg.substr(7).c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -605,9 +605,11 @@ struct ShregmapPass : public Pass {
|
|||
log("\n");
|
||||
log(" -tech greenpak4\n");
|
||||
log(" map to greenpak4 shift registers.\n");
|
||||
log(" this option also implies -clkpol pos -zinit\n");
|
||||
log("\n");
|
||||
log(" -tech xilinx\n");
|
||||
log(" map to xilinx dynamic-length shift registers.\n");
|
||||
log(" this option also implies -params -init\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
|
|
|
@ -74,7 +74,7 @@ static void run_ice40_unlut(Module *module)
|
|||
}
|
||||
|
||||
struct Ice40UnlutPass : public Pass {
|
||||
Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: perform simple optimizations") { }
|
||||
Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: transform SB_LUT4 cells to $lut cells") { }
|
||||
void help() YS_OVERRIDE
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
*.log
|
||||
*.out
|
||||
/*_ref.v
|
||||
|
|
|
@ -10,8 +10,9 @@ for aag in *.aag; do
|
|||
# Since ABC cannot read *.aag, read the *.aig instead
|
||||
# (which would have been created by the reference aig2aig utility,
|
||||
# available from http://fmv.jku.at/aiger/)
|
||||
../../yosys-abc -c "read -c ${aag%.*}.aig; write ${aag%.*}_ref.v"
|
||||
../../yosys -p "
|
||||
echo "Checking $aag."
|
||||
../../yosys-abc -q "read -c ${aag%.*}.aig; write ${aag%.*}_ref.v"
|
||||
../../yosys -qp "
|
||||
read_verilog ${aag%.*}_ref.v
|
||||
prep
|
||||
design -stash gold
|
||||
|
@ -26,8 +27,9 @@ sat -verify -prove-asserts -show-ports -seq 16 miter
|
|||
done
|
||||
|
||||
for aig in *.aig; do
|
||||
../../yosys-abc -c "read -c $aig; write ${aig%.*}_ref.v"
|
||||
../../yosys -p "
|
||||
echo "Checking $aig."
|
||||
../../yosys-abc -q "read -c $aig; write ${aig%.*}_ref.v"
|
||||
../../yosys -qp "
|
||||
read_verilog ${aig%.*}_ref.v
|
||||
prep
|
||||
design -stash gold
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
module uut_arrays02(clock, we, addr, wr_data, rd_data);
|
||||
|
||||
input clock, we;
|
||||
input [3:0] addr, wr_data;
|
||||
output [3:0] rd_data;
|
||||
reg [3:0] rd_data;
|
||||
|
||||
reg [3:0] memory [16];
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (we)
|
||||
memory[addr] <= wr_data;
|
||||
rd_data <= memory[addr];
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,22 @@
|
|||
module top(input clock, input [3:0] delta, output [3:0] cnt1, cnt2);
|
||||
cnt #(1) foo (.clock, .cnt(cnt1), .delta);
|
||||
cnt #(2) bar (.clock, .cnt(cnt2));
|
||||
endmodule
|
||||
|
||||
module cnt #(
|
||||
parameter integer initval = 0
|
||||
) (
|
||||
input clock,
|
||||
output logic [3:0] cnt = initval,
|
||||
`ifdef __ICARUS__
|
||||
input [3:0] delta
|
||||
`else
|
||||
input [3:0] delta = 10
|
||||
`endif
|
||||
);
|
||||
`ifdef __ICARUS__
|
||||
assign (weak0, weak1) delta = 10;
|
||||
`endif
|
||||
always @(posedge clock)
|
||||
cnt <= cnt + delta;
|
||||
endmodule
|
|
@ -89,8 +89,7 @@ done
|
|||
|
||||
compile_and_run() {
|
||||
exe="$1"; output="$2"; shift 2
|
||||
ext=${1##*.}
|
||||
if [ "$ext" == "sv" ]; then
|
||||
if [ "${2##*.}" == "sv" ]; then
|
||||
language_gen="-g2012"
|
||||
else
|
||||
language_gen="-g2005"
|
||||
|
@ -142,23 +141,25 @@ do
|
|||
cd ${bn}.out
|
||||
fn=$(basename $fn)
|
||||
bn=$(basename $bn)
|
||||
refext=v
|
||||
|
||||
rm -f ${bn}_ref.fir
|
||||
if [[ "$ext" == "v" ]]; then
|
||||
egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext}
|
||||
elif [[ "$ext" == "aig" ]] || [[ "$ext" == "aag" ]]; then
|
||||
"$toolsdir"/../../yosys-abc -c "read_aiger ../${fn}; write ${bn}_ref.v"
|
||||
"$toolsdir"/../../yosys-abc -c "read_aiger ../${fn}; write ${bn}_ref.${refext}"
|
||||
else
|
||||
cp ../${fn} ${bn}_ref.${ext}
|
||||
refext=$ext
|
||||
cp ../${fn} ${bn}_ref.${refext}
|
||||
fi
|
||||
|
||||
if [ ! -f ../${bn}_tb.v ]; then
|
||||
"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "test_autotb $autotb_opts" -o ${bn}_tb.v ${bn}_ref.v
|
||||
"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "test_autotb $autotb_opts" -o ${bn}_tb.v ${bn}_ref.${refext}
|
||||
else
|
||||
cp ../${bn}_tb.v ${bn}_tb.v
|
||||
fi
|
||||
if $genvcd; then sed -i 's,// \$dump,$dump,g' ${bn}_tb.v; fi
|
||||
compile_and_run ${bn}_tb_ref ${bn}_out_ref ${bn}_tb.v ${bn}_ref.v $libs \
|
||||
compile_and_run ${bn}_tb_ref ${bn}_out_ref ${bn}_tb.v ${bn}_ref.${refext} $libs \
|
||||
"$toolsdir"/../../techlibs/common/simlib.v \
|
||||
"$toolsdir"/../../techlibs/common/simcells.v
|
||||
if $genvcd; then mv testbench.vcd ${bn}_ref.vcd; fi
|
||||
|
@ -175,25 +176,25 @@ do
|
|||
test_count=$(( test_count + 1 ))
|
||||
}
|
||||
|
||||
if [ "$frontend" = "verific" -o "$frontend" = "verific_gates" ] && grep -q VERIFIC-SKIP ${bn}_ref.v; then
|
||||
if [ "$frontend" = "verific" -o "$frontend" = "verific_gates" ] && grep -q VERIFIC-SKIP ${bn}_ref.${refext}; then
|
||||
touch ../${bn}.skip
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$scriptfiles" ]; then
|
||||
test_passes -f "$frontend $include_opts" ${bn}_ref.v $scriptfiles
|
||||
test_passes -f "$frontend $include_opts" ${bn}_ref.${refext} $scriptfiles
|
||||
elif [ -n "$scriptopt" ]; then
|
||||
test_passes -f "$frontend $include_opts" -p "$scriptopt" ${bn}_ref.v
|
||||
test_passes -f "$frontend $include_opts" -p "$scriptopt" ${bn}_ref.${refext}
|
||||
elif [ "$frontend" = "verific" ]; then
|
||||
test_passes -p "verific -vlog2k ${bn}_ref.v; verific -import -all; opt; memory;;"
|
||||
test_passes -p "verific -vlog2k ${bn}_ref.${refext}; verific -import -all; opt; memory;;"
|
||||
elif [ "$frontend" = "verific_gates" ]; then
|
||||
test_passes -p "verific -vlog2k ${bn}_ref.v; verific -import -gates -all; opt; memory;;"
|
||||
test_passes -p "verific -vlog2k ${bn}_ref.${refext}; verific -import -gates -all; opt; memory;;"
|
||||
else
|
||||
test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.v
|
||||
test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.v
|
||||
test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.${refext}
|
||||
test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.${refext}
|
||||
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
|
||||
"$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.${refext}
|
||||
$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
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
*.log
|
||||
/*.log
|
||||
/*.out
|
||||
|
|
Loading…
Reference in New Issue