0% found this document useful (0 votes)
17 views10 pages

ELEC0010 Digital Design Lab

The document outlines a series of lab activities for designing and testing components of a central processing unit (CPU) using SystemVerilog. Key components include an arithmetic logic unit (ALU), a register file, instruction memory, a program counter, and a control unit, with detailed instructions for implementation and testing. Each module requires a corresponding testbench and simulation to validate functionality, culminating in a complete CPU design that executes a specific program.

Uploaded by

unoruno
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views10 pages

ELEC0010 Digital Design Lab

The document outlines a series of lab activities for designing and testing components of a central processing unit (CPU) using SystemVerilog. Key components include an arithmetic logic unit (ALU), a register file, instruction memory, a program counter, and a control unit, with detailed instructions for implementation and testing. Each module requires a corresponding testbench and simulation to validate functionality, culminating in a complete CPU design that executes a specific program.

Uploaded by

unoruno
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

ELEC0010 Digital Design lab

Design and test activities:


1. Arithmetic Logic Unit (ALU)
2. Register file
3. Combined ALU and register file
4. Read-only memory (ROM)
5. Program counter
6. Combining the ROM with program counter
7. Control unit
8. Complete CPU design

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

1. Arithmetic logic unit (ALU)

ALUControl1:0

Zero
SrcA7:0
ALUResult7:0

ALU
SrcB7:0

Module name alu


Output ports ALUResult[7:0], Zero
Input ports SrcA[7:0], SrcB[7:0], ALUControl[1: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.

ALUControl Operation Description


00 a&b Bitwise logical operation: a AND b
01 a|b Bitwise logical operation: a OR b
10 a+b Arithmetic operation, addition: a + b
11 a−b Arithmetic operation, subtraction: a − b

Note that, in SystemVerilog, negative values are represented in 2’s-complement, so for


example, 410 − 710 = −310 would be implemented as:
000001002 + 111110012 = 111111012, or, expressed in hexadecimal: 0x04 + 0xF9 = 0xFD

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

Module name reg_file


Output ports RD1[7:0, RD2[7:0], cpu_out[7:0]
Input ports RA1[3:0], RA2[3:0], WA[3:0], ALUResult[7:0], write_enable, CLK

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

3. Combining the ALU and register file

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

Module name reg_file_alu


Output ports ALUResult[7:0], cpu_out[7:0], Zero
Input ports RA1[3:0], RA2[3:0], WA[3:0], immediate[7:0], write_enable, ALUSrc,
ALUControl[1:0], CLK

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

Module name instruction_memory


Output port Instr[23:0]
Input port PC[7:0]

Write a SystemVerilog module, with the name instruction_memory, implementing a read-only


memory (ROM) array, storing 256 words of data, with each word being 24 bits wide. Use the
example code for the ROM array in the ‘Example SystemVerilog modules’ document.
The output Instr23:0 is asynchronous (it updates instantly whenever the input address is
changed). The machine code program to be stored in the ROM is read in from a text file (with
the filename ‘program.txt’, saved in the same folder as the SystemVerilog modules) in a single
pass behaviour (keyword initial), using the $readmemh system task.
In the text file, list the eight 24-bit values (written as 6-digital hexadecimal numbers) listed in
the ‘Machine code program’ column in the table below. This is a machine code program which
finds the binary logarithm (log2) of the value stored in register x2, and stores the result in
register x15:

Instruction Machine Assembly program


memory code
address program
00 610001 addi x1, x0, 1 # Write the value 1 into register x1
01 620020 addi x2, x0, 32 # Write the value 32 into x2
02 6F0000 addi x15, x0, 0 # Write the value 0 into x15
03 701207 beq x1, x2, 7 # Branch to instruction 7 if x1 == x2 == 32
04 211100 add x1, x1, x1 # x1 = 2 * x1
05 6FF001 addi x15, x15, 1 # Increment value in register x15
06 700003 beq x0, x0, 3 # Unconditional branch to instruction 3
07 700007 beq x0, x0, 7 # Unconditional branch to instruction 7

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

6. Combining the ROM with program counter

PCSrc

CLK

+ 0
8’b1 A RD Instr23:0
1 PC’7:0 PC7:0
Instruction
Memory
reset

immediate7:0

Module name instruction_memory_pc


Output ports Instr[23:0]
Input ports immediate[7:0], PCSrc, CLK, reset

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

Module name control_unit


Output ports Branch, ALUControl[1:0], ALUSrc, RegWrite
Input ports opcode[3:0]

Write a SystemVerilog module implementing the control unit, with the name control_unit. This
is combinational logic, with the following truth table:

Instruction Op code RegWrite ALUSrc ALUControl1:0 Branch


and 0000 1 0 00 0
or 0001 1 0 01 0
add 0010 1 0 10 0
sub 0011 1 0 11 0
andi 0100 1 1 00 0
ori 0101 1 1 01 0
addi 0110 1 1 10 0
beq 0111 0 0 11 1

The simplest approach is to write it using a case statement.


Write a testbench for the control_unit module, and test it with at least 8 test vectors.
[10 marks]

9
ELEC0010 Digital Design Lab

8. Complete CPU design

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

Module name cpu


Output ports ALUResult[7:0], cpu_out[7:0]
Input ports CLK, reset

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

You might also like