6. Register File
This lab implements a register file in SystemVerilog and brings our design to the DE10-Lite board. SystemVerilog has powerful built-in features which allow us to realize entire registers within a few lines of code.
1module register_en( input logic i_clk,
2 input logic i_en,
3 input logic [63:0] i_d,
4 output logic [63:0] o_q );
5 always_ff @(posedge i_clk)
6 begin
7 if(i_en) o_q <= i_d;
8 end
9endmodule
For example, Listing 6.1 shows the implementation of an enabled 64-bit register.
The register sets the internal 64-bit state to i_d
on rising edges of the input clock i_clk
when the enable signal i_en
is asserted.
In all other cases the register remembers its internal state and returns it through o_q
.
SystemVerilog’s advanced features are key to accelerate development in production settings.
However, we’ll strive for an end-to-end understanding by following a bottom-up approach.
This means that we design our register file from simple SR latches which only store a single bit of information.
Our targeted register file is shown in Fig. 6.1 and has four internal 4-bit registers. The outside world may read data by using the two read ports or use the file’s single write port for writing data. An interactive implementation of the targeted register file is available on CircuitVerse.
6.1. Building Blocks
Following the provided schematic, we identify key building blocks:
A single 2:4 decoder:
module decoder_2_4( input logic [1:0] i_binary, output logic [3:0] o_one_hot );
Two 4:1 multiplexers:
module mux_4( input logic [1:0] i_s, input logic [3:0] i_in0, input logic [3:0] i_in1, input logic [3:0] i_in2, input logic [3:0] i_in3, output logic [3:0] o_out );
Four enabled 4-bit registers:
module register_en_4( input logic i_clk, input logic i_en, input logic [3:0] i_d, output logic [3:0] o_q );
We’d like to implement our register file from simple SR latches. This means that we’ll first implement a standalone SR latch (module
sr_latch
). We then use the implemented SR latch to realize a D latch (moduled_latch
). Next, we use two D latches to implement a D flip-flop with rising-edge trigger (moduled_flip_flop
). The D flip-flop can then be used to realize an enabled flip-flop (moduled_flip_flop_en
). Ultimately, the combination of four enabled D flip-flops gives us our targeted enabled four-bit register (moduleregister_en_4
).
Hint
We implemented the modules sr_latch
, d_latch
and d_flip_flop
together with fitting testbenches in the lectures.
You may use these implementations in this task.
Tasks
Implement the module
decoder_2_4
in the filedecoder_2_4.sv
. Test your implementation in the testbenchdecoder_2_4_tb
in the filedecoder_2_4_tb.sv
.Implement the module
mux_4
in the filemux_4.sv
. You may reuse your module implemented as part of the ALU lab (see Section 5).Implement the register-related modules, i.e.:
sr_latch
in the filesr_latch.sv
.d_latch
in the filed_latch.sv
.d_flip_flop
in the filed_flip_flop.sv
.d_flip_flop_en
in the filed_flip_flop_en.sv
.register_en_4
in the fileregister_en_4.sv
.
Test your implementations in respective testbenches.
6.2. Four-bit Register File
This task combines our building blocks into the targeted four-bit register file. We’ll use the following SystemVerilog declaration for the register file:
module register_file_4( input logic i_clk,
input logic [1:0] i_reg_read_0,
input logic [1:0] i_reg_read_1,
input logic [1:0] i_reg_write,
input logic [3:0] i_port_write,
input logic i_write_enable,
output logic [3:0] o_port_read_0,
output logic [3:0] o_port_read_1 );
An unfinished testbench is provided in the file register_file_4_tb.sv
.
Tasks
Implement the module
register_file_4
in the fileregister_file_4.sv
.Provide the internal register values in the comments of the testbench
register_file_4_tb
. Usexxxx
if the register was never written. Uncomment and finish the assertions in the testbench.
6.3. Register File in Praxis
It is time to deploy our register file.
The DE10-Lite board provides a clock signal through MAX10_CLK1_50
which we wire to i_clk
.
Further, we’ll use the first four switches to specify the ids of the two registers from which data is returned at the read ports.
The following two switches specify the id of the register to which we write data.
The remaining four switches provide the input data at the write port.
Specifically, we wire the two switches SW[1:0]
to i_reg_read_0
, the switches SW[3:2]
to i_reg_read_1
, SW[5:4]
to i_reg_write
, and SW[9:6]
to i_port_write
.
We’ll use the first push button as write enable signal, meaning that i_write_enable
should be asserted if KEY[0:0]
is low.
In terms of outputs, we display the ids of the read registers on HEX0
and HEX1
, and the id of the write register using HEX2
.
Further, we show the data at the write port using HEX3
and the data returned at the read ports using HEX4
and HEX5
.
Lastly, we enable the first led (LEDR[0:0]
) when the write enable signal is asserted.
A template of the top-level module register_file_de10_lite
is provided in the file register_file_de10_lite.sv
.
Tasks
Finish the top-level module
register_file_de10_lite
. Use the provided template.Program the FPGA of a DE10-Lite board. Explain and illustrate your programmed FPGA to the teaching personnel. In your submission include a scan of this week’s tailored coversheet which represents the deliverable of this subtask.