Section 7: Verilog Memory Arrays
In this discussion section, you will use what you have learned in the previous discussion sections to implement a simple register file memory array at the register-transfer level (RTL). In the past discussion sections, we have focused on how to use Verilog to model combinational and sequential logic at both the gate-level and RTL. In this discussion section, we will only be using RTL. Remember from previous discussion sections that it is critical that students always know what is the hardware they are modeling; students should understand what their RTL would likely turn into at the gate-level.
1. Logging Into verilog-exam with VS Code
The Verilog coding exam is meant to assess students' ability to independently implement and test simple hardware modules. It will take place before the Thanksgiving break during a student's officially assigned discussion section in 225 Upson Hall.
Students must use the workstations for this discussion section!
Students cannot use their own laptops for the Verilog coding exam.
Students must use the workstations in the 225 Upson Hall computer lab
for the Verilog coding exam. So all students must use the
workstations for this discussion section. Students should not log
into ecelinux. They should instead log into
verilog-exam.ece.cornell.edu. This will enable students to get
familar with using the workstations and ensure there are no technical
issues.
Find a free workstation and log into the workstation using your NetID and
standard NetID password. Then complete the following steps. Do not log
into ecelinux-XX.ece.cornell.edu. You must log into
verilog-exam.ece.cornell.edu!
- Start VS Code
- Install the Remote-SSH, Verilog, and Surfer extensions
- Use View > Command Palette to execute Remote-SSH: Connect Current Window to Host...
- Enter
netid@verilog-exam.ece.cornell.edu - Install the Verilog extension on the server
- Use View > Explorer to open your home directory on
verilog-exam - Use View > Terminal to open a terminal on
verilog-exam
There is no need to fork or clone the repo for today's discussion
section. The code for today's discussion section should already be in
your home directory on verilog-exam. This is the same process we will
use for the Verilog coding exam.
The repo includes the following files:
Makefile.in: Makefile for the build systemconfigure: Configure script for the build systemconfigure.ac: Used to generate the configure scriptscripts: Scripts used by the build systemece2300: ECE 2300 unit testing library and miscellaneous macrosmem/mem.mk: Tells build system about files in this subprojectmem/Mux4_4b_RTL.v: 4-to-1 4-bit mux in RTLmem/Decoder_RTL.v: 2-to-4 binary decoder in RTLmem/Register_RTL.v: 4-bit register with enable in RTLmem/RegfileStruct1r1w_4x4b_RTL.v: Register file using structural RTLmem/RegfileFlat1r1w_4x4b_RTL.v: Register file using flat RTLmem/test: Directory with unit tests for each hardware module
Go ahead and create a build directory, run configure to generate a Makefile, and run the tests.
To make it easier to cut-and-paste commands from this handout onto the
command line, you can tell Bash to ignore the % character using the
following command:
Now you can cut-and-paste a sequence of commands from this tutorial
document and Bash will not get confused by the % character which begins
each line.
2. Memory Arrays
A memory array is a two-dimensional array of sequential logic gates (also called "bit cells"). The following diagram illustrates the high-level idea for a memory array.

In this discussion section, we will be building a register file, a
specific kind of memory array where D flip-flops are used as the
sequental logic gates. You will start by implementing a 4-to-1 4-bit mux,
2-to-4 decoder, and 4-bit register. You will then implement a 4-word
4-bit register file memory array in two ways: (1) structurally by
composing the mux, register, and decoder; and (2) flat using a single
always_ff and always_comb block.
3. 4-to-1 RTL Multiplexor
We have provided you the interface for the mux in Mux4_4b_RTL.v.
Use what you have learned about RTL modeling to create a Verilog hardware
design that implements a 4-to-1 4-bit mux. You should have a single
always_comb block. You can use use if/else conditional operators or a
case statement instead. We provide you all of the tests you need. You can
run the test simulator for the mux as follows.
4. 2-to-4 RTL Decoder
We will now implement a 2-to-4 binary decoder using RTL modeling. Recall that a decoder takes as input a binary number and produces a one-hot encoding of that binary number. If the input is 0, then bit 0 should be 1 and the remaining bits should be 0. If the input is 1, then bit 1 should be 1 and the remaining bits should be 0.
We have provided you the interface for the decoder in Decoder_2b_RTL.v.
Use what you have learned to create a Verilog hardware design that
implements a 2-to-4 decoder. You should have a single always_comb
block. We provide you all of the tests you need. You can run the test
simulator for the mux as follows.
5. 4-bit RTL Register
We will now implement a 4-bit register with enable (but no reset!) using
RTL modeling. We have provided you the interface for the register in
Register_4b_RTL.v.
Use what you have learned to create a Verilog hardware design that
implements a 4-bit register. You should have a single always_ff block
with an if/else conditional operation to handle the enable signals. You
will need to correctly handle explicit X-propagation using the
ECE2300_SEQ_XPROP macro. We provide you all of the tests you need. You
can run the test simulator for the mux as follows.
6. Structural Register File
A memory array is a two-dimensional array of sequential logic gates (also called "bit cells"). A register file is a specific kind of memory array where D flip-flops are used as the sequental logic gates. We can implement a register file structurally using the mux, decoder, and register developed earlier in this discussion section.

This register file has four "words" and each word is 4-bits. The register file has one write port and one read port (i.e., we can do a 4-bit write and a 4-bit read at the same time). The read port is combinational; if we set the read address then the read data comes back that same cycle (i.e., combinationally).
We have provided you the interface for the register file in
RegfileStruct1r1w_4x4b_RTL.v:
Notice there is no reset signal. Register files often include many bit cells and the hardware required to reset every single bit cell can be significant; so register files usually do not include a reset signal.
The following construct creates an array of multi-bit signals:
This creates an array of four signals, each signal is four-bits. This can be a useful way to create an array of multi-bit signals for the output of each register.
Use what you have learned to create a Verilog hardware design that implements a 4-word 4-bit register file. We provide you all of the tests you need. You can run the test simulator for the mux as follows.
% cd ${HOME}/ece2300/sec07/build
% make RegfileStruct1r1w_4x4b_RTL-test
% ./RegfileStruct1r1w_4x4b_RTL-test
7. Flat Register File
We can also implement a register file flat using a single always_ff
block for the write ports and a single always_comb block for the read
port. This register file has the exact same interface as the structural
version implemented in the previous section.
We will use an array of signals to act as the state.
You can read and write four-bit signals from this array by simply indexing into it. So the following will write the binary value 0011 into the second signal in this array.
Implement the flat register file using a single always_ff block and a
single always_comb block. We provide you all of the tests
you need. You can run the test simulator for the mux as follows.
% cd ${HOME}/ece2300/sec07/build
% make RegfileFlat1r1w_4x4b_RTL-test
% ./RegfileFlat1r1w_4x4b_RTL-test
8. Clean Build
As a final step, do a clean build to verify everything is working correctly.