ELEC0010 Digital Design Lab
ELEC0010 Digital Design Lab
Introduction
In these lab activities, you will design and simulate the central processing unit (CPU)
microarchitecture shown below. Read the accompanying notes on microprocessor
architecture and implementation, before starting the design activities.
PCSrc
Control Branch
23:20
Unit
ALUControl1:0
ALUSrc
RegWrite
CLK
CLK
15:12 WE3 Zero
+ 0 Instr A1 SrcA
A RD 11:8 RD1
8’b1 1 PC’ PC A2
ALU
Instruction 19:16
Memory A3 RD2 0 SrcB ALUResult
reset Register
WD3 File 1
cpu_out
7:0
cpu_out7:0
immediate
The components you will implement are: the arithmetic logic unit (ALU), the register file, the
program memory, the program counter and the control unit. You will then combine these in a
hierarchical design to implement the microprocessor, and program it with simple machine code
ELEC0010 Digital Design Lab
instructions. To assist you with your designs, you can refer to the document ‘Example
SystemVerilog modules’ on Moodle.
The SystemVerilog code should be written in Visual Studio Code editor, simulated using Icarus
Verilog and the simulation waveforms plotted using GTKWave. Refer to the guide to using
these tools on Moodle.
Write a lab report, presenting the SystemVerilog code for each module, the associated
testbench code, and the simulation results (input and output signal values and waveforms).
The marks awarded for each activity are specified at the bottom of each page.
2
ELEC0010 Digital Design Lab
ALUControl1:0
Zero
SrcA7:0
ALUResult7:0
ALU
SrcB7:0
Write, as a SystemVerilog module with the name alu, a behavioural description of an arithmetic
logic unit.
The data inputs, SrcA and SrcB, and the data output, ALUResult, are 8-bit vectors. The
ALUControl input is a 2-bit vector.
The 1-bit output flag Zero = 1 if ALUResult == 0, else Zero = 0. The ALU carries out bitwise
logical operations, and addition and subtraction operations, as specified in the table below.
Write a testbench to test the ALU. Since it’s infeasible to test your design with all possible input
vectors (there are too many), it is sufficient to test each of the ALU operations using one set
of test vectors (input values). Carry out the simulation using Icarus Verilog.
[10 marks]
3
ELEC0010 Digital Design Lab
2. Register file
write_enable
CLK
RA13:0
A1 WE3
RD1 RD17:0
RA23:0 A2
WA3:0 A3 RD27:0
Register RD2
ALUResult7:0 WD3 File
cpu_out
cpu_out7:0
The register file has sixteen 8-bit registers. The register with address 0 always contains the
value 0. The other 15 registers can have values written into them through the WD3 port.
The contents of any two of the registers (with addresses specified by the 4-bit inputs RA1 and
RA2) are continuously output as RD1 and RD2. On the positive edge of the clock, if
write_enable is asserted, and A3 > 0, the input ALUResult is written into the register at address
A3 through the WD3 port.
The module includes an output port cpu_out7:0, which continuously outputs the contents of the
register at address 15. This will form the main external output of the microprocessor.
Write a SystemVerilog module, with the name reg_file, implementing this register file.
Write a testbench to simulate your register. Test your design with at least 8 sets of test vectors.
[10 marks]
4
ELEC0010 Digital Design Lab
write_enable
ALUSrc
ALUControl1:0
CLK
Zero
RA13:0
A1 WE3 SrcA7:0
RD1
RA23:0 A2 ALUResult7:0
ALU
WA3:0 A3
Register RD2 0 SrcB7:0
WD3 File 1
cpu_out
cpu_out7:0
immediate7:0
Write a SystemVerilog module with the name reg_file_alu, implementing the combined ALU
and register file as shown above.
Include a 2-to-1 multiplexer, which selects either the RD2 output from the register file, or an
external input (immediate) to be input to the ALU input port SrcB.
Write a testbench to simulate the reg_file_alu module, and test it with at least 8 sets of test
vectors.
Note that, when the simulation starts, all the registers except x0 will contain 8’hx. To write a
value into a register, input the value through the immediate port (ALUSrc = 1), add it to the
contents of the register x0 (RA1 = 4’h0, ALUControl = 2’b10) and write the result into the
register file (write_enable = 1).
[20 marks]
5
ELEC0010 Digital Design Lab
4. Instruction memory
PC7:0 A RD Instr23:0
Instruction
Memory
Write a testbench and test the operation of the ROM module, with 8 input test vectors:
PC[7:0] = 8h’00, 8h’01, 8h’02, 8h’03, … 8h’07. Check that each of the machine code
instructions is output correctly.
[10 marks]
6
ELEC0010 Digital Design Lab
5. Program Counter
PCSrc
CLK
+ 0
8’b1 1 PC’7:0 PC7:0
reset
immediate7:0
Module name pc
Output ports PC[7:0]
Input ports immediate[7:0], PCSrc, CLK, reset
Implement the 8-bit program counter shown above, as a SystemVerilog module with the name
pc. The register should be updated on the positive edges of the clock, and have an active high
reset. The 2-to-1 multiplexer selects the next value of PC as either PC+1 (the next instruction
in the program will be fetched) or the input immediate (the program branches to an instruction
elsewhere).
Write a testbench to test the operation of your program counter module, with at least 8 sets of
test vectors. Remember to assert the reset during the first part of the simulation to set the
program counter to 0x00.
[10 marks]
7
ELEC0010 Digital Design Lab
PCSrc
CLK
+ 0
8’b1 A RD Instr23:0
1 PC’7:0 PC7:0
Instruction
Memory
reset
immediate7:0
Implement the system shown above, as a SystemVerilog module with the name
instruction_memory_pc, combining the ROM array and the counter you wrote in Activities 4
and 5.
Write a testbench to test the operation of the instruction_memory_pc module, ensuring that it
correctly outputs all 7 instructions in the memory. Remember to apply a reset at the start of
the simulation.
[10 marks]
8
ELEC0010 Digital Design Lab
7. Control unit
Control Branch
opcode3:0 Unit
ALUControl1:0
ALUSrc
RegWrite
Write a SystemVerilog module implementing the control unit, with the name control_unit. This
is combinational logic, with the following truth table:
9
ELEC0010 Digital Design Lab
PCSrc
Control Branch
23:20
Unit
ALUControl1:0
ALUSrc
RegWrite
CLK
CLK
15:12 WE3 Zero
+ 0 Instr A1 SrcA
A RD 11:8 RD1
8’b1 1 PC’ PC A2
ALU
Instruction 19:16
Memory A3 RD2 0 SrcB ALUResult
reset Register
WD3 File 1
cpu_out
7:0
cpu_out7:0
immediate
As the final step, write a top-level module with the name cpu which instantiates the lower-level
modules (reg_file_alu, instruction_memory_pc, control_unit), and interconnects them,
together with an AND gate, as shown in the microarchitecture schematic shown above.
Write a testbench to test that the program in the instruction memory is correctly executed by
the microprocessor. Remember to apply a reset at the start of the simulations. The cpu_output
should be log2(32) = 5 after the program has been executed.
[20 marks]
10