I need help with this particular .pl file I picked up from http://www.veritools-usa.com/xnf2vhdl.htm
What it's supposed to do is really convert an xnf file to a vhdl file. I need it for my fpga design work.
I tried rectifying the errors that occurred - added the semicolon in line 459 , removed the brackets in line 460 and aligned the 'line' word in line 274 .
This removed the compiler errors but I'm unsure of what exactly to do now. I tried placing a xnf file in the same folder as the pl script and then running the pl on command. This didn't work. Could anybody please explain to me the process for executing this program successfully?
Thanks so much,
Code.pl :::
Expand|Select|Wrap|Line Numbers
- # This perl script takes an XNF netlist and returns a VHDL architecture
- # containing a series of continuous assignments and clocked-register
- # instantiations that implement the same function specified in the
- # XNF netlist. This tool is useful when you're not sure whether
- # Xilinx spit out the correct synthesis result, and you want to
- # simulate the resulting code against your VHDL behavioral code.
- # ################################################
- # Open the XVF file. Hey Rex! Make this a bit more
- # pleasant, OK?
- $xnffilename = $ARGV[0];
- $hackfilename = $ARGV[1];
- # ################################################
- # Read in all signals and figure out which are internal and which
- # are external. Build signal definitions for all internal signals.
- &BuildSignalList($xnffilename);
- # Print the architecture header
- $archfilename = $xnffilename;
- $archfilename =~ s/\.xnf/_netlist.vhd/;
- open(ARCHFILE,"> ".$archfilename);
- &PrintHeader($archfilename);
- &PrintSignals();
- &HackSignals($hackfilename);
- &PrintNetlist($xnffilename);
- &PrintAliases($xnffilename);
- &HackNetlist($hackfilename);
- &PrintTrailer($archfilename);
- # #################################################
- # Clean up after yourself...
- # #################################################
- # Some useful subroutines
Expand|Select|Wrap|Line Numbers
- sub BuildSignalList {
- local($xnffilename) = @_;
- open(XNFFILE,$xnffilename);
- while($theline = <XNFFILE>) {
- # If the line has a PIN declaration, go to work
- if(($theline =~ /^PIN/) && !($theline =~ /\$\$/)) {
- # For each PIN declaration, split to find the name
- ($type, $formal, $direction, $name) = split(/,/,$theline);
- # Remove spaces and newlines and $ signs
- $name =~ s/[ \n]+//g;
- # If the name has a < in it, it's a bus of some sort
- if($name =~ /\</) {
- # Split the name out from the bit indicator
- ($name,$size) = split(/</,$name);
- # Hack the > off the end of the bit indicator
- $size =~ s/>//;
- # Add 1 to it, because we want the number of pins
- $size = $size + 1;
- # Check to see if the name is in the assiociative array
- if($namearray{$name} eq "") {
- # If not, put it there with the current size estimate
- $namearray{$name} = $size;
- }
- else {
- # If it's already in, check to see if the new pin
- # uses a larger bit indicator than the currently
- # stored one.
- if($namearray{$name} < $size) {
- # If this is a higher pin number, put that in
- # the associative array as the new size estimate
- $namearray{$name} = $size;
- }
- }
- }
- else {
- # For single-bit buses, set the associative array entry
- # to 1.
- if($namearray{$name} eq "") {
- $namearray{$name} = 1;
- }
- }
- }
Expand|Select|Wrap|Line Numbers
- # If the line contains a SYM declaration with a BOUNDS
- # directive, use the bounds to set the highest bit number for the
- # bus.
- if($theline =~ /^SYM/) {
- if($theline =~ /BUS_DEF/) {
- # Find the name and the bounds directive in the line
- ($type, $name, $blocktype, $def, $bounds) = split(/,/,$theline);
- # Clean up the name
- $name =~ s/[ \n]+//g;
- # Clean up the bounds directive and find the upper and lower
- $bounds =~ s/[\=a-zA-Z]+//g;
- ($left, $right) = split(/:/,$bounds);
- if($left > $right) {
- $aliasarray{$name} = $left + 1;
- }
- else {
- $aliasarray{$name} = $right + 1;
- }
- }
- }
- # If the line contains an EXT declaration, store it in
- # the EXT array, with size.
- if($theline =~ /^EXT/) {
- # For each EXT declaration, split to find the name
- ($type, $name, $direction) = split(/,/,$theline);
- # Remove spaces and newlines
- $name =~ s/[ \n]+//g;
- # If the name has a < in it, it's a bus of some sort
- if($name =~ /\</) {
- # Split the name out from the bit indicator
- ($name,$size) = split(/</,$name);
- # Hack the > off the end of the bit indicator
- $size =~ s/>//;
- # Add 1 to it, because we want the number of pins
- $size = $size + 1;
- # Check to see if the name is in the assiociative array
- if($extarray{$name} eq "") {
- # If not, put it there with the current size estimate
- $extarray{$name} = $size;
- }
- else {
- # If it's already in, check to see if the new pin
- # uses a larger bit indicator than the currently
- # stored one.
- if($extarray{$name} < $size) {
- # If this is a higher pin number, put that in
- # the associative array as the new size estimate
- $extarray{$name} = $size;
- }
- }
- }
- else {
- # For single-bit buses, set the associative array entry
- # to 1.
- $extarray{$name} = 1;
- }
- }
- }
- # foreach $name (sort(keys(%namearray))) {
- # if($extarray{$name} eq "") {
- # printf("PIN: %s\t%d\n",$name,$namearray{$name});
- # }
- # }
- # foreach $name (sort(keys(%extarray))) {
- # printf("EXT: %s\t%d\n",$name,$extarray{$name});
- # }
- close(XNFFILE);
- }
Expand|Select|Wrap|Line Numbers
- sub PrintHeader {
- local($archfilename) = @_;
- ($entname, $archname) = split(/_/,$archfilename);
- $archname =~ s/\.vhd//;
- printf(ARCHFILE "library lib;\n");
- printf(ARCHFILE "use ieee.std_logic_arith.all;\n");
- printf(ARCHFILE "\n");
- printf(ARCHFILE "architecture %s of %s is\n",$archname,$entname);
- printf(ARCHFILE "\n");
- }
- sub PrintSignals {
- foreach $signal (sort(keys(%namearray))) {
- if(($extarray{$signal} eq "") && ($aliasarray{$signal} eq "")) {
- if($namearray{$signal} == 1) {
- printf(ARCHFILE "signal %s:std_logic;\n",$signal);
- }
- else {
- printf(ARCHFILE "signal %s:std_logic_vector(%d downto %d);\n",
- $signal, $namearray{$signal}-1, 0);
- }
- }
- }
- foreach $signal (sort(keys(%aliasarray))) {
- if($aliasarray{$signal} ne "") {
- printf(ARCHFILE "signal %s:std_logic_vector(%d downto %d);\n",
- $signal, $aliasarray{$signal}-1, 0);
- }
- }
- }
- sub PrintAliases {
- local($xnffilename) = @_;
- # Start building the list signals for each alias we'll need.
- foreach $signal (sort(keys(%aliasarray))) {
- $aliaselement{$signal} = "";
- }
- open(XNFFILE,$xnffilename);
- # For each SYM block found in the file, convert it into a corresponding
- # function.
- while($theline = <XNFFILE>) {
- # Look for a symbol instantiation
- if($theline =~ /^SYM/) {
- ($sym, $name, $type) = split(/,/,$theline);
- $type =~ s/[ \n]+//g;
- if($type eq "ELEMENT") {
- &AddElement($theline);
- }
- }
- }
- # Start building the list signals for each alias we'll need.
- foreach $signal (sort(keys(%aliasarray))) {
- &PrintAlias($signal);
- }
- close(XNFFILE);
- }
- sub PrintNetlist {
- local($xnffilename) = @_;
- printf(ARCHFILE "\nbegin\n");
- printf(ARCHFILE " VCC <= '1';\n");
- printf(ARCHFILE " GND <= '0';\n");
- open(XNFFILE,$xnffilename);
- # For each SYM block found in the file, convert it into a corresponding
- # function.
- while($theline = <XNFFILE>) {
- # Look for a symbol instantiation
- if($theline =~ /^SYM/) {
- ($sym, $name, $type) = split(/,/,$theline);
- $type =~ s/[ \n]+//g;
- if($type eq "AND") {
- &PrintGATE($theline,"and");
- }
- if($type eq "OR") {
- &PrintGATE($theline,"or");
- }
- if($type eq "BUFGP") {
- &PrintBUF($theline,"");
- }
- if($type eq "INV") {
- &PrintBUF($theline,"not");
- }
- if($type eq "OBUF") {
- &PrintBUF($theline,"");
- }
- if($type eq "IBUF") {
- &PrintBUF($theline,"");
- }
- if($type eq "OBUFT") {
- &PrintOBUFT($theline);
- }
- if($type eq "DFF") {
- &PrintDFF($theline,0);
- }
- if($type eq "OUTFFT") {
- &PrintDFF($theline,1);
- }
- if($type eq "ADD_SUB") {
- &PrintADDSUB($theline);
- }
- if($type eq "COMPARE") {
- &PrintCOMPARE($theline);
- }
- }
- }
- close(XNFFILE);
- }
Expand|Select|Wrap|Line Numbers
- sub PrintGATE {
- local($theline,$optype) = @_;
- local(%inputarray,$output);
- $done = 0;
- %inputarray = ();
- while(!$done) {
- $theline = <XNFFILE>;
- $theline =~ s/[ \n]+//g;
- if($theline =~ /END/) {
- $done = 1;
- }
- else {
- $invert = "NORM";
- ($pin, $formal, $direction, $name,$blank,$invert) = split(/,/,$theline);
- $name = &FixName($name);
- if($direction eq "I") {
- if($invert eq "INV") {
- $inputarray{$name} = -1;
- }
- else {
- $inputarray{$name} = 1;
- }
- }
- else {
- $output = $name;
- }
- }
- }
- printf(ARCHFILE " %s <=",$output);
- $firstprinted = 0;
- foreach $input (sort(keys(%inputarray))) {
- if($firstprinted) {
- printf(ARCHFILE " and");
- }
- else {
- $firstprinted = 1;
- }
- if($inputarray{$input} == -1) {
- printf(ARCHFILE " not");
- }
- printf(ARCHFILE " %s",$input);
- }
- printf(ARCHFILE ";\n");
- }
- sub PrintBUF {
- local($theline,$optype) = @_;
- local($input,$output);
- $done = 0;
- while(!$done) {
- $theline = <XNFFILE>;
- $theline =~ s/[ \n]+//g;
- if($theline =~ /END/) {
- $done = 1;
- }
- else {
- ($pin, $formal, $direction, $name) = split(/,/,$theline);
- $name = &FixName($name);
- if($direction eq "I") {
- $input = $name;
- }
- else {
- $output = $name;
- }
- }
- }
- printf(ARCHFILE " %s <=",$output);
- printf(ARCHFILE " %s",$optype);
- printf(ARCHFILE " %s",$input);
- printf(ARCHFILE ";\n");
- }
- sub PrintOBUFT {
- local($theline) = @_;
- local($input,$output,$tristate);
- $done = 0;
- while(!$done) {
- $theline = <XNFFILE>;
- $theline =~ s/[ \n]+//g;
- if($theline =~ /END/) {
- $done = 1;
- }
- else {
- ($pin, $formal, $direction, $name) = split(/,/,$theline);
- $name = &FixName($name);
- if($formal eq "I") {
- $input = $name;
- }
- if($formal eq "O") {
- $output = $name;
- }
- if($formal eq "T") {
- $tristate = $name;
- }
- }
- }
- printf(ARCHFILE " %s <= %s when %s = '0' else 'Z'",$output,$input,$tristate
- );
- printf(ARCHFILE ";\n");
- }
Expand|Select|Wrap|Line Numbers
- sub PrintDFF {
- local($theline,$tristateable) = @_;
- local($input,$output,$clock,$tristate);
- $done = 0;
- while(!$done) {
- $theline = <XNFFILE>;
- $theline =~ s/[ \n]+//g;
- if($theline =~ /END/) {
- $done = 1;
- }
- else {
- ($pin, $formal, $direction, $name) = split(/,/,$theline);
- $name = &FixName($name);
- if($formal eq "D") {
- $input = $name;
- }
- if(($formal eq "Q") || ($formal eq "O")) {
- $output = $name;
- }
- if($formal eq "C") {
- $clock = $name;
- }
- if($formal eq "T") {
- $tristate = $name;
- }
- }
- }
- printf(ARCHFILE "process begin\n");
- printf(ARCHFILE " wait until %s'event and %s = '1';\n",$clock,$clock);
- if($tristateable) {
- printf(ARCHFILE " if(%s = '0') then %s <= %s; else %s <= 'Z'; end if;\n
- ",
- $tristate, $output, $input,
- $output);
- }
- else {
- printf(ARCHFILE " %s <= %s;\n",$output,$input);
- }
- printf(ARCHFILE "end process;\n");
- }
- sub PrintADDSUB {
- local($theline) = @_;
- local($inputa,$inputb,$output);
- $done = 0;
- while(!$done) {
- $theline = <XNFFILE>;
- $theline =~ s/[ \n]+//g;
- if($theline =~ /END/) {
- $done = 1;
- }
- else {
- ($pin, $formal, $direction, $name) = split(/,/,$theline);
- $name = &FixName($name);
- if($formal eq "A") {
- $inputa = $name;
- }
- if($formal eq "B") {
- $inputb = $name;
- }
- if($formal eq "FUNC") {
- $output = $name;
- }
- }
- }
- printf(ARCHFILE " %s <= %s + %s;\n",$output,$inputa,$inputb);
- }
- sub PrintCOMPARE {
- local($theline) = @_;
- local($inputa,$inputb,$output);
- $done = 0;
- while(!$done) {
- $theline = <XNFFILE>;
- $theline =~ s/[ \n]+//g;
- if($theline =~ /END/) {
- $done = 1;
- }
- else {
- ($pin, $formal, $direction, $name) = split(/,/,$theline);
- $name = &FixName($name);
- if($formal eq "A") {
- $inputa = $name;
- }
- if($formal eq "B") {
- $inputb = $name;
- }
- if($formal eq "A_EQ_B") {
- $output = $name;
- }
- }
- }
- printf(ARCHFILE " %s <= '1' when %s = %s else '0';\n",$output,$inputa,$inputb);
- }
- sub AddElement {
- local($theline) = @_;
- local($busname,$signame);
- $done = 0;
- # Extract the element number from the first line
- ($sym, $name, $type, $def, $elemnum) = split(/,/,$theline);
- $elemnum =~ s/[ =ELEM]+//g;
- # Find the bus name and the individual signal name
- while(!$done) {
- $theline = <XNFFILE>;
- $theline =~ s/[ \n]+//g;
- if($theline =~ /END/) {
- $done = 1;
- }
- else {
- ($pin, $formal, $direction, $name) = split(/,/,$theline);
- $name = &FixName($name);
- if($formal eq "XBLOX_BUS") {
- $busname = $name;
- }
- if($formal eq "ELEM") {
- $signame = $name;
- }
- }
- }
- # If the signal name is just the bus-ripped version of the bus name,
- # clear the list. It will be deleted and no alias will be constructed.
- # If the signal name is different, add it to the list.
- if($signame =~ /\(/) {
- $aliaselement{$busname} = "";
- }
- else {
- $aliaselement{$busname} = $aliaselement{$busname} .
- $signame . "," . $elemnum . ":";
- }
- }
- sub PrintAlias {
- local($signal) = @_;
- local($busname,$signame);
- $elementlist = $aliaselement{$signal};
- if($elementlist ne "") {
- @elementarray = split(/:/,$elementlist);
- @sortedelement = ();
- for($i=0; $i<=$#elementarray; $i=$i+1) {
- ($element,$elemnum) = split(/,/,$elementarray[$i]);
- $sortedelement[$elemnum] = $element;
- }
- printf(ARCHFILE " %s <= (",$signal,$aliasarray{$signal});
- for($i=$#sortedelement; $i>=1; $i=$i-1) {
- printf(ARCHFILE "%s & ",$sortedelement[$i]);
- }
- printf(ARCHFILE "%s);\n",$sortedelement[0]);
- }
- }
- sub FixName {
- local($name) = @_;
- $name =~ s/\</\(/;
- $name =~ s/\>/\)/;
- $name =~ s/\$+//;
- return $name;
- }
- sub PrintTrailer {
- local($archfilename) = @_;
- ($entname, $archname) = split(/_/,$archfilename);
- $archname =~ s/\.vhd//;
- printf(ARCHFILE "\n");
- printf(ARCHFILE "end %s;\n",$archname);
- }
- sub HackSignals {
- local($hackfilename) = @_;
- open(HACKFILE,$hackfilename);
- while($theline = <HACKFILE>) {
- if($theline =~ /^signal/) {
- printf(ARCHFILE "%s",$theline);
- }
- }
- close(HACKFILE);
- }
- sub HackNetlist {
- local($hackfilename) = @_;
- open(HACKFILE,$hackfilename);
- while($theline = <HACKFILE>) {
- if($theline =~ /<=/) {
- printf(ARCHFILE "%s",$theline);
- }
- }
- close(HACKFILE);