Laboratory Exercise 8: Memory Blocks
Laboratory Exercise 8: Memory Blocks
Memory Blocks
A diagram of the random access memory (RAM) module that we will implement is shown in Figure 1a. It contains
32 four-bit words (rows), which are accessed using a five-bit address port, a four-bit data port, and a write control
input.
The FPGAs that are included on the Intel FPGA DE10-Lite, DE0-CV, DE1-SoC, and DE2-115 boards provide
dedicated memory resources. The MAX 10 FPGA on the DE10-Lite, and Cyclone IV FPGA on the DE2-115
contain dedicated memory resources called M9K blocks. The Cyclone V FPGA on the DE0-CV and DE1-SoC
boards have M10K blocks. Each M9K block contains 9216 memory bits, while each M10K block contains 10240
memory bits. Both M9K and M10k blocks can be configured to implement memories of various sizes. A common
term used to specify the size of a memory is its aspect ratio, which gives the depth in words and the width in bits
(depth x width). In this exercise we will use an aspect ratio that is four bits wide, and we will use only the first 32
words in the memory. Although the M9K and M10K blocks support many other modes of operation, we will not
discuss them here.
5
Address
4
32 x 4 RAM Data
Write
5 5
Address
4 4
DataIn 32 x 4 RAM 4
DataOut
Write
Clock
1
There are two important features of the M9K and M10K blocks that have to be mentioned. First, they includes
registers that can be used to synchronize all of the input and output signals to a clock input. The registers on the
input ports must always be used, and the registers on the output ports are optional. Second, the blocks have separate
ports for data being written to the memory and data being read from the memory. Given these requirements, we
will implement the modified 32 x 4 RAM module shown in Figure 1b. It includes registers for the address, data
input, and write ports, and uses a separate unregistered data output port.
Part I
Commonly used logic structures, such as adders, registers, counters and memories, can be implemented in an
FPGA chip by using prebuilt modules that are provided in libraries. In this exercise we will use such a module to
implement the memory shown in Figure 1b.
module ram32x4 (input [4:0] address, input clock, input [3:0] data, input wren, output [3:0] q);
2
Figure 3: Configuring input and output ports.
3. Instantiate this subcircuit in a top-level Verilog file that includes appropriate input and output signals for the
memory ports given in Figure 1b. Compile the circuit. Observe in the Compilation Report that the Quartus
Compiler uses 128 bits in one of the FPGA memory blocks to implement the RAM circuit.
4. Simulate the behavior of your circuit and ensure that you can read and write data in the memory. An example
simulation output is given in Figure 4.
3
Part II
Now, we want to realize the memory circuit in the FPGA on your DE-series board, and use slide switches to load
some data into the created memory. We also want to display the contents of the RAM on the 7-segment displays.
1. Make a new Quartus project which will be used to implement the desired circuit on your DE-series board.
2. Create another Verilog file that instantiates the ram32x4 module and that includes the required input and
output pins on your DE-series board. Use slide switches SW3−0 to provide input data for the RAM, and
use switches switches SW8−4 to specify the address. Use SW9 as the Write signal and use KEY0 as the
Clock input. Show the address value on the 7-segment displays HEX5 − 4, show the data being input to the
memory on HEX2, and show the data read out of the memory on HEX0.
3. Test your circuit and make sure that data can be stored into the memory at various locations.
Part III
Instead of creating a memory module subcircuit by using the IP Catalog, we can implement the required memory
by specifying its structure in Verilog code. In a Verilog-specified design it is possible to define the memory as a
multidimensional array. A 32 x 4 array, which has 32 words with 4 bits per word, can be declared by the statement
In the Cyclone series of FPGAs, such an array can be implemented either by using the flip-flops that each logic
element contains or, more efficiently, by using the built-in memory blocks. The Quartus Help provides other
examples of Verilog code that show how memory can be specified (search in the Help for “Inferred memory”).
1. Create a new project which will be used to implement the desired circuit on your DE-series board.
2. Write a Verilog file that provides the necessary functionality, including the ability to load the RAM and read
its contents as was done in Part II.
3. Assign the pins on the FPGA to connect to the switches and the 7-segment displays.
Part IV
The SRAM block in Figure 1 has a single port that provides the address for both read and write operations. For
this part you will create a different type of memory module, in which there is one port for supplying the address
for a read operation, and a separate port that gives the address for a write operation. Perform the following steps.
1. Create a new Quartus project for your circuit. To generate the desired memory module open the IP Catalog
and select the RAM: 2-PORT module in the Basic Functions > On Chip Memory category. As shown in
Figure 5, choose With one read port and one write port in the category called How will you be using
the dual port ram?
Configure the memory size, clocking method, and registered ports the same way as Part II. As shown in
Figure 6 select I do not care (The outputs will be undefined) for Mixed Port Read-During-Write for
Single Input Clock RAM. This setting specifies that it does not matter whether the memory outputs the
new data being written, or the old data previously stored, in the case that the write and read addresses are
the same during a write operation.
4
Figure 5: Configuring the two input ports of the RAM.
Figure 6: Configuring the output of the RAM when reading and writing to the same address.
5
Figure 7 shows how the memory words can be initialized to specific values. It makes use of a feature that
allows the memory module to be loaded with data when the circuit is programmed into the FPGA chip.
As shown in the figure, choose the setting Yes, use this file for the memory content data, and specify
the filename ram32x4.mif. An example of a MIF file is provided in Figure 8. You can also learn about the
format of a memory initialization file (MIF) by using the Quartus Help. You will need to create a MIF file
like the one in Figure 8 to test your circuit. Finish the Wizard and then examine the generated memory
module in the file ram32x4.v.
DEPTH = 32;
WIDTH = 4;
ADDRESS_RADIX = HEX;
DATA_RADIX = BIN;
CONTENT
BEGIN
0 : 0000;
1 : 0001;
2 : 0010;
3 : 0011;
. . . (some lines not shown)
1E : 1110;
1F : 1111;
END;
2. Write a Verilog file that instantiates your dual-port memory. To see the RAM contents, add to your design
a capability to display the content of each four-bit word (in hexadecimal format) on the 7-segment display
6
HEX0. Use a counter as a read address, and scroll through the memory locations by displaying each word
for about one second. As each word is being displayed, show its address (in hex format) on the 7-segment
displays HEX3−2. Use the 50 MHz clock, CLOCK_50, and use KEY0 as a reset input. For the write address
and corresponding data use switches SW8−4 and SW3−0 . Show the write address on HEX5 − 4 and show the
write data on HEX1. Make sure that you properly synchronize the slide switch inputs to the 50 MHz clock
signal.
3. Test your circuit and verify that the initial contents of the memory match your ram32x4.mif file. Make sure
that you can independently write data to any address by using the slide switches.
7
Copyright
c 1991-2016 Intel Corporation. All rights reserved. Intel, The Programmable Solutions Company,
the stylized Intel logo, specific device designations, and all other words and logos that are identified as trademarks
and/or service marks are, unless noted otherwise, the trademarks and service marks of Intel Corporation in the
U.S. and other countries. All other product or service names are the property of their respective holders. Intel
products are protected under numerous U.S. and foreign patents and pending applications, mask work rights, and
copyrights. Intel warrants performance of its semiconductor products to current specifications in accordance with
Intel’s standard warranty, but reserves the right to make changes to any products and services at any time without
notice. Intel assumes no responsibility or liability arising out of the application or use of any information, product,
or service described herein except as expressly agreed to in writing by Intel Corporation. Intel customers are ad-
vised to obtain the latest version of device specifications before relying on any published information and before
placing orders for products or services.
This document is being provided on an “as-is” basis and as an accommodation and therefore all warranties, rep-
resentations or guarantees of any kind (whether express, implied or statutory) including, without limitation, war-
ranties of merchantability, non-infringement, or fitness for a particular purpose, are specifically disclaimed.