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:
Clifford Wolf 2019-06-07 23:13:34 +02:00 committed by GitHub
commit 7395a80690
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 128 additions and 45 deletions

View File

@ -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"

View File

@ -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

View File

@ -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();

View File

@ -1,3 +0,0 @@
aig 3 2 0 1 1
6


View File

@ -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

5
tests/aiger/and_.aig Normal file
View File

@ -0,0 +1,5 @@
aig 3 2 0 1 1
6
i0 pi0
i1 pi1
o0 po0

View File

@ -1,3 +1,5 @@
aag 1 1 0 1 0 aag 1 1 0 1 0
2 2
2 2
i0 pi0
o0 po0

View File

@ -1,2 +1,4 @@
aig 1 1 0 1 0 aig 1 1 0 1 0
2 2
i0 pi0
o0 po0

View File

@ -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

View File

@ -1,3 +1,4 @@
aig 1 0 1 0 0 1 aig 1 0 1 0 0 1
3 3
2 2
b0 po0

View File

@ -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

View File

@ -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

View File

@ -1,2 +1,3 @@
aag 0 0 0 1 0 aag 0 0 0 1 0
0 0
o0 po0

View File

@ -1,2 +1,3 @@
aig 0 0 0 1 0 aig 0 0 0 1 0
0 0
o0 po0

View File

@ -1,3 +1,5 @@
aag 1 1 0 1 0 aag 1 1 0 1 0
2 2
3 3
i0 pi0
o0 po0

View File

@ -1,2 +1,4 @@
aig 1 1 0 1 0 aig 1 1 0 1 0
3 3
i0 pi0
o0 po0

View File

@ -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

View File

@ -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

View File

@ -1,3 +0,0 @@
aig 3 2 0 1 1
7


View File

@ -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

5
tests/aiger/or_.aig Normal file
View File

@ -0,0 +1,5 @@
aig 3 2 0 1 1
7
i0 pi0
i1 pi1
o0 po0

View File

@ -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

View File

@ -2,3 +2,5 @@ aag 1 0 1 2 0
2 3 2 3
2 2
3 3
o0 po0
o1 po1

View File

@ -2,3 +2,5 @@ aig 1 0 1 2 0
3 3
2 2
3 3
o0 po0
o1 po1

View File

@ -1,2 +1,3 @@
aag 0 0 0 1 0 aag 0 0 0 1 0
1 1
o0 po0

View File

@ -1,2 +1,3 @@
aig 0 0 0 1 0 aig 0 0 0 1 0
1 1
o0 po0

View File

@ -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