By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,760 Members | 1,630 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,760 IT Pros & Developers. It's quick & easy.

Help with a .pl file

P: 1
Hello All,
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
  1. # This perl script takes an XNF netlist and returns a VHDL architecture
  2. # containing a series of continuous assignments and clocked-register
  3. # instantiations that implement the same function specified in the
  4. # XNF netlist. This tool is useful when you're not sure whether
  5. # Xilinx spit out the correct synthesis result, and you want to
  6. # simulate the resulting code against your VHDL behavioral code.
  7.  
  8. # ################################################
  9. # Open the XVF file. Hey Rex! Make this a bit more
  10. # pleasant, OK?
  11. $xnffilename = $ARGV[0];
  12. $hackfilename = $ARGV[1];
  13.  
  14. # ################################################
  15. # Read in all signals and figure out which are internal and which
  16. # are external. Build signal definitions for all internal signals.
  17. &BuildSignalList($xnffilename);
  18. # Print the architecture header
  19. $archfilename = $xnffilename;
  20. $archfilename =~ s/\.xnf/_netlist.vhd/;
  21. open(ARCHFILE,"> ".$archfilename);
  22. &PrintHeader($archfilename);
  23. &PrintSignals();
  24. &HackSignals($hackfilename);
  25. &PrintNetlist($xnffilename);
  26. &PrintAliases($xnffilename);
  27. &HackNetlist($hackfilename);
  28. &PrintTrailer($archfilename);
  29.  
  30. # #################################################
  31. # Clean up after yourself...
  32.  
  33. # #################################################
  34. # Some useful subroutines
  35.  
Expand|Select|Wrap|Line Numbers
  1. sub BuildSignalList {
  2. local($xnffilename) = @_;
  3.  
  4. open(XNFFILE,$xnffilename);
  5. while($theline = <XNFFILE>) {
  6. # If the line has a PIN declaration, go to work
  7. if(($theline =~ /^PIN/) && !($theline =~ /\$\$/)) {
  8. # For each PIN declaration, split to find the name
  9. ($type, $formal, $direction, $name) = split(/,/,$theline);
  10. # Remove spaces and newlines and $ signs
  11. $name =~ s/[ \n]+//g;
  12. # If the name has a < in it, it's a bus of some sort
  13. if($name =~ /\</) {
  14. # Split the name out from the bit indicator
  15. ($name,$size) = split(/</,$name);
  16. # Hack the > off the end of the bit indicator
  17. $size =~ s/>//;
  18. # Add 1 to it, because we want the number of pins
  19. $size = $size + 1;
  20. # Check to see if the name is in the assiociative array
  21. if($namearray{$name} eq "") {
  22. # If not, put it there with the current size estimate
  23. $namearray{$name} = $size;
  24. }
  25. else {
  26. # If it's already in, check to see if the new pin
  27. # uses a larger bit indicator than the currently
  28. # stored one.
  29. if($namearray{$name} < $size) {
  30. # If this is a higher pin number, put that in
  31. # the associative array as the new size estimate
  32. $namearray{$name} = $size;
  33. }
  34. }
  35. }
  36. else {
  37. # For single-bit buses, set the associative array entry
  38. # to 1.
  39. if($namearray{$name} eq "") {
  40. $namearray{$name} = 1;
  41. }
  42. }
  43. }
  44.  
Expand|Select|Wrap|Line Numbers
  1. # If the line contains a SYM declaration with a BOUNDS
  2. # directive, use the bounds to set the highest bit number for the
  3. # bus.
  4. if($theline =~ /^SYM/) {
  5. if($theline =~ /BUS_DEF/) {
  6. # Find the name and the bounds directive in the line
  7. ($type, $name, $blocktype, $def, $bounds) = split(/,/,$theline);
  8. # Clean up the name
  9. $name =~ s/[ \n]+//g;
  10. # Clean up the bounds directive and find the upper and lower
  11. $bounds =~ s/[\=a-zA-Z]+//g;
  12. ($left, $right) = split(/:/,$bounds);
  13. if($left > $right) {
  14. $aliasarray{$name} = $left + 1;
  15. }
  16. else {
  17. $aliasarray{$name} = $right + 1;
  18. }
  19. }
  20. }
  21. # If the line contains an EXT declaration, store it in
  22. # the EXT array, with size.
  23. if($theline =~ /^EXT/) {
  24. # For each EXT declaration, split to find the name
  25. ($type, $name, $direction) = split(/,/,$theline);
  26. # Remove spaces and newlines
  27. $name =~ s/[ \n]+//g;
  28. # If the name has a < in it, it's a bus of some sort
  29. if($name =~ /\</) {
  30. # Split the name out from the bit indicator
  31. ($name,$size) = split(/</,$name);
  32. # Hack the > off the end of the bit indicator
  33. $size =~ s/>//;
  34. # Add 1 to it, because we want the number of pins
  35. $size = $size + 1;
  36. # Check to see if the name is in the assiociative array
  37. if($extarray{$name} eq "") {
  38. # If not, put it there with the current size estimate
  39. $extarray{$name} = $size;
  40. }
  41. else {
  42. # If it's already in, check to see if the new pin
  43. # uses a larger bit indicator than the currently
  44. # stored one.
  45. if($extarray{$name} < $size) {
  46. # If this is a higher pin number, put that in
  47. # the associative array as the new size estimate
  48. $extarray{$name} = $size;
  49. }
  50. }
  51. }
  52. else {
  53. # For single-bit buses, set the associative array entry
  54. # to 1.
  55. $extarray{$name} = 1;
  56. }
  57. }
  58. }
  59. # foreach $name (sort(keys(%namearray))) {
  60. # if($extarray{$name} eq "") {
  61. # printf("PIN: %s\t%d\n",$name,$namearray{$name});
  62. # }
  63. # }
  64. # foreach $name (sort(keys(%extarray))) {
  65. # printf("EXT: %s\t%d\n",$name,$extarray{$name});
  66. # }
  67. close(XNFFILE);
  68. }
  69.  
Expand|Select|Wrap|Line Numbers
  1. sub PrintHeader {
  2. local($archfilename) = @_;
  3.  
  4. ($entname, $archname) = split(/_/,$archfilename);
  5. $archname =~ s/\.vhd//;
  6. printf(ARCHFILE "library lib;\n");
  7. printf(ARCHFILE "use ieee.std_logic_arith.all;\n");
  8. printf(ARCHFILE "\n");
  9. printf(ARCHFILE "architecture %s of %s is\n",$archname,$entname);
  10. printf(ARCHFILE "\n");
  11. }
  12.  
  13. sub PrintSignals {
  14. foreach $signal (sort(keys(%namearray))) {
  15. if(($extarray{$signal} eq "") && ($aliasarray{$signal} eq "")) {
  16. if($namearray{$signal} == 1) {
  17. printf(ARCHFILE "signal %s:std_logic;\n",$signal);
  18. }
  19. else {
  20. printf(ARCHFILE "signal %s:std_logic_vector(%d downto %d);\n",
  21. $signal, $namearray{$signal}-1, 0);
  22. }
  23. }
  24. }
  25. foreach $signal (sort(keys(%aliasarray))) {
  26. if($aliasarray{$signal} ne "") {
  27. printf(ARCHFILE "signal %s:std_logic_vector(%d downto %d);\n",
  28. $signal, $aliasarray{$signal}-1, 0);
  29. }
  30. }
  31. }
  32.  
  33. sub PrintAliases {
  34. local($xnffilename) = @_;
  35.  
  36. # Start building the list signals for each alias we'll need.
  37. foreach $signal (sort(keys(%aliasarray))) {
  38. $aliaselement{$signal} = "";
  39. }
  40. open(XNFFILE,$xnffilename);
  41. # For each SYM block found in the file, convert it into a corresponding
  42. # function.
  43. while($theline = <XNFFILE>) {
  44. # Look for a symbol instantiation
  45. if($theline =~ /^SYM/) {
  46. ($sym, $name, $type) = split(/,/,$theline);
  47. $type =~ s/[ \n]+//g;
  48. if($type eq "ELEMENT") {
  49. &AddElement($theline);
  50. }
  51. }
  52. }
  53. # Start building the list signals for each alias we'll need.
  54. foreach $signal (sort(keys(%aliasarray))) {
  55. &PrintAlias($signal);
  56. }
  57. close(XNFFILE);
  58. }
  59.  
  60. sub PrintNetlist {
  61. local($xnffilename) = @_;
  62.  
  63. printf(ARCHFILE "\nbegin\n");
  64. printf(ARCHFILE " VCC <= '1';\n");
  65. printf(ARCHFILE " GND <= '0';\n");
  66. open(XNFFILE,$xnffilename);
  67. # For each SYM block found in the file, convert it into a corresponding
  68. # function.
  69. while($theline = <XNFFILE>) {
  70. # Look for a symbol instantiation
  71. if($theline =~ /^SYM/) {
  72. ($sym, $name, $type) = split(/,/,$theline);
  73. $type =~ s/[ \n]+//g;
  74. if($type eq "AND") {
  75. &PrintGATE($theline,"and");
  76. }
  77. if($type eq "OR") {
  78. &PrintGATE($theline,"or");
  79. }
  80. if($type eq "BUFGP") {
  81. &PrintBUF($theline,"");
  82. }
  83. if($type eq "INV") {
  84. &PrintBUF($theline,"not");
  85. }
  86. if($type eq "OBUF") {
  87. &PrintBUF($theline,"");
  88. }
  89. if($type eq "IBUF") {
  90. &PrintBUF($theline,"");
  91. }
  92. if($type eq "OBUFT") {
  93. &PrintOBUFT($theline);
  94. }
  95. if($type eq "DFF") {
  96. &PrintDFF($theline,0);
  97. }
  98. if($type eq "OUTFFT") {
  99. &PrintDFF($theline,1);
  100. }
  101. if($type eq "ADD_SUB") {
  102. &PrintADDSUB($theline);
  103. }
  104. if($type eq "COMPARE") {
  105. &PrintCOMPARE($theline);
  106. }
  107. }
  108. }
  109. close(XNFFILE);
  110. }
  111.  
Expand|Select|Wrap|Line Numbers
  1.  
  2. sub PrintGATE {
  3. local($theline,$optype) = @_;
  4. local(%inputarray,$output);
  5.  
  6. $done = 0;
  7. %inputarray = ();
  8. while(!$done) {
  9. $theline = <XNFFILE>;
  10. $theline =~ s/[ \n]+//g;
  11. if($theline =~ /END/) {
  12. $done = 1;
  13. }
  14. else {
  15. $invert = "NORM";
  16. ($pin, $formal, $direction, $name,$blank,$invert) = split(/,/,$theline);
  17. $name = &FixName($name);
  18. if($direction eq "I") {
  19. if($invert eq "INV") {
  20. $inputarray{$name} = -1;
  21. }
  22. else {
  23. $inputarray{$name} = 1;
  24. }
  25. }
  26. else {
  27. $output = $name;
  28. }
  29. }
  30. }
  31. printf(ARCHFILE " %s <=",$output);
  32. $firstprinted = 0;
  33. foreach $input (sort(keys(%inputarray))) {
  34. if($firstprinted) {
  35. printf(ARCHFILE " and");
  36. }
  37. else {
  38. $firstprinted = 1;
  39. }
  40. if($inputarray{$input} == -1) {
  41. printf(ARCHFILE " not");
  42. }
  43. printf(ARCHFILE " %s",$input);
  44. }
  45. printf(ARCHFILE ";\n");
  46. }
  47.  
  48. sub PrintBUF {
  49. local($theline,$optype) = @_;
  50. local($input,$output);
  51.  
  52. $done = 0;
  53. while(!$done) {
  54. $theline = <XNFFILE>;
  55. $theline =~ s/[ \n]+//g;
  56. if($theline =~ /END/) {
  57. $done = 1;
  58. }
  59. else {
  60. ($pin, $formal, $direction, $name) = split(/,/,$theline);
  61. $name = &FixName($name);
  62. if($direction eq "I") {
  63. $input = $name;
  64. }
  65. else {
  66. $output = $name;
  67. }
  68. }
  69. }
  70. printf(ARCHFILE " %s <=",$output);
  71. printf(ARCHFILE " %s",$optype);
  72. printf(ARCHFILE " %s",$input);
  73. printf(ARCHFILE ";\n");
  74. }
  75.  
  76. sub PrintOBUFT {
  77. local($theline) = @_;
  78. local($input,$output,$tristate);
  79.  
  80. $done = 0;
  81. while(!$done) {
  82. $theline = <XNFFILE>;
  83. $theline =~ s/[ \n]+//g;
  84. if($theline =~ /END/) {
  85. $done = 1;
  86. }
  87. else {
  88. ($pin, $formal, $direction, $name) = split(/,/,$theline);
  89. $name = &FixName($name);
  90. if($formal eq "I") {
  91. $input = $name;
  92. }
  93. if($formal eq "O") {
  94. $output = $name;
  95. }
  96. if($formal eq "T") {
  97. $tristate = $name;
  98. }
  99. }
  100. }
  101. printf(ARCHFILE " %s <= %s when %s = '0' else 'Z'",$output,$input,$tristate
  102. );
  103. printf(ARCHFILE ";\n");
  104. }
  105.  
Expand|Select|Wrap|Line Numbers
  1.  
  2. sub PrintDFF {
  3. local($theline,$tristateable) = @_;
  4. local($input,$output,$clock,$tristate);
  5.  
  6. $done = 0;
  7. while(!$done) {
  8. $theline = <XNFFILE>;
  9. $theline =~ s/[ \n]+//g;
  10. if($theline =~ /END/) {
  11. $done = 1;
  12. }
  13. else {
  14. ($pin, $formal, $direction, $name) = split(/,/,$theline);
  15. $name = &FixName($name);
  16. if($formal eq "D") {
  17. $input = $name;
  18. }
  19. if(($formal eq "Q") || ($formal eq "O")) {
  20. $output = $name;
  21. }
  22. if($formal eq "C") {
  23. $clock = $name;
  24. }
  25. if($formal eq "T") {
  26. $tristate = $name;
  27. }
  28. }
  29. }
  30. printf(ARCHFILE "process begin\n");
  31. printf(ARCHFILE " wait until %s'event and %s = '1';\n",$clock,$clock);
  32. if($tristateable) {
  33. printf(ARCHFILE " if(%s = '0') then %s <= %s; else %s <= 'Z'; end if;\n
  34. ",
  35. $tristate, $output, $input,
  36. $output);
  37. }
  38. else {
  39. printf(ARCHFILE " %s <= %s;\n",$output,$input);
  40. }
  41. printf(ARCHFILE "end process;\n");
  42. }
  43.  
  44. sub PrintADDSUB {
  45. local($theline) = @_;
  46. local($inputa,$inputb,$output);
  47.  
  48. $done = 0;
  49. while(!$done) {
  50. $theline = <XNFFILE>;
  51. $theline =~ s/[ \n]+//g;
  52. if($theline =~ /END/) {
  53. $done = 1;
  54. }
  55. else {
  56. ($pin, $formal, $direction, $name) = split(/,/,$theline);
  57. $name = &FixName($name);
  58. if($formal eq "A") {
  59. $inputa = $name;
  60. }
  61. if($formal eq "B") {
  62. $inputb = $name;
  63. }
  64. if($formal eq "FUNC") {
  65. $output = $name;
  66. }
  67. }
  68. }
  69. printf(ARCHFILE " %s <= %s + %s;\n",$output,$inputa,$inputb);
  70. }
  71.  
  72. sub PrintCOMPARE {
  73. local($theline) = @_;
  74. local($inputa,$inputb,$output);
  75.  
  76. $done = 0;
  77. while(!$done) {
  78. $theline = <XNFFILE>;
  79. $theline =~ s/[ \n]+//g;
  80. if($theline =~ /END/) {
  81. $done = 1;
  82. }
  83. else {
  84. ($pin, $formal, $direction, $name) = split(/,/,$theline);
  85. $name = &FixName($name);
  86. if($formal eq "A") {
  87. $inputa = $name;
  88. }
  89. if($formal eq "B") {
  90. $inputb = $name;
  91. }
  92. if($formal eq "A_EQ_B") {
  93. $output = $name;
  94. }
  95. }
  96. }
  97. printf(ARCHFILE " %s <= '1' when %s = %s else '0';\n",$output,$inputa,$inputb);
  98. }
  99.  
  100. sub AddElement {
  101. local($theline) = @_;
  102. local($busname,$signame);
  103.  
  104. $done = 0;
  105. # Extract the element number from the first line
  106. ($sym, $name, $type, $def, $elemnum) = split(/,/,$theline);
  107. $elemnum =~ s/[ =ELEM]+//g;
  108. # Find the bus name and the individual signal name
  109. while(!$done) {
  110. $theline = <XNFFILE>;
  111. $theline =~ s/[ \n]+//g;
  112. if($theline =~ /END/) {
  113. $done = 1;
  114. }
  115. else {
  116. ($pin, $formal, $direction, $name) = split(/,/,$theline);
  117. $name = &FixName($name);
  118. if($formal eq "XBLOX_BUS") {
  119. $busname = $name;
  120. }
  121. if($formal eq "ELEM") {
  122. $signame = $name;
  123. }
  124. }
  125. }
  126. # If the signal name is just the bus-ripped version of the bus name,
  127. # clear the list. It will be deleted and no alias will be constructed.
  128. # If the signal name is different, add it to the list.
  129. if($signame =~ /\(/) {
  130. $aliaselement{$busname} = "";
  131. }
  132. else {
  133. $aliaselement{$busname} = $aliaselement{$busname} .
  134. $signame . "," . $elemnum . ":";
  135. }
  136. }
  137.  
  138. sub PrintAlias {
  139. local($signal) = @_;
  140. local($busname,$signame);
  141.  
  142. $elementlist = $aliaselement{$signal};
  143. if($elementlist ne "") {
  144. @elementarray = split(/:/,$elementlist);
  145. @sortedelement = ();
  146. for($i=0; $i<=$#elementarray; $i=$i+1) {
  147. ($element,$elemnum) = split(/,/,$elementarray[$i]);
  148. $sortedelement[$elemnum] = $element;
  149. }
  150. printf(ARCHFILE " %s <= (",$signal,$aliasarray{$signal});
  151. for($i=$#sortedelement; $i>=1; $i=$i-1) {
  152. printf(ARCHFILE "%s & ",$sortedelement[$i]);
  153. }
  154. printf(ARCHFILE "%s);\n",$sortedelement[0]);
  155. }
  156. }
  157.  
  158. sub FixName {
  159. local($name) = @_;
  160. $name =~ s/\</\(/;
  161. $name =~ s/\>/\)/;
  162. $name =~ s/\$+//;
  163. return $name;
  164. }
  165.  
  166. sub PrintTrailer {
  167. local($archfilename) = @_;
  168.  
  169. ($entname, $archname) = split(/_/,$archfilename);
  170. $archname =~ s/\.vhd//;
  171. printf(ARCHFILE "\n");
  172. printf(ARCHFILE "end %s;\n",$archname);
  173. }
  174.  
  175. sub HackSignals {
  176. local($hackfilename) = @_;
  177.  
  178. open(HACKFILE,$hackfilename);
  179. while($theline = <HACKFILE>) {
  180. if($theline =~ /^signal/) {
  181. printf(ARCHFILE "%s",$theline);
  182. }
  183. }
  184. close(HACKFILE);
  185. }
  186.  
  187. sub HackNetlist {
  188. local($hackfilename) = @_;
  189.  
  190. open(HACKFILE,$hackfilename);
  191. while($theline = <HACKFILE>) {
  192. if($theline =~ /<=/) {
  193. printf(ARCHFILE "%s",$theline);
  194. }
  195. }
  196. close(HACKFILE);
  197.  
Mar 10 '08 #1
Share this Question
Share on Google+
4 Replies


numberwhun
Expert Mod 2.5K+
P: 3,503
If you truly want to start ridding this script of issues, then you should really think about adding the "use strict;" and "use warnings;" pragmas at the beginning of the script. You will have to do a lot of firefighting after you do that, but the script will be that much better in the end.

Regards,

Jeff
Mar 10 '08 #2

nithinpes
Expert 100+
P: 410
Also, try to catch the exceptions wherever you are opening files.
Expand|Select|Wrap|Line Numbers
  1. open(ARCHFILE,">$archfilename") or die "failed to open $archfilename:$!";
  2. #
  3. #
  4. open(XNFFILE,$xnffilename) or die "failed to open $xnffilename:$!";
  5.  
  6.  
Mar 10 '08 #3

KevinADC
Expert 2.5K+
P: 4,059
To run the perl script:

Expand|Select|Wrap|Line Numbers
  1. perl nameofperlscript.pl xnffilename hackfilename
  2.  
Mar 10 '08 #4

eWish
Expert 100+
P: 971
Since there was so much code and the [CODE][/CODE] tag bug prevented your post from appearing. I have broken your code up into smaller sections. In the future please only post the relevant code rather than the whole script. That is a lot of code to look over.

Thank Youl

--Kevin
Mar 10 '08 #5

Post your reply

Sign in to post your reply or Sign up for a free account.