3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-05-06 15:25:47 +00:00

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

This commit is contained in:
Eddie Hung 2019-08-07 13:44:08 -07:00
commit e3d898dccb
49 changed files with 1136 additions and 554 deletions

View file

@ -325,6 +325,8 @@ Aig::Aig(Cell *cell)
int A = mk.inport("\\A", i);
int B = mk.inport("\\B", i);
int Y = mk.mux_gate(A, B, S);
if (cell->type == "$_NMUX_")
Y = mk.not_gate(Y);
mk.outport(Y, "\\Y", i);
}
goto optimize;

View file

@ -193,6 +193,7 @@ struct CellTypes
setup_type("$_ANDNOT_", {A, B}, {Y}, true);
setup_type("$_ORNOT_", {A, B}, {Y}, true);
setup_type("$_MUX_", {A, B, S}, {Y}, true);
setup_type("$_NMUX_", {A, B, S}, {Y}, true);
setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true);
setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true);

View file

@ -145,7 +145,7 @@ struct ConstEval
if (cell->hasPort("\\B"))
sig_b = cell->getPort("\\B");
if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_")
if (cell->type.in("$mux", "$pmux", "$_MUX_", "$_NMUX_"))
{
std::vector<RTLIL::SigSpec> y_candidates;
int count_maybe_set_s_bits = 0;
@ -175,7 +175,10 @@ struct ConstEval
for (auto &yc : y_candidates) {
if (!eval(yc, undef, cell))
return false;
y_values.push_back(yc.as_const());
if (cell->type == "$_NMUX_")
y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc)));
else
y_values.push_back(yc.as_const());
}
if (y_values.size() > 1)

View file

@ -24,62 +24,92 @@
YOSYS_NAMESPACE_BEGIN
int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
inline int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr)
struct CellCosts
{
static dict<RTLIL::IdString, int> gate_cost = {
{ "$_BUF_", 1 },
{ "$_NOT_", 2 },
{ "$_AND_", 4 },
{ "$_NAND_", 4 },
{ "$_OR_", 4 },
{ "$_NOR_", 4 },
{ "$_ANDNOT_", 4 },
{ "$_ORNOT_", 4 },
{ "$_XOR_", 8 },
{ "$_XNOR_", 8 },
{ "$_AOI3_", 6 },
{ "$_OAI3_", 6 },
{ "$_AOI4_", 8 },
{ "$_OAI4_", 8 },
{ "$_MUX_", 4 }
};
if (gate_cost.count(type))
return gate_cost.at(type);
if (parameters.empty() && design && design->module(type))
{
RTLIL::Module *mod = design->module(type);
if (mod->attributes.count("\\cost"))
return mod->attributes.at("\\cost").as_int();
dict<RTLIL::IdString, int> local_mod_cost_cache;
if (mod_cost_cache == nullptr)
mod_cost_cache = &local_mod_cost_cache;
if (mod_cost_cache->count(mod->name))
return mod_cost_cache->at(mod->name);
int module_cost = 1;
for (auto c : mod->cells())
module_cost += get_cell_cost(c, mod_cost_cache);
(*mod_cost_cache)[mod->name] = module_cost;
return module_cost;
static const dict<RTLIL::IdString, int>& default_gate_cost() {
static const dict<RTLIL::IdString, int> db = {
{ "$_BUF_", 1 },
{ "$_NOT_", 2 },
{ "$_AND_", 4 },
{ "$_NAND_", 4 },
{ "$_OR_", 4 },
{ "$_NOR_", 4 },
{ "$_ANDNOT_", 4 },
{ "$_ORNOT_", 4 },
{ "$_XOR_", 5 },
{ "$_XNOR_", 5 },
{ "$_AOI3_", 6 },
{ "$_OAI3_", 6 },
{ "$_AOI4_", 7 },
{ "$_OAI4_", 7 },
{ "$_MUX_", 4 },
{ "$_NMUX_", 4 }
};
return db;
}
log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(type), GetSize(parameters));
return 1;
}
static const dict<RTLIL::IdString, int>& cmos_gate_cost() {
static const dict<RTLIL::IdString, int> db = {
{ "$_BUF_", 1 },
{ "$_NOT_", 2 },
{ "$_AND_", 6 },
{ "$_NAND_", 4 },
{ "$_OR_", 6 },
{ "$_NOR_", 4 },
{ "$_ANDNOT_", 6 },
{ "$_ORNOT_", 6 },
{ "$_XOR_", 12 },
{ "$_XNOR_", 12 },
{ "$_AOI3_", 6 },
{ "$_OAI3_", 6 },
{ "$_AOI4_", 8 },
{ "$_OAI4_", 8 },
{ "$_MUX_", 12 },
{ "$_NMUX_", 10 }
};
return db;
}
inline int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
{
return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache);
}
dict<RTLIL::IdString, int> mod_cost_cache;
const dict<RTLIL::IdString, int> *gate_cost = nullptr;
Design *design = nullptr;
int get(RTLIL::IdString type) const
{
if (gate_cost && gate_cost->count(type))
return gate_cost->at(type);
log_warning("Can't determine cost of %s cell.\n", log_id(type));
return 1;
}
int get(RTLIL::Cell *cell)
{
if (gate_cost && gate_cost->count(cell->type))
return gate_cost->at(cell->type);
if (design && design->module(cell->type) && cell->parameters.empty())
{
RTLIL::Module *mod = design->module(cell->type);
if (mod->attributes.count("\\cost"))
return mod->attributes.at("\\cost").as_int();
if (mod_cost_cache.count(mod->name))
return mod_cost_cache.at(mod->name);
int module_cost = 1;
for (auto c : mod->cells())
module_cost += get(c);
mod_cost_cache[mod->name] = module_cost;
return module_cost;
}
log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters));
return 1;
}
};
YOSYS_NAMESPACE_END

View file

@ -522,6 +522,12 @@ int main(int argc, char **argv)
if (!backend_command.empty())
run_backend(output_filename, backend_command);
yosys_design->check();
for (auto it : saved_designs)
it.second->check();
for (auto it : pushed_designs)
it->check();
if (!depsfile.empty())
{
FILE *f = fopen(depsfile.c_str(), "wt");

View file

@ -41,6 +41,45 @@ void decompress_gzip(const std::string &filename, std::stringstream &out)
}
gzclose(gzf);
}
/*
An output stream that uses a stringbuf to buffer data internally,
using zlib to write gzip-compressed data every time the stream is flushed.
*/
class gzip_ostream : public std::ostream {
public:
gzip_ostream()
{
rdbuf(&outbuf);
}
bool open(const std::string &filename)
{
return outbuf.open(filename);
}
private:
class gzip_streambuf : public std::stringbuf {
public:
gzip_streambuf() { };
bool open(const std::string &filename)
{
gzf = gzopen(filename.c_str(), "wb");
return gzf != nullptr;
}
virtual int sync() override
{
gzwrite(gzf, reinterpret_cast<const void *>(str().c_str()), unsigned(str().size()));
str("");
return 0;
}
~gzip_streambuf()
{
sync();
gzclose(gzf);
}
private:
gzFile gzf = nullptr;
} outbuf;
};
PRIVATE_NAMESPACE_END
#endif
@ -256,8 +295,6 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
pass_register[args[0]]->post_execute(state);
while (design->selection_stack.size() > orig_sel_stack_pos)
design->selection_stack.pop_back();
design->check();
}
void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command)
@ -339,8 +376,10 @@ void ScriptPass::run(std::string command, std::string info)
log(" %s\n", command.c_str());
else
log(" %s %s\n", command.c_str(), info.c_str());
} else
} else {
Pass::call(active_design, command);
active_design->check();
}
}
void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
@ -534,8 +573,6 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string
args.push_back(filename);
frontend_register[args[0]]->execute(args, design);
}
design->check();
}
Backend::Backend(std::string name, std::string short_help) :
@ -588,14 +625,28 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
filename = arg;
rewrite_filename(filename);
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), std::ofstream::trunc);
yosys_output_files.insert(filename);
if (ff->fail()) {
delete ff;
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
if (filename.size() > 3 && filename.substr(filename.size()-3) == ".gz") {
#ifdef YOSYS_ENABLE_ZLIB
gzip_ostream *gf = new gzip_ostream;
if (!gf->open(filename)) {
delete gf;
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
}
yosys_output_files.insert(filename);
f = gf;
#else
log_cmd_error("Yosys is compiled without zlib support, unable to write gzip output.\n");
#endif
} else {
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), std::ofstream::trunc);
yosys_output_files.insert(filename);
if (ff->fail()) {
delete ff;
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
}
f = ff;
}
f = ff;
}
if (called_with_fp)
@ -645,8 +696,6 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f
while (design->selection_stack.size() > orig_sel_stack_pos)
design->selection_stack.pop_back();
design->check();
}
static struct CellHelpMessages {

View file

@ -1249,6 +1249,7 @@ namespace {
if (cell->type == "$_ANDNOT_") { check_gate("ABY"); return; }
if (cell->type == "$_ORNOT_") { check_gate("ABY"); return; }
if (cell->type == "$_MUX_") { check_gate("ABSY"); return; }
if (cell->type == "$_NMUX_") { check_gate("ABSY"); return; }
if (cell->type == "$_AOI3_") { check_gate("ABCY"); return; }
if (cell->type == "$_OAI3_") { check_gate("ABCY"); return; }
if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; }
@ -1976,6 +1977,7 @@ DEF_METHOD_3(XnorGate, "$_XNOR_", A, B, Y)
DEF_METHOD_3(AndnotGate, "$_ANDNOT_", A, B, Y)
DEF_METHOD_3(OrnotGate, "$_ORNOT_", A, B, Y)
DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y)
DEF_METHOD_4(NmuxGate, "$_NMUX_", A, B, S, Y)
DEF_METHOD_4(Aoi3Gate, "$_AOI3_", A, B, C, Y)
DEF_METHOD_4(Oai3Gate, "$_OAI3_", A, B, C, Y)
DEF_METHOD_5(Aoi4Gate, "$_AOI4_", A, B, C, D, Y)
@ -3354,13 +3356,7 @@ RTLIL::SigSpec RTLIL::SigSpec::extract(int offset, int length) const
{
unpack();
cover("kernel.rtlil.sigspec.extract_pos");
auto it = bits_.begin() + std::min<int>(offset, width_);
decltype(it) ie;
if (length >= 0)
ie = bits_.begin() + std::min<int>(offset + length, width_);
else
ie = bits_.end() + std::max<int>(length + 1, offset - width_);
return std::vector<RTLIL::SigBit>(it, ie);
return std::vector<RTLIL::SigBit>(bits_.begin() + offset, bits_.begin() + offset + length);
}
void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)

View file

@ -788,6 +788,7 @@ public:
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const;
RTLIL::SigSpec extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const;
RTLIL::SigSpec extract(int offset, int length = 1) const;
RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); }
void append(const RTLIL::SigSpec &signal);
void append_bit(const RTLIL::SigBit &bit);
@ -1155,6 +1156,7 @@ public:
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addNmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = "");
@ -1230,6 +1232,7 @@ public:
RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit OrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
RTLIL::SigBit NmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = "");

View file

@ -475,7 +475,7 @@ struct SatGen
return true;
}
if (cell->type == "$_MUX_" || cell->type == "$mux")
if (cell->type == "$_MUX_" || cell->type == "$mux" || cell->type == "$_NMUX_")
{
std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
@ -483,7 +483,10 @@ struct SatGen
std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
if (cell->type == "$_NMUX_")
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy));
else
ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
if (model_undef)
{

View file

@ -964,14 +964,18 @@ void run_frontend(std::string filename, std::string command, std::string *backen
command += next_line;
}
handle_label(command, from_to_active, run_from, run_to);
if (from_to_active)
if (from_to_active) {
Pass::call(design, command);
design->check();
}
}
if (!command.empty()) {
handle_label(command, from_to_active, run_from, run_to);
if (from_to_active)
if (from_to_active) {
Pass::call(design, command);
design->check();
}
}
}
catch (...) {
@ -1000,6 +1004,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
Pass::call(design, vector<string>({command, filename}));
else
Frontend::frontend_call(design, NULL, filename, command);
design->check();
}
void run_frontend(std::string filename, std::string command, RTLIL::Design *design)
@ -1183,6 +1188,7 @@ void shell(RTLIL::Design *design)
design->selection_stack.pop_back();
log_reset_stack();
}
design->check();
}
if (command == NULL)
printf("exit\n");

View file

@ -88,6 +88,10 @@ extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName);
extern void Tcl_Finalize(void);
extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr);
extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length);
extern Tcl_Obj *Tcl_NewIntObj(int intValue);
extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]);
extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags);
# endif
#endif