Using Memories in Xilinx Foundation 2



Xilinx 3.1i Memory Tutorial: (Original Idea by Greg Helm(GTA 2001) for Xilinx 2.1i tutorial)

Modified and Edited by Karthikeyan Balasundaram & Sridhar Ramachandran (Dec 2002)

The purpose of this tutorial is to become familiar with the memory components needed to complete CEG360/560, EE451/651 Lab #4.

Many more details that you actually need to know are presented here. So don’t get discouraged! The bare essentials will be noted by the use of the Arial Black Font, so you can just look for those sections.

Topics to be covered include:

The RAM library macros

The Logiblox Module Generator

- generating a ROM

- ROM initialization file (specifying ROM contents)

- generating a RAM

Simulations with RAM

- viewing memory contents in the Foundation simulator

- Viewing memory contents – the brute force method.

Memory basics.

All memories in the Xilinx libraries are based on 16x1 primitive memory elements (4 address lines and 1 data bit), and also several closely related variations. Thru 32x1 element (5 addresses) and the 16x1 dual port RAM element. Our design will require only single ported memory. We need a 16x4 RAM, which is essentially constructed using four 16x1 RAM primitives. We also need a 256x16 ROM memory, which is constructed using a large array of 16x1 ROM primitives and a considerable amount of multiplexer logic. These details are transparent and irrelevant to the student working on lab 4 (for the most part) and are presented here only as a foundation for future discussions.

The RAM library macro:

Our computer system requires a 16x4 RAM memory for “external” data storage. The XC4000E library provides us with a ready-made RAM16X4 macro. Using this macro is your simplest solution for implementing the system memory.

The Macro is called “RAM16X4”. The naming convention for the memory components in the library is as follows

RAMmXnt

RAM: indicates a RAM component

m: then memory depth or number of memory locations, log2m = # address lines

n: the memory width, number of bits per address location

t: the memory type. If no letter is present, then the memory is simply an asynchronous RAM. “S” indicates that it is a synchronous RAM. “D” indicates a dual ported RAM.

For the purposes of our lab project, the simple asynchronous RAM style is recommended.

Advanced Note: For real world FPGA designs the asynchronous style RAM is strongly discouraged, due to internal placement/routing and timing issues – we do not compile this lab design for actual FPGA configuration, and no simulation issues arise from the asynchronous RAM type – so it is a good fit for our project. The synchronous RAM style requires a clock input and RAM writes occur on a clock edge. This clock delay is incompatible with the non-pipelined datapath architecture presented in the lab; therefore undergrads will wish to avoid it. Grad students may however want to experiment with the synchronous style RAM (at their own risk ().

Note: “Advanced Note”s can be ignored by the casual reader.

The following figure shows the suggested RAM16X4 component and also the RAM selections available in the library

[pic]

RAM macro pin descriptions

A3, A2, A1, A0 : Address inputs

D3, D2, D1, D0 : Write data inputs

WE : Active high write enable

O3, O2, O1, O0 : Read data outputs

The following figure shows the internal structure of the RAM16X4 macro. This structure will be handy to know about if you choose to use the simulator to display the memory contents. You can use the “hierarchy push” tool to descend into the macro in your own schematics.

[pic]

That covers what you need to know (and more) about the RAM16X4 macro for now.

The Logiblox Module Generator:

The Logiblox module generator is a handy tool for generating customized macros that can be used in our designs. There are many module types. You can adjust the parameters of each module (e.g. size, control inputs, implementation style, default values etc.) to meet your needs. Our primary concern will be the “memories” module type … but you may wish to take a look at some of the other types available.

The Logiblox tool is accessible from the schematic editor. Go to the menu bar and click “Tools” then “Logiblox Module Generator”.

[pic]

You will now see the Logiblox user interface and the default module type of Accumulator will be shown.

Click on “Module Type” and select memories.

[pic][pic]

You will now have a window that looks like this….

[pic]

Generating a ROM

Now we will generate a ROM macro. The ROM must be generated using the logiblox tool, because there is no 256x16 ROM available in the standard library.

Advanced Note: “Large” ROMs cannot be implemented efficiently in the XC4000 FPGA architecture, due to the fact that the fundamental building block is a 16X1 ROM look-up-table. In order to implement a ROM this large (relatively speaking) many FPGA logic resources are required, and will result in a big, slow circuit that rapidly eats up costly FPGA real-estate. A 256 x n memory is the absolute maximum recommended for a real-world FPGA designs (using the XC4000 architecture), and even memories of this magnitude were strongly discouraged. In the past, for memories of this size, it was recommended to use a dedicated ROM (or RAM) chip external to the FPGA. This would eat up extra FPGA I/O pins for the memory interface and possibly slow the design down due to the need to go off chip, but potentially allowed for a cost savings by allowing a smaller FPGA (in terms of gate count) to be used. Since many designers needed memories on the order of kilobits (which are quite large relative to the 16x1 primitive), newer FPGA architectures contain dedicated RAM blocks that can store several kilobits of data.

To Create the ROM, complete the following steps:

1. Make sure Memories module type is selected

2. Type in a ModuleName. The macro will be stored in your project library using this name.

3. Select the “ROM” radio button in order to generate a ROM Macro

4. Enter 16 into the Data Bus Width field. This is the number of bits per memory location.

5. Set the Memory Depth = 256

6. Choose Multiplexer Style = Normal Gates. This is necessary in order to prevent bus errors during simulation. These errors would occur due to the relatively large size of this ROM and the way that “Maximum Speed” would be implemented in the FPGA (using tristate buffer style multiplexers)

7. Set Mem File = filename.mem where filename is the name you want to use for the ROM data initialization listing

8. Click Edit. This will bring up the WordPad editor so that you can edit your memory contents. Important Note: The first time you click Edit the file will be created. You must save the file in WordPad before the ROM module can be generated. A description of the file format follows shortly. For week #2 of the lab, the default file can be used. You do not need to specify ROM contents, although some “dummy code” may assist your debug efforts. During week #3 you will fully specify the ROM contents.

9. After saving the .mem file, click “OK” in the logiblox window – this will compile the macro and store it in your library. See below for a view of what your logiblox window should look like before clicking OK.

[pic]

Important Note: To update your ROM file. First make sure that you have added the macro to your schematics. To make an update, double-click the symbol and that will bring up the following Properties window…

[pic]

Click the “Configure Logiblox Symbol” button and then continue from step 8. Above.

ROM initialization files (filename.mem)

Here is the default file created when you click Edit in the Logiblox window.

[pic]

Description:

; indicates comment, text following a; and to the end of that line is considered to be a comment

There is a header section which details the memory size, and default value.

There is a data section where the initial memory contents are defined.

Header Section:

RADIX ; the base in which all numbers in the header section are described the default is 10 (decimal)

DEPTH ; the number of memory locations (make sure this matches what was specified in the Logiblox user interface – it will match the setting you had entered when you first clicked Edit from the user interface.

WIDTH ; the data word size (make sure this matches your Logiblox window too)

DEFAULT ; if any addresses are not specified in the Data section then this value will be stored there (note: the default RADIX has been specified as decimal) the default DEFAULT is “0”

Data Section:

RADIX ; the base in which all numbers in the header section are described the default is 16 (hexadecimal)

DATA ; indicates the start of your data

Data is entered in the following format

Address: Data

I recommend using one line per address location, which allows for easier debug and code reading.

For example…

DATA

00:9000

10:1234

11:2345

12:34AB

13:9000

This file will store 5 values in the ROM at addresses x0, x10, x11, x12 and x13. Remember the default radix is now hexadecimal. All other locations in the ROM will contain the Default value, which is 0000 in this case.

Note: it is not necessary to specify leading zeros. In other words, 32 is the same as 0032.

Note: you may wish to add comments on each line to describe the RTL operation for each code.

Alternate methods to specify the same data…

DATA

00:9000,10:1234,11:2345,12:34AB,13:9000

…Where address and data are explicitly specified on the same line for each location, but are separated by commas

Or…

DATA

00:9000

10:1234, 2345, 34AB, 9000

…Where, if the address is not specified, it is considered to be “previous address + 1”. Addresses 11, 12, 13 did not need to be explicitly written.

That should be everything you need to know about the “.mem” text file format.

Generating a RAM with Logiblox:

Follow the same procedure as for generating a ROM. Just make sure to select RAM, and adjust the width and depth accordingly.

No “.mem” file is necessary for generating a RAM.

If you like the logiblox RAM macro better than the standard library macro, feel free to use it. The Logiblox macro will give you bussed Address and Data pins rather than single bit pins.

Coming Soon: Simulation Issues … It’s here now, just go to the next page. (

Simulating Memories in Foundation 3.1i

ROMs:

To simulate a ROM, there is nothing special that you must do. Just treat it like any other component and add probes to the inputs and outputs. When you apply an address to a ROM the data will be displayed on the output after the associated propagation delay (which is zero in our functional simulation). You should already know the contents of all ROM locations, so just take a look at your most recent .mem file.

RAMs:

RAMs are a little trickier, because they store variable data that is not readily visible on the outputs of the macro. During a simulation, we would like to be able to see those contents. Without disrupting the operation of the circuit.

I will present two methods for viewing the RAM memory contents; one of those methods will not disrupt circuit operation, and it is the more complicated method, and a 2nd method that requires minor modification to the schematic and addition of some test inputs. Method 1 is not for the faint-of-heart, but if you can get through it once, then it doesn’t seem so difficult. If you would rather not borer, then go straight to method 2 on page 16 (last page).

Method 1: Using the simulator to view memory contents

Here is the circuit to be used for this simulation demonstration, it is just a ram with all of its I/O pine tied to wires and buses…

[pic]

The first step is to add probes as you normally would for a simulation. The probes already been added in the above figure (oops, except for DATA_READ).

Then click the “SIM” button to bring up the simulator, as usual…

The first thing that we need to do in order to view the memory contents is to configure a memory block for the simulator.

In the simulator window menu bar, you need to select “Device” -> “Memory Contents” -> “Block Configuration”

[pic]

That will bring up a new window…

[pic]

In the Select memory block window, you will need to click the Define Block button.

[pic]

In this block you will need to enter a block name, then the memory depth (16) and also the memory width (4).

Then click OK. Your new block is now available in the “Select memory block” Window (see below).

[pic]

Next you need to click on the “Select” button.

You will now see the “Memory Configurator” window…

[pic]

Now, we will need to clock the Select button again in the “Memory Configurator” window. It is time for us to locate our RAM block and determine the order each of the 16x1 RAM primitive elements. This step should become clearer as we move on. The following figure is something similar to what you will see, but you should expect a long list beneath “Scan hierarchy” – this will be a tree style listing of all the macro elements in your design. (See the following figure)

[pic]

Since this test design only contains a single RAM16X4 macro and nothing else it is easy to find. (

Scan through your listing and find the RAM. When you find you RAM block click it to highlight it and that will display all of the RAM16x1 primitives within that macro over in the Chip Selection window.

You will need to hold down the “shift” key or the “Ctrl” key and select all of the RAM16X1 items in the “Chip Selection” list

[pic]

Then click Select again. and close that window. You should now be back to the “Memory Configurator” window.

Next, you will need to assign each primitive RAM16X1 block to its appropriate bit location. In other words you must tell the simulator which block will be MSB and which will be LSB, etc.

You will see the part reference numbers and you will need to know which bit is which. So you will need to look at the inside of the RAM16X4 macro using the hierarchy push tool. (Or you can just look at the figure towards the beginning of this tutorial.)

[pic]

After looking at the inside of the RAM16X4 macro you will see the following connections.

Block $1I81 ( O0 (LSB)

Block $1I77 ( O1

Block $1I74 ( O2

Block $1I66 ( O3 (MSB)

This is always the case if you are using the RAM16X4 from the XC4000E library. (So you don’t really need to figure it out ( )

NOTE: If you are using a Logiblox generated RAM, each primitive will be labeled with its bit index. So it is much easier to figure out the bit order.

Next you will need to Select and drag each of the RAM chips on the left into its appropriate column on the right.

[pic]

Note that $1I81 is in the ‘0’ column and $1I66 is in the 3 column (msb)

Once you have completed this step you can close the “Memory Configurator” Window.

We are almost ready now!

Next go to the simulator window menu bar and select “Device” -> “Memory Contents” -> “Edit”

[pic]

You will now see this window…

[pic]

In the “Chip/Block” Selection column, double-click the RAM block that you defined (my_ram).

This will bring up the window that we have been waiting for!! (

This window it the Memory Editor window. As you run the simulation, you can now see the contents of memory change in this window whenever you write new values.

[pic]

The Memory Editor Window: all locations are initialized to ‘0’

So in order to finish of this portion of the tutorial I will write some memory locations and show the resulting window….

Final Simulation printout

[pic]

The operations perfomed were

M[x3] ( x5

M[x8] ( x2

You can see the results in the memory editor window. Also, in the simulation you can see a memory read at Address x3 as the last operation – The data read displays the correct results in the simulation waveform as well.

This concludes this tutorial.

Best wishes, and good luck on Lab 4.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download