Lab 0
Lab 0
Lab 0 — SystemVerilog
Abstract
This document helps you familiarize yourself with SystemVerilog HDL (Hard-
ware Description Language), which you will use to design digital logic blocks, and
then you will learn the basic of verifying your RTL design.
In case you meet an error or have any improvement in this document, please
email the TA: [email protected] with the subject
“[COMPARCH203: FEEDBACK]”
1 Objectives
• Familiarize yourself with basic design flow.
1.1 Prerequisites
• Ubuntu
• Quartus
Additionally, you need to learn some common commands to work in UNIX/Linux en-
vironment. You may find this cheatsheet useful.
1
2 Design Flow
Figure 1 shows the basic design flow of design a digital logic block. In this diagram,
designers have to follow four steps:
2. Lint Check is a process of static code analysis to check the quality of the code.
Lint Check will check your code with a list of rules, to find any violations —
syntax errors or potential code lines or blocks that may cause errors or bugs when
running. This step is needed to perform right after you finish RTL Coding. If
there are any flags or errors, you need to read them carefully to know exactly the
rules you violated to fix your code.
Lab 0 2
3 Combinational Logic Modeling
3.1 Problem
! → The data width of data0 , data1 , and result is 3, and that of sel is 2.
3.2 Design
A project should be organized systematically to manage and maintain easily later. First,
in the terminal, type the below command to download the example projects of lab 0
from GitHub to your local computer.
Inside the new-downloaded directory, lab0 , there are two directories, ex01 and ex02 .
The former is of this section, go to that directory by typing cd lab0/ex01 . Type ls
to see all files and directories in the current directory; an alternative is tree which
displays the tree directory.
~/gi/c/lab0/ex01 $ ls
drwxr-xr-x@ - ioachimus 21 Feb 15:53 quartus
drwxr-xr-x@ - ioachimus 21 Feb 15:53 src
drwxr-xr-x@ - ioachimus 21 Feb 15:55 tb
Lab 0 3
~/gi/c/lab0/ex01 $ tree
.
|-- quartus
| |-- de10_pin.qsf
| |-- de2_pin.qsf
| `-- wrapper.sv
|-- src
| `-- design_1.sv
`-- tb
|-- driver.cpp
|-- filelist
|-- makefile
|-- tb_top.cpp
`-- top.sv
4 directories, 9 files
~/gi/c/lab0/ex01 $
– de2_pin.qsf is a pin assignments file for DE2 with its pins named accord-
ing to this file.
– de10_pin.qsf is a pin assignments file for DE10 with its pins named ac-
cording to this file.
– wrapper.sv is to connect the design’s pins to those of DE2/DE10.
Question
Lab 0 4
3.2.2 RTL Coding
As all design files are placed into src , type gedit src/design_1.sv to open that file
while you’re in directory ex01 . If you want to use vim , you could check this website
for some basic commands in vim.
1 module design_1 (
2 // input
3 input logic [2:0] data0_i,
4 input logic [2:0] data1_i,
5 input logic [1:0] sel_i,
6
7 // output
8 output logic [2:0] result_o
9 );
10
11 // local declaration
12 logic [2:0] and_tmp; // temporary for and result
13 logic [2:0] or_tmp; // temporary for or result
14 logic [2:0] xor_tmp; // temporary for xor result
15
29 endmodule : design_1
Lab 0 5
3.2.3 Lint Check
1 ../src/design_1.sv
Lab 0 6
The example code has 6 warnings. For the first one — %Warning-IMPLICIT , the
log specifically states the violation, a suggestion to tackle it, and also a link for more
information on that particular warning. The original design, indeed, has a typo in line
16, fix it and lint again.
This time, linting alerts the violation of CASEOVERLAP , which is, according to the log,
“case values overlap” because of the value 2’b10 is repeated twice. Fix this error at
line 25 and lint again, and there are no warnings or errors.
Now, the design is free of syntax errors and potential bugs, but, still, the next step will
prove its correctness.
Question
Lab 0 7
3.3 Verification
3.3.1 Setup
This process is to verify the correctness of the design — for each set of inputs, only
one set of outputs is right. Although designers could drive a list of inputs and com-
pare the corresponding outputs they’ve already computed with the design’s outputs —
directed tests, verifying a design with a vast number of inputs will be improbable and
tedious. Hence, randomly driving the inputs and automatically monitoring the outputs
will provides a more accurate and reliable verification methodology as in Figure 3.
First, preparing top.sv , which is alreay written and placed into tb directory.
Lab 0 8
1 module top (
2 // inputs
3 input logic clk_i,
4 input logic [2:0] data0_i,
5 input logic [2:0] data1_i,
6 input logic [1:0] sel_i ,
7
8 // outputs
9 output logic [2:0] result_o
10 );
11
12 design_1 dut (
13 .data0_i (data0_i ),
14 .data1_i (data1_i ),
15 .sel_i (sel_i ),
16 .result_o(result_o)
17 );
18
30 endmodule : top
1 #define MAX_SIM 20
2
Lab 0 9
MAX_SIM is the number of inputs generated. Basically, illustrated in the code above, the
randomized values are set by following a syntax of dut-> and the inputs with rand()
function. This function in C++ generates a 32-bit number, but because an input varies
in width, the modulo operator will restrict the value, which rand() assigns to the input.
Question
3.3.2 Simulation
The error states that the assertion at line 27 failed. In top.sv , that line indicates the
design failed to handle the case 2’b11 , the xor operator. To investigate the waveform
for debugging, run make wave . Figure 5 shows the result 3’b101 instead of 3’b010 .
A little bit further, design_1.sv in src directory containing the source code has a bug
in line 18. The operator is intentionally altered, which is xnor instead. Fix it and run
simulation again.
Lab 0 10
Figure 5: Waveform of the first simulation
3.4 Implementation
3.4.1 Setup
To implement the design in FPGA, wrapper.sv is to instantiate the design and connect
FPGA pins to it. In this example, DE2 is used, so you could look up the pin names in
this link. You may check DE2 User Manual in quartus directory. design_1.sv uses
switches for inputs and LEDs for outputs. The example wrapper.sv is already written
and placed into quartus directory.
1 module wrapper (
2 // inputs
3 input logic [7:0] SW,
4 // outputs
5 output logic [2:0] LEDR
6 );
7
8 design_1 dut (
9 .data0_i ( SW[2:0]),
10 .data1_i ( SW[5:3]),
11 .sel_i ( SW[7:6]),
12 .result_o(LEDR[2:0])
13 );
14
15 endmodule : wrapper
Lab 0 11
Question
Lab 0 12
4 Sequential Logic/FSM Modeling
Problem
Design a counter to count each time a button is pressed then display the number
using 7-segment LED.
4.1 Analysis
The design requires a button and a 7-segment LED. It, absolutely, needs a clock and an
active low reset. Based on the requirements:
• A module to receive the signal from a button and its output will be high in only
one cycle if the button is pressed.
• A counter to count, let’s say, from 0 to 9 (maximum).
• A module to decode a binary number to data that drives a 7-segment LED.
The button module is designed as an FSM with three states: IDLE, PRESS, and HOLD.
Lab 0 13
4.2 Design
4.3 Verification
Before diving into linting and simulating, here are some notices regarding writing as-
sertions:
1. This “more complex” example needs to assert the data between module button
(output) and counter (input), so the assertions have to be placed in design_2.sv .
The “clock requirement” of using assertions is satisfied.
2. $past keyword is to sample the data in the previous cycle, and thus line 2–6 and
line 14 are needed to sample the write data. Also, When using $past , remember
to AND the pastvld .
3. Line 1 and 15 are to make sure the assertions are checked when running simula-
tion with Verilator but ignored when running Quartus.
1 `ifdef VERILATOR
2 /*verilator lint_off UNUSED*/
3 logic pastvld;
4 always @(posedge clk_i) begin : proc_setup_past
5 pastvld <= 1'b1;
6 end
7
Question
1. This design has the maximum number of 9, so MAX_SIM must be set to a large
number.
Lab 0 14
2. Because driver.cpp is a C++ file, assigned values could be manipulated use-
fully. Such as, the reset should be low for several cycles from the beginning, so
using sim_unit , illustrated in Figure 8, as in line 4, it will certainly be low for 4
cycles from the beginning. Yet, it is just a part of the story.
Figure 8: sim_unit
3. The reset should be 0 at some points, to prove that the counter will reset to 0 and
count again, but its probability should be low to show the case that the counter
only counts to 9 and stop. The expression rand()%30 != 0 has 1/30 = 3.3%
chance of being FALSE or 0. It is sufficient to create a reset to verify this design.
Question
Question
Lab 0 15
4.4 Implementation
Question
5 Exercise
Question
Design a traffic light that has 3 colors: RED, AMBER, and GREEN. This traffic
light cycles through:
• GREEN in 6 seconds
• AMBER in 2 seconds
• RED in 7 seconds
It also has a button for pedestrians, when one pushes it, the traffic light itself will
turn RED.
Try to use assertions to verify the design.
Lab 0 16