URL
https://opencores.org/ocsvn/scan_based_serial_communication/scan_based_serial_communication/trunk
Subversion Repositories scan_based_serial_communication
Compare Revisions
- This comparison shows the changes necessary to convert path
/scan_based_serial_communication
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/SCAN_README.txt
0,0 → 1,100
|
FILES |
scan.perl.v |
scan_signal_list.pl |
scan_testbench.perl.v |
|
AUTHOR |
David Fick - dfick@umich.edu |
|
VERSION |
1.0 - June 27, 2010 |
|
SCAN DESCRIPTION |
This is a simple scan chain implemented with deperlify. It has been |
used, successfully, on multiple tapeouts. |
|
This scan chain is designed to safely and easily move data onto and |
off of a chip with a minimal number of pins. Performance is not a |
priority, however, we have found it to be sufficiently fast for |
any student project. |
|
For safety, this scan uses two non-overlapping "clocks" that operate |
out of phase. Each bit in the scan chain has a master latch and |
a slave latch. The master latch is connected to the signal "phi", |
and the slave latch is connected to the signal "phi_bar". To clock |
in one bit (and out another), "data_in" is first set to the correct |
value, then "phi" is *pulsed*, afterward "phi_bar" is *pulsed*. The |
process then repeats for the next bit. Since each clock is pulsed |
individually, they will never overlap. Note that this design |
is immune to signal bouncing. |
|
Every data_bit coming out of the scan chain unit is first buffered |
with a latch. This latch is transparent when "scan_load_chip" is |
high. Thus, data is loaded onto the chip by first clocking in all |
of the data as described above, then pulsing "scan_load_chip". |
This means that the signals coming out of the scan unit to the |
rest of the chip do not toggle randomly when the scan chain is |
being loaded, and therefore the scan chain can be operated while |
the chip is running. |
|
The signal "scan_load_chain" controls a mux on the input of each |
latch pair. If "scan_load_chain" is high, then data from the chip |
is loaded into the scan chain when the two clocks are pulsed, |
instead of data from the preceding bit. Thus, to read data |
from the chip, first raise "scan_load_chain" high, pulse the two |
clocks once as normal, then lower "scan_load_chain". Now that |
the chip data has been loaded into the scan chain, clock out the |
data as normal. |
|
Due to the buffering latch, complex internal interfaces can be |
emulated using the scan chain. For instance, an SRAM could be |
connected to a clock, chip select, write enable, 64-bit data-in, |
and 64-bit data-out, all of which are connected to the scan |
chain. The scan chain would need to be used a few times for each |
"cycle" of the SRAM. For instance, each time the clock signal |
toggles the scan chain would need to be completely reloaded. |
Although this process is slow, it works reliably. |
|
The example description below has additional information about |
how to use the scan chain. |
|
|
EXAMPLE DESCRIPTION |
To run the example, use deperlify to generate scan.v and |
scan_testbench.v: |
|
perl deperlify.pl scan.perl.v |
perl depeflify.pl scan_testbench.perl.v |
|
Then use your Verilog simulator of choice. |
|
This example takes advantage of the DEPERLIFY_INCLUDE command. The |
scan.perl.v file reads in the data structure scan_signal_list.pl |
in order to generate the scan chain. The file scan_testbench.perl.v |
uses the same data structure to generate variables and functions |
to access the scan chain. |
|
The testbench generates a write variable and read variable for |
each element in the scan chain. The write variable is called |
<NAME> and the read variable is called <NAME>_read. The values |
with the name <NAME> are what is scanned into the scan chain |
by the task "rotate_chain". The task "rotate_chain" writes the |
variables with the name <NAME>_read with the data that is scanned |
out by the scan chain. Note that data is simultaneously scanned |
in and out. |
|
To write a value: |
1. Set the value of <NAME> to what you desire |
2. Call "rotate_chain" |
3. Call "load_chip" |
|
To read a value: |
1. Call "load_chain" |
2. Call "rotate_chain" |
3. Read the value of <NAME>_read |
|
|
|
|
|
trunk/SCAN_README.txt
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/scan_signal_list.pl
===================================================================
--- trunk/scan_signal_list.pl (nonexistent)
+++ trunk/scan_signal_list.pl (revision 2)
@@ -0,0 +1,24 @@
+
+
+# The list at the beginning defines the scan lists. Defining an input name or output
+# name determines what type of scan signal it is.
+
+# Values are always readable (the buffering latch is what is read if writable)
+
+my @signal_list = ( # Inputs - outside to chip
+ { size => 1, writable => 1, name => 'write_data_1'},
+ { size => 2, writable => 1, name => 'write_data_2'},
+ { size => 3, writable => 1, name => 'write_data_3'},
+
+ # Outputs - chip to outside
+ { size => 1, writable => 0, name => 'read_data_1'},
+ { size => 2, writable => 0, name => 'read_data_2'},
+ { size => 3, writable => 0, name => 'read_data_3'},
+ );
+
+my $scan_chain_length = 0;
+
+for (my $i = 0; $i < scalar @signal_list; $i++) {
+ $signal_list[$i]{start} = $scan_chain_length;
+ $scan_chain_length += $signal_list[$i]{size};
+}
trunk/scan_signal_list.pl
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/scan_testbench.perl.v
===================================================================
--- trunk/scan_testbench.perl.v (nonexistent)
+++ trunk/scan_testbench.perl.v (revision 2)
@@ -0,0 +1,222 @@
+
+`define SCAN_DELAY #1
+
+module tbench();
+
+ // Scan
+ reg scan_phi, scan_phi_bar, scan_data_in, scan_load_chip, scan_load_chain;
+ wire scan_data_out;
+
+ //-----------------------------------------
+ // Scan Chain Registers and Tasks
+ //-----------------------------------------
+
+ // Scan Registers and Initializations
+
+ PERL begin
+ /*
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ print "`define SCAN_CHAIN_LENGTH $scan_chain_length\n\n";
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+
+ my $begin = 0;
+ my $end = $signal_list[$i]{size} - 1;
+
+ print " reg [$end:$begin] " . $signal_list[$i]{name} . ";\n";
+ print " reg [$end:$begin] " . $signal_list[$i]{name} . "_read;\n";
+ print " initial " . $signal_list[$i]{name} . " = " .$signal_list[$i]{size} . "'d0;\n";
+ print " initial " . $signal_list[$i]{name} . "_read = " .$signal_list[$i]{size} . "'d0;\n";
+ }
+
+ */
+ end
+
+ // Scan chain tasks
+
+ task load_chip;
+ begin
+ `SCAN_DELAY scan_load_chip = 1;
+ `SCAN_DELAY scan_load_chip = 0;
+ end
+ endtask
+
+ task load_chain;
+ begin
+ `SCAN_DELAY scan_load_chain = 1;
+ `SCAN_DELAY scan_phi = 1;
+ `SCAN_DELAY scan_phi = 0;
+ `SCAN_DELAY scan_phi_bar = 1;
+ `SCAN_DELAY scan_phi_bar = 0;
+ `SCAN_DELAY scan_load_chain = 0;
+ end
+ endtask
+
+ task rotate_chain;
+
+ integer i;
+
+ reg [`SCAN_CHAIN_LENGTH-1:0] data_in;
+ reg [`SCAN_CHAIN_LENGTH-1:0] data_out;
+
+ begin
+ PERL begin
+ /*
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+
+ my $begin = $signal_list[$i]{start};
+ my $end = $signal_list[$i]{start} + $signal_list[$i]{size} - 1;
+
+ print " data_in[$end:$begin] = " . $signal_list[$i]{name} . ";\n";
+ }
+
+ */
+ end
+
+ for (i = 0; i < `SCAN_CHAIN_LENGTH; i=i+1) begin
+ scan_data_in = data_in[0];
+ data_out = {scan_data_out, data_out[`SCAN_CHAIN_LENGTH-1:1]};
+ `SCAN_DELAY scan_phi = 1;
+ `SCAN_DELAY scan_phi = 0;
+ `SCAN_DELAY scan_phi_bar = 1;
+ `SCAN_DELAY scan_phi_bar = 0;
+ `SCAN_DELAY data_in = data_in >> 1;
+ end
+
+ PERL begin
+ /*
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+
+ my $begin = $signal_list[$i]{start};
+ my $end = $signal_list[$i]{start} + $signal_list[$i]{size} - 1;
+
+ print " " . $signal_list[$i]{name} . "_read = data_out[$end:$begin];\n";
+ }
+
+ */
+ end
+ end
+
+ endtask
+
+ //-----------------------------------------
+ // Scan chain DUT
+ //-----------------------------------------
+
+ // We're going to use the name chip_iternal_ for the signals that would
+ // normally be inside the chip that we're interacting with. We'll generate them
+ // here
+
+ PERL begin
+ /*
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+ if ($signal_list[$i]{writable} == 1) {
+ print " wire ";
+ } else {
+ print " reg ";
+ }
+
+ print "[$signal_list[$i]{size}-1:0] chip_internal_$signal_list[$i]{name};\n";
+ }
+
+ */
+ end
+
+ scan scan_dut ( // Inputs & outputs to the chip
+ PERL begin
+ /*
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+ print " .$signal_list[$i]{name}(chip_internal_$signal_list[$i]{name}),\n";
+ }
+
+ */
+ end
+
+ // To the pads
+ .scan_phi (scan_phi),
+ .scan_phi_bar (scan_phi_bar),
+ .scan_data_in (scan_data_in),
+ .scan_data_out (scan_data_out),
+ .scan_load_chip (scan_load_chip),
+ .scan_load_chain (scan_load_chain)
+ );
+
+
+ //-----------------------------------------
+ // Testbench
+ //-----------------------------------------
+
+ initial begin
+
+ $display("Starting scan chain test");
+
+ scan_phi = 0;
+ scan_phi_bar = 0;
+ scan_data_in = 0;
+ scan_load_chip = 0;
+ scan_load_chain = 0;
+
+ rotate_chain();
+ load_chip();
+
+ // Write each variable
+ write_data_1 = 1'd1;
+ write_data_2 = 2'd2;
+ write_data_3 = 3'd3;
+
+ rotate_chain();
+ load_chip();
+
+ // Check that the chip sees the new variables
+ if (chip_internal_write_data_1 != 1'd1 ||
+ chip_internal_write_data_2 != 2'd2 ||
+ chip_internal_write_data_3 != 3'd3 )
+ $display("TEST 1 FAILED");
+ else
+ $display("TEST 1 PASSED");
+
+ // Set internal values to read out
+ chip_internal_read_data_1 = 1'd0; // As if the chip had this value internally
+ chip_internal_read_data_2 = 2'd3;
+ chip_internal_read_data_3 = 3'd5;
+
+ // Read all of the values for both writable and non-writable variables
+ load_chain();
+ rotate_chain();
+
+ // Check to see that we read out all values properly
+ if (write_data_1_read != 1'd1 ||
+ write_data_2_read != 2'd2 ||
+ write_data_3_read != 3'd3 ||
+ read_data_1_read != 1'd0 ||
+ read_data_2_read != 2'd3 ||
+ read_data_3_read != 3'd5 ) begin
+ $display("TEST 2 FAILED");
+ $display("%d %d %d %d %d %d",
+ write_data_1_read,
+ write_data_2_read,
+ write_data_3_read,
+ read_data_1_read,
+ read_data_2_read,
+ read_data_3_read);
+ end else
+ $display("TEST 2 PASSED");
+
+
+ $finish;
+ end
+
+ //////////
+
+endmodule // tbench
+
+
\ No newline at end of file
trunk/scan_testbench.perl.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/scan.perl.v
===================================================================
--- trunk/scan.perl.v (nonexistent)
+++ trunk/scan.perl.v (revision 2)
@@ -0,0 +1,120 @@
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+module scan (
+
+ // Inputs & outputs to the chip
+ PERL begin
+ /*
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+ print " $signal_list[$i]{name},\n";
+ }
+
+ */
+ end
+
+ // To the pads
+ scan_phi,
+ scan_phi_bar,
+ scan_data_in,
+ scan_data_out,
+ scan_load_chip,
+ scan_load_chain
+
+ );
+
+
+ // /////////////////////////////////////////////////////////////////////
+ // Ports
+
+ // Scans
+ input scan_phi;
+ input scan_phi_bar;
+ input scan_data_in;
+ output scan_data_out;
+ input scan_load_chain;
+ input scan_load_chip;
+
+
+ PERL begin
+ /*
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+ if ($signal_list[$i]{writable} == 1) {
+ print " output reg ";
+ } else {
+ print " input ";
+ }
+
+ print "[$signal_list[$i]{size}-1:0] $signal_list[$i]{name};\n";
+ }
+
+ */
+ end
+
+
+ // /////////////////////////////////////////////////////////////////////
+ // Implementation
+
+ // The scan chain is comprised of two sets of latches: scan_master and scan_slave.
+
+ PERL begin
+ /*
+
+ ##############################################################
+ # Modify scan_signal_list.pl in order to change the signals. #
+ ##############################################################
+
+ DEPERLIFY_INCLUDE(scan_signal_list.pl);
+
+ # Print scan chain latches
+ print " reg [$scan_chain_length-1:0] scan_master;\n";
+ print " reg [$scan_chain_length-1:0] scan_slave;\n\n";
+
+ # Print scan_load and scan_next logic
+ print " wire [$scan_chain_length-1:0] scan_load;\n";
+ print " wire [$scan_chain_length-1:0] scan_next;\n\n";
+
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+
+ my $begin = $signal_list[$i]{start};
+ my $end = $signal_list[$i]{start} + $signal_list[$i]{size} - 1;
+
+ print " assign scan_load[$end:$begin] = " . $signal_list[$i]{name} . ";\n";
+ }
+
+ print "\n assign scan_next = scan_load_chain ? scan_load : {scan_data_in, scan_slave[$'$scan_chain_length-1:1]};\n\n";
+
+ # Print latches
+ print " //synopsys one_hot \"scan_phi, scan_phi_bar\"\n";
+ print " always @ (*) begin\n";
+ print " if (scan_phi)\n";
+ print " scan_master = scan_next;\n";
+ print " if (scan_phi_bar)\n";
+ print " scan_slave = scan_master;\n";
+ print " end\n\n";
+
+ # Print input latches
+ for (my $i = 0; $i < scalar @signal_list; $i++) {
+ if ($signal_list[$i]{writable} == 1) {
+ my $begin = $signal_list[$i]{start};
+ my $end = $signal_list[$i]{start} + $signal_list[$i]{size} - 1;
+ my $name = $signal_list[$i]{name};
+ print " always @ (*) if (scan_load_chip) $name = scan_slave[$end:$begin];\n";
+ }
+ }
+
+ # Print data_out
+ print " assign scan_data_out = scan_slave[0];\n";
+
+ */
+ end
+
+
+ // /////////////////////////////////////////////////////////////////////
+
+endmodule
trunk/scan.perl.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/deperlify.pl
===================================================================
--- trunk/deperlify.pl (nonexistent)
+++ trunk/deperlify.pl (revision 2)
@@ -0,0 +1,245 @@
+ #!/usr/bin/perl
+
+#################################################################################################
+#
+# Copyright 2010 David Fick. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification, are
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this list of
+# conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice, this list
+# of conditions and the following disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY DAVID FICK ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID FICK OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation are those of the
+# authors and should not be interpreted as representing official policies, either expressed
+# or implied, of David Fick.
+#
+#################################################################################################
+
+
+use strict;
+use integer;
+
+my $warning_verilog = "\n\n\n
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// !! THIS IS A TEMPORARY FILE GENERATED BY DEPERILFY !!
+// !! DO NOT MODIFY DIRECTLY! !!
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+\n";
+
+my $warning_io = "\n\n\n
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# !! THIS IS A TEMPORARY FILE GENERATED BY DEPERILFY !!
+# !! DO NOT MODIFY DIRECTLY! !!
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+\n";
+
+sub max {
+ my $a = shift;
+ my $b = shift;
+
+ return $a > $b ? $a : $b;
+}
+
+
+################################################################################################
+# Grab Defines
+
+my %defines;
+
+sub grab_defines {
+
+ my @params = @_;
+ my $file_name = $params[0];
+
+ # Read the entire file
+ my $file_contents;
+
+ {
+ local( $/, *FH ) ;
+ open(FH, "< " . $file_name) or die "Failed to open \"". $file_name . "\" correctly.";
+ $file_contents = ;
+ close(FH)
+ }
+
+ # Remove all comments
+ $file_contents =~ s-//.*\n-\n-g;
+ $file_contents =~ s-/\*.*\*/- -g;
+
+ # Grab all of the defines
+ while ($file_contents =~ /\`define\s+(\w+)[ \t]+([^\n]*)?\n/g) {
+
+ my $macro = $1;
+ my $definition = $2;
+
+ $defines{$macro} = $definition;
+ }
+
+ return;
+}
+
+
+################################################################################################
+# Lookup Define
+
+sub lookup {
+
+ my $define = shift;
+ my $definition = $defines{$define};
+
+ $definition = deep_replace($definition);
+
+ return $definition ne "" ? $definition : "undef";
+}
+
+################################################################################################
+# Deep Replace - replaces ` defines with their values
+
+sub deep_replace {
+
+ no integer;
+
+ my $text = shift;
+
+ # Find and replace all defines
+ $text =~ s-\`LG\(([^()]+?)\)-int(0.99999+log(eval(deep_replace($1)))/log(2))-ge; # Special case for `LG macro
+ $text =~ s-\`MAX\(([^()]+?),([^()]+?)\)-max(eval(deep_replace($1)),eval(deep_replace($2)))-ge; # Special case for `MAX macro
+
+ # Check for errors in the eval statement
+ if ($@) {
+ print "Error in perl section:\n" . $text . "\n ERRORS: \n" . $@;
+ die;
+ }
+
+ # Do additional normal lookups
+ $text =~ s/\`(\w+)/lookup($1)/ge;
+
+ return $text;
+}
+
+
+################################################################################################
+# Shallow Replace - replaces $` defines with their values
+
+sub shallow_replace {
+
+ my $text = shift;
+
+ # Find and replace all defines
+ $text =~ s/\$\`(\w+)/lookup($1)/ge;
+
+ return $text;
+}
+
+
+################################################################################################
+# This function takes a string, executes it, and returns everything that was printed
+
+sub execute_block {
+
+ my $text = shift;
+ my $generated_text = "";
+
+ # Inject the DEPERLIFY_INCLUDE files
+ $text =~ s/DEPERLIFY_INCLUDE\(([^\)]+)\)/`cat $1`/gse;
+
+ # Find and replace all defines
+ $text = shallow_replace($text);
+
+ # Execute the block of text that now has the generate statements
+ # write perl code to a file
+ my $temp_file = `mktemp deperlify.XXXXXXXXX`;
+ chomp $temp_file;
+
+ open (BLOCK_CODE, ">" . $temp_file);
+ print BLOCK_CODE $text;
+ # run perl on block
+ $generated_text = `perl $temp_file`;
+ `rm $temp_file`;
+
+ # Check for errors in the eval statement
+ if ($@) {
+ print "Error in perl section:\n" . $text . "\n ERRORS: \n" . $@;
+ die;
+ }
+
+ return $generated_text;
+}
+
+
+################################################################################################
+# This function takes a file name and runs the program on that file
+
+sub convert_file {
+
+ my @params = @_;
+
+ my $file_name = $params[0];
+ my $output_file_name = $file_name;
+
+ $output_file_name =~ s/\.perl\./\./;
+
+ # determine warning based on file type (determines type of comments used)
+ my $warning;
+ if ($file_name =~ /\.io/) {
+ $warning = $warning_io;
+ } else {
+ $warning = $warning_verilog;
+ }
+
+ # Read the entire file
+ my $file_contents;
+
+ {
+ local( $/, *FH ) ;
+ open(FH, "< " . $file_name) or die "Failed to open \"". $file_name . "\" correctly";
+ $file_contents = ;
+ close(FH)
+ }
+
+ # Do some operation
+ $file_contents =~ s/[\t ]*PERL\s+begin\s+\/\*(.*?)\*\/\s+end\s*?\n/execute_block($1)/gse;
+
+ $file_contents = $warning . $file_contents;
+
+ # Write the entire file
+ {
+ local( *FH ) ;
+ open(FH, "> " . $output_file_name) or die "Failed to write \"". $output_file_name . "\" correctly";
+ print FH $file_contents;
+ close(FH)
+ }
+
+}
+
+
+################################################################################################
+# Main code
+
+foreach my $argnum (0 .. $#ARGV) {
+
+ grab_defines($ARGV[$argnum]);
+
+ if ($ARGV[$argnum] =~ /(\.perl\.v)|(\.perl\.io)/) {
+ convert_file($ARGV[$argnum]);
+ }
+}
+
+
+################################################################################################
+
+
trunk/deperlify.pl
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/DEPERLIFY_README.txt
===================================================================
--- trunk/DEPERLIFY_README.txt (nonexistent)
+++ trunk/DEPERLIFY_README.txt (revision 2)
@@ -0,0 +1,53 @@
+
+FILE
+ deperlify.pl
+
+AUTHOR
+ David Fick - dfick@umich.edu
+
+VERSION
+ 1.0 - June 27, 2010
+
+DESCRIPTION
+ Deperlify generates *.v files from *.perl.v.
+ Deperlify can also generate *.io from *.perl.io
+
+ *.perl.v files have Perl injected inside of them with the following syntax
+
+ PERL begin /*
+
+
+
+ */
+ end
+
+ Deperlify finds these blocks, executes them, and replaces the block with
+ its output. The output of the Perl code (that is, anything printed to
+ STDOUT) is what replaces the block.
+
+ This style works well with emacs syntax highlighting and tabs. However, the
+ Perl code is not syntax highlighted since it appears as a comment. It is
+ sometimes beneficial to have a scratch Perl file to first the Perl code
+ in and then copy from there to the Verilog.
+
+ Deperlify also finds all of the defines from a file and inserts them
+ where Perl code is used. $`define_name must be used instead of `define_name,
+ however.
+
+ Deperlify can be given multiple files. Variable definitions found in one
+ file roll over to the subsequent files.
+
+ The order of files is important for variable replacement. *.vh files should
+ be included before any *.perl.v files that needs those definitions.
+
+ Additional Perl code may be included from other files. This can be
+ particularly useful for using the same data structure across multiple files.
+ The scan example takes advantage of this, by reusing a scan signal list
+ many times. Adding a signal to a scan chain would normally require adding
+ the signal in nearly a dozen places. Using Deperlify, however, allows that
+ change to be localized to only one place.
+
+ The syntax to include a Perl file is:
+ DEPERLIFY_INCLUDE(another_perl_file.pl);
+
+
\ No newline at end of file
trunk/DEPERLIFY_README.txt
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property