mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #1079 from YosysHQ/eddie/fix_read_aiger
Fix read_aiger to really get tested, and fix some uncovered read_aiger issues
This commit is contained in:
commit
7395a80690
|
@ -16,6 +16,7 @@ Yosys 0.8 .. Yosys 0.8-dev
|
||||||
- Added "gate2lut.v" techmap rule
|
- Added "gate2lut.v" techmap rule
|
||||||
- Added "rename -src"
|
- Added "rename -src"
|
||||||
- Added "equiv_opt" pass
|
- Added "equiv_opt" pass
|
||||||
|
- Added "read_aiger" frontend
|
||||||
- "synth_xilinx" to now infer hard shift registers, using new "shregmap -tech xilinx"
|
- "synth_xilinx" to now infer hard shift registers, using new "shregmap -tech xilinx"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -81,11 +81,26 @@ end_of_header:
|
||||||
else
|
else
|
||||||
log_abort();
|
log_abort();
|
||||||
|
|
||||||
|
RTLIL::Wire* n0 = module->wire("\\n0");
|
||||||
|
if (n0)
|
||||||
|
module->connect(n0, RTLIL::S0);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < outputs.size(); ++i) {
|
||||||
|
RTLIL::Wire *wire = outputs[i];
|
||||||
|
if (wire->port_input) {
|
||||||
|
RTLIL::Wire *o_wire = module->addWire(wire->name.str() + "_o");
|
||||||
|
o_wire->port_output = true;
|
||||||
|
wire->port_output = false;
|
||||||
|
module->connect(o_wire, wire);
|
||||||
|
outputs[i] = o_wire;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parse footer (symbol table, comments, etc.)
|
// Parse footer (symbol table, comments, etc.)
|
||||||
unsigned l1;
|
unsigned l1;
|
||||||
std::string s;
|
std::string s;
|
||||||
for (int c = f.peek(); c != EOF; c = f.peek(), ++line_count) {
|
for (int c = f.peek(); c != EOF; c = f.peek(), ++line_count) {
|
||||||
if (c == 'i' || c == 'l' || c == 'o') {
|
if (c == 'i' || c == 'l' || c == 'o' || c == 'b') {
|
||||||
f.ignore(1);
|
f.ignore(1);
|
||||||
if (!(f >> l1 >> s))
|
if (!(f >> l1 >> s))
|
||||||
log_error("Line %u cannot be interpreted as a symbol entry!\n", line_count);
|
log_error("Line %u cannot be interpreted as a symbol entry!\n", line_count);
|
||||||
|
@ -97,11 +112,12 @@ end_of_header:
|
||||||
if (c == 'i') wire = inputs[l1];
|
if (c == 'i') wire = inputs[l1];
|
||||||
else if (c == 'l') wire = latches[l1];
|
else if (c == 'l') wire = latches[l1];
|
||||||
else if (c == 'o') wire = outputs[l1];
|
else if (c == 'o') wire = outputs[l1];
|
||||||
|
else if (c == 'b') wire = bad_properties[l1];
|
||||||
else log_abort();
|
else log_abort();
|
||||||
|
|
||||||
module->rename(wire, stringf("\\%s", s.c_str()));
|
module->rename(wire, stringf("\\%s", s.c_str()));
|
||||||
}
|
}
|
||||||
else if (c == 'b' || c == 'j' || c == 'f') {
|
else if (c == 'j' || c == 'f') {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
else if (c == 'c') {
|
else if (c == 'c') {
|
||||||
|
@ -153,7 +169,7 @@ void AigerReader::parse_aiger_ascii()
|
||||||
unsigned l1, l2, l3;
|
unsigned l1, l2, l3;
|
||||||
|
|
||||||
// Parse inputs
|
// Parse inputs
|
||||||
for (unsigned i = 0; i < I; ++i, ++line_count) {
|
for (unsigned i = 1; i <= I; ++i, ++line_count) {
|
||||||
if (!(f >> l1))
|
if (!(f >> l1))
|
||||||
log_error("Line %u cannot be interpreted as an input!\n", line_count);
|
log_error("Line %u cannot be interpreted as an input!\n", line_count);
|
||||||
log_debug("%d is an input\n", l1);
|
log_debug("%d is an input\n", l1);
|
||||||
|
@ -187,8 +203,10 @@ void AigerReader::parse_aiger_ascii()
|
||||||
if (!(f >> l3))
|
if (!(f >> l3))
|
||||||
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
|
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
|
||||||
|
|
||||||
if (l3 == 0 || l3 == 1)
|
if (l3 == 0)
|
||||||
q_wire->attributes["\\init"] = RTLIL::Const(l3);
|
q_wire->attributes["\\init"] = RTLIL::S0;
|
||||||
|
else if (l3 == 1)
|
||||||
|
q_wire->attributes["\\init"] = RTLIL::S1;
|
||||||
else if (l3 == l1) {
|
else if (l3 == l1) {
|
||||||
//q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
|
//q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +215,7 @@ void AigerReader::parse_aiger_ascii()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// AIGER latches are assumed to be initialized to zero
|
// AIGER latches are assumed to be initialized to zero
|
||||||
q_wire->attributes["\\init"] = RTLIL::Const(0);
|
q_wire->attributes["\\init"] = RTLIL::S0;
|
||||||
}
|
}
|
||||||
latches.push_back(q_wire);
|
latches.push_back(q_wire);
|
||||||
}
|
}
|
||||||
|
@ -212,11 +230,17 @@ void AigerReader::parse_aiger_ascii()
|
||||||
wire->port_output = true;
|
wire->port_output = true;
|
||||||
outputs.push_back(wire);
|
outputs.push_back(wire);
|
||||||
}
|
}
|
||||||
std::getline(f, line); // Ignore up to start of next line
|
|
||||||
|
|
||||||
// TODO: Parse bad state properties
|
// Parse bad properties
|
||||||
for (unsigned i = 0; i < B; ++i, ++line_count)
|
for (unsigned i = 0; i < B; ++i, ++line_count) {
|
||||||
std::getline(f, line); // Ignore up to start of next line
|
if (!(f >> l1))
|
||||||
|
log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
|
||||||
|
|
||||||
|
log_debug("%d is a bad state property\n", l1);
|
||||||
|
RTLIL::Wire *wire = createWireIfNotExists(module, l1);
|
||||||
|
wire->port_output = true;
|
||||||
|
bad_properties.push_back(wire);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Parse invariant constraints
|
// TODO: Parse invariant constraints
|
||||||
for (unsigned i = 0; i < C; ++i, ++line_count)
|
for (unsigned i = 0; i < C; ++i, ++line_count)
|
||||||
|
@ -290,8 +314,10 @@ void AigerReader::parse_aiger_binary()
|
||||||
if (!(f >> l3))
|
if (!(f >> l3))
|
||||||
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
|
log_error("Line %u cannot be interpreted as a latch!\n", line_count);
|
||||||
|
|
||||||
if (l3 == 0 || l3 == 1)
|
if (l3 == 0)
|
||||||
q_wire->attributes["\\init"] = RTLIL::Const(l3);
|
q_wire->attributes["\\init"] = RTLIL::S0;
|
||||||
|
else if (l3 == 1)
|
||||||
|
q_wire->attributes["\\init"] = RTLIL::S1;
|
||||||
else if (l3 == l1) {
|
else if (l3 == l1) {
|
||||||
//q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
|
//q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
|
||||||
}
|
}
|
||||||
|
@ -300,7 +326,7 @@ void AigerReader::parse_aiger_binary()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// AIGER latches are assumed to be initialized to zero
|
// AIGER latches are assumed to be initialized to zero
|
||||||
q_wire->attributes["\\init"] = RTLIL::Const(0);
|
q_wire->attributes["\\init"] = RTLIL::S0;
|
||||||
}
|
}
|
||||||
latches.push_back(q_wire);
|
latches.push_back(q_wire);
|
||||||
}
|
}
|
||||||
|
@ -317,8 +343,17 @@ void AigerReader::parse_aiger_binary()
|
||||||
}
|
}
|
||||||
std::getline(f, line); // Ignore up to start of next line
|
std::getline(f, line); // Ignore up to start of next line
|
||||||
|
|
||||||
// TODO: Parse bad state properties
|
// Parse bad properties
|
||||||
for (unsigned i = 0; i < B; ++i, ++line_count)
|
for (unsigned i = 0; i < B; ++i, ++line_count) {
|
||||||
|
if (!(f >> l1))
|
||||||
|
log_error("Line %u cannot be interpreted as a bad state property!\n", line_count);
|
||||||
|
|
||||||
|
log_debug("%d is a bad state property\n", l1);
|
||||||
|
RTLIL::Wire *wire = createWireIfNotExists(module, l1);
|
||||||
|
wire->port_output = true;
|
||||||
|
bad_properties.push_back(wire);
|
||||||
|
}
|
||||||
|
if (B > 0)
|
||||||
std::getline(f, line); // Ignore up to start of next line
|
std::getline(f, line); // Ignore up to start of next line
|
||||||
|
|
||||||
// TODO: Parse invariant constraints
|
// TODO: Parse invariant constraints
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct AigerReader
|
||||||
std::vector<RTLIL::Wire*> inputs;
|
std::vector<RTLIL::Wire*> inputs;
|
||||||
std::vector<RTLIL::Wire*> latches;
|
std::vector<RTLIL::Wire*> latches;
|
||||||
std::vector<RTLIL::Wire*> outputs;
|
std::vector<RTLIL::Wire*> outputs;
|
||||||
|
std::vector<RTLIL::Wire*> bad_properties;
|
||||||
|
|
||||||
AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name);
|
AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name);
|
||||||
void parse_aiger();
|
void parse_aiger();
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
aig 3 2 0 1 1
|
|
||||||
6
|
|
||||||
|
|
|
@ -3,3 +3,6 @@ aag 3 2 0 1 1
|
||||||
4
|
4
|
||||||
6
|
6
|
||||||
6 2 4
|
6 2 4
|
||||||
|
i0 pi0
|
||||||
|
i1 pi1
|
||||||
|
o0 po0
|
|
@ -0,0 +1,5 @@
|
||||||
|
aig 3 2 0 1 1
|
||||||
|
6
|
||||||
|
i0 pi0
|
||||||
|
i1 pi1
|
||||||
|
o0 po0
|
|
@ -1,3 +1,5 @@
|
||||||
aag 1 1 0 1 0
|
aag 1 1 0 1 0
|
||||||
2
|
2
|
||||||
2
|
2
|
||||||
|
i0 pi0
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
aig 1 1 0 1 0
|
aig 1 1 0 1 0
|
||||||
2
|
2
|
||||||
|
i0 pi0
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
aag 1 0 1 0 0 1
|
aag 1 0 1 0 0 1
|
||||||
2 3
|
2 3
|
||||||
2
|
2
|
||||||
|
b0 po0
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
aig 1 0 1 0 0 1
|
aig 1 0 1 0 0 1
|
||||||
3
|
3
|
||||||
2
|
2
|
||||||
|
b0 po0
|
||||||
|
|
|
@ -6,3 +6,4 @@ aag 5 1 1 0 3 1
|
||||||
8 4 2
|
8 4 2
|
||||||
10 9 7
|
10 9 7
|
||||||
b0 AIGER_NEVER
|
b0 AIGER_NEVER
|
||||||
|
i0 po0
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
aig 5 1 1 0 3 1
|
aig 5 1 1 0 3 1
|
||||||
10
|
10
|
||||||
4
|
4
|
||||||
b0 AIGER_NEVER
|
i0 po0
|
||||||
|
b0 AIGER_NEVER
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
aag 0 0 0 1 0
|
aag 0 0 0 1 0
|
||||||
0
|
0
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
aig 0 0 0 1 0
|
aig 0 0 0 1 0
|
||||||
0
|
0
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
aag 1 1 0 1 0
|
aag 1 1 0 1 0
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
|
i0 pi0
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
aig 1 1 0 1 0
|
aig 1 1 0 1 0
|
||||||
3
|
3
|
||||||
|
i0 pi0
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -6,3 +6,4 @@ aag 5 1 1 0 3 1
|
||||||
8 4 2
|
8 4 2
|
||||||
10 9 7
|
10 9 7
|
||||||
b0 AIGER_NEVER
|
b0 AIGER_NEVER
|
||||||
|
i0 pi0
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
aig 5 1 1 0 3 1
|
aig 5 1 1 0 3 1
|
||||||
10
|
10
|
||||||
5
|
5
|
||||||
b0 AIGER_NEVER
|
i0 pi0
|
||||||
|
b0 AIGER_NEVER
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
aig 3 2 0 1 1
|
|
||||||
7
|
|
||||||
|
|
|
@ -3,3 +3,6 @@ aag 3 2 0 1 1
|
||||||
4
|
4
|
||||||
7
|
7
|
||||||
6 3 5
|
6 3 5
|
||||||
|
i0 pi0
|
||||||
|
i1 pi1
|
||||||
|
o0 po0
|
|
@ -0,0 +1,5 @@
|
||||||
|
aig 3 2 0 1 1
|
||||||
|
7
|
||||||
|
i0 pi0
|
||||||
|
i1 pi1
|
||||||
|
o0 po0
|
|
@ -1,24 +1,37 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
OPTIND=1
|
set -e
|
||||||
seed="" # default to no seed specified
|
|
||||||
while getopts "S:" opt
|
for aag in *.aag; do
|
||||||
do
|
# Since ABC cannot read *.aag, read the *.aig instead
|
||||||
case "$opt" in
|
# (which would have been created by the reference aig2aig utility)
|
||||||
S) arg="${OPTARG#"${OPTARG%%[![:space:]]*}"}" # remove leading space
|
../../yosys-abc -c "read -c ${aag%.*}.aig; write ${aag%.*}_ref.v"
|
||||||
seed="SEED=$arg" ;;
|
../../yosys -p "
|
||||||
esac
|
read_verilog ${aag%.*}_ref.v
|
||||||
|
prep
|
||||||
|
design -stash gold
|
||||||
|
read_aiger -clk_name clock $aag
|
||||||
|
prep
|
||||||
|
design -stash gate
|
||||||
|
design -import gold -as gold
|
||||||
|
design -import gate -as gate
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -show-ports -seq 16 miter
|
||||||
|
"
|
||||||
done
|
done
|
||||||
shift "$((OPTIND-1))"
|
|
||||||
|
|
||||||
# check for Icarus Verilog
|
for aig in *.aig; do
|
||||||
if ! which iverilog > /dev/null ; then
|
../../yosys-abc -c "read -c $aig; write ${aig%.*}_ref.v"
|
||||||
echo "$0: Error: Icarus Verilog 'iverilog' not found."
|
../../yosys -p "
|
||||||
exit 1
|
read_verilog ${aig%.*}_ref.v
|
||||||
fi
|
prep
|
||||||
|
design -stash gold
|
||||||
echo "===== AAG ======"
|
read_aiger -clk_name clock $aig
|
||||||
${MAKE:-make} -f ../tools/autotest.mk $seed *.aag EXTRA_FLAGS="-f aiger"
|
prep
|
||||||
|
design -stash gate
|
||||||
echo "===== AIG ======"
|
design -import gold -as gold
|
||||||
exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.aig EXTRA_FLAGS="-f aiger"
|
design -import gate -as gate
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -show-ports -seq 16 miter
|
||||||
|
"
|
||||||
|
done
|
||||||
|
|
|
@ -2,3 +2,5 @@ aag 1 0 1 2 0
|
||||||
2 3
|
2 3
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
|
o0 po0
|
||||||
|
o1 po1
|
||||||
|
|
|
@ -2,3 +2,5 @@ aig 1 0 1 2 0
|
||||||
3
|
3
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
|
o0 po0
|
||||||
|
o1 po1
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
aag 0 0 0 1 0
|
aag 0 0 0 1 0
|
||||||
1
|
1
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
aig 0 0 0 1 0
|
aig 0 0 0 1 0
|
||||||
1
|
1
|
||||||
|
o0 po0
|
||||||
|
|
|
@ -146,9 +146,10 @@ do
|
||||||
rm -f ${bn}_ref.fir
|
rm -f ${bn}_ref.fir
|
||||||
if [[ "$ext" == "v" ]]; then
|
if [[ "$ext" == "v" ]]; then
|
||||||
egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext}
|
egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext}
|
||||||
|
elif [[ "$ext" == "aig" ]] || [[ "$ext" == "aag" ]]; then
|
||||||
|
"$toolsdir"/../../yosys-abc -c "read_aiger ../${fn}; write ${bn}_ref.v"
|
||||||
else
|
else
|
||||||
"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "verilog" -o ${bn}_ref.v ../${fn}
|
cp ../${fn} ${bn}_ref.${ext}
|
||||||
frontend="verilog -noblackbox"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f ../${bn}_tb.v ]; then
|
if [ ! -f ../${bn}_tb.v ]; then
|
||||||
|
|
Loading…
Reference in New Issue