6. Register File

This lab implements a register file in SystemVerilog and brings the design to the DE10-Lite board. SystemVerilog has built-in features that let us implement whole registers in a few lines of code.

Listing 6.1 Module register_en which implements an enabled 64-bit register.
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 an enabled 64-bit register. On the rising edge of i_clk, the register sets the internal 64-bit state to i_d when i_en is asserted. Otherwise, the register holds its state and drives o_q. These features accelerate development in production settings. However, we aim for end-to-end understanding with a bottom-up approach. So we build the register file from single-bit SR latches.

../_images/register_file_4.svg

Fig. 6.1 Register file with two read ports and one write port. The register file contains four 4-bit registers.

Fig. 6.1 shows a register file with four internal 4-bit registers. External logic reads through two ports and writes through one port. An interactive implementation of the targeted register file is available on CircuitVerse.

6.1. Building Blocks

From the provided schematic, the building blocks are:

  1. A single 2:4 decoder:

    module decoder_2_4( input  logic [1:0] i_binary,
                        output logic [3:0] o_one_hot );
    
  2. 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 );
    
  3. 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 implement the register file using SR latches. First, implement a standalone SR latch (module sr_latch). Then use it to build a D latch (module d_latch). Next, two D latches form a rising-edge triggered D flip-flop (module d_flip_flop). From that, derive an enabled flip-flop (module d_flip_flop_en). Four enabled D flip-flops make an enabled 4-bit register (module register_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

  1. Implement the module decoder_2_4 in decoder_2_4.sv. Test it with the testbench decoder_2_4_tb in decoder_2_4_tb.sv.

  2. Implement the module mux_4 in mux_4.sv. You may reuse code from the ALU lab (see Section 5).

  3. Implement and test the following modules:

    • sr_latch in sr_latch.sv.

    • d_latch in d_latch.sv.

    • d_flip_flop in d_flip_flop.sv.

    • d_flip_flop_en in d_flip_flop_en.sv.

    • register_en_4 in register_en_4.sv.

6.2. Four-bit Register File

This task combines the building blocks into the four-bit register file. We’ll use the following SystemVerilog declaration for the register file:

Listing 6.2.1 SystemVerilog declaration of the four-bit 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: register_file_4_tb.sv.

Tasks

  1. Implement the module register_file_4 in the file register_file_4.sv.

  2. Provide the internal register values in the comments of the testbench register_file_4_tb. Use xxxx if the register was never written. Uncomment and finish the assertions in the testbench.

6.3. Register File in Practice

Now deploy the register file. Use the 50 MHz board clock MAX10_CLK1_50 for i_clk. Use the first four switches to select the two read-register IDs. The next two switches select the ID of the write-register. The remaining four switches provide the 4-bit write data. Wire SW[1:0] to i_reg_read_0, SW[3:2] to i_reg_read_1, SW[5:4] to i_reg_write, and SW[9:6] to i_port_write. Use push-button KEY0 as the write-enable and treat low as asserted.

Display the read-register IDs on HEX0 and HEX1 and the write-register ID on HEX2. Show the write-port data on HEX3 and the read-port data on HEX4 and HEX5. Lastly, drive LEDR[0] when the write-enable is asserted. A template for register_file_de10_lite is provided: register_file_de10_lite.sv.

Tasks

  1. Finish register_file_de10_lite using the template.

  2. Program the FPGA of a DE10-Lite board. Demonstrate the design to the teaching personnel. Include a scan of the tailored coversheet in your submission.