mirror of https://github.com/YosysHQ/yosys.git
dfflibmap: Refactor to use dfflegalize internally.
This commit is contained in:
parent
68babb2ae4
commit
7ed9d18907
|
@ -115,7 +115,7 @@ static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval, bool prepare_mode)
|
||||
static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval)
|
||||
{
|
||||
LibertyAst *best_cell = nullptr;
|
||||
std::map<std::string, char> best_cell_ports;
|
||||
|
@ -222,21 +222,12 @@ static void find_cell(LibertyAst *ast, IdString cell_type, bool clkpol, bool has
|
|||
if (best_cell != nullptr) {
|
||||
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
|
||||
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
|
||||
if (prepare_mode) {
|
||||
cell_mappings[cell_type].cell_name = cell_type;
|
||||
cell_mappings[cell_type].ports["C"] = 'C';
|
||||
if (has_reset)
|
||||
cell_mappings[cell_type].ports["R"] = 'R';
|
||||
cell_mappings[cell_type].ports["D"] = 'D';
|
||||
cell_mappings[cell_type].ports["Q"] = 'Q';
|
||||
} else {
|
||||
cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
|
||||
cell_mappings[cell_type].ports = best_cell_ports;
|
||||
}
|
||||
cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
|
||||
cell_mappings[cell_type].ports = best_cell_ports;
|
||||
}
|
||||
}
|
||||
|
||||
static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol, bool prepare_mode)
|
||||
static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool setpol, bool clrpol)
|
||||
{
|
||||
LibertyAst *best_cell = nullptr;
|
||||
std::map<std::string, char> best_cell_ports;
|
||||
|
@ -339,141 +330,12 @@ static void find_cell_sr(LibertyAst *ast, IdString cell_type, bool clkpol, bool
|
|||
if (best_cell != nullptr) {
|
||||
log(" cell %s (%sinv, pins=%d, area=%.2f) is a direct match for cell type %s.\n",
|
||||
best_cell->args[0].c_str(), best_cell_noninv ? "non" : "", best_cell_pins, best_cell_area, cell_type.c_str());
|
||||
if (prepare_mode) {
|
||||
cell_mappings[cell_type].cell_name = cell_type;
|
||||
cell_mappings[cell_type].ports["C"] = 'C';
|
||||
cell_mappings[cell_type].ports["S"] = 'S';
|
||||
cell_mappings[cell_type].ports["R"] = 'R';
|
||||
cell_mappings[cell_type].ports["D"] = 'D';
|
||||
cell_mappings[cell_type].ports["Q"] = 'Q';
|
||||
} else {
|
||||
cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
|
||||
cell_mappings[cell_type].ports = best_cell_ports;
|
||||
}
|
||||
cell_mappings[cell_type].cell_name = RTLIL::escape_id(best_cell->args[0]);
|
||||
cell_mappings[cell_type].ports = best_cell_ports;
|
||||
}
|
||||
}
|
||||
|
||||
static bool expand_cellmap_worker(std::string from, std::string to, std::string inv)
|
||||
{
|
||||
if (cell_mappings.count(to) > 0)
|
||||
return false;
|
||||
|
||||
log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
|
||||
cell_mappings[to].cell_name = cell_mappings[from].cell_name;
|
||||
cell_mappings[to].ports = cell_mappings[from].ports;
|
||||
|
||||
for (auto &it : cell_mappings[to].ports) {
|
||||
char cmp_ch = it.second;
|
||||
if ('a' <= cmp_ch && cmp_ch <= 'z')
|
||||
cmp_ch -= 'a' - 'A';
|
||||
if (inv.find(cmp_ch) == std::string::npos)
|
||||
continue;
|
||||
if ('a' <= it.second && it.second <= 'z')
|
||||
it.second -= 'a' - 'A';
|
||||
else if ('A' <= it.second && it.second <= 'Z')
|
||||
it.second += 'a' - 'A';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool expand_cellmap(std::string pattern, std::string inv)
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> from_to_list;
|
||||
bool return_status = false;
|
||||
|
||||
for (auto &it : cell_mappings) {
|
||||
std::string from = it.first.str(), to = it.first.str();
|
||||
if (from.size() != pattern.size())
|
||||
continue;
|
||||
for (size_t i = 0; i < from.size(); i++) {
|
||||
if (pattern[i] == '*') {
|
||||
to[i] = from[i] == 'P' ? 'N' :
|
||||
from[i] == 'N' ? 'P' :
|
||||
from[i] == '1' ? '0' :
|
||||
from[i] == '0' ? '1' : '*';
|
||||
} else
|
||||
if (pattern[i] != '?' && pattern[i] != from[i])
|
||||
goto pattern_failed;
|
||||
}
|
||||
from_to_list.push_back(std::pair<std::string, std::string>(from, to));
|
||||
pattern_failed:;
|
||||
}
|
||||
|
||||
for (auto &it : from_to_list)
|
||||
return_status = return_status || expand_cellmap_worker(it.first, it.second, inv);
|
||||
return return_status;
|
||||
}
|
||||
|
||||
static void map_sr_to_arst(IdString from, IdString to)
|
||||
{
|
||||
if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
|
||||
return;
|
||||
|
||||
char from_clk_pol = from[8];
|
||||
char from_set_pol = from[9];
|
||||
char from_clr_pol = from[10];
|
||||
char to_clk_pol = to[6];
|
||||
char to_rst_pol = to[7];
|
||||
char to_rst_val = to[8];
|
||||
|
||||
log_assert(from_clk_pol == to_clk_pol);
|
||||
log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol);
|
||||
|
||||
log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
|
||||
cell_mappings[to].cell_name = cell_mappings[from].cell_name;
|
||||
cell_mappings[to].ports = cell_mappings[from].ports;
|
||||
|
||||
for (auto &it : cell_mappings[to].ports)
|
||||
{
|
||||
bool is_set_pin = it.second == 'S' || it.second == 's';
|
||||
bool is_clr_pin = it.second == 'R' || it.second == 'r';
|
||||
|
||||
if (!is_set_pin && !is_clr_pin)
|
||||
continue;
|
||||
|
||||
if ((to_rst_val == '0' && is_set_pin) || (to_rst_val == '1' && is_clr_pin))
|
||||
{
|
||||
// this is the unused set/clr pin -- deactivate it
|
||||
if (is_set_pin)
|
||||
it.second = (from_set_pol == 'P') == (it.second == 'S') ? '0' : '1';
|
||||
else
|
||||
it.second = (from_clr_pol == 'P') == (it.second == 'R') ? '0' : '1';
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is the used set/clr pin -- rename it to 'reset'
|
||||
if (it.second == 'S')
|
||||
it.second = 'R';
|
||||
if (it.second == 's')
|
||||
it.second = 'r';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void map_adff_to_dff(IdString from, IdString to)
|
||||
{
|
||||
if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
|
||||
return;
|
||||
|
||||
char from_clk_pol = from[6];
|
||||
char from_rst_pol = from[7];
|
||||
char to_clk_pol = to[6];
|
||||
|
||||
log_assert(from_clk_pol == to_clk_pol);
|
||||
|
||||
log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
|
||||
cell_mappings[to].cell_name = cell_mappings[from].cell_name;
|
||||
cell_mappings[to].ports = cell_mappings[from].ports;
|
||||
|
||||
for (auto &it : cell_mappings[to].ports) {
|
||||
if (it.second == 'S' || it.second == 'R')
|
||||
it.second = from_rst_pol == 'P' ? '0' : '1';
|
||||
if (it.second == 's' || it.second == 'r')
|
||||
it.second = from_rst_pol == 'P' ? '1' : '0';
|
||||
}
|
||||
}
|
||||
|
||||
static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare_mode)
|
||||
static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
|
||||
{
|
||||
log("Mapping DFF cells in module `%s':\n", module->name.c_str());
|
||||
|
||||
|
@ -499,7 +361,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module, bool prepare
|
|||
module->remove(cell);
|
||||
|
||||
cell_mapping &cm = cell_mappings[cell_type];
|
||||
RTLIL::Cell *new_cell = module->addCell(cell_name, prepare_mode ? cm.cell_name : cm.cell_name);
|
||||
RTLIL::Cell *new_cell = module->addCell(cell_name, cm.cell_name);
|
||||
|
||||
new_cell->set_src_attribute(src);
|
||||
|
||||
|
@ -552,7 +414,7 @@ struct DfflibmapPass : public Pass {
|
|||
void help() override
|
||||
{
|
||||
log("\n");
|
||||
log(" dfflibmap [-prepare] -liberty <file> [selection]\n");
|
||||
log(" dfflibmap [-prepare] [-map-only] [-info] -liberty <file> [selection]\n");
|
||||
log("\n");
|
||||
log("Map internal flip-flop cells to the flip-flop cells in the technology\n");
|
||||
log("library specified in the given liberty file.\n");
|
||||
|
@ -562,15 +424,27 @@ struct DfflibmapPass : public Pass {
|
|||
log("\n");
|
||||
log("When called with -prepare, this command will convert the internal FF cells\n");
|
||||
log("to the internal cell types that best match the cells found in the given\n");
|
||||
log("liberty file.\n");
|
||||
log("liberty file, but won't actually map them to the target cells.\n");
|
||||
log("\n");
|
||||
log("When called with -map-only, this command will only map internal cell\n");
|
||||
log("types that are already of exactly the right type to match the target\n");
|
||||
log("cells, leaving remaining internal cells untouched.\n");
|
||||
log("\n");
|
||||
log("When called with -info, this command will only print the target cell\n");
|
||||
log("list, along with their associated internal cell types, and the arguments");
|
||||
log("that would be passed to the dfflegalize pass. The design will not be\n");
|
||||
log("changed.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
log_header(design, "Executing DFFLIBMAP pass (mapping DFF cells to sequential cells from liberty file).\n");
|
||||
log_push();
|
||||
|
||||
std::string liberty_file;
|
||||
bool prepare_mode = false;
|
||||
bool map_only_mode = false;
|
||||
bool info_mode = false;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
|
@ -585,10 +459,28 @@ struct DfflibmapPass : public Pass {
|
|||
prepare_mode = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-map-only") {
|
||||
map_only_mode = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-info") {
|
||||
info_mode = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
int modes = 0;
|
||||
if (prepare_mode)
|
||||
modes++;
|
||||
if (map_only_mode)
|
||||
modes++;
|
||||
if (info_mode)
|
||||
modes++;
|
||||
if (modes > 1)
|
||||
log_cmd_error("Only one of -prepare, -map-only, or -info options should be given!\n");
|
||||
|
||||
if (liberty_file.empty())
|
||||
log_cmd_error("Missing `-liberty liberty_file' option!\n");
|
||||
|
||||
|
@ -599,74 +491,49 @@ struct DfflibmapPass : public Pass {
|
|||
LibertyParser libparser(f);
|
||||
f.close();
|
||||
|
||||
find_cell(libparser.ast, ID($_DFF_N_), false, false, false, false, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_P_), true, false, false, false, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_N_), false, false, false, false);
|
||||
find_cell(libparser.ast, ID($_DFF_P_), true, false, false, false);
|
||||
|
||||
find_cell(libparser.ast, ID($_DFF_NN0_), false, true, false, false, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_NN1_), false, true, false, true, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_NP0_), false, true, true, false, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_NP1_), false, true, true, true, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_PN0_), true, true, false, false, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_PN1_), true, true, false, true, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_PP0_), true, true, true, false, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_PP1_), true, true, true, true, prepare_mode);
|
||||
find_cell(libparser.ast, ID($_DFF_NN0_), false, true, false, false);
|
||||
find_cell(libparser.ast, ID($_DFF_NN1_), false, true, false, true);
|
||||
find_cell(libparser.ast, ID($_DFF_NP0_), false, true, true, false);
|
||||
find_cell(libparser.ast, ID($_DFF_NP1_), false, true, true, true);
|
||||
find_cell(libparser.ast, ID($_DFF_PN0_), true, true, false, false);
|
||||
find_cell(libparser.ast, ID($_DFF_PN1_), true, true, false, true);
|
||||
find_cell(libparser.ast, ID($_DFF_PP0_), true, true, true, false);
|
||||
find_cell(libparser.ast, ID($_DFF_PP1_), true, true, true, true);
|
||||
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NNN_), false, false, false, prepare_mode);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NNP_), false, false, true, prepare_mode);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NPN_), false, true, false, prepare_mode);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NPP_), false, true, true, prepare_mode);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PNN_), true, false, false, prepare_mode);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PNP_), true, false, true, prepare_mode);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PPN_), true, true, false, prepare_mode);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PPP_), true, true, true, prepare_mode);
|
||||
|
||||
// try to implement as many cells as possible just by inverting
|
||||
// the SET and RESET pins. If necessary, implement cell types
|
||||
// by inverting both D and Q. Only invert clock pins if there
|
||||
// is no other way of implementing the cell.
|
||||
while (1)
|
||||
{
|
||||
if (expand_cellmap("$_DFF_?*?_", "R") ||
|
||||
expand_cellmap("$_DFFSR_?*?_", "S") ||
|
||||
expand_cellmap("$_DFFSR_??*_", "R"))
|
||||
continue;
|
||||
|
||||
if (expand_cellmap("$_DFF_??*_", "DQ"))
|
||||
continue;
|
||||
|
||||
if (expand_cellmap("$_DFF_*_", "C") ||
|
||||
expand_cellmap("$_DFF_*??_", "C") ||
|
||||
expand_cellmap("$_DFFSR_*??_", "C"))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN0_));
|
||||
map_sr_to_arst(ID($_DFFSR_NNN_), ID($_DFF_NN1_));
|
||||
map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP0_));
|
||||
map_sr_to_arst(ID($_DFFSR_NPP_), ID($_DFF_NP1_));
|
||||
map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN0_));
|
||||
map_sr_to_arst(ID($_DFFSR_PNN_), ID($_DFF_PN1_));
|
||||
map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP0_));
|
||||
map_sr_to_arst(ID($_DFFSR_PPP_), ID($_DFF_PP1_));
|
||||
|
||||
map_adff_to_dff(ID($_DFF_NN0_), ID($_DFF_N_));
|
||||
map_adff_to_dff(ID($_DFF_NN1_), ID($_DFF_N_));
|
||||
map_adff_to_dff(ID($_DFF_NP0_), ID($_DFF_N_));
|
||||
map_adff_to_dff(ID($_DFF_NP1_), ID($_DFF_N_));
|
||||
map_adff_to_dff(ID($_DFF_PN0_), ID($_DFF_P_));
|
||||
map_adff_to_dff(ID($_DFF_PN1_), ID($_DFF_P_));
|
||||
map_adff_to_dff(ID($_DFF_PP0_), ID($_DFF_P_));
|
||||
map_adff_to_dff(ID($_DFF_PP1_), ID($_DFF_P_));
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NNN_), false, false, false);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NNP_), false, false, true);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NPN_), false, true, false);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_NPP_), false, true, true);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PNN_), true, false, false);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PNP_), true, false, true);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PPN_), true, true, false);
|
||||
find_cell_sr(libparser.ast, ID($_DFFSR_PPP_), true, true, true);
|
||||
|
||||
log(" final dff cell mappings:\n");
|
||||
logmap_all();
|
||||
|
||||
for (auto module : design->selected_modules())
|
||||
if (!module->get_blackbox_attribute())
|
||||
dfflibmap(design, module, prepare_mode);
|
||||
if (!map_only_mode) {
|
||||
std::string dfflegalize_cmd = "dfflegalize";
|
||||
for (auto it : cell_mappings)
|
||||
dfflegalize_cmd += stringf(" -cell %s 01", it.first.c_str());
|
||||
dfflegalize_cmd += " t:$_DFF* t:$_SDFF*";
|
||||
if (info_mode) {
|
||||
log("dfflegalize command line: %s\n", dfflegalize_cmd.c_str());
|
||||
} else {
|
||||
Pass::call(design, dfflegalize_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
if (!prepare_mode && !info_mode) {
|
||||
for (auto module : design->selected_modules())
|
||||
if (!module->get_blackbox_attribute())
|
||||
dfflibmap(design, module);
|
||||
}
|
||||
|
||||
log_pop();
|
||||
cell_mappings.clear();
|
||||
}
|
||||
} DfflibmapPass;
|
||||
|
|
|
@ -5,6 +5,6 @@ for x in *.lib; do
|
|||
echo "Running $x.."
|
||||
echo "read_verilog small.v" > test.ys
|
||||
echo "synth -top small" >> test.ys
|
||||
echo "dfflibmap -liberty ${x}" >> test.ys
|
||||
echo "dfflibmap -info -liberty ${x}" >> test.ys
|
||||
../../yosys -ql ${x%.lib}.log -s test.ys
|
||||
done
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
module dffn(input CLK, D, output reg Q, output QN);
|
||||
|
||||
always @(negedge CLK)
|
||||
Q <= D;
|
||||
|
||||
assign QN = ~Q;
|
||||
|
||||
endmodule
|
||||
|
||||
module dffsr(input CLK, D, CLEAR, PRESET, output reg Q, output QN);
|
||||
|
||||
always @(posedge CLK, posedge CLEAR, posedge PRESET)
|
||||
if (CLEAR)
|
||||
Q <= 0;
|
||||
else if (PRESET)
|
||||
Q <= 1;
|
||||
else
|
||||
Q <= D;
|
||||
|
||||
assign QN = ~Q;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,55 @@
|
|||
library(test) {
|
||||
/* D-type flip-flop with asynchronous reset and preset */
|
||||
cell (dffn) {
|
||||
area : 6;
|
||||
ff("IQ", "IQN") {
|
||||
next_state : "D";
|
||||
clocked_on : "!CLK";
|
||||
}
|
||||
pin(D) {
|
||||
direction : input;
|
||||
}
|
||||
pin(CLK) {
|
||||
direction : input;
|
||||
}
|
||||
pin(Q) {
|
||||
direction: output;
|
||||
function : "IQ";
|
||||
}
|
||||
pin(QN) {
|
||||
direction: output;
|
||||
function : "IQN";
|
||||
}
|
||||
}
|
||||
cell (dffsr) {
|
||||
area : 6;
|
||||
ff("IQ", "IQN") {
|
||||
next_state : "D";
|
||||
clocked_on : "CLK";
|
||||
clear : "CLEAR";
|
||||
preset : "PRESET";
|
||||
clear_preset_var1 : L;
|
||||
clear_preset_var2 : L;
|
||||
}
|
||||
pin(D) {
|
||||
direction : input;
|
||||
}
|
||||
pin(CLK) {
|
||||
direction : input;
|
||||
}
|
||||
pin(CLEAR) {
|
||||
direction : input;
|
||||
}
|
||||
pin(PRESET) {
|
||||
direction : input;
|
||||
}
|
||||
pin(Q) {
|
||||
direction: output;
|
||||
function : "IQ";
|
||||
}
|
||||
pin(QN) {
|
||||
direction: output;
|
||||
function : "IQN";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
read_verilog -icells <<EOT
|
||||
|
||||
module top(input C, D, S, R, output [9:0] Q);
|
||||
|
||||
$_DFF_P_ ff0 (.C(C), .D(D), .Q(Q[0]));
|
||||
$_DFF_PP0_ ff1 (.C(C), .D(D), .R(R), .Q(Q[1]));
|
||||
$_DFF_PP1_ ff2 (.C(C), .D(D), .R(R), .Q(Q[2]));
|
||||
$_DFFSR_PPP_ ff3 (.C(C), .D(D), .R(R), .S(S), .Q(Q[3]));
|
||||
$_DFFSR_NNN_ ff4 (.C(C), .D(D), .R(R), .S(S), .Q(Q[4]));
|
||||
|
||||
assign Q[9:5] = ~Q[4:0];
|
||||
|
||||
endmodule
|
||||
|
||||
EOT
|
||||
|
||||
simplemap
|
||||
|
||||
design -save orig
|
||||
|
||||
#equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -liberty dfflibmap.lib
|
||||
#equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -prepare -liberty dfflibmap.lib
|
||||
dfflibmap -prepare -liberty dfflibmap.lib
|
||||
equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -map-only -liberty dfflibmap.lib
|
||||
|
||||
design -load orig
|
||||
dfflibmap -liberty dfflibmap.lib
|
||||
clean
|
||||
|
||||
select -assert-count 4 t:$_NOT_
|
||||
select -assert-count 1 t:dffn
|
||||
select -assert-count 4 t:dffsr
|
||||
select -assert-none t:dffn t:dffsr t:$_NOT_ %% %n t:* %i
|
||||
|
||||
design -load orig
|
||||
dfflibmap -prepare -liberty dfflibmap.lib
|
||||
|
||||
select -assert-count 9 t:$_NOT_
|
||||
select -assert-count 1 t:$_DFF_N_
|
||||
select -assert-count 4 t:$_DFFSR_PPP_
|
||||
select -assert-none t:$_DFF_N_ t:$_DFFSR_PPP_ t:$_NOT_ %% %n t:* %i
|
||||
|
||||
design -load orig
|
||||
dfflibmap -map-only -liberty dfflibmap.lib
|
||||
|
||||
select -assert-count 5 t:$_NOT_
|
||||
select -assert-count 0 t:dffn
|
||||
select -assert-count 1 t:dffsr
|
||||
|
||||
design -load orig
|
||||
dfflibmap -prepare -liberty dfflibmap.lib
|
||||
dfflibmap -map-only -liberty dfflibmap.lib
|
||||
clean
|
||||
|
||||
select -assert-count 4 t:$_NOT_
|
||||
select -assert-count 1 t:dffn
|
||||
select -assert-count 4 t:dffsr
|
||||
select -assert-none t:dffn t:dffsr t:$_NOT_ %% %n t:* %i
|
Loading…
Reference in New Issue