Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due
Laboratory 3 (individual) -- Registers and memory
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:- Their current "state" depends on the past sequence of inputs they've seen.
- They respond to a "clock" signal, i.e. they only change behavior or state at the instant in time when the clock signal changes from 0 to 1. This instant is called the "positive edge" of the clock signal.
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):
- Reset sets the value of the register to all 0s. A reset operation will occur at the positive edge of the clock if the value of the reset signal at that time is 1.
- Write changes the value currently stored in the register to equal the value of the input parameter data_in. For shorthand, we say that we are "writing data_in to the register". A write will occur at the positive edge of the clock if the value of the write signal at that time is 1.
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 called 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:
- always @(posedge clock) specifies that the actions in this always block should occur only at the positive edge of the clock. These are called "edge triggered" always blocks.
- <= is used as the assignment operator (instead of the normal = operator) within an edge-triggered always block.
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:
- ~KEY[1] is connected to the register's clock.
- ~KEY[0] feeds into the reset_toggle module, which generates the reset signal for the register. reset is initialized to 1 when the circuit is downloaded to the FPGA, and changes (between 0 and 1) each time ~KEY[0] is pushed and released. The value of reset is displayed on LED_GREEN[8] (located between the 7-segment LEDs).
- SW[8] is connected to the register's write.
- SW[3:0] is connected to the register's data_in.
- The register's data_out drives the variable register_out, which is then connected to HEX0.
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.
- SW[7:4] is connected to the memory's address_in, i.e. the data_in signal to memory_address_register.
- SW[10] is connected to the memory's address_write, i.e. the write signal to memory_address_register. (side note: we invert SW[10] before passing it to the ram module because the ram module uses an inverted version to generate memory_address_register's write signal).
- ~KEY[1] is the clock signal for both memory_address_register and the memory array.
- SW[3:0] is connected to the memory's data_in.
- SW[9] is connected to the memory's memory_write.
- The memory's data_out drives the variable memory_out, which is then connected to HEX1.
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:
- the action you will take, e.g., move specific switches to a specified value, push or release a specific push button.
- the visible effect you expect that action to have on the LEDs on the DE2-115. If you expect no visible effects, then state what internal change you expect to take place.
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.