MEMCPY - A First Tutorial (Batch)
1. Introduction
MEMCPY is a simple tutorial designed to demonstrate the use of reading
and writing a single memory in TERAMAC. A memory is preloaded with
the contents of an input file "mem.in". The circuit then reads words
from this memory until the word 0xFFFFFFFF is read. As it does so, it
copies the words read up in memory by an address offset of 0x40.
Thus, after a complete execution the contents of memory starting at
location 0x0 should have been copied up to locations starting at 0x40.
In both simulation and execution it is possible to dump out the memory
contents to determine whether it operated correctly.
This is a "batch" tutorial. That is, execution is controlled via a
text command file. The next tutorial "MEMCPY2" is an interactive tutorial.
2. Setting Up to Run the Tutorial
You may copy the tutorial in its entirety to your area by executing:
cp -r $TMAC/demos/memcpy .
at a shell prompt.
3. Simulation
The first task to complete with this tutorial is to simulate the
design. The code for this example lives in the directory
$TMAC/tutorial/memcpy and consists of the following required files:
- "memcpy.vhd"
- This is the VHDL code for the design. It gets
synthesized.
- "membank.vhd"
- This is the VHDL code for the MEMBANK blocks. It has generics
which configure each instance for the size of address and data
busses it is to accomodate. It is called by the "memcpy.vhd"
code. It gets synthesized.
- "system.vhd"
- This represents the top level entity which is compiled
to provide an environment for the design to simulate in. It
provides a clock waveform and a reset signal. This file is not
synthesized - it is used for simulation only and calls the
entity defined in "memcpy.vhd".
- "config.vhd"
- This is the configuration VHDL file. It pulls together the
required library elements along with the "memcpy" entity to make
a complete system simulation possible. This file is not
synthesized - it is used for simulation only.
- "mem.in"
- This file contains the data which is used to initialize the
memory for simulation.
- "memdump"
- This file contains the results which are written out during the
simulation.
3.1 The VHDL Code
The file "membank.vhd"
contains a VHDL entity for the MEMBANK. It is parameterized with
generics, some of which are used for simulation only. You should not
have to modify this file at all. Multiple calls to this entity can be
made using generics to customize the port widths.
The file "memcpy.vhd"
contains the VHDL code. It has some counters and instantiates a
single memory. The format of the memory calls is quite important.
Suffice it to say that you should mimic this call, only changing the
actual signals passed in as port values and the actual generic values
passed in.
The pragma calls in both these files is used to allow the simulation
model to initialize the memory but also allow the same code to be
synthesized.
3.2 The Configuration File
The file "config.vhd"
contains the VHDL configuration to create a full TERAMAC system for
simulation. All configuration information is included in this file
since putting it in the original VHDL files causes synthesis warnings
and it seems most reasonable to do the structure that results in the
fewest warnings to have to ignore, especially for novice SYNOPSYS users.
The "config.vhd" file must be augmented as your design hierarchy grows.
3.3 The Input File
The file "mem.in" contains the input data. Each
line contains a single HEX number. Unlike the SPLASH memory files,
these can be of type HEX or DEC. Also unlike the SPLASH memory files,
in the case of HEX files any number of hex digits (up to 8) can be
included on a line. If the data word specified is wider than a single
memory word holds the leftmost bits are just truncated.
Unlike with "C-syntax" a leading "0x" is NOT permitted. If you
specify the memory initialization file to be of type
HEX when you instance the memory then the simulator will just
interpret the digits in your file as HEX. Otherwise, it will expect
decimal values.
The format of a memory initialization file for simulation allows the
use of an address specifier to initialize starting at locations other
than 0. To do this simply put the word "addr" followed by an address
on a line by itself. Subsequent values will be placed into memory
starting at that location. If the file type is HEX, a hexadecimal
address is expected, if DEC a decimal address is expected.
3.4 Compiling the VHDL Description for Simulation
The command to compile the above files to prepare for simulation is:
vhdlan membank memcpy system config
This will create the file "TOP.sim" which is the file
which will be simulated using VHDLDBX.
At times the local license server will be down when you attempt to run the
VHDL analyzer. If you are informed it is down when you attempt to
compile, you may execute the UNIX command
"/etc/rc.synopsys" to restart it.
3.5 Simulating the Design Using VHDLDBX
You start up the simulation by typing:
vhdldbx TOP
The command file "memcpy.cmd" may be used to drive the simulation like this:
include memcpy.cmd
where "memcpy.cmd" contains the needed
commands to exercise the design. After simulating, the output file
"memdump" should contain the same
data as was found in "mem.in"
to begin with but in a decimal format (memory dumps are always in
decimal - sorry!).
In "memcpy.cmd" you will notice a
couple of things:
- The simulation doesn't stop by itself. It just runs long
enough to copy the data over and copies 0's when it runs past
the initialized section.
- A trick the command file uses to get a memory dump is to go to
the memory entity, set the "dumpmem" signal to a
'1' and then run long enough for a clock edge. The resulting
memory dump is created in
"memdump".
4. Synthesizing Your Design to a TERAMAC Netlist
4.1 Synthesizing in SYNOPSYS
Once the simulation is working to your satisfaction you may compile it
in preparation for downloading it into TERAMAC. For this example, a
command file for "dc_shell" is used:
"memcpy.dc".
Some key points about the compilation process include:
- First, the MEMBANK is compiled. Appropriate "pragma"
statements in the VHDL source turns these into dummy entities.
- The result MEMBANK entity is marked as "dont_touch" in order to
prevent compilation of the "memcpy" module from optimizing it
away.
- The "memcpy" module is compiled and then flattened so that a
flat VERILOG netlist is written out.
You may "include"
"memcpy.dc" from either
"dc_shell" or "design_analyzer" or run it from the command line as:
dc_shell -f memcpy.dc
or
design_analyzer -f memcpy.dc
If all goes well, a ".ver" file should result. The only warnings that
you should see as you compile tell you the memory instance is not
being compiled.
As the VHDL files are being read in registers are inferred and printed
to the log file. Watch carefully to ensure that no latches result.
If they do, you will end up with warnings laters about "*FFGEN* cell
not translated".
Figure out what the script is doing!
Hierarchical compilation and optimization will be required for large
TERAMAC designs. Learn to do it with the SYNOPSYS tools. The key
commands to learn include "set_dont_touch",
"find", "link", and "ungroup -all -flatten".
4.2 Converting your VERILOG Netlist to a TERAMAC Netlist
At this point you may exit the SYNOPSYS tools and finish the
compilation process by typing:
vl2opt < memcpy.ver
which should result in the file memcpy.opt. Watch
carefully the messages as they scroll past to make sure everything
went OK. The "vl2opt" program parses the VERILOG
netlist, generates temporary files, and then calls the program
"netfold" to fold signal constants (reducing netlist
size), fixes up the MEMBANK and REGFILE calls, and changes the node
names to satisfy TERAMAC's back end requirements.
By default, extra circuitry will be added to your design to make the
outputs of your MEMBANK's visible during execution. To reduce this
circuitry overhead you may prevent it by setting the environment
variable "NO_WATCH_MEM_OUT" as in:
setenv NO_WATCH_MEM_OUT
To later reverse that use:
unsetenv NO_WATCH_MEM_OUT
4.2.1 What If I Get Errors During This Conversion?
There are at least two sources of errors you may encounter. The first
is a problem with your design which may include:
- Your VERILOG file has **FFGEN** calls. Your VHDL design
inferred latches. These are currently not
supported so SYNOPSYS doesn't know how to map them to the
TERAMAC primitives. This will be changed in the future since
TERAMAC does support latches.
- Your VERILOG file has **FFGEN** calls.
Your VHDL design inferred asynchronous sets or resets to flip
flops. Once again, SYNOPSYS doesn't know how to map them to
TERAMAC primitives. If this is the case you must change your
VHDL code.
- Your memory cell calls don't have enough ports. For now be
sure that you wire something real up to each memory port
(byte_enable, write_data, read_data, write_address,
read_address, clk).
Other errors at this step are likely errors with the tools and you
should contact me immediately. The tools consist of 2 separate
parsers based on LEX/YACC/C and 3 other C programs. In total, the
system contains 1,000+ lines of VHDL, 700+ lines of YACC code, 300+
lines of LEX code, and 1,600+ lines of C code --- all written in a
little over two weeks. A good assumption is that bugs exist!
This ends the VHDL-specific section of the tutorial. The sections
below would be applicable regardless of how your arrived at a
".opt" file.
5. Compiling Your Design
To compile, simply execute:
tc memcpy.opt
If you get errors, once again it is a tools bug and so contact me.
The result should be a directory called "memcpy.opt.tc" which contains
all the bit files needed to execute.
During the compilation process the critical path timing is
determined. The program "path.p" is a PERL script I wrote which will
associate labels with this critical path information . To use this
you should compile as:
tc memcpy.opt >& memcpy.out
and then execute the following:
path.p memcpy
What is printed will be the critical path information with signal
names attached where they exist.
6. Preparing to Execute
A set of things must be done to prepare for execution. All of this is
done in the "debug" subdirectory of your "memcpy" directory so go
there now.
6.1 Create A Memory Initialization File
While the simulation was happy with an ASCII memory initialization
file, execution requires a binary memory file. You may execute:
thexbin mem.bin 32 < ../mem.in
This program will convert "mem.in" into a binary file.
The "32" tells it how many bits wide the memory is (the bits will be
left-justified in the resulting words).
6.2 Running the "mk_mem_scripts" Program
Each TERAMAC board has multiple memory units. You need to be able to
figure out which one is used in your compiled design. The program
"mk_mem_scripts" is used for this purpose.
For this simple design, however, you can tell which memory is being used by
listing the files in "memcpy.opt.tc" and looking to see
which one has the word "mem" in it. The last digit before the word
"mem" is the memory number. Only works if your design has
only one memory.
This file contains the names of the signals you can look at during
simulation. It provides the information required for you to create
the "wire.labels" file. To create this file execute the following:
name -a ../memcpy.opt | sort > names
Look in this file. What you will see is that any signal name whose
line does not end in "???" can be watched during execution.
Do not ever assume that a given signal in your VHDL code will be
available to be watched during execution for a number of reasons:
- SYNOPSYS often optimizes signals away. Thus, you may think the
memory address in your design
is "MA_20_" through "MA_0_". However, it may be the
case that SYNOPSYS realized "MA_0_" was the same as "FOO_5_" and so
everywhere you might expect "MA_0_" you will see "FOO_5_". Trying
to watch a vector containing "MA_0_" will result in an error.
- The netlist generation and
conversion process changes node names due to
requirements of the various netlist formats and the
TERAMAC tools. Thus, a signal in your VHDL source
called "DATA_OUT(4)" may show up in the VERILOG netlist as
"\DATA_OUT[4]" but may show up as"$DATA_OUT<4>" in the final ".opt"
file.
Thus, make sure you examine your "names" file carefully
to see what node names are available to watch.
If you want to treat a group of signals as
a named vector or simply want to assign an alias for a signal, you
create that vector or alias definition in this file. Look in it. The
syntax should be pretty obvious. More details are given in the
TMAC hard-copy manual. Use the "names" to be sure you have the signal
names correct.
6.5 The "init" File
This file contains commands to initialize the array and load up the
memory. It is called by the next file "tmac.config.batch".
This file is that main startup file. It calls everything else using
"INCLUDE" commands. When you execute using "btmac" this is the
control file it executes.
This file contains commands to run the execution once all the setup is
complete. It easily could
have been combined with the "init" file above. It was
separated out since if you were to run interactively rather than in
batch mode you would still use the "init" file but not
this file. Also, this file repeatedly calls
"disp". You may want to
look in it for ideas on displaying signals.
Finally, this file shows two ways to execute. In the first, it simply
tells TERAMAC to free-run at the designed clock speed for 10 seconds
(approximate) or until the BREAKPOINT_NOT signal is asserted. After
re-initializing the circuit it demonstrates single stepping the clock
and displaying signals like you would get from a logic simulator.
Read and understand this file.
7. The TERAMAC Hardware
The TERAMAC hardware is attached to teramac. Each time you do
anything with the hardware it then spends about a minute resetting
itself for the next user. Thus, you will have to get used to waiting
after each attempt at execution while it resets.
To tell if the hardware is up and ready, execute:
checktmac
This should return the serial number of TERAMAC. You will
have to wait the minute after executing this regardless (it returns
the serial number first, then does the rest). If it seems
to be wedged you may execute:
wacktmac
to to try to unwedge it. In extreme cases you may be reduced to
rebooting teramac. This is rare, however (it has happened twice in
the first 3 weeks of operation). This is known as having to do a
wackteramac.
8. Executing on TERAMAC using "btmac"
The program "btmac" is a script I have written which
copies the file "tmac.config.batch" to
"tmac.config" and then executes the actual program
"tmac". Forgetting the proper options when running
"tmac" is a good way to wedge teramac. The script
"btmac" was designed to prevent this. Run it by simply typing:
btmac
If you execute this way in batch mode you should be able to watch the
data words read from memory and watch them written back to memory.
Also, when the program is done executing, the file
"mem.out" should show that the copy was done. You may
examine that file with:
od -x mem.out
The first time you execute after compiling, "TMAC" will check all your
bit files for consistency and legality. This takes a minute or two.
After that, each time will go faster.
Also, note that batch mode is just that - it parses your files and runs
to completion. Any requirement for interaction must be accomplished
as shown in the next tutorial.
9. Looking Forward
The next tutorial, "MEMCPY2", covers the
following:
- interactive execution
- use of the "mk_mem_scripts" program
Last updated: 7 February 1996
Brent Nelson
nelson@ee.byu.edu