DEF to Verilog Script  Go To Script Pool

# Please feel free to modify this script as you see fit.
# I hereby release it to the public domain. If you make significant
# modifications, please email me a copy at rex@arl.wustl.edu
# or send cookies.
#
# This script converts a DEF-format netlist to a Verilog-format netlist.
# It discards the following information:
# CREATETIME
# SAVETIME
# UNITS
# HISTORY
# VIAS
# COMPONENT PLACED data
# NET ROUTED data
#
# The converter does not (yet) handle explicit PIN statements in the
# DEF file to determine the pins in a design. (Cell3 doesn't seem to
# output them in the DEF file). Instead, it looks for names without a
# hierarchy separator in them. This is apparently how the ASPEC
# tools determine pins as well. You can change the hierarchy separator
# character in the first line of the script below.
#
# Note that the converter also relies on a consistent naming of inputs
# and outputs for cells instantiated in the design. For the ASPEC
# TSMC library, the following regular expressions match the pin names
# for the following directions:
#Output from cell: / [YQ][N]* /
# Tristate from cell: / Z[N]* /
# Pad cell I/O: / PAD /
# Input to cell: (everything else - fall through case)
#
# If a net connects to a PAD, a second direction resolution is run to
# decide what type of pad is driving it. If the script finds / TN / in the
# attached instance's final component binding list, the pad is tristateable.
# Similarly, the script may find a / A / or / Y / for output and input
# pads. Note that a pad can be both I/O if it has all three types in its
# instance list. Specifically, I set the type of any pad to inout if it is
# tristateable.

$hierarchySeparator = '\|';

# Get the DEF file name
$defFileName = $ARGV[0];
($vlogFileName = $defFileName) =~ s/.def/.v/;
print("Converting $defFileName to $vlogFileName\n");
open(DEFFILE,$defFileName);
open(VLOGFILE,">".$vlogFileName);

$| = 1;
$linenum = 0;
$totalnets = 0;
$done = 0;
while($done == 0) {
$theline = <DEFFILE>;
$linenum++;
if($theline =~ /^END DESIGN/) {
$done = 1;
} elsif($theline =~ /^DESIGN/) {
&ParseDesign($theline);
} elsif($theline =~ /^COMPONENTS/) {
&ParseComponents($theline);
} elsif($theline =~ /^SPECIALNETS/) {
&ParseNets($theline);
} elsif($theline =~ /^NETS/) {
&ParseNets($theline);
}
}

&ResolvePADDirections();

&WriteVerilogHeader();
&WriteDefs("u");
&WriteDefs("input");
&WriteDefs("output");
&WriteDefs("inout");
&WriteDefs("wire");

&WriteComponents();

&WriteVerilogTrailer();

close(DEFFILE);
close(VLOGFILE);

#------------------------ Subroutines ----------------------
sub ParseDesign {
local($theline) = @_;

($type,$designname,$rest) = split(/\s+/,$theline);
print(" Design name: $designname\n");
}

# This function scans through the file, looking
# at each component in the design. It builds
# an associative array of components indexed
# by component instance names.
sub ParseComponents {
local($theline) = @_;
local($i);

# Set the line separator to ;
$/ = ";";
# Find out how many components we should have
($type,$numcomponents,$rest) = split(/\s+/,$theline);
print(" Number of components: $numcomponents\n");
# Read in each component
for($i=0;$i<$numcomponents;$i++) {
$theline = <DEFFILE>;
if($theline =~ /END/) {
print("Error: END line found - $theline\n");
exit(-1);
}
&ParseSingleComponent($theline);
}
# Set the line separator back to newline
$/ = "\n";
print(" Done parsing components\n");
}

# This function parses a line to find a component
# declaration.
#
# The component should be of the form
# - <instname> <compname> +.*
#
# The component names are stored in an associative
# array indexed by the instance name for each component
sub ParseSingleComponent {
local($theline) = @_;
$theline =~ s/\s*-\s*//;
($instname,$compname) = split(/\s+/,$theline);
$comparray{$instname} = $compname.":";
}

# This function walks through the DEF file, looking at
# each net in a NETS section. It adds nets to the
# $comparray associative array as a string indicating
# that the net is bound to that component. In addition,
# it builds a nets array that will allow us to declare
# wires in the Verilog file.
# XXX SHOULD it do a binding from ORIGINALS?
sub ParseNets {
local($theline) = @_;
local($i);

# Set the line separator to ;
$/ = ";";
# Find out how many nets we should have
($type,$numnets,$rest) = split(/\s+/,$theline);
$totalnets = $totalnets + $numnets;
print(" Number of nets: $numnets\n");
print(" Total number of nets so far: $totalnets\n");
# Read in each net
for($i=0;$i<$numnets;$i++) {
$theline = <DEFFILE>;
if($theline =~ /END/) {
print("Error: END [SPECIAL]NETS line found - $theline\n");
exit(-1);
}
&ParseSingleNet($theline);
}
# Set the line separator back to newline
$/ = "\n";
print(" Done parsing nets\n");
}

# This function parses a line and extracts the connections for
# each net, adding them to the list of connections in the
# associative %comparray. Each %comparray entry is composed
# of a component type, a colon, and a comma-separated list of
# .PIN(netname) pairs.
sub ParseSingleNet {
local($theline) = @_;
local($i);
local($pinname,$driven,$sinked,$tristate,$unresolved);

# Set the net to neither driven nor sinked. We can
# then decipher the direction of the pin:
# Driven - output
# Sinked - input
# Driven and sinked - wire
# Driventristate - inout
$driven = 0; $sinked = 0; $tristate = 0; $unresolved = 0;

# Remove all newlines from the line (remember that
# it was a multi-line string because the input record
# separator was ';'.
$theline =~ s/\n//g;


# Remove the initial "-" character
$theline =~ s/^\s*\-\s*//;

# Remove everything after the first "+" character
$theline =~ s/\+.*//;

# The line now consists of a net name followed by
# a list of (component pin) pairs.
# Separate the line into an array by splitting on the
# '(' character. The first element in the array
# will be the netname and the other elements will be
# pin bindings.
@bindings = split(/\(/,$theline);
($netname = $bindings[0]) =~ s/\s+//g;

if($netname =~ "VDD" || $netname =~ "VSS") {
# Do nothing - power or ground net.
} else {
# Parse each pin binding
for($i=1;$i<=$#bindings;$i++) {
$pinname = &ParseSinglePinBinding($netname,$bindings[$i]);
$pinarray{$pinname} = 1;
if($netname =~ /$hierarchySeparator/) {
# This is not a top-level net name, so set the
# type to "w" (wire).
$netarray{$netname} = "wire";
} else {
# This is a top-level net name, so decide whether
# it is an input/output/bidirect/unresolved.
if($bindings[$i] =~ / [YQ][N]* / ) {
$driven = 1;
}
if($bindings[$i] =~ / A /) {
$sinked = 1;
}
if($bindings[$i] =~ / Z[N]* /) {
$tristate = 1;
}
if($bindings[$i] =~ / PAD /) {
$unresolved = 1;
}
}
}
if(!($netname =~ /$hierarchySeparator/)) {
if($unresolved) {
$netarray{$netname} = "u";
if($driven) {
printf("ERROR: net $netname attached to PAD is also driven\n
");
exit(-1);
}
if($tristate) {
printf("ERROR: net $netname attached to PAD is also tristate
\n");
exit(-1);
}
if($sinked) {
printf("ERROR: net $netname attached to PAD is also sinked\n
");
exit(-1);
}
} elsif($tristate) {
$netarray{$netname} = "inout";
} elsif($driven) {
$netarray{$netname} = "output";
} elsif($sinked) {
$netarray{$netname} = "input";
} else {
printf("ERROR: net $netname is not used anywhere!\n");
exit(-1);
}
}
}
}

sub ParseSinglePinBinding {
local($netname,$binding) = @_;
local($pinname);

# Remove leading whitespace
$binding =~ s/^\s+//;
# Split the instance name from the pin name
($instname,$pinname) = split(/\s+/,$binding);
if($comparray{$instname} eq "") {
print("ERROR: can't find instance $instname referenced by net $netname\n
");
exit(-1);
} else {
$comparray{$instname} = $comparray{$instname}.",.$pinname(\\$netname )";
}
return $pinname;
}

# For every component in the design, find the net that connects to its
# PAD pin. It should still be unresolved ("u") in the %netarray array.
# Find whether the pad we're looking at is an input, output, or inout
# and set the %netarray entry to "input", "output", or "inout".


sub ResolvePADDirections {
print(" Resolving PAD directions\n");
foreach $instname (keys(%comparray)) {
if($comparray{$instname} =~ /\.PAD/) {
# This is a pad in the instance array.
# Determine the type of pad.
if($comparray{$instname} =~ /\.TN/) {
$direction = "inout";
} elsif($comparray{$instname} =~ /\.Y/) {
$direction = "input";
} elsif($comparray{$instname} =~ /\.A/) {
$direction = "output";
} else {
print("ERROR: unable to determine direction of pad $instname\n")
;
}
($netname = $comparray{$instname}) =~ s/.*.PAD\(([^)]+).*/\1/;
$netname =~ s/\s+//;
$netname =~ s/\\//;
print(" Resolving net $netname: $direction\n");
if($netarray{$netname} ne "u") {
print("ERROR: $netname was already resolved to $netarray{$netnam
e}\n");
} else {
$netarray{$netname} = $direction;
}
}
}
print(" Done resolving\n");
}

# This function prints out the module definition
# with all inputs and outputs in it.
sub WriteVerilogHeader {
local($i);

# Print the module declaration
print(VLOGFILE "module $designname(\n");
# Build a non-associative array of all the non-wire
# elements in the net array. These should be the
# inputs, outputs, and bidirects.
$i = 0;
foreach $wirename (sort(keys(%netarray))) {
if(!($netarray{$wirename} eq "wire")) {
$ioarray[$i] = $wirename;
$i++;
}
}
# Now that we have the non-associative array, we can
# print the comma-separated list of I/Os without
# a trailing comma.
for($i=0;$i<$#ioarray;$i++) {
print(VLOGFILE " $ioarray[$i],\n");
}
print(VLOGFILE " $ioarray[$#ioarray]\n");
print(VLOGFILE " );\n");
}

# This function prints out all the wires in the
# module.
sub WriteDefs {
local($wiretype) = @_;

foreach $wirename (keys(%netarray)) {
if($netarray{$wirename} eq $wiretype) {
print(VLOGFILE "$wiretype \\$wirename ;\n");
}
}
}

# This function walks through the %comparray component
# array and prints out the component type, instance
# name, and the pin bindings for each component.
sub WriteComponents {
local($i);

foreach $instname (keys(%comparray)) {
@instarray = split(/,/,$comparray{$instname});
($typename = $instarray[0]) =~ s/://;
print(VLOGFILE "$typename \\$instname (\n");
for($i=1;$i<$#instarray;$i++) {
print(VLOGFILE " $instarray[$i],\n");
}
print(VLOGFILE " $instarray[$#instarray]\n");
print(VLOGFILE " );\n");
}
}

sub WriteVerilogTrailer {
print(VLOGFILE "endmodule\n");
}

 

Other Scripts:

Batch Simulation
Convert
bullet.gif (859 bytes) Def2Verilog
Gen XOR Tree
GetValue
IHEX2VHEX
nand tree
Name Instance
OnesCompSum
Preprocessor
Verilog Tag

Verilog Tag2
Verilog2DEF
VHDL2HTML
VRename
XNF2VHDL

 

Products:

Undertow Suite
Undertow
Interactive_tool
Optimizing_tool
VeriPower
Power_tool
Toggle_tool
Express_VCT
Personal_VCT
VBIT«
verilog2vhdl™
vhdl2verilogmkt
Script Pool


 

 Company    Products     News    Assistance     Download     Contact Us    Sales

Veritools, Inc.
459 Hamilton Avenue, Suite 200, Palo Alto, California 94301
(650) 462 - 5590 Main    (650) 462 - 5593 Fax
inquiry@veritools.com

For Web site information please email Webmaster