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:


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: 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:
  1. 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.
  2. 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.
  3. 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.

6.3 The "names" File

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:

  1. 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.
  2. 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.

6.4 The "wire.labels" File

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".

6.6 The "tmac.config.batch" File

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.

6.7 The "batch.cmd" File

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:
Last updated: 7 February 1996
Brent Nelson
nelson@ee.byu.edu