mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-13 04:28:18 +00:00
Merge pull request #4222 from jix/pdr-X
write_aiger: Include `$assert` and `$assume` cells in -ywmap output
This commit is contained in:
commit
04ecabdd1f
2
Makefile
2
Makefile
|
@ -165,7 +165,7 @@ bumpversion:
|
||||||
# is just a symlink to your actual ABC working directory, as 'make mrproper'
|
# is just a symlink to your actual ABC working directory, as 'make mrproper'
|
||||||
# will remove the 'abc' directory and you do not want to accidentally
|
# will remove the 'abc' directory and you do not want to accidentally
|
||||||
# delete your work on ABC..
|
# delete your work on ABC..
|
||||||
ABCREV = 896e5e7
|
ABCREV = 0cd90d0
|
||||||
ABCPULL = 1
|
ABCPULL = 1
|
||||||
ABCURL ?= https://github.com/YosysHQ/abc
|
ABCURL ?= https://github.com/YosysHQ/abc
|
||||||
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q)
|
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q)
|
||||||
|
|
|
@ -67,6 +67,8 @@ struct AigerWriter
|
||||||
int initstate_ff = 0;
|
int initstate_ff = 0;
|
||||||
|
|
||||||
dict<SigBit, int> ywmap_clocks;
|
dict<SigBit, int> ywmap_clocks;
|
||||||
|
vector<Cell *> ywmap_asserts;
|
||||||
|
vector<Cell *> ywmap_assumes;
|
||||||
|
|
||||||
int mkgate(int a0, int a1)
|
int mkgate(int a0, int a1)
|
||||||
{
|
{
|
||||||
|
@ -269,6 +271,7 @@ struct AigerWriter
|
||||||
unused_bits.erase(A);
|
unused_bits.erase(A);
|
||||||
unused_bits.erase(EN);
|
unused_bits.erase(EN);
|
||||||
asserts.push_back(make_pair(A, EN));
|
asserts.push_back(make_pair(A, EN));
|
||||||
|
ywmap_asserts.push_back(cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +282,7 @@ struct AigerWriter
|
||||||
unused_bits.erase(A);
|
unused_bits.erase(A);
|
||||||
unused_bits.erase(EN);
|
unused_bits.erase(EN);
|
||||||
assumes.push_back(make_pair(A, EN));
|
assumes.push_back(make_pair(A, EN));
|
||||||
|
ywmap_assumes.push_back(cell);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,6 +856,19 @@ struct AigerWriter
|
||||||
for (auto &it : init_lines)
|
for (auto &it : init_lines)
|
||||||
json.value(it.second);
|
json.value(it.second);
|
||||||
json.end_array();
|
json.end_array();
|
||||||
|
|
||||||
|
json.name("asserts");
|
||||||
|
json.begin_array();
|
||||||
|
for (Cell *cell : ywmap_asserts)
|
||||||
|
json.value(witness_path(cell));
|
||||||
|
json.end_array();
|
||||||
|
|
||||||
|
json.name("assumes");
|
||||||
|
json.begin_array();
|
||||||
|
for (Cell *cell : ywmap_assumes)
|
||||||
|
json.value(witness_path(cell));
|
||||||
|
json.end_array();
|
||||||
|
|
||||||
json.end_object();
|
json.end_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1117,7 +1117,18 @@ struct Smt2Worker
|
||||||
|
|
||||||
string name_a = get_bool(cell->getPort(ID::A));
|
string name_a = get_bool(cell->getPort(ID::A));
|
||||||
string name_en = get_bool(cell->getPort(ID::EN));
|
string name_en = get_bool(cell->getPort(ID::EN));
|
||||||
if (cell->name[0] == '$' && cell->attributes.count(ID::src))
|
bool private_name = cell->name[0] == '$';
|
||||||
|
|
||||||
|
if (!private_name && cell->has_attribute(ID::hdlname)) {
|
||||||
|
for (auto const &part : cell->get_hdlname_attribute()) {
|
||||||
|
if (part == "_witness_") {
|
||||||
|
private_name = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (private_name && cell->attributes.count(ID::src))
|
||||||
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), cell->attributes.at(ID::src).decode_string().c_str()));
|
decls.push_back(stringf("; yosys-smt2-%s %d %s %s\n", cell->type.c_str() + 1, id, get_id(cell), cell->attributes.at(ID::src).decode_string().c_str()));
|
||||||
else
|
else
|
||||||
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell)));
|
decls.push_back(stringf("; yosys-smt2-%s %d %s\n", cell->type.c_str() + 1, id, get_id(cell)));
|
||||||
|
|
|
@ -649,14 +649,20 @@ if aimfile is not None:
|
||||||
num_steps = max(num_steps, step+2)
|
num_steps = max(num_steps, step+2)
|
||||||
step += 1
|
step += 1
|
||||||
|
|
||||||
|
ywfile_hierwitness_cache = None
|
||||||
|
|
||||||
def ywfile_constraints(inywfile, constr_assumes, map_steps=None, skip_x=False):
|
def ywfile_constraints(inywfile, constr_assumes, map_steps=None, skip_x=False):
|
||||||
|
global ywfile_hierwitness_cache
|
||||||
if map_steps is None:
|
if map_steps is None:
|
||||||
map_steps = {}
|
map_steps = {}
|
||||||
|
|
||||||
with open(inywfile, "r") as f:
|
with open(inywfile, "r") as f:
|
||||||
inyw = ReadWitness(f)
|
inyw = ReadWitness(f)
|
||||||
|
|
||||||
inits, seqs, clocks, mems = smt.hierwitness(topmod, allregs=True, blackbox=True)
|
if ywfile_hierwitness_cache is None:
|
||||||
|
ywfile_hierwitness_cache = smt.hierwitness(topmod, allregs=True, blackbox=True)
|
||||||
|
|
||||||
|
inits, seqs, clocks, mems = ywfile_hierwitness_cache
|
||||||
|
|
||||||
smt_wires = defaultdict(list)
|
smt_wires = defaultdict(list)
|
||||||
smt_mems = defaultdict(list)
|
smt_mems = defaultdict(list)
|
||||||
|
|
|
@ -79,6 +79,20 @@ def except_hook(exctype, value, traceback):
|
||||||
sys.excepthook = except_hook
|
sys.excepthook = except_hook
|
||||||
|
|
||||||
|
|
||||||
|
def recursion_helper(iteration, *request):
|
||||||
|
stack = [iteration(*request)]
|
||||||
|
|
||||||
|
while stack:
|
||||||
|
top = stack.pop()
|
||||||
|
try:
|
||||||
|
request = next(top)
|
||||||
|
except StopIteration:
|
||||||
|
continue
|
||||||
|
|
||||||
|
stack.append(top)
|
||||||
|
stack.append(iteration(*request))
|
||||||
|
|
||||||
|
|
||||||
hex_dict = {
|
hex_dict = {
|
||||||
"0": "0000", "1": "0001", "2": "0010", "3": "0011",
|
"0": "0000", "1": "0001", "2": "0010", "3": "0011",
|
||||||
"4": "0100", "5": "0101", "6": "0110", "7": "0111",
|
"4": "0100", "5": "0101", "6": "0110", "7": "0111",
|
||||||
|
@ -298,10 +312,22 @@ class SmtIo:
|
||||||
return stmt
|
return stmt
|
||||||
|
|
||||||
def unroll_stmt(self, stmt):
|
def unroll_stmt(self, stmt):
|
||||||
if not isinstance(stmt, list):
|
result = []
|
||||||
return stmt
|
recursion_helper(self._unroll_stmt_into, stmt, result)
|
||||||
|
return result.pop()
|
||||||
|
|
||||||
stmt = [self.unroll_stmt(s) for s in stmt]
|
def _unroll_stmt_into(self, stmt, output, depth=128):
|
||||||
|
if not isinstance(stmt, list):
|
||||||
|
output.append(stmt)
|
||||||
|
return
|
||||||
|
|
||||||
|
new_stmt = []
|
||||||
|
for s in stmt:
|
||||||
|
if depth:
|
||||||
|
yield from self._unroll_stmt_into(s, new_stmt, depth - 1)
|
||||||
|
else:
|
||||||
|
yield s, new_stmt
|
||||||
|
stmt = new_stmt
|
||||||
|
|
||||||
if len(stmt) >= 2 and not isinstance(stmt[0], list) and stmt[0] in self.unroll_decls:
|
if len(stmt) >= 2 and not isinstance(stmt[0], list) and stmt[0] in self.unroll_decls:
|
||||||
assert stmt[1] in self.unroll_objs
|
assert stmt[1] in self.unroll_objs
|
||||||
|
@ -330,12 +356,19 @@ class SmtIo:
|
||||||
decl[2] = list()
|
decl[2] = list()
|
||||||
|
|
||||||
if len(decl) > 0:
|
if len(decl) > 0:
|
||||||
decl = self.unroll_stmt(decl)
|
tmp = []
|
||||||
|
if depth:
|
||||||
|
yield from self._unroll_stmt_into(decl, tmp, depth - 1)
|
||||||
|
else:
|
||||||
|
yield decl, tmp
|
||||||
|
|
||||||
|
decl = tmp.pop()
|
||||||
self.write(self.unparse(decl), unroll=False)
|
self.write(self.unparse(decl), unroll=False)
|
||||||
|
|
||||||
return self.unroll_cache[key]
|
output.append(self.unroll_cache[key])
|
||||||
|
return
|
||||||
|
|
||||||
return stmt
|
output.append(stmt)
|
||||||
|
|
||||||
def p_thread_main(self):
|
def p_thread_main(self):
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -134,7 +134,6 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
||||||
cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||||
renames.emplace_back(cell, new_id);
|
renames.emplace_back(cell, new_id);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) {
|
if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) {
|
||||||
|
@ -165,6 +164,20 @@ static bool rename_witness(RTLIL::Design *design, dict<RTLIL::Module *, int> &ca
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (cell->type.in(ID($assert), ID($assume), ID($cover), ID($live), ID($fair), ID($check))) {
|
||||||
|
has_witness_signals = true;
|
||||||
|
if (cell->name.isPublic())
|
||||||
|
continue;
|
||||||
|
std::string name = stringf("%s_%s", cell->type.c_str() + 1, cell->name.c_str() + 1);
|
||||||
|
for (auto &c : name)
|
||||||
|
if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_')
|
||||||
|
c = '_';
|
||||||
|
auto new_id = module->uniquify("\\_witness_." + name);
|
||||||
|
renames.emplace_back(cell, new_id);
|
||||||
|
cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (auto rename : renames) {
|
for (auto rename : renames) {
|
||||||
module->rename(rename.first, rename.second);
|
module->rename(rename.first, rename.second);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -ex
|
set -e
|
||||||
|
|
||||||
prefix=${1%.ok}
|
prefix=${1%.ok}
|
||||||
prefix=${prefix%.sv}
|
prefix=${prefix%.sv}
|
||||||
|
@ -58,16 +58,33 @@ generate_sby() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -f $prefix.ys ]; then
|
if [ -f $prefix.ys ]; then
|
||||||
|
set -x
|
||||||
$PWD/../../yosys -q -e "Assert .* failed." -s $prefix.ys
|
$PWD/../../yosys -q -e "Assert .* failed." -s $prefix.ys
|
||||||
elif [ -f $prefix.sv ]; then
|
elif [ -f $prefix.sv ]; then
|
||||||
generate_sby pass > ${prefix}_pass.sby
|
generate_sby pass > ${prefix}_pass.sby
|
||||||
generate_sby fail > ${prefix}_fail.sby
|
generate_sby fail > ${prefix}_fail.sby
|
||||||
sby --yosys $PWD/../../yosys -f ${prefix}_pass.sby
|
|
||||||
sby --yosys $PWD/../../yosys -f ${prefix}_fail.sby
|
# Check that SBY is up to date enough for this yosys version
|
||||||
|
if sby --help | grep -q -e '--status'; then
|
||||||
|
set -x
|
||||||
|
sby --yosys $PWD/../../yosys -f ${prefix}_pass.sby
|
||||||
|
sby --yosys $PWD/../../yosys -f ${prefix}_fail.sby
|
||||||
|
else
|
||||||
|
echo "sva test '${prefix}' requires an up to date SBY, skipping"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
generate_sby pass > ${prefix}.sby
|
generate_sby pass > ${prefix}.sby
|
||||||
sby --yosys $PWD/../../yosys -f ${prefix}.sby
|
|
||||||
|
# Check that SBY is up to date enough for this yosys version
|
||||||
|
if sby --help | grep -q -e '--status'; then
|
||||||
|
set -x
|
||||||
|
sby --yosys $PWD/../../yosys -f ${prefix}.sby
|
||||||
|
else
|
||||||
|
echo "sva test '${prefix}' requires an up to date SBY, skipping"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
{ set +x; } &>/dev/null
|
||||||
|
|
||||||
touch $prefix.ok
|
touch $prefix.ok
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue