mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	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
					
				
					 27 changed files with 128 additions and 45 deletions
				
			
		|  | @ -16,6 +16,7 @@ Yosys 0.8 .. Yosys 0.8-dev | |||
|     - Added "gate2lut.v" techmap rule | ||||
|     - Added "rename -src" | ||||
|     - Added "equiv_opt" pass | ||||
|     - Added "read_aiger" frontend | ||||
|     - "synth_xilinx" to now infer hard shift registers, using new "shregmap -tech xilinx" | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -81,11 +81,26 @@ end_of_header: | |||
|     else | ||||
|         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.)
 | ||||
|     unsigned l1; | ||||
|     std::string s; | ||||
|     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); | ||||
|             if (!(f >> l1 >> s)) | ||||
|                 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]; | ||||
|             else if (c == 'l') wire = latches[l1]; | ||||
|             else if (c == 'o') wire = outputs[l1]; | ||||
|             else if (c == 'b') wire = bad_properties[l1]; | ||||
|             else log_abort(); | ||||
| 
 | ||||
|             module->rename(wire, stringf("\\%s", s.c_str())); | ||||
|         } | ||||
|         else if (c == 'b' || c == 'j' || c == 'f') { | ||||
|         else if (c == 'j' || c == 'f') { | ||||
|             // TODO
 | ||||
|         } | ||||
|         else if (c == 'c') { | ||||
|  | @ -153,7 +169,7 @@ void AigerReader::parse_aiger_ascii() | |||
|     unsigned l1, l2, l3; | ||||
| 
 | ||||
|     // Parse inputs
 | ||||
|     for (unsigned i = 0; i < I; ++i, ++line_count) { | ||||
|     for (unsigned i = 1; i <= I; ++i, ++line_count) { | ||||
|         if (!(f >> l1)) | ||||
|             log_error("Line %u cannot be interpreted as an input!\n", line_count); | ||||
|         log_debug("%d is an input\n", l1); | ||||
|  | @ -187,8 +203,10 @@ void AigerReader::parse_aiger_ascii() | |||
|             if (!(f >> l3)) | ||||
|                 log_error("Line %u cannot be interpreted as a latch!\n", line_count); | ||||
| 
 | ||||
|             if (l3 == 0 || l3 == 1) | ||||
|                 q_wire->attributes["\\init"] = RTLIL::Const(l3); | ||||
|             if (l3 == 0) | ||||
|                 q_wire->attributes["\\init"] = RTLIL::S0; | ||||
|             else if (l3 == 1) | ||||
|                 q_wire->attributes["\\init"] = RTLIL::S1; | ||||
|             else if (l3 == l1) { | ||||
|                 //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
 | ||||
|             } | ||||
|  | @ -197,7 +215,7 @@ void AigerReader::parse_aiger_ascii() | |||
|         } | ||||
|         else { | ||||
|             // 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); | ||||
|     } | ||||
|  | @ -212,11 +230,17 @@ void AigerReader::parse_aiger_ascii() | |||
|         wire->port_output = true; | ||||
|         outputs.push_back(wire); | ||||
|     } | ||||
|     std::getline(f, line); // Ignore up to start of next line
 | ||||
| 
 | ||||
|     // TODO: Parse bad state properties
 | ||||
|     for (unsigned i = 0; i < B; ++i, ++line_count) | ||||
|         std::getline(f, line); // Ignore up to start of next line
 | ||||
|     // Parse bad properties
 | ||||
|     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); | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Parse invariant constraints
 | ||||
|     for (unsigned i = 0; i < C; ++i, ++line_count) | ||||
|  | @ -290,8 +314,10 @@ void AigerReader::parse_aiger_binary() | |||
|             if (!(f >> l3)) | ||||
|                 log_error("Line %u cannot be interpreted as a latch!\n", line_count); | ||||
| 
 | ||||
|             if (l3 == 0 || l3 == 1) | ||||
|                 q_wire->attributes["\\init"] = RTLIL::Const(l3); | ||||
|             if (l3 == 0) | ||||
|                 q_wire->attributes["\\init"] = RTLIL::S0; | ||||
|             else if (l3 == 1) | ||||
|                 q_wire->attributes["\\init"] = RTLIL::S1; | ||||
|             else if (l3 == l1) { | ||||
|                 //q_wire->attributes["\\init"] = RTLIL::Const(RTLIL::State::Sx);
 | ||||
|             } | ||||
|  | @ -300,7 +326,7 @@ void AigerReader::parse_aiger_binary() | |||
|         } | ||||
|         else { | ||||
|             // 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); | ||||
|     } | ||||
|  | @ -317,8 +343,17 @@ void AigerReader::parse_aiger_binary() | |||
|     } | ||||
|     std::getline(f, line); // Ignore up to start of next line
 | ||||
| 
 | ||||
|     // TODO: Parse bad state properties
 | ||||
|     for (unsigned i = 0; i < B; ++i, ++line_count) | ||||
|     // Parse bad properties
 | ||||
|     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
 | ||||
| 
 | ||||
|     // TODO: Parse invariant constraints
 | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ struct AigerReader | |||
|     std::vector<RTLIL::Wire*> inputs; | ||||
|     std::vector<RTLIL::Wire*> latches; | ||||
|     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); | ||||
|     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 | ||||
| 6 | ||||
| 6 2 4 | ||||
| i0 pi0 | ||||
| i1 pi1 | ||||
| o0 po0 | ||||
							
								
								
									
										5
									
								
								tests/aiger/and_.aig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/aiger/and_.aig
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
| 2 | ||||
| 2 | ||||
| i0 pi0 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -1,2 +1,4 @@ | |||
| aig 1 1 0 1 0 | ||||
| 2 | ||||
| i0 pi0 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| aag 1 0 1 0 0 1 | ||||
| 2 3 | ||||
| 2 | ||||
| b0 po0 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| aig 1 0 1 0 0 1 | ||||
| 3 | ||||
| 2 | ||||
| b0 po0 | ||||
|  |  | |||
|  | @ -6,3 +6,4 @@ aag 5 1 1 0 3 1 | |||
| 8 4 2 | ||||
| 10 9 7 | ||||
| b0 AIGER_NEVER | ||||
| i0 po0 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| aig 5 1 1 0 3 1 | ||||
| 10 | ||||
| 4 | ||||
| b0 AIGER_NEVER | ||||
| i0 po0 | ||||
| b0 AIGER_NEVER | ||||
|  |  | |||
|  | @ -1,2 +1,3 @@ | |||
| aag 0 0 0 1 0 | ||||
| 0 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -1,2 +1,3 @@ | |||
| aig 0 0 0 1 0 | ||||
| 0 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| aag 1 1 0 1 0 | ||||
| 2 | ||||
| 3 | ||||
| i0 pi0 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -1,2 +1,4 @@ | |||
| aig 1 1 0 1 0 | ||||
| 3 | ||||
| i0 pi0 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -6,3 +6,4 @@ aag 5 1 1 0 3 1 | |||
| 8 4 2 | ||||
| 10 9 7 | ||||
| b0 AIGER_NEVER | ||||
| i0 pi0 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| aig 5 1 1 0 3 1 | ||||
| 10 | ||||
| 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 | ||||
| 7 | ||||
| 6 3 5 | ||||
| i0 pi0 | ||||
| i1 pi1 | ||||
| o0 po0 | ||||
							
								
								
									
										5
									
								
								tests/aiger/or_.aig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/aiger/or_.aig
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| aig 3 2 0 1 1 | ||||
| 7 | ||||
| i0 pi0 | ||||
| i1 pi1 | ||||
| o0 po0 | ||||
|  | @ -1,24 +1,37 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| OPTIND=1 | ||||
| seed=""    # default to no seed specified | ||||
| while getopts "S:" opt | ||||
| do | ||||
|     case "$opt" in | ||||
| 	S) arg="${OPTARG#"${OPTARG%%[![:space:]]*}"}" # remove leading space | ||||
| 	   seed="SEED=$arg" ;; | ||||
|     esac | ||||
| set -e | ||||
| 
 | ||||
| for aag in *.aag; do | ||||
|     # Since ABC cannot read *.aag, read the *.aig instead | ||||
|     # (which would have been created by the reference aig2aig utility) | ||||
|     ../../yosys-abc -c "read -c ${aag%.*}.aig; write ${aag%.*}_ref.v" | ||||
|     ../../yosys -p " | ||||
| 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 | ||||
| shift "$((OPTIND-1))" | ||||
| 
 | ||||
| # check for Icarus Verilog | ||||
| if ! which iverilog > /dev/null ; then | ||||
|   echo "$0: Error: Icarus Verilog 'iverilog' not found." | ||||
|   exit 1 | ||||
| fi | ||||
| 
 | ||||
| echo "===== AAG ======" | ||||
| ${MAKE:-make} -f ../tools/autotest.mk $seed *.aag EXTRA_FLAGS="-f aiger" | ||||
| 
 | ||||
| echo "===== AIG ======" | ||||
| exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.aig EXTRA_FLAGS="-f aiger" | ||||
| for aig in *.aig; do | ||||
|     ../../yosys-abc -c "read -c $aig; write ${aig%.*}_ref.v" | ||||
|     ../../yosys -p " | ||||
| read_verilog ${aig%.*}_ref.v | ||||
| prep | ||||
| design -stash gold | ||||
| read_aiger -clk_name clock $aig | ||||
| 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 | ||||
|  |  | |||
|  | @ -2,3 +2,5 @@ aag 1 0 1 2 0 | |||
| 2 3 | ||||
| 2 | ||||
| 3 | ||||
| o0 po0 | ||||
| o1 po1 | ||||
|  |  | |||
|  | @ -2,3 +2,5 @@ aig 1 0 1 2 0 | |||
| 3 | ||||
| 2 | ||||
| 3 | ||||
| o0 po0 | ||||
| o1 po1 | ||||
|  |  | |||
|  | @ -1,2 +1,3 @@ | |||
| aag 0 0 0 1 0 | ||||
| 1 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -1,2 +1,3 @@ | |||
| aig 0 0 0 1 0 | ||||
| 1 | ||||
| o0 po0 | ||||
|  |  | |||
|  | @ -146,9 +146,10 @@ do | |||
| 		rm -f ${bn}_ref.fir | ||||
| 		if [[ "$ext" == "v" ]]; then | ||||
| 			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 | ||||
| 			"$toolsdir"/../../yosys -f "$frontend $include_opts" -b "verilog" -o ${bn}_ref.v ../${fn} | ||||
| 			frontend="verilog -noblackbox" | ||||
| 			cp ../${fn} ${bn}_ref.${ext} | ||||
| 		fi | ||||
| 
 | ||||
| 		if [ ! -f ../${bn}_tb.v ]; then | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue