User Tools


Register File

In this lab you will learn how to use sequential flip-flop circuits to build a 8×4 register file.

Learning Outcomes

  • Create a sequential circuit using FDCE flip-flop primitives
  • Learn how to organize flip-flops into a register and register file

Preliminary

The Artix-7 FPGA we are using has built-in flip-flops that you can use to make sequential circuits. You will use FDCE flip-flop primitives to create a 4-bit register and then combine several 4-bit registers to construct a collection of registers aka a register file. The FDCE flip-flop is available to you without any extra work required on your part, you merely need to instance them into your design the same way you instance your own modules into your designs. Read the following pdf file to learn about the FDCE module, its ports, and how to instance the module in your SystemVerilog.

fdce.pdf

The SystemVerilog example below demonstrates how to instance a single FDCE flip-flop into a design:

FDCE my_ff (.Q(ff_output), .C(clk), .CE(clock_enable), .CLR(1'b0), .D(ff_input));

The example shown above assigns a constant zero to the CLR input for the common case when you never apply an asynchronous clear.

Create a waveform for the signal Q on an FDCE element using the waveform provided below.

Exercises

Exercise #1 - 4-Bit Register

For this exercise you will create a 4-bit register. Begin this exercise by creating an empty SystemVerilog module with the following name and ports.

Module Name: register4
Port Name Direction Width Function
clk Input 1 Clock input
reset Input 1 Reset input
datain Input 4 Data to be loaded into register
we Input 1 Write enable
dataout Output 4 Register output

For the body of this module, instance four FDCE flip-flops and complete the following steps.

  • Attach the clock of each flip flop, C, to the 4-bit register module's clk signal.
  • Attach the asynchronous clear of each flip flop, CLR, to the 4-bit register module's reset signal.
  • Attach the 4-bit register's we signal to the ce input of each flip-flop.
  • Attach a different bit of datain to the D input of each FDCE flip-flop.
  • Attach the Q output of each flip-flop to a corresponding dataout bit.

After creating your 4-bit register, simulate your register with a TCL script. The following set of TCL commands demonstrates a simple test for your register file. You can use this script and add to or modify it to test your register as you like.

Make sure that your TCL file includes a run 100ns at the beginning. For the first 100ns, the FDCE primitive resets itself. During this time it won't operate at all, so wait for this time to be over.

restart
# run for 100ns so the FDCE can properly reset
run 100 ns
 
# add oscillating clock input
add_force clk {0 0} {1 5ns} -repeat_every 10ns
 
# clear value
add_force reset 1
run 10 ns
add_force reset 0
 
# initialize signals
add_force we 0
add_force datain 0000
run 10 ns
# Prepare for a write
add_force datain 1101
add_force we 1
run 10 ns
add_force datain 0110
add_force we 0
run 10 ns

Exercise 1 Pass-off: Show a TA your code for your register4 module and your simulation waveform.

Exercise #2 - 8x4 Register File

In this exercise, you will create a 8×4 register file (eight registers of 4 bits each). In particular, you will be creating a triple-ported register file or a register file that has one write port and two read ports. The register file you will construct is loosely based on Figure 19.3 in your textbook. Begin your register file module by creating the module declaration and the input and output ports as follows:

Module Name: register_file_8x4
Port Name Direction Width Function
clk Input 1 Clock input
reset Input 1 Active-high reset, clears all registers
datain Input 4 Data to be loaded into register file
we Input 1 Write enable
waddr Input 3 Write address
raddr1 Input 3 Read address for port 1
raddr2 Input 3 Read address for port 2
dataout1 Output 4 Data out for port 1
dataout2 Output 4 Data out for port 2

After creating the module interface, construct your register file by including each of the following components that are shown in Figure 19.3.

  1. Create the Write Decoder that generates a unique register write signal for each of the eight registers. As described in the reading, this decoder will decode write address (waddr) and use the we signal to generate a write enable for each register.
  2. Instance eight of the 4-bit registers that you created in the previous exercise. These eight registers form the core of the register file module.
  3. Attach the clock and reset inputs to all eight registers and the datain signal to the input to each register.
  4. Create two 8:1 multiplixers for the read ports.

After creating your register file and removing all syntax errors, simulate your register file by creating a TCL script. In this script, make sure you perform the following tests.

  1. Perform a write to several different address locations.
  2. Read these addresses and make sure the data was properly loaded.
  3. Perform reads on both ports simultaneously with different addresses to demonstrate the ability to read two different locations at the same time.

Provide a copy of your TCL script you used to simulate the register file.

Exercise 2 Pass-off: Show a TA your code for your register8x4 module and your simulation waveform. Show that your tcl file meets the requirements listed above.

Exercise #3 - Top-level design and Testbench

For this final exercise you will create a top-level module that instances your register file. This top-level module will include other circuitry to interface the Nexys4 board with your register file. Begin this exercise by creating a module with the following top-level ports.

Module Name: register_top
Port Name Direction Width Function
clk Input 1 Clock input
CPU_RESETN Input 1 Active-low reset, clears all registers
sw Input 10 Switches for address input and data input
btnc Input 1 Write to register file
btnr Input 1 Display the value of data2
btnu Input 1 Display the value of data1+data2
btnd Input 1 Display the value of data1-data2
btnl Input 1 Display the value of data1&data2
segment Output 8 Cathode signals for seven segment display
anode Output 8 Anode signals for each of the eight digits

Instance your register_file_8x4 module you created in the previous exercise and complete the following.

  • Attach the top-level clock input to the clock port of the register file.
  • Attach the top-level reset input (CPU_RESETN) to the reset port of the register file. Note: The CPU_RESETN button is active-low (0 when pressed), so you will want to connect the inverted signal (~CPU_RESETN) to the register file.
  • Attach the btnc input to the we input of the register file (the center button will be used to write new values into the register file).
  • Attach sw[3:0] to the datain input of the register file. The lower four switches will be used to set the data that is written into the register file.
  • Attach sw[6:4] to the waddr and raddr input ports of the register file. These three switches will be used for the write address and first read address.
  • Attach sw[9:7] to the raddr2 input port of the register file. These three switches will be used for the second read address.

After connecting your register file, add a seven segment decoder. You can instance your module from the seven segment decoder lab or you can use the dataflow code from lab 6. In either case, you should only turn on the right most segment of the display and do not turn on any of the digit points.

Create a dataflow circuit that displays register values on the seven segment display based on the buttons as follows, from highest to lowest precedence.

  • When btnr is pressed, display the value from the second read port dataout2.
  • When btnu is pressed, display the sum of the two read port values dataout1+dataout2.
  • When btnd is pressed, display the difference of the read port values dataout1-dataout2.
  • When btnl is pressed, display the bitwise AND of the two read port values dataout1&dataout2.
  • If none of the buttons listed above are pressed (btnd, btnu, or btnr), display the value of the first register dataout1.

Once you have completed your top-level design, simulate it with the following testbench file. Continue to debug your code until your top-level design passes the testbench with no errors.

Copy the console output for your testbench simulation and add it to your laboratory report.

Exercise 3 Pass-off: Show a TA your code for your top level module and your testbench output.

Exercise #4 - Synthesis, Implementation, and Download

When your design has passed the testbench, create an XDC file for your design to declare the pin number for each top-level port of the design.

For the first time you will be attaching a clock signal. You will also need a create_clock command to declare the frequency of the clock. These commands are available in the master XDC file and can be used by uncommenting it in your project-specific XDC file.

set_property -dict { PACKAGE_PIN E3    IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {clk}];

Perform the steps of Synthesis, Implementation, and Bitstream Generation. Download your design and experiment with several cases on the board to be sure that it is working properly.

Provide a summary of your synthesis warnings.

Summarize the size of your circuit (LUTs and FFs). You'll find the number of FFs used in the same place you find the number LUTs used.

Final Pass Off

Pass off your laboratory by demonstrating the following to the TA:

  • Pass offs for Exercises 1, 2, and 3
  • Your working circuit on the Nexys4 board

How many hours did you work on the lab?

Provide any suggestions for improving this lab in the future.

Submit your SystemVerilog modules using the code submission on Learning Suite. (Make sure your SystemVerilog conforms to the lab SystemVerilog coding standards).

Personal Exploration

Here are some ideas for personal exploration in this laboratory:

  • Experiment with a different sized register file.
  • Create additional functionality for your top-level circuit.
  • Explore the internals of the FPGA design and see how the register file is mapped onto the FPGA.

Describe your personal exploration activities.


TA Notes and Feedback