singrdk/base/Applications/Benchmarks/sharpSAT/blifparser.cs

430 lines
16 KiB
C#

///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
using System.Collections;
using System.Text;
using System.IO;
using System;
//using Microsoft.Zap;
namespace SharpSAT
{
public class NetConst
{
public const int PI_MASK = 1;
public const int PO_MASK = (1 << 1);
public const int LATCH_OUT_MASK = (1 << 2);
public const int LATCH_IN_MASK = (1 << 3);
public const int COMB_MASK = (1 << 4);
//private NetConst() {}
}
public enum ELatchDefault
{
LATCH_0 = 0,
LATCH_1 = 1,
LATCH_DC = 2,
LATCH_X = 3
};
public enum EGateType
{
G_UNKNOWN,
G_NOT, //o = a'
G_AND_11, //o = ab
G_AND_10, //o = ab'
G_AND_01, //o = a'b
G_AND_00, //o = a'b'
G_OR_11, //o = a+b
G_OR_10, //o = a+b'
G_OR_01, //o = a'+b
G_OR_00, //o = a'+b'
G_CONST_1,
G_CONST_0,
G_WIRE,
};
public class Gate
{
public int index = -1;
public EGateType gate_type = EGateType.G_UNKNOWN;
public string name;
public IntVector fanins = new IntVector(2);
public IntVector fanouts = new IntVector(2);
public int type ;
public ELatchDefault latch_default ;
public ObjVector fanin_names = new ObjVector(1);
public bool is_PI() { return ((type & NetConst.PI_MASK) != 0); }
public bool is_PO() { return ((type & NetConst.PO_MASK) != 0); }
public bool is_LATCH_IN() { return ((type & NetConst.LATCH_IN_MASK) != 0); }
public bool is_LATCH() { return ((type & NetConst.LATCH_OUT_MASK) != 0); }
public bool is_COMB() { return ((type & NetConst.COMB_MASK) != 0); }
public void set_PI() { type |= NetConst.PI_MASK; }
public void set_PO() { type |= NetConst.PO_MASK; }
public void set_LATCH_IN() { type |= NetConst.LATCH_IN_MASK; }
public void set_LATCH() { type |= NetConst.LATCH_OUT_MASK; }
public void set_COMB() { type |= NetConst.COMB_MASK; }
}
class NetList : SATCommon
{
public string name;
public ObjVector nodes = new ObjVector(128);
public IntVector primary_inputs = new IntVector(4);
public IntVector primary_outputs = new IntVector(4);
public IntVector latches = new IntVector(4);
public IntVector combs = new IntVector(4);
public IntVector inputs = new IntVector(4); //include PI and latch's outputs
public IntVector outputs = new IntVector(4); //include PO and latch's inputs
public MyHashtable name2nodeid = new MyHashtable();
public Gate node (int k)
{
return (Gate)nodes[k];
}
Gate new_node(string name)
{
Gate node = new Gate();
node.name = name;;
node.index = nodes.size();
nodes.push_back(node);
name2nodeid[name] = node.index;
return node;
}
Gate find_node_by_name(string name)
{
object o = name2nodeid[name];
if (o == null)
return null;
else
return (Gate)nodes[(int)o];
}
Gate create_pi(string name)
{
Gate n;
if ( (n = find_node_by_name(name)) != null)
{
sharp_assert (n.is_PI());
return n;
}
n = new_node(name);
n.set_PI();
return n;
}
Gate create_po(string name)
{
Gate n;
if ((n = find_node_by_name(name)) == null)
n = new_node(name);
n.set_PO();
return n;
}
Gate create_latch(string latch_in, string latch_out, ELatchDefault deft)
{
Gate n;
if ((n = find_node_by_name(latch_out)) == null)
n = new_node(latch_out);
//int id = n.index;
sharp_assert (n.fanin_names.empty());
n.fanin_names.push_back(latch_in);
n.latch_default = deft;
n.set_LATCH();
return n;
}
Gate create_comb(string name, string [] inputs)
{
Gate n;
if ( (n = find_node_by_name(name)) == null)
n = new_node(name);
//int id = n.index;
sharp_assert (n.fanin_names.empty());
foreach (string s in inputs)
n.fanin_names.push_back(s);
n.set_COMB();
return n;
}
static string get_multiple_line (StreamReader input)
{
string line = null;
StringBuilder str = new StringBuilder();
while (true)
{
try
{
line = input.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
fatal();
}
if (line == null)
return null;
if (line.IndexOf('\\') == -1)
{
str.Append(line);
return str.ToString();
}
else
str.Append(line.Replace('\\',' '));
}
}
void finalize_construct_network()
{
for ( int i=0; i< nodes.size(); ++i)
{
Gate n = node(i);
for ( int j=0; j< n.fanin_names.size(); ++j)
{
string name = (string)n.fanin_names[j];
Gate pin = find_node_by_name(name);
sharp_assert (pin != null);
n.fanins.push_back(pin.index);
pin.fanouts.push_back(n.index);
if (n.is_LATCH())
pin.set_LATCH_IN();
}
}
for ( int i=0; i< nodes.size(); ++i)
{
Gate n = node(i);
if (n.is_PI())
primary_inputs.push_back(n.index);
if (n.is_PI() || n.is_LATCH())
inputs.push_back(n.index);
if (n.is_PO())
primary_outputs.push_back(n.index);
if (n.is_PO() || n.is_LATCH_IN())
outputs.push_back(n.index);
if (n.is_LATCH())
latches.push_back(n.index);
if (n.is_COMB())
combs.push_back(n.index);
}
}
public void read_blif (string filename)
{
StreamReader input = null;
ObjVector lines = new ObjVector(128);
try
{
input = new StreamReader(filename);
}
catch (Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
fatal();
}
while (true)
{
string line = get_multiple_line(input);
if (line == null)
break;
lines.push_back(line);
if (line == ".end")
break;
}
for ( int i=0; i< lines.size(); ++i)
{
string line = (string)lines[i];
string [] temp_tokens = line.Split(new char[] {' ','\t'});
int total_tokens = 0;
foreach (string str in temp_tokens)
if (str != String.Empty)
++ total_tokens;
if (total_tokens == 0)
continue;
string [] tokens = new string[total_tokens];
foreach (string str in temp_tokens)
{
if (str != String.Empty)
{
tokens[tokens.Length - total_tokens] = str;
-- total_tokens;
}
}
string first_token = tokens[0];
if (first_token == ".model")
{
this.name = tokens[1];
}
else if (first_token == ".inputs")
{
for ( int k=1; k< tokens.Length; ++k)
create_pi(tokens[k]);
}
else if (first_token == ".outputs")
{
for ( int k=1; k< tokens.Length; ++k)
create_po(tokens[k]);
}
else if (first_token == ".latch")
{
sharp_assert (tokens.Length == 3 || tokens.Length == 4);
ELatchDefault dft_v = ELatchDefault.LATCH_X;
if (tokens.Length == 4)
{
string last_token = tokens[3];
sharp_assert (last_token.Length == 1);
dft_v = (ELatchDefault) Int32.Parse(last_token);
}
create_latch(tokens[1], tokens[2], dft_v);
}
else if (first_token == ".names")
{
string [] inputs = new string [tokens.Length - 2];
sharp_assert (inputs.Length == 1 || inputs.Length == 2);
string name = tokens[tokens.Length - 1];
for ( int k=1; k< tokens.Length - 1; ++k)
inputs[k-1] = tokens[k];
Gate node = create_comb(name, inputs);
if ((string)lines[i+1] == "1 1" &&
(string)lines[i+2] == "0 1" )
{
node.gate_type = EGateType.G_CONST_1;
i+=2;
}
else if ((string)lines[i+1] == "1 1")
{
warning ("A gate is a wire, sweep first ");
node.gate_type = EGateType.G_WIRE; ++ i;
}
else if ((string)lines[i+1] == "0 1")
{
node.gate_type = EGateType.G_NOT; ++ i;
}
else if ((string)lines[i+1] == "11 1")
{
node.gate_type = EGateType.G_AND_11; ++ i;
}
else if ((string)lines[i+1] == "10 1")
{
node.gate_type = EGateType.G_AND_10; ++ i;
}
else if ((string)lines[i+1] == "01 1")
{
node.gate_type = EGateType.G_AND_01; ++ i;
}
else if ((string)lines[i+1] == "00 1")
{
node.gate_type = EGateType.G_AND_00; ++ i;
}
else if ((string)lines[i+1] == "0- 1" &&
(string)lines[i+2] == "-0 1")
{
node.gate_type = EGateType.G_OR_00; i+=2;
}
else if ((string)lines[i+1] == "0- 1" &&
(string)lines[i+2] == "-1 1")
{
node.gate_type = EGateType.G_OR_01; i+=2;
}
else if ((string)lines[i+1] == "1- 1" &&
(string)lines[i+2] == "-0 1")
{
node.gate_type = EGateType.G_OR_10; i+=2;
}
else if ((string)lines[i+1] == "1- 1" &&
(string)lines[i+2] == "-1 1")
{
node.gate_type = EGateType.G_OR_11; i+=2;
}
else
{
fatal ("Don't know gate type for " + line);
}
sharp_assert ( ((string)lines[i+1])[0] == '.');
}
else if (first_token == ".end")
{
break;
}
else if (first_token == ".wire_load_slope")
{
warning("Warning: Ignoring " + first_token);
}
else if (first_token[0] == '.')
{
fatal (first_token + ": Unable to handle this keyword");
}
}
finalize_construct_network();
}
public void write_blif(string filename)
{
StreamWriter outfile = new StreamWriter(filename);
outfile.WriteLine ( ".model " + this.name );
outfile.Write ( ".inputs" );
for ( int i=0; i< primary_inputs.size(); ++i)
outfile.Write ( " " + node(primary_inputs[i]).name) ;
outfile.WriteLine ();
outfile.Write ( ".outputs" );
for ( int i=0; i< primary_outputs.size(); ++i)
outfile.Write ( " " + node(primary_outputs[i]).name) ;
outfile.WriteLine ();
for ( int i=0; i< latches.size(); ++i)
{
Gate n = node(latches[i]);
outfile.WriteLine ( ".latch " + node(n.fanins[0]).name + " " + n.name + " " + (int) n.latch_default );
}
for ( int i=0; i< combs.size(); ++i)
{
Gate n = node(combs[i]);
outfile.Write ( ".names");
for ( int j=0; j< n.fanins.size(); ++j)
outfile.Write ( " " + node(n.fanins[j]).name);
outfile.WriteLine (" " + n.name );
if (n.gate_type == EGateType.G_NOT)
outfile.WriteLine ( "0 1" );
else if (n.gate_type == EGateType.G_AND_11)
outfile.WriteLine ( "11 1" );
else if (n.gate_type == EGateType.G_AND_10)
outfile.WriteLine ( "10 1" );
else if (n.gate_type == EGateType.G_AND_01)
outfile.WriteLine ( "01 1" );
else if (n.gate_type == EGateType.G_AND_00)
outfile.WriteLine ( "00 1" );
else if (n.gate_type == EGateType.G_OR_11)
outfile.WriteLine ( "1- 1" + '\n' + "-1 1" );
else if (n.gate_type == EGateType.G_OR_10)
outfile.WriteLine ( "1- 1" + '\n' + "-0 1" );
else if (n.gate_type == EGateType.G_OR_01)
outfile.WriteLine ( "0- 1" + '\n' + "-1 1" );
else if (n.gate_type == EGateType.G_OR_00)
outfile.WriteLine ( "0- 1" + '\n' + "-0 1" );
// else if (n.gate_type == EGateType.G_EQUAL)
// outfile.WriteLine ( "11 1" + '\n' + "00 1" );
else if (n.gate_type == EGateType.G_CONST_1)
outfile.WriteLine ( "1 1" + '\n' + "0 1" );
else if (n.gate_type == EGateType.G_WIRE)
outfile.WriteLine ( "1 1" + '\n' + "0 0" );
else
fatal ("Unknown gate type" );
}
outfile.WriteLine ( ".end" );
outfile.Close();
}
}
}