Laboratory 3 (individual) -- Registers and memory

Worth: 20 points
Due: 29 January 2016

Overview

The circuits you wrote in Labs 1 and 2 were combinational circuits; i.e. they computed an output value based on the current values of the inputs. In this lab, you will use sequential circuits, in which the output values may depend on the past values of the inputs. You will use two types of components: register and memory. These components have two properties that distinguish them from the circuits in Labs 1 and 2:

You will instantiate a register and memory component, store values in them, and retrieve those values later. You will also gain experience with Quartus' In-System Memory Content Editor.

Registers

A register is used to remember a multi-bit value for later use. Each register can remember exactly one multi-bit value. We call the value currently remembered in the register the register's "value" or the value "stored" by the register.

The operation of a register is controlled by four signals: clock, reset, write, and data_in. A register supports two operations (based on the values of these signals):

The register outputs a multi-bit value, data_out, which is the value currently stored in the register. This value changes immediately after the value stored in the register changes.

Memory

A memory is an array of registers. Like a register, memory is controlled by the signals clock, write, and data_in (memories have no reset signal). Like a register, memory outputs a signal data_out. However, because memory is an array of registers, it needs additional information to control which element of the array is being operated on. This additional information is called the memory's address; it is similar to an array index.

The address is stored in an internal register of the memory, which is called memory_address_register. To operate on the memory, one must first write an address to memory_address_register. The current value of memory_address_register determines which array element is written to or read from on subsequent memory operations. I.e., a write operation will write to the address currently stored in memory_address_register, and the memory's data_out always outputs the value stored at the address stored in memory_address_register.

Like all registers, memory_address_register is controlled by the signals write, data_in, and clock. The memory_address_register's write signal is called address_write, and the memory_address_register's data_in signal is called address_in. memory_address_register shares the same clock signal as the memory. Unlike other registers, memory_address_register is not affected by the reset signal.

For example, here's how to write the value V to the memory element at address A (in C++, you might express this operation as memory[A] = V). First, write A to memory_address_register by setting address_write and address_in to the appropriate value and waiting for a positive clock edge. Next, write to memory element A by setting the memory's write and data_in signals and waiting for another positive clock edge.

Here's how to read the value stored in memory element A (in C++, you might express this operation as reading memory[A]). First, write A to memory_address_register by setting address_write and address_in to the appropriate value and waiting for a positive clock edge. After this positive clock edge, the value of memory element A will start to be output on data_out.

Demonstration circuit

All the Verilog for this lab is provided for you (except for hexdigit.v, which you wrote for Lab 2). Create a new Quartus project for lab3. Remember to download top.qsf into your project directory after you create the project but before you add any files. After downloading top.qsf, download top.v, register.v, reset_toggle.v, and ram.v into the project directory. Also copy your hexdigit.v from Lab 2 into the project directory. Add these Verilog files to your project as you did in Lab 2.

Read register.v and identify the operations supported by this component (which is a 4-bit register). This module introduces two new Verilog constructs:

Next, look through top.v. The module top connects a register (module register) and a memory (module ram) to the DE2-115's push buttons, switches, and LEDs. These connections allow you to control the inputs to the register and memory components and to observe their outputs. The only new I/O device used in top is KEY[3:0]; these refer to the four push buttons in the lower, right-hand corner of the DE2-115. These buttons generate a value of 0 when they pressed down and generate a value of 1 when they are released. This is the reverse of most people's intuition, so we invert the values with Verilog's ~ operator. Thus, ~KEY[1] is 1 when the button is pressed and 0 when the button is released.

Now observe how top connects the DE2-115's I/O devices to the inputs and outputs of the register component:

Finally, look at the connections that top makes to the memory module ram (you need not look at the file ram.v--this is a somewhat-obscure file that Quartus uses to interface to its memory component). The module ram is a memory with 16 words of memory, with each word being 4 bits wide.

Pre-lab assignment

Your pre-lab assignment is to understand the demonstration circuit and to create a testing plan that demonstrates the use of registers and memory on the circuit. Your testing plan should exercise the full range of capabilities of both components (hint: is there anything that memory can do that a register cannot?).

Your testing plan should show the sequence of steps you will take after downloading the circuit. For each step, you should state:

Print/export your testing plan to a PDF file.

In-lab demonstration

In the lab, you will carry out your testing plan, verify that it behaves as you expect, and adjust it as needed to demonstrate the full range of capabilities of both components. Then you will demonstrate your testing plan to a lab instructor. Submit your testing plan after you've demonstrated it to a lab instructor.

Quartus' In-System Memory Content Editor

You've used the In-System Memory Content Editor to download a circuit to the FPGA. The memory editor also allows you to view and modify the contents of the memory components on the DE2-115's Cyclone IV FPGA. Your testing plan for this lab should not use the memory editor. However, you should try using the memory editor after your in-lab demonstration, as it will be an essential tool for later labs.

After you've downloaded a circuit, the main window of the memory editor can be used to display or modify the contents of the memory component in your circuit (screenshot). Each row shows the contents of a set of words in memory. The starting address of these words is shown in hexadecimal on the left-hand side of the memory-editor window.

The contents of memory may change as the circuit continues to operate. You can refresh your view of the memory's contents by right-clicking anywhere in the contents of memory and selecting Read Data from In-System Memory. You can also edit the contents of memory on the screen and write these new contents to the memory on the FPGA, but you will not need to do this until Lab 4.