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
/
- from Rev 2 to Rev 1
- ↔ Reverse comparison
Rev 2 → Rev 1
/scan_based_serial_communication/trunk/deperlify.pl
File deleted
scan_based_serial_communication/trunk/deperlify.pl
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: scan_based_serial_communication/trunk/scan.perl.v
===================================================================
--- scan_based_serial_communication/trunk/scan.perl.v (revision 2)
+++ scan_based_serial_communication/trunk/scan.perl.v (nonexistent)
@@ -1,120 +0,0 @@
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-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
scan_based_serial_communication/trunk/scan.perl.v
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: scan_based_serial_communication/trunk/DEPERLIFY_README.txt
===================================================================
--- scan_based_serial_communication/trunk/DEPERLIFY_README.txt (revision 2)
+++ scan_based_serial_communication/trunk/DEPERLIFY_README.txt (nonexistent)
@@ -1,53 +0,0 @@
-
-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
scan_based_serial_communication/trunk/DEPERLIFY_README.txt
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: scan_based_serial_communication/trunk/scan_testbench.perl.v
===================================================================
--- scan_based_serial_communication/trunk/scan_testbench.perl.v (revision 2)
+++ scan_based_serial_communication/trunk/scan_testbench.perl.v (nonexistent)
@@ -1,222 +0,0 @@
-
-`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
scan_based_serial_communication/trunk/scan_testbench.perl.v
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: scan_based_serial_communication/trunk/scan_signal_list.pl
===================================================================
--- scan_based_serial_communication/trunk/scan_signal_list.pl (revision 2)
+++ scan_based_serial_communication/trunk/scan_signal_list.pl (nonexistent)
@@ -1,24 +0,0 @@
-
-
-# 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};
-}
scan_based_serial_communication/trunk/scan_signal_list.pl
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: scan_based_serial_communication/trunk/SCAN_README.txt
===================================================================
--- scan_based_serial_communication/trunk/SCAN_README.txt (revision 2)
+++ scan_based_serial_communication/trunk/SCAN_README.txt (nonexistent)
@@ -1,100 +0,0 @@
-
-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
- and the read variable is called _read. The values
- with the name are what is scanned into the scan chain
- by the task "rotate_chain". The task "rotate_chain" writes the
- variables with the 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 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 _read
-
-
-
-
-
\ No newline at end of file
scan_based_serial_communication/trunk/SCAN_README.txt
Property changes :
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property