mirror of https://github.com/YosysHQ/yosys.git
Merge branch 'master' into xaig
This commit is contained in:
commit
f9af902532
|
@ -23,7 +23,11 @@
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/cellaigs.h"
|
#include "kernel/cellaigs.h"
|
||||||
#include "kernel/log.h"
|
#include "kernel/log.h"
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <regex>
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -37,6 +41,7 @@ static const FDirection FD_NODIRECTION = 0x0;
|
||||||
static const FDirection FD_IN = 0x1;
|
static const FDirection FD_IN = 0x1;
|
||||||
static const FDirection FD_OUT = 0x2;
|
static const FDirection FD_OUT = 0x2;
|
||||||
static const FDirection FD_INOUT = 0x3;
|
static const FDirection FD_INOUT = 0x3;
|
||||||
|
static const int FIRRTL_MAX_DSH_WIDTH_ERROR = 20; // For historic reasons, this is actually one greater than the maximum allowed shift width
|
||||||
|
|
||||||
// Get a port direction with respect to a specific module.
|
// Get a port direction with respect to a specific module.
|
||||||
FDirection getPortFDirection(IdString id, Module *module)
|
FDirection getPortFDirection(IdString id, Module *module)
|
||||||
|
@ -173,6 +178,26 @@ struct FirrtlWorker
|
||||||
void process_instance(RTLIL::Cell *cell, vector<string> &wire_exprs)
|
void process_instance(RTLIL::Cell *cell, vector<string> &wire_exprs)
|
||||||
{
|
{
|
||||||
std::string cell_type = fid(cell->type);
|
std::string cell_type = fid(cell->type);
|
||||||
|
std::string instanceOf;
|
||||||
|
// If this is a parameterized module, its parent module is encoded in the cell type
|
||||||
|
if (cell->type.substr(0, 8) == "$paramod")
|
||||||
|
{
|
||||||
|
std::string::iterator it;
|
||||||
|
for (it = cell_type.begin(); it < cell_type.end(); it++)
|
||||||
|
{
|
||||||
|
switch (*it) {
|
||||||
|
case '\\': /* FALL_THROUGH */
|
||||||
|
case '=': /* FALL_THROUGH */
|
||||||
|
case '\'': /* FALL_THROUGH */
|
||||||
|
case '$': instanceOf.append("_"); break;
|
||||||
|
default: instanceOf.append(1, *it); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instanceOf = cell_type;
|
||||||
|
}
|
||||||
|
|
||||||
std::string cell_name = cellname(cell);
|
std::string cell_name = cellname(cell);
|
||||||
std::string cell_name_comment;
|
std::string cell_name_comment;
|
||||||
|
@ -182,7 +207,13 @@ struct FirrtlWorker
|
||||||
cell_name_comment = "";
|
cell_name_comment = "";
|
||||||
// Find the module corresponding to this instance.
|
// Find the module corresponding to this instance.
|
||||||
auto instModule = design->module(cell->type);
|
auto instModule = design->module(cell->type);
|
||||||
wire_exprs.push_back(stringf("%s" "inst %s%s of %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), cell_type.c_str()));
|
// If there is no instance for this, just return.
|
||||||
|
if (instModule == NULL)
|
||||||
|
{
|
||||||
|
log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wire_exprs.push_back(stringf("%s" "inst %s%s of %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceOf.c_str()));
|
||||||
|
|
||||||
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
|
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
|
||||||
if (it->second.size() > 0) {
|
if (it->second.size() > 0) {
|
||||||
|
@ -194,20 +225,20 @@ struct FirrtlWorker
|
||||||
std::string source, sink;
|
std::string source, sink;
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case FD_INOUT:
|
case FD_INOUT:
|
||||||
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", log_id(cell_type), log_signal(it->second));
|
log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
|
||||||
case FD_OUT:
|
case FD_OUT:
|
||||||
source = firstName;
|
source = firstName;
|
||||||
sink = secondName;
|
sink = secondName;
|
||||||
break;
|
break;
|
||||||
case FD_NODIRECTION:
|
case FD_NODIRECTION:
|
||||||
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", log_id(cell_type), log_signal(it->second));
|
log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
|
||||||
/* FALL_THROUGH */
|
/* FALL_THROUGH */
|
||||||
case FD_IN:
|
case FD_IN:
|
||||||
source = secondName;
|
source = secondName;
|
||||||
sink = firstName;
|
sink = firstName;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", log_id(cell_type), log_signal(it->second), dir);
|
log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sink.c_str(), source.c_str()));
|
wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sink.c_str(), source.c_str()));
|
||||||
|
@ -217,6 +248,20 @@ struct FirrtlWorker
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given an expression for a shift amount, and a maximum width,
|
||||||
|
// generate the FIRRTL expression for equivalent dynamic shift taking into account FIRRTL shift semantics.
|
||||||
|
std::string gen_dshl(const string b_expr, const int b_padded_width)
|
||||||
|
{
|
||||||
|
string result = b_expr;
|
||||||
|
if (b_padded_width >= FIRRTL_MAX_DSH_WIDTH_ERROR) {
|
||||||
|
int max_shift_width_bits = FIRRTL_MAX_DSH_WIDTH_ERROR - 1;
|
||||||
|
string max_shift_string = stringf("UInt<%d>(%d)", max_shift_width_bits, (1<<max_shift_width_bits) - 1);
|
||||||
|
// Deal with the difference in semantics between FIRRTL and verilog
|
||||||
|
result = stringf("mux(gt(%s, %s), %s, bits(%s, %d, 0))", b_expr.c_str(), max_shift_string.c_str(), max_shift_string.c_str(), b_expr.c_str(), max_shift_width_bits - 1);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
f << stringf(" module %s:\n", make_id(module->name));
|
f << stringf(" module %s:\n", make_id(module->name));
|
||||||
|
@ -225,6 +270,12 @@ struct FirrtlWorker
|
||||||
for (auto wire : module->wires())
|
for (auto wire : module->wires())
|
||||||
{
|
{
|
||||||
const auto wireName = make_id(wire->name);
|
const auto wireName = make_id(wire->name);
|
||||||
|
// If a wire has initial data, issue a warning since FIRRTL doesn't currently support it.
|
||||||
|
if (wire->attributes.count("\\init")) {
|
||||||
|
log_warning("Initial value (%s) for (%s.%s) not supported\n",
|
||||||
|
wire->attributes.at("\\init").as_string().c_str(),
|
||||||
|
log_id(module), log_id(wire));
|
||||||
|
}
|
||||||
if (wire->port_id)
|
if (wire->port_id)
|
||||||
{
|
{
|
||||||
if (wire->port_input && wire->port_output)
|
if (wire->port_input && wire->port_output)
|
||||||
|
@ -240,6 +291,7 @@ struct FirrtlWorker
|
||||||
|
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
{
|
{
|
||||||
|
bool extract_y_bits = false; // Assume no extraction of final bits will be required.
|
||||||
// Is this cell is a module instance?
|
// Is this cell is a module instance?
|
||||||
if (cell->type[0] != '$')
|
if (cell->type[0] != '$')
|
||||||
{
|
{
|
||||||
|
@ -266,19 +318,19 @@ struct FirrtlWorker
|
||||||
string primop;
|
string primop;
|
||||||
bool always_uint = false;
|
bool always_uint = false;
|
||||||
if (cell->type == "$not") primop = "not";
|
if (cell->type == "$not") primop = "not";
|
||||||
if (cell->type == "$neg") primop = "neg";
|
else if (cell->type == "$neg") primop = "neg";
|
||||||
if (cell->type == "$logic_not") {
|
else if (cell->type == "$logic_not") {
|
||||||
primop = "eq";
|
primop = "eq";
|
||||||
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
|
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
|
||||||
}
|
}
|
||||||
if (cell->type == "$reduce_and") primop = "andr";
|
else if (cell->type == "$reduce_and") primop = "andr";
|
||||||
if (cell->type == "$reduce_or") primop = "orr";
|
else if (cell->type == "$reduce_or") primop = "orr";
|
||||||
if (cell->type == "$reduce_xor") primop = "xorr";
|
else if (cell->type == "$reduce_xor") primop = "xorr";
|
||||||
if (cell->type == "$reduce_xnor") {
|
else if (cell->type == "$reduce_xnor") {
|
||||||
primop = "not";
|
primop = "not";
|
||||||
a_expr = stringf("xorr(%s)", a_expr.c_str());
|
a_expr = stringf("xorr(%s)", a_expr.c_str());
|
||||||
}
|
}
|
||||||
if (cell->type == "$reduce_bool") {
|
else if (cell->type == "$reduce_bool") {
|
||||||
primop = "neq";
|
primop = "neq";
|
||||||
// Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand.
|
// Use the sign of the a_expr and its width as the type (UInt/SInt) and width of the comparand.
|
||||||
bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool();
|
bool a_signed = cell->parameters.at("\\A_SIGNED").as_bool();
|
||||||
|
@ -305,6 +357,7 @@ struct FirrtlWorker
|
||||||
int y_width = cell->parameters.at("\\Y_WIDTH").as_int();
|
int y_width = cell->parameters.at("\\Y_WIDTH").as_int();
|
||||||
string a_expr = make_expr(cell->getPort("\\A"));
|
string a_expr = make_expr(cell->getPort("\\A"));
|
||||||
string b_expr = make_expr(cell->getPort("\\B"));
|
string b_expr = make_expr(cell->getPort("\\B"));
|
||||||
|
int b_padded_width = cell->parameters.at("\\B_WIDTH").as_int();
|
||||||
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
|
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
|
||||||
|
|
||||||
if (cell->parameters.at("\\A_SIGNED").as_bool()) {
|
if (cell->parameters.at("\\A_SIGNED").as_bool()) {
|
||||||
|
@ -315,10 +368,13 @@ struct FirrtlWorker
|
||||||
if (cell->parameters.at("\\B_SIGNED").as_bool()) {
|
if (cell->parameters.at("\\B_SIGNED").as_bool()) {
|
||||||
b_expr = "asSInt(" + b_expr + ")";
|
b_expr = "asSInt(" + b_expr + ")";
|
||||||
}
|
}
|
||||||
b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
|
if (b_padded_width < y_width) {
|
||||||
|
auto b_sig = cell->getPort("\\B");
|
||||||
|
b_padded_width = y_width;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
|
auto a_sig = cell->getPort("\\A");
|
||||||
|
|
||||||
if (cell->parameters.at("\\A_SIGNED").as_bool() & (cell->type == "$shr")) {
|
if (cell->parameters.at("\\A_SIGNED").as_bool() & (cell->type == "$shr")) {
|
||||||
a_expr = "asUInt(" + a_expr + ")";
|
a_expr = "asUInt(" + a_expr + ")";
|
||||||
|
@ -327,55 +383,78 @@ struct FirrtlWorker
|
||||||
string primop;
|
string primop;
|
||||||
bool always_uint = false;
|
bool always_uint = false;
|
||||||
if (cell->type == "$add") primop = "add";
|
if (cell->type == "$add") primop = "add";
|
||||||
if (cell->type == "$sub") primop = "sub";
|
else if (cell->type == "$sub") primop = "sub";
|
||||||
if (cell->type == "$mul") primop = "mul";
|
else if (cell->type == "$mul") primop = "mul";
|
||||||
if (cell->type == "$div") primop = "div";
|
else if (cell->type == "$div") primop = "div";
|
||||||
if (cell->type == "$mod") primop = "rem";
|
else if (cell->type == "$mod") primop = "rem";
|
||||||
if (cell->type == "$and") {
|
else if (cell->type == "$and") {
|
||||||
primop = "and";
|
primop = "and";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if (cell->type == "$or" ) {
|
else if (cell->type == "$or" ) {
|
||||||
primop = "or";
|
primop = "or";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if (cell->type == "$xor") {
|
else if (cell->type == "$xor") {
|
||||||
primop = "xor";
|
primop = "xor";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if ((cell->type == "$eq") | (cell->type == "$eqx")) {
|
else if ((cell->type == "$eq") | (cell->type == "$eqx")) {
|
||||||
primop = "eq";
|
primop = "eq";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if ((cell->type == "$ne") | (cell->type == "$nex")) {
|
else if ((cell->type == "$ne") | (cell->type == "$nex")) {
|
||||||
primop = "neq";
|
primop = "neq";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if (cell->type == "$gt") {
|
else if (cell->type == "$gt") {
|
||||||
primop = "gt";
|
primop = "gt";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if (cell->type == "$ge") {
|
else if (cell->type == "$ge") {
|
||||||
primop = "geq";
|
primop = "geq";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if (cell->type == "$lt") {
|
else if (cell->type == "$lt") {
|
||||||
primop = "lt";
|
primop = "lt";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if (cell->type == "$le") {
|
else if (cell->type == "$le") {
|
||||||
primop = "leq";
|
primop = "leq";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if ((cell->type == "$shl") | (cell->type == "$sshl")) primop = "dshl";
|
else if ((cell->type == "$shl") | (cell->type == "$sshl")) {
|
||||||
if ((cell->type == "$shr") | (cell->type == "$sshr")) primop = "dshr";
|
// FIRRTL will widen the result (y) by the amount of the shift.
|
||||||
if ((cell->type == "$logic_and")) {
|
// We'll need to offset this by extracting the un-widened portion as Verilog would do.
|
||||||
|
extract_y_bits = true;
|
||||||
|
// Is the shift amount constant?
|
||||||
|
auto b_sig = cell->getPort("\\B");
|
||||||
|
if (b_sig.is_fully_const()) {
|
||||||
|
primop = "shl";
|
||||||
|
} else {
|
||||||
|
primop = "dshl";
|
||||||
|
// Convert from FIRRTL left shift semantics.
|
||||||
|
b_expr = gen_dshl(b_expr, b_padded_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((cell->type == "$shr") | (cell->type == "$sshr")) {
|
||||||
|
// We don't need to extract a specific range of bits.
|
||||||
|
extract_y_bits = false;
|
||||||
|
// Is the shift amount constant?
|
||||||
|
auto b_sig = cell->getPort("\\B");
|
||||||
|
if (b_sig.is_fully_const()) {
|
||||||
|
primop = "shr";
|
||||||
|
} else {
|
||||||
|
primop = "dshr";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((cell->type == "$logic_and")) {
|
||||||
primop = "and";
|
primop = "and";
|
||||||
a_expr = "neq(" + a_expr + ", UInt(0))";
|
a_expr = "neq(" + a_expr + ", UInt(0))";
|
||||||
b_expr = "neq(" + b_expr + ", UInt(0))";
|
b_expr = "neq(" + b_expr + ", UInt(0))";
|
||||||
always_uint = true;
|
always_uint = true;
|
||||||
}
|
}
|
||||||
if ((cell->type == "$logic_or")) {
|
else if ((cell->type == "$logic_or")) {
|
||||||
primop = "or";
|
primop = "or";
|
||||||
a_expr = "neq(" + a_expr + ", UInt(0))";
|
a_expr = "neq(" + a_expr + ", UInt(0))";
|
||||||
b_expr = "neq(" + b_expr + ", UInt(0))";
|
b_expr = "neq(" + b_expr + ", UInt(0))";
|
||||||
|
@ -388,6 +467,11 @@ struct FirrtlWorker
|
||||||
|
|
||||||
string expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str());
|
string expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str());
|
||||||
|
|
||||||
|
// Deal with FIRRTL's "shift widens" semantics
|
||||||
|
if (extract_y_bits) {
|
||||||
|
expr = stringf("bits(%s, %d, 0)", expr.c_str(), y_width - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((is_signed && !always_uint) || cell->type.in("$sub"))
|
if ((is_signed && !always_uint) || cell->type.in("$sub"))
|
||||||
expr = stringf("asUInt(%s)", expr.c_str());
|
expr = stringf("asUInt(%s)", expr.c_str());
|
||||||
|
|
||||||
|
@ -513,7 +597,65 @@ struct FirrtlWorker
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_error("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell));
|
// This may be a parameterized module - paramod.
|
||||||
|
if (cell->type.substr(0, 8) == "$paramod")
|
||||||
|
{
|
||||||
|
process_instance(cell, wire_exprs);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cell->type == "$shiftx") {
|
||||||
|
// assign y = a[b +: y_width];
|
||||||
|
// We'll extract the correct bits as part of the primop.
|
||||||
|
|
||||||
|
string y_id = make_id(cell->name);
|
||||||
|
int y_width = cell->parameters.at("\\Y_WIDTH").as_int();
|
||||||
|
string a_expr = make_expr(cell->getPort("\\A"));
|
||||||
|
// Get the initial bit selector
|
||||||
|
string b_expr = make_expr(cell->getPort("\\B"));
|
||||||
|
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
|
||||||
|
|
||||||
|
if (cell->getParam("\\B_SIGNED").as_bool()) {
|
||||||
|
// Use validif to constrain the selection (test the sign bit)
|
||||||
|
auto b_string = b_expr.c_str();
|
||||||
|
int b_sign = cell->parameters.at("\\B_WIDTH").as_int() - 1;
|
||||||
|
b_expr = stringf("validif(not(bits(%s, %d, %d)), %s)", b_string, b_sign, b_sign, b_string);
|
||||||
|
}
|
||||||
|
string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str());
|
||||||
|
|
||||||
|
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
|
||||||
|
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cell->type == "$shift") {
|
||||||
|
// assign y = a >> b;
|
||||||
|
// where b may be negative
|
||||||
|
|
||||||
|
string y_id = make_id(cell->name);
|
||||||
|
int y_width = cell->parameters.at("\\Y_WIDTH").as_int();
|
||||||
|
string a_expr = make_expr(cell->getPort("\\A"));
|
||||||
|
string b_expr = make_expr(cell->getPort("\\B"));
|
||||||
|
auto b_string = b_expr.c_str();
|
||||||
|
int b_padded_width = cell->parameters.at("\\B_WIDTH").as_int();
|
||||||
|
string expr;
|
||||||
|
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
|
||||||
|
|
||||||
|
if (cell->getParam("\\B_SIGNED").as_bool()) {
|
||||||
|
// We generate a left or right shift based on the sign of b.
|
||||||
|
std::string dshl = stringf("bits(dshl(%s, %s), 0, %d)", a_expr.c_str(), gen_dshl(b_expr, b_padded_width).c_str(), y_width);
|
||||||
|
std::string dshr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
|
||||||
|
expr = stringf("mux(%s < 0, %s, %s)",
|
||||||
|
b_string,
|
||||||
|
dshl.c_str(),
|
||||||
|
dshr.c_str()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
|
||||||
|
}
|
||||||
|
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
|
||||||
|
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
log_warning("Cell type not supported: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto conn : module->connections())
|
for (auto conn : module->connections())
|
||||||
|
@ -629,38 +771,53 @@ struct FirrtlBackend : public Backend {
|
||||||
log(" write_firrtl [options] [filename]\n");
|
log(" write_firrtl [options] [filename]\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("Write a FIRRTL netlist of the current design.\n");
|
log("Write a FIRRTL netlist of the current design.\n");
|
||||||
|
log("The following commands are executed by this command:\n");
|
||||||
|
log(" pmuxtree\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||||
{
|
{
|
||||||
size_t argidx;
|
size_t argidx = args.size(); // We aren't expecting any arguments.
|
||||||
for (argidx = 1; argidx < args.size(); argidx++)
|
|
||||||
{
|
// If we weren't explicitly passed a filename, use the last argument (if it isn't a flag).
|
||||||
// if (args[argidx] == "-aig") {
|
if (filename == "") {
|
||||||
// aig_mode = true;
|
if (argidx > 0 && args[argidx - 1][0] != '-') {
|
||||||
// continue;
|
// extra_args and friends need to see this argument.
|
||||||
// }
|
argidx -= 1;
|
||||||
break;
|
filename = args[argidx];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
extra_args(f, filename, args, argidx);
|
extra_args(f, filename, args, argidx);
|
||||||
|
|
||||||
|
if (!design->full_selection())
|
||||||
|
log_cmd_error("This command only operates on fully selected designs!\n");
|
||||||
|
|
||||||
log_header(design, "Executing FIRRTL backend.\n");
|
log_header(design, "Executing FIRRTL backend.\n");
|
||||||
|
log_push();
|
||||||
|
|
||||||
Module *top = design->top_module();
|
Pass::call(design, stringf("pmuxtree"));
|
||||||
|
|
||||||
if (top == nullptr)
|
|
||||||
log_error("No top module found!\n");
|
|
||||||
|
|
||||||
namecache.clear();
|
namecache.clear();
|
||||||
autoid_counter = 0;
|
autoid_counter = 0;
|
||||||
|
|
||||||
|
// Get the top module, or a reasonable facsimile - we need something for the circuit name.
|
||||||
|
Module *top = design->top_module();
|
||||||
|
Module *last = nullptr;
|
||||||
|
// Generate module and wire names.
|
||||||
for (auto module : design->modules()) {
|
for (auto module : design->modules()) {
|
||||||
make_id(module->name);
|
make_id(module->name);
|
||||||
|
last = module;
|
||||||
|
if (top == nullptr && module->get_bool_attribute("\\top")) {
|
||||||
|
top = module;
|
||||||
|
}
|
||||||
for (auto wire : module->wires())
|
for (auto wire : module->wires())
|
||||||
if (wire->port_id)
|
if (wire->port_id)
|
||||||
make_id(wire->name);
|
make_id(wire->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (top == nullptr)
|
||||||
|
top = last;
|
||||||
|
|
||||||
*f << stringf("circuit %s:\n", make_id(top->name));
|
*f << stringf("circuit %s:\n", make_id(top->name));
|
||||||
|
|
||||||
for (auto module : design->modules())
|
for (auto module : design->modules())
|
||||||
|
|
|
@ -293,7 +293,7 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_reg_init(std::ostream &f, SigSpec sig, bool write_equals = true)
|
void dump_reg_init(std::ostream &f, SigSpec sig)
|
||||||
{
|
{
|
||||||
Const initval;
|
Const initval;
|
||||||
bool gotinit = false;
|
bool gotinit = false;
|
||||||
|
@ -308,7 +308,7 @@ void dump_reg_init(std::ostream &f, SigSpec sig, bool write_equals = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gotinit) {
|
if (gotinit) {
|
||||||
if (write_equals) f << " = ";
|
f << " = ";
|
||||||
dump_const(f, initval);
|
dump_const(f, initval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1250,14 +1250,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
||||||
dump_attributes(f, indent, cell->attributes);
|
dump_attributes(f, indent, cell->attributes);
|
||||||
f << stringf("%s" "%s", indent.c_str(), id(cell->type, false).c_str());
|
f << stringf("%s" "%s", indent.c_str(), id(cell->type, false).c_str());
|
||||||
|
|
||||||
std::string init;
|
if (!defparam && cell->parameters.size() > 0) {
|
||||||
if (reg_ct.count(cell->type) && cell->hasPort("\\Q")) {
|
|
||||||
std::stringstream ss;
|
|
||||||
dump_reg_init(ss, cell->getPort("\\Q"), false /* write_equals */);
|
|
||||||
init = ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!defparam && (cell->parameters.size() > 0 || !init.empty())) {
|
|
||||||
f << stringf(" #(");
|
f << stringf(" #(");
|
||||||
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
|
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
|
||||||
if (it != cell->parameters.begin())
|
if (it != cell->parameters.begin())
|
||||||
|
@ -1267,11 +1260,6 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
||||||
dump_const(f, it->second, -1, 0, false, is_signed);
|
dump_const(f, it->second, -1, 0, false, is_signed);
|
||||||
f << stringf(")");
|
f << stringf(")");
|
||||||
}
|
}
|
||||||
if (!init.empty()) {
|
|
||||||
if (!cell->parameters.empty())
|
|
||||||
f << stringf(",");
|
|
||||||
f << stringf("\n%s .INIT(%s)", indent.c_str(), init.c_str());
|
|
||||||
}
|
|
||||||
f << stringf("\n%s" ")", indent.c_str());
|
f << stringf("\n%s" ")", indent.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1313,17 +1301,24 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
|
||||||
}
|
}
|
||||||
f << stringf("\n%s" ");\n", indent.c_str());
|
f << stringf("\n%s" ");\n", indent.c_str());
|
||||||
|
|
||||||
if (defparam && (cell->parameters.size() > 0 || !init.empty())) {
|
if (defparam && cell->parameters.size() > 0) {
|
||||||
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
|
for (auto it = cell->parameters.begin(); it != cell->parameters.end(); ++it) {
|
||||||
f << stringf("%sdefparam %s.%s = ", indent.c_str(), cell_name.c_str(), id(it->first).c_str());
|
f << stringf("%sdefparam %s.%s = ", indent.c_str(), cell_name.c_str(), id(it->first).c_str());
|
||||||
bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
|
bool is_signed = (it->second.flags & RTLIL::CONST_FLAG_SIGNED) != 0;
|
||||||
dump_const(f, it->second, -1, 0, false, is_signed);
|
dump_const(f, it->second, -1, 0, false, is_signed);
|
||||||
f << stringf(";\n");
|
f << stringf(";\n");
|
||||||
}
|
}
|
||||||
if (!init.empty())
|
|
||||||
f << stringf("%sdefparam %s.INIT = %s;\n", indent.c_str(), cell_name.c_str(), init.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reg_ct.count(cell->type) && cell->hasPort("\\Q")) {
|
||||||
|
std::stringstream ss;
|
||||||
|
dump_reg_init(ss, cell->getPort("\\Q"));
|
||||||
|
if (!ss.str().empty()) {
|
||||||
|
f << stringf("%sinitial %s.Q", indent.c_str(), cell_name.c_str());
|
||||||
|
f << ss.str();
|
||||||
|
f << ";\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
|
void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
|
||||||
|
|
|
@ -451,9 +451,8 @@ endmodule
|
||||||
//- 1 1 | y
|
//- 1 1 | y
|
||||||
//-
|
//-
|
||||||
module \$_SR_NN_ (S, R, Q);
|
module \$_SR_NN_ (S, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input S, R;
|
input S, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge S, negedge R) begin
|
always @(negedge S, negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -476,9 +475,8 @@ endmodule
|
||||||
//- 1 0 | y
|
//- 1 0 | y
|
||||||
//-
|
//-
|
||||||
module \$_SR_NP_ (S, R, Q);
|
module \$_SR_NP_ (S, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input S, R;
|
input S, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge S, posedge R) begin
|
always @(negedge S, posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -501,9 +499,8 @@ endmodule
|
||||||
//- 0 1 | y
|
//- 0 1 | y
|
||||||
//-
|
//-
|
||||||
module \$_SR_PN_ (S, R, Q);
|
module \$_SR_PN_ (S, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input S, R;
|
input S, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge S, negedge R) begin
|
always @(posedge S, negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -526,9 +523,8 @@ endmodule
|
||||||
//- 0 0 | y
|
//- 0 0 | y
|
||||||
//-
|
//-
|
||||||
module \$_SR_PP_ (S, R, Q);
|
module \$_SR_PP_ (S, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input S, R;
|
input S, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge S, posedge R) begin
|
always @(posedge S, posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -546,9 +542,8 @@ endmodule
|
||||||
//- type is usually only used in netlists for formal verification.)
|
//- type is usually only used in netlists for formal verification.)
|
||||||
//-
|
//-
|
||||||
module \$_FF_ (D, Q);
|
module \$_FF_ (D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D;
|
input D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @($global_clock) begin
|
always @($global_clock) begin
|
||||||
Q <= D;
|
Q <= D;
|
||||||
end
|
end
|
||||||
|
@ -567,9 +562,8 @@ endmodule
|
||||||
//- - - | q
|
//- - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_N_ (D, C, Q);
|
module \$_DFF_N_ (D, C, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C;
|
input D, C;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C) begin
|
always @(negedge C) begin
|
||||||
Q <= D;
|
Q <= D;
|
||||||
end
|
end
|
||||||
|
@ -587,9 +581,8 @@ endmodule
|
||||||
//- - - | q
|
//- - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_P_ (D, C, Q);
|
module \$_DFF_P_ (D, C, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C;
|
input D, C;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C) begin
|
always @(posedge C) begin
|
||||||
Q <= D;
|
Q <= D;
|
||||||
end
|
end
|
||||||
|
@ -607,9 +600,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFE_NN_ (D, C, E, Q);
|
module \$_DFFE_NN_ (D, C, E, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, E;
|
input D, C, E;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C) begin
|
always @(negedge C) begin
|
||||||
if (!E) Q <= D;
|
if (!E) Q <= D;
|
||||||
end
|
end
|
||||||
|
@ -627,9 +619,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFE_NP_ (D, C, E, Q);
|
module \$_DFFE_NP_ (D, C, E, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, E;
|
input D, C, E;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C) begin
|
always @(negedge C) begin
|
||||||
if (E) Q <= D;
|
if (E) Q <= D;
|
||||||
end
|
end
|
||||||
|
@ -647,9 +638,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFE_PN_ (D, C, E, Q);
|
module \$_DFFE_PN_ (D, C, E, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, E;
|
input D, C, E;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C) begin
|
always @(posedge C) begin
|
||||||
if (!E) Q <= D;
|
if (!E) Q <= D;
|
||||||
end
|
end
|
||||||
|
@ -667,9 +657,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFE_PP_ (D, C, E, Q);
|
module \$_DFFE_PP_ (D, C, E, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, E;
|
input D, C, E;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C) begin
|
always @(posedge C) begin
|
||||||
if (E) Q <= D;
|
if (E) Q <= D;
|
||||||
end
|
end
|
||||||
|
@ -688,9 +677,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_NN0_ (D, C, R, Q);
|
module \$_DFF_NN0_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C or negedge R) begin
|
always @(negedge C or negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -712,9 +700,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_NN1_ (D, C, R, Q);
|
module \$_DFF_NN1_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C or negedge R) begin
|
always @(negedge C or negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 1;
|
Q <= 1;
|
||||||
|
@ -736,9 +723,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_NP0_ (D, C, R, Q);
|
module \$_DFF_NP0_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C or posedge R) begin
|
always @(negedge C or posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -760,9 +746,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_NP1_ (D, C, R, Q);
|
module \$_DFF_NP1_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C or posedge R) begin
|
always @(negedge C or posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 1;
|
Q <= 1;
|
||||||
|
@ -784,9 +769,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_PN0_ (D, C, R, Q);
|
module \$_DFF_PN0_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C or negedge R) begin
|
always @(posedge C or negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -808,9 +792,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_PN1_ (D, C, R, Q);
|
module \$_DFF_PN1_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C or negedge R) begin
|
always @(posedge C or negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 1;
|
Q <= 1;
|
||||||
|
@ -832,9 +815,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_PP0_ (D, C, R, Q);
|
module \$_DFF_PP0_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C or posedge R) begin
|
always @(posedge C or posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -856,9 +838,8 @@ endmodule
|
||||||
//- - - - | q
|
//- - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFF_PP1_ (D, C, R, Q);
|
module \$_DFF_PP1_ (D, C, R, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input D, C, R;
|
input D, C, R;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C or posedge R) begin
|
always @(posedge C or posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 1;
|
Q <= 1;
|
||||||
|
@ -881,9 +862,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_NNN_ (C, S, R, D, Q);
|
module \$_DFFSR_NNN_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C, negedge S, negedge R) begin
|
always @(negedge C, negedge S, negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -909,9 +889,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_NNP_ (C, S, R, D, Q);
|
module \$_DFFSR_NNP_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C, negedge S, posedge R) begin
|
always @(negedge C, negedge S, posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -937,9 +916,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_NPN_ (C, S, R, D, Q);
|
module \$_DFFSR_NPN_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C, posedge S, negedge R) begin
|
always @(negedge C, posedge S, negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -964,9 +942,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_NPP_ (C, S, R, D, Q);
|
module \$_DFFSR_NPP_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(negedge C, posedge S, posedge R) begin
|
always @(negedge C, posedge S, posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -991,9 +968,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_PNN_ (C, S, R, D, Q);
|
module \$_DFFSR_PNN_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C, negedge S, negedge R) begin
|
always @(posedge C, negedge S, negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1019,9 +995,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_PNP_ (C, S, R, D, Q);
|
module \$_DFFSR_PNP_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C, negedge S, posedge R) begin
|
always @(posedge C, negedge S, posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1047,9 +1022,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_PPN_ (C, S, R, D, Q);
|
module \$_DFFSR_PPN_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C, posedge S, negedge R) begin
|
always @(posedge C, posedge S, negedge R) begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1074,9 +1048,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DFFSR_PPP_ (C, S, R, D, Q);
|
module \$_DFFSR_PPP_ (C, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input C, S, R, D;
|
input C, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @(posedge C, posedge S, posedge R) begin
|
always @(posedge C, posedge S, posedge R) begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1099,9 +1072,8 @@ endmodule
|
||||||
//- - - | q
|
//- - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCH_N_ (E, D, Q);
|
module \$_DLATCH_N_ (E, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, D;
|
input E, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (E == 0)
|
if (E == 0)
|
||||||
Q <= D;
|
Q <= D;
|
||||||
|
@ -1120,9 +1092,8 @@ endmodule
|
||||||
//- - - | q
|
//- - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCH_P_ (E, D, Q);
|
module \$_DLATCH_P_ (E, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, D;
|
input E, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (E == 1)
|
if (E == 1)
|
||||||
Q <= D;
|
Q <= D;
|
||||||
|
@ -1143,9 +1114,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_NNN_ (E, S, R, D, Q);
|
module \$_DLATCHSR_NNN_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1171,9 +1141,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_NNP_ (E, S, R, D, Q);
|
module \$_DLATCHSR_NNP_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1199,9 +1168,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_NPN_ (E, S, R, D, Q);
|
module \$_DLATCHSR_NPN_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1226,9 +1194,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_NPP_ (E, S, R, D, Q);
|
module \$_DLATCHSR_NPP_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1253,9 +1220,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_PNN_ (E, S, R, D, Q);
|
module \$_DLATCHSR_PNN_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1281,9 +1247,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_PNP_ (E, S, R, D, Q);
|
module \$_DLATCHSR_PNP_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1309,9 +1274,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_PPN_ (E, S, R, D, Q);
|
module \$_DLATCHSR_PPN_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 0)
|
if (R == 0)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
@ -1336,9 +1300,8 @@ endmodule
|
||||||
//- - - - - | q
|
//- - - - - | q
|
||||||
//-
|
//-
|
||||||
module \$_DLATCHSR_PPP_ (E, S, R, D, Q);
|
module \$_DLATCHSR_PPP_ (E, S, R, D, Q);
|
||||||
parameter INIT = 1'bx;
|
|
||||||
input E, S, R, D;
|
input E, S, R, D;
|
||||||
output reg Q = INIT;
|
output reg Q;
|
||||||
always @* begin
|
always @* begin
|
||||||
if (R == 1)
|
if (R == 1)
|
||||||
Q <= 0;
|
Q <= 0;
|
||||||
|
|
|
@ -1464,11 +1464,10 @@ module \$dff (CLK, D, Q);
|
||||||
|
|
||||||
parameter WIDTH = 0;
|
parameter WIDTH = 0;
|
||||||
parameter CLK_POLARITY = 1'b1;
|
parameter CLK_POLARITY = 1'b1;
|
||||||
parameter INIT = {WIDTH > 0 ? WIDTH : 1{1'bx}};
|
|
||||||
|
|
||||||
input CLK;
|
input CLK;
|
||||||
input [WIDTH-1:0] D;
|
input [WIDTH-1:0] D;
|
||||||
output reg [WIDTH-1:0] Q = INIT;
|
output reg [WIDTH-1:0] Q;
|
||||||
wire pos_clk = CLK == CLK_POLARITY;
|
wire pos_clk = CLK == CLK_POLARITY;
|
||||||
|
|
||||||
always @(posedge pos_clk) begin
|
always @(posedge pos_clk) begin
|
||||||
|
@ -1484,11 +1483,10 @@ module \$dffe (CLK, EN, D, Q);
|
||||||
parameter WIDTH = 0;
|
parameter WIDTH = 0;
|
||||||
parameter CLK_POLARITY = 1'b1;
|
parameter CLK_POLARITY = 1'b1;
|
||||||
parameter EN_POLARITY = 1'b1;
|
parameter EN_POLARITY = 1'b1;
|
||||||
parameter INIT = {WIDTH > 0 ? WIDTH : 1{1'bx}};
|
|
||||||
|
|
||||||
input CLK, EN;
|
input CLK, EN;
|
||||||
input [WIDTH-1:0] D;
|
input [WIDTH-1:0] D;
|
||||||
output reg [WIDTH-1:0] Q = INIT;
|
output reg [WIDTH-1:0] Q;
|
||||||
wire pos_clk = CLK == CLK_POLARITY;
|
wire pos_clk = CLK == CLK_POLARITY;
|
||||||
|
|
||||||
always @(posedge pos_clk) begin
|
always @(posedge pos_clk) begin
|
||||||
|
@ -1506,11 +1504,10 @@ parameter WIDTH = 0;
|
||||||
parameter CLK_POLARITY = 1'b1;
|
parameter CLK_POLARITY = 1'b1;
|
||||||
parameter SET_POLARITY = 1'b1;
|
parameter SET_POLARITY = 1'b1;
|
||||||
parameter CLR_POLARITY = 1'b1;
|
parameter CLR_POLARITY = 1'b1;
|
||||||
parameter INIT = {WIDTH > 0 ? WIDTH : 1{1'bx}};
|
|
||||||
|
|
||||||
input CLK;
|
input CLK;
|
||||||
input [WIDTH-1:0] SET, CLR, D;
|
input [WIDTH-1:0] SET, CLR, D;
|
||||||
output reg [WIDTH-1:0] Q = INIT;
|
output reg [WIDTH-1:0] Q;
|
||||||
|
|
||||||
wire pos_clk = CLK == CLK_POLARITY;
|
wire pos_clk = CLK == CLK_POLARITY;
|
||||||
wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET;
|
wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET;
|
||||||
|
@ -1540,11 +1537,10 @@ parameter WIDTH = 0;
|
||||||
parameter CLK_POLARITY = 1'b1;
|
parameter CLK_POLARITY = 1'b1;
|
||||||
parameter ARST_POLARITY = 1'b1;
|
parameter ARST_POLARITY = 1'b1;
|
||||||
parameter ARST_VALUE = 0;
|
parameter ARST_VALUE = 0;
|
||||||
parameter INIT = {WIDTH > 0 ? WIDTH : 1{1'bx}};
|
|
||||||
|
|
||||||
input CLK, ARST;
|
input CLK, ARST;
|
||||||
input [WIDTH-1:0] D;
|
input [WIDTH-1:0] D;
|
||||||
output reg [WIDTH-1:0] Q = INIT;
|
output reg [WIDTH-1:0] Q;
|
||||||
wire pos_clk = CLK == CLK_POLARITY;
|
wire pos_clk = CLK == CLK_POLARITY;
|
||||||
wire pos_arst = ARST == ARST_POLARITY;
|
wire pos_arst = ARST == ARST_POLARITY;
|
||||||
|
|
||||||
|
@ -1563,11 +1559,10 @@ module \$dlatch (EN, D, Q);
|
||||||
|
|
||||||
parameter WIDTH = 0;
|
parameter WIDTH = 0;
|
||||||
parameter EN_POLARITY = 1'b1;
|
parameter EN_POLARITY = 1'b1;
|
||||||
parameter INIT = {WIDTH > 0 ? WIDTH : 1{1'bx}};
|
|
||||||
|
|
||||||
input EN;
|
input EN;
|
||||||
input [WIDTH-1:0] D;
|
input [WIDTH-1:0] D;
|
||||||
output reg [WIDTH-1:0] Q = INIT;
|
output reg [WIDTH-1:0] Q;
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
if (EN == EN_POLARITY)
|
if (EN == EN_POLARITY)
|
||||||
|
@ -1585,11 +1580,10 @@ parameter WIDTH = 0;
|
||||||
parameter EN_POLARITY = 1'b1;
|
parameter EN_POLARITY = 1'b1;
|
||||||
parameter SET_POLARITY = 1'b1;
|
parameter SET_POLARITY = 1'b1;
|
||||||
parameter CLR_POLARITY = 1'b1;
|
parameter CLR_POLARITY = 1'b1;
|
||||||
parameter INIT = {WIDTH > 0 ? WIDTH : 1{1'bx}};
|
|
||||||
|
|
||||||
input EN;
|
input EN;
|
||||||
input [WIDTH-1:0] SET, CLR, D;
|
input [WIDTH-1:0] SET, CLR, D;
|
||||||
output reg [WIDTH-1:0] Q = INIT;
|
output reg [WIDTH-1:0] Q;
|
||||||
|
|
||||||
wire pos_en = EN == EN_POLARITY;
|
wire pos_en = EN == EN_POLARITY;
|
||||||
wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET;
|
wire [WIDTH-1:0] pos_set = SET_POLARITY ? SET : ~SET;
|
||||||
|
|
|
@ -11,4 +11,4 @@ do
|
||||||
done
|
done
|
||||||
shift "$((OPTIND-1))"
|
shift "$((OPTIND-1))"
|
||||||
|
|
||||||
exec ${MAKE:-make} -f ../tools/autotest.mk $seed EXTRA_FLAGS="-e" *.v
|
exec ${MAKE:-make} -f ../tools/autotest.mk $seed EXTRA_FLAGS+="-e" *.v
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# This file contains the names of verilog files to exclude from verilog to FIRRTL regression tests due to known failures.
|
||||||
|
code_hdl_models_arbiter.v error: reg rst; cannot be driven by primitives or continuous assignment.
|
||||||
|
code_hdl_models_clk_div_45.v yosys issue: 2nd PMUXTREE pass yields: ERROR: Negative edge clock on FF clk_div_45.$procdff$49.
|
||||||
|
code_hdl_models_d_ff_gates.v combinational loop
|
||||||
|
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
|
||||||
|
code_verilog_tutorial_escape_id.v make_id issues (name begins with a digit)
|
||||||
|
code_verilog_tutorial_explicit.v firrtl backend bug (empty module)
|
||||||
|
code_verilog_tutorial_first_counter.v error: reg rst; cannot be driven by primitives or continuous assignment.
|
||||||
|
code_verilog_tutorial_fsm_full.v error: reg reset; cannot be driven by primitives or continuous assignment.
|
||||||
|
code_verilog_tutorial_if_else.v empty module (everything is under 'always @ (posedge clk)')
|
||||||
|
[code_verilog_tutorial_n_out_primitive.v empty module
|
||||||
|
code_verilog_tutorial_parallel_if.v empty module (everything is under 'always @ (posedge clk)')
|
||||||
|
code_verilog_tutorial_simple_function.v empty module (no hardware)
|
||||||
|
code_verilog_tutorial_simple_if.v empty module (everything is under 'always @ (posedge clk)')
|
||||||
|
code_verilog_tutorial_task_global.v empty module (everything is under 'always @ (posedge clk)')
|
||||||
|
code_verilog_tutorial_v2k_reg.v empty module
|
||||||
|
code_verilog_tutorial_which_clock.v $adff
|
|
@ -0,0 +1,26 @@
|
||||||
|
# This file contains the names of verilog files to exclude from verilog to FIRRTL regression tests due to known failures.
|
||||||
|
arraycells.v inst id[0] of
|
||||||
|
dff_different_styles.v
|
||||||
|
generate.v combinational loop
|
||||||
|
hierdefparam.v inst id[0] of
|
||||||
|
i2c_master_tests.v $adff
|
||||||
|
macros.v drops modules
|
||||||
|
mem2reg.v drops modules
|
||||||
|
mem_arst.v $adff
|
||||||
|
memory.v $adff
|
||||||
|
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
|
||||||
|
scopes.v original verilog issues ( -x where x isn't declared signed)
|
||||||
|
sincos.v $adff
|
||||||
|
specify.v no code (empty module generates error
|
||||||
|
subbytes.v $adff
|
||||||
|
task_func.v drops modules
|
||||||
|
values.v combinational loop
|
||||||
|
vloghammer.v combinational loop
|
||||||
|
wreduce.v original verilog issues ( -x where x isn't declared signed)
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
EXTRA_FLAGS=
|
# Don't bother defining default values for SEED and EXTRA_FLAGS.
|
||||||
SEED=
|
# Their "natural" default values should be sufficient,
|
||||||
|
# and they may be overridden in the environment.
|
||||||
ifneq ($(strip $(SEED)),)
|
ifneq ($(strip $(SEED)),)
|
||||||
SEEDOPT=-S$(SEED)
|
SEEDOPT=-S$(SEED)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -17,12 +17,18 @@ scriptfiles=""
|
||||||
scriptopt=""
|
scriptopt=""
|
||||||
toolsdir="$(cd $(dirname $0); pwd)"
|
toolsdir="$(cd $(dirname $0); pwd)"
|
||||||
warn_iverilog_git=false
|
warn_iverilog_git=false
|
||||||
|
# The following are used in verilog to firrtl regression tests.
|
||||||
|
# Typically these will be passed as environment variables:
|
||||||
|
#EXTRA_FLAGS="--firrtl2verilog 'java -cp /.../firrtl/utils/bin/firrtl.jar firrtl.Driver'"
|
||||||
|
# The tests are skipped if firrtl2verilog is the empty string (the default).
|
||||||
|
firrtl2verilog=""
|
||||||
|
xfirrtl="../xfirrtl"
|
||||||
|
|
||||||
if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdata ]; then
|
if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdata ]; then
|
||||||
( set -ex; ${CC:-gcc} -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1
|
( set -ex; ${CC:-gcc} -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while getopts xmGl:wkjvref:s:p:n:S:I:B: opt; do
|
while getopts xmGl:wkjvref:s:p:n:S:I:B:-: opt; do
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
x)
|
x)
|
||||||
use_xsim=true ;;
|
use_xsim=true ;;
|
||||||
|
@ -61,8 +67,24 @@ while getopts xmGl:wkjvref:s:p:n:S:I:B: opt; do
|
||||||
minclude_opts="$minclude_opts +incdir+$OPTARG" ;;
|
minclude_opts="$minclude_opts +incdir+$OPTARG" ;;
|
||||||
B)
|
B)
|
||||||
backend_opts="$backend_opts $OPTARG" ;;
|
backend_opts="$backend_opts $OPTARG" ;;
|
||||||
|
-)
|
||||||
|
case "${OPTARG}" in
|
||||||
|
xfirrtl)
|
||||||
|
xfirrtl="${!OPTIND}"
|
||||||
|
OPTIND=$(( $OPTIND + 1 ))
|
||||||
|
;;
|
||||||
|
firrtl2verilog)
|
||||||
|
firrtl2verilog="${!OPTIND}"
|
||||||
|
OPTIND=$(( $OPTIND + 1 ))
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Usage: $0 [-x|-m] [-G] [-w] [-k] [-j] [-v] [-r] [-e] [-l libs] [-f frontend] [-s script] [-p cmdstring] [-n iters] [-S seed] [-I incdir] [-B backend_opt] verilog-files\n" >&2
|
if [ "$OPTERR" == 1 ] && [ "${optspec:0:1}" != ":" ]; then
|
||||||
|
echo "Unknown option --${OPTARG}" >&2
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [-x|-m] [-G] [-w] [-k] [-j] [-v] [-r] [-e] [-l libs] [-f frontend] [-s script] [-p cmdstring] [-n iters] [-S seed] [-I incdir] [-B backend_opt] [--xfirrtl FIRRTL test exclude file] [--firrtl2verilog command to generate verilog from firrtl] verilog-files\n" >&2
|
||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
@ -118,6 +140,7 @@ do
|
||||||
"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "verilog" -o ${bn}_ref.v ../${fn}
|
"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "verilog" -o ${bn}_ref.v ../${fn}
|
||||||
frontend="verilog"
|
frontend="verilog"
|
||||||
fi
|
fi
|
||||||
|
rm -f ${bn}_ref.fir
|
||||||
|
|
||||||
if [ ! -f ../${bn}_tb.v ]; then
|
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.v
|
||||||
|
@ -157,6 +180,13 @@ do
|
||||||
else
|
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; 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; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.v
|
||||||
|
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
|
||||||
|
test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.fir.v
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
touch ../${bn}.log
|
touch ../${bn}.log
|
||||||
}
|
}
|
||||||
|
@ -169,14 +199,18 @@ do
|
||||||
( set -ex; body; ) > ${bn}.err 2>&1
|
( set -ex; body; ) > ${bn}.err 2>&1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
did_firrtl=""
|
||||||
|
if [ -f ${bn}.out/${bn}_ref.fir ]; then
|
||||||
|
did_firrtl="+FIRRTL "
|
||||||
|
fi
|
||||||
if [ -f ${bn}.log ]; then
|
if [ -f ${bn}.log ]; then
|
||||||
mv ${bn}.err ${bn}.log
|
mv ${bn}.err ${bn}.log
|
||||||
echo "${status_prefix}-> ok"
|
echo "${status_prefix}${did_firrtl}-> ok"
|
||||||
elif [ -f ${bn}.skip ]; then
|
elif [ -f ${bn}.skip ]; then
|
||||||
mv ${bn}.err ${bn}.skip
|
mv ${bn}.err ${bn}.skip
|
||||||
echo "${status_prefix}-> skip"
|
echo "${status_prefix}-> skip"
|
||||||
else
|
else
|
||||||
echo "${status_prefix}-> ERROR!"
|
echo "${status_prefix}${did_firrtl}-> ERROR!"
|
||||||
if $warn_iverilog_git; then
|
if $warn_iverilog_git; then
|
||||||
echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of Icarus Verilog."
|
echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of Icarus Verilog."
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in New Issue