introduction to verilog & digital logic
TRANSCRIPT
Tools Needed Before Start
• A laptop with a web browser you like• Chrome, Edge and Firefox are all OK.
• All the experiments are based on the EDA Playground (edaplayground.com).
• Git, and register a GitHub account
• Microsoft Visual Studio Code• A lots of great extensions to explore!
• Xilinx Vivado, which is a FPGA IDE with a simulator• Webpack edition is enough if you don’t have a valid license.
• This is a plan B (because I am not sure whether the classroom has WiFi).
27 October 2019 2
About Me
Haozhe Zhu(朱浩哲)• [email protected]• 152-2176-6023• GitHub @zhutmost
Experiences• Recently, PhD. student advised by Prof. Xiaoyang Zeng.• Received B.Eng. in Micro-electronics from Fudan
University in 2017.
Research Interest• Intelligent machine vision on silicon• Deep learning acceleration
27 October 2019 3
00 01 11 10
0 1 0 1
1 1 0 1
0 1 0 0
0 1 0 0
00
01
11
10
Prerequisites
Boolean expressions• 𝑦 = 𝑎 ∪ 𝑏 ∩ 𝑐
• De Morgan’s Law
• Karnaugh Map
Gates and Registers• AND, OR, XOR, INV
• RS/D flip-flop, latch
Programming Basics• C / Python programming
• Bash command line on Linux
27 October 2019 4
ҧ𝑆
ത𝑅 ത𝑄
𝑄
D QCLK
D
Q
Courses Objectives
How to write Verilog HDL?
How to construct hierarchical digital hardware in RTL-level Verilog HDL?
How to keep a Verilog HDL-based project healthy and strong?
Note that digital backend and verification are not included in this course.
27 October 2019 5
Contents
• Section 1. Verilog Basics
• Section 2. Digital Systems – FSM, Clock & Reset
• Section 3. Why SystemVerilog is Better For Design
• Section 4. Join or Manage a Project
27 October 2019 6
Verilog BasicsSection 1
27 October 2019 7
What is Verilog HDL?
Verilog HDL• IEEE industry standard HDL used to model (describe) a digital system.
• Used in both hardware simulation and synthesis.
The History of Verilog HDL• Let’s skip it (:D).
• In 2009, Verilog is merged with SystemVerilog becoming IEEE Standard 1800.
27 October 2019 8
Hardware Modeling
Behavior Modeling Structural Modeling
Input Output
Lower-level component
Lower-level component
Higher-level component
27 October 2019 9
out[0] <= #10 in[0];for (int i = 1; i < 16; i ++){ out[i] <= #10 in[i-1] & in[i];}
Input Output
Which does RTL-level hardware description belong to, Behavior or Structural modeling?
More Terminology
• HDL = Hardware Description LanguageWhy hardware engineers are not programmers?
• RTL = Register-Transfer-LevelThe differences with gate-level or algorithm-level.
• Digital frontendWrite RTL code per specification, and then synthesize them with constrains to generate netlists.
• FPGA vs. ASICThe differences between FPGA frontend and ASIC frontend.
• Verilog HDL vs. VHDL vs. SystemVerilog
27 October 2019 10
D Q Combinational D Q
CLK
Verilog BasicsSection 1 Pro
27 October 2019 11
1. Module Structure• Port Declaration
2. Numeric Literals3. Parameters4. Signal Types
• wire• reg
5. Expressions6. Assignment7. Block Statement8. Control Logic
• if• case• for-loop
9. Generate Block10. Always Block
A Small Case – Adder
• The basic design block of Verilog is module.
• A module declaration is multiple statementssurrounded by keyword module and endmodule.
• Each statement ends with a semicolon.
• All keywords are lowercase.
• Whitespace is just for readability (in most cases).• Freedom!
• C-like comments: /*….*/, //….
`timescale 1ns/1ns
module myadder(
input wire clk,
input wire [3:0] a,
input wire [3:0] b,
output wire [3:0] c
);
reg [3:0] p;
always @(posedge clk) p <= a + b;
assign c = p;
endmodule // myadder
27 October 2019 12
D Q
clk
b
a
c
4
4 4
Module Structure
• Module port declarationmodule ABC(PORT1, PORT2, …);
• Port declaration
• Internal signal declaration
• Functional descriptionalways, assign, module instantiation
• Timing specification for simulationNot discussed in this course.
27 October 2019 13
`timescale 1ns/1ns
module myalu(
input wire clk,
input wire [3:0] a,
input wire [3:0] b,
output wire [3:0] c,
input wire mode
);
reg [3:0] p;
wire [3:0] q;
always @(posedge clk) p <= a + b;
mymul mymul0 (a, b, q);
assign c = mode == 0 ? p : q;
endmodule // myadder
Port & Signal Declaration
• Direction + Type + Bit-width + Name
• Another unusual port declaration style is non-ANSIC (Verilog-1995).• Independent type & direction declaration statements.
• Port declarations are put outside the module (task, function) statement.
27 October 2019 14
inputoutputinout
wire reg [1:0] foo_bar,+++
module myadder(a, b, c);input [3:0] a;wire [3:0] a;
// ..
Numeric Literals
• <width> Any positive numbers, 32 by default.
• <sign>If omitted, this is an unsigned number.
• <system>Binary, decimal, octal, hexadecimal.
• <digits>xX: undefined state
?zZ: high-Z state
Can be spited with underscore (_) for better readability.
27 October 2019 15
<width> <sign><system><digits>1732
sbBoOdDhH
01xX?zZ010_1
DEAD_BEEF
Parameters
• Keyword parameter is used to mark a constant signal.
• In most cases, parameters are used to configure bit-width.
• Parameter declaration & override.
27 October 2019 16
parameter integer HAOZHE = 42;parameter wire [2:0] TRUMP = 3’b101;parameter signed [3:0] TARGET_PAT = 4’hE;
module myadder #(parameter WIDTH = 3)(input wire [WIDTH-1:0] a,// ..
);localparam STATE_TRUE = 1’b1;// ..
module top();// module instantiationmyadder #(.WIDTH(4)) myadder0 (..);endmodule // top
Signal Types – wire
• wire connects physical entities, such as sub-modules and gates.
• wire-typed signals cannot store values, and must be driven by other signals.
27 October 2019 17
Input Output
Lower-level component
Lower-level component
Higher-level component
wire signed [7:0] lovely;wire [3:0] cloudy, rainy;assign lovely = cloudy & rainy;
Signal Types – reg
• reg is a abstract concept, and it is NOT a real register. (confusing?)It can be synthesized to anything, including register, latch and wire.
• reg can be assigned in always blocks.
• Which device a reg will be synthesized to, is decided by the style of always block.
• reg holds a undefined X value until it is assigned.
27 October 2019 18
reg [3:0] slam [7:0];reg signed [5:0] alsm;reg lsma;
WARNING
Wire is always a wire, reg is not always a register.
Expressions
• Logical operation vs. Bit-wise operation
a && b || !c a & b | ~c
• === vs. ==
• Logical shift vs. arithmetic shift
a >> 1 a >>> 1
• Concatenation operation. {a[2:0], b[4:3]}, {{3{a}}, b}
• Reduced operation.
&a ^b |c
• Ternary conditional operation. are_you_baby ? come_in : go_out
• Conversion between signed and unsigned. $signed(a), $unsigned(b)
• Vector slicing. a[3:0], b[7-:4], b[4+:4]
27 October 2019 19
WARNINGSome expressions if difficult to be synthesized with reasonable resources on a specific platform.
Assignment
• Continuous AssignmentLHS of the statement must be a wire-typed signal.
assign a = b + c * t;assign {a[2], a[0]} = 2’b10;
• Blocking AssignmentThe value is assigned to the LHS at once. (just like C language)
begin a = b; c = a; end
• Non-blocking AssignmentThe difference will be introduced later.
begin a <= b; c<= a; end
27 October 2019 20
Block Statement
• begin-end block• Process in serial
begin<Statement0>;<Statement1>;
end
• fork-join block (Un-synthesized)• Process in parallel
fork<Statement0>;<Statement1>;
join
• Guess the result?• Blocking assignment
• Non-blocking assignment
27 October 2019 21
integer a=3, b=4, c=5;initial begin
b = a;c = b;
end
integer a=3, b=4, c=5;initial begin
b <= a;c <= b;
end
If-else Block
• if blockif (<expression>)
<block statement>
• if-else blockif (<expression>)
<block statement>
else
<block statement>
A simple case
if (mode == 2’b01) begin
y = a + b;
z = a – b;
end
else if (mode == 2’b10) begin
y = a * b;
z = a >> b;
end
27 October 2019 22
Case Block
case(<expression>)<expression>: <block statement><expression>: <block statement>default: <block statement>
endcase
• Don’t forget default to avoid unpredictable behavior.
• The entries in a same case block is not parallel. That is to say, case is just a grammar candy of if.
• Usual Casecase(a)
3’b001: // Do something3’b010: // Do something elsedefault: ;
endcase
• Reversed Casecase(1)
a[0]: // Do somethinga[1]: // Do something elsedefault: ;
endcase
27 October 2019 23
For-loop Block
integer k;
for (k = 0; k < 16; k = k + 1)
<block statement>
• Don’t use a iteration index variable (k) in multiple loops.
• k shouldn’t be a logic signal.
• while, repeat blocks are similar.
• The (almost) only case you need for-loop in hardware is to initialize a memory.
reg [3:0] mem [7:0];
integer k;
always @(posedge clk) begin
if (rst) begin
for (k = 0; k < 8; k = k + 1) begin
mem[k] <= 0;
end
end else begin //..
end
27 October 2019 24
Generate Block
• Loop Generate Blockgenvar i;
generate
for (i = 0; i < 16; i = i + 1) begin: gen_add
myadder a0(.a(a[i]), .b(b[i]), .c(c[i]));
end
endgenerate
• Conditional Generate Block
• Case Generate Block
• One genvar can be used only once!
• The block statement inside a generate block needs a name (gen_add).
\gen_add[0] .a0.a
• The generate expression must be decided when synthesized!
27 October 2019 25
Combinational Always Block
always @(<event> or <event>)
<block statement>
• As long as the event list is valid, the block statement is processed once.
• Combinational Always Blockalways @(a or b) begin
if (&a == 1’b1) begin
c = b + 3’d1;
end
else begin
c = b;
end
end
assign c = &a ? b + 3’d1 : b;
27 October 2019 26
WARNINGc is a reg-typed variable, but physically it is a wire.
Latch Always Block
• Latch Always Blockalways @(a or b) begin
if (&a == 1’b1) begin
c = b + 3’d1;
end
end
• We rarely use latches in most digital systems. To avoid create unwanted latches, please ensure that there is no undefined result in your combinational always block.• If a latch is synthesized, your lint tool will report a
warning.
• Don’t forget default entry in case block
• Add a default result at first of the always block.always @(a or b) begin
c = b;if (&a == 1’b1) begin
c = b + 3’d1;end
end
27 October 2019 27
WARNINGc is a reg-typed variable, but physically it is a latch.
Sequential Always Block
• How to create a real register?reg [2:0] c;
always @(posedge t) begin
if (!k) begin
c <= 3’d0;
end
else begin
c <= b + 3’d1;
end
end
D Q
t
b
k
33
301
0
c
27 October 2019 28
Note that signals t and k can be any general signals, besides clock and reset.
Always Block & Blocking Assignment
• Combinational & Latch Always BlockBlocking Assignment
• Sequential Always BlockNon-blocking Assignment
27 October 2019 29
Quiz 1 – Leading Zero Computing
• Given a N-bit unsigned integer input, where N is 2k. Please calculate the leading zeros in this input in Verilog. Such a circuit is also known as thermometer decoder, which widely used in ADC.• Step 1. Complete this challenge in combinational circuit, without registers.
• Step 2. Stage the outputs with registers. Why is it better?
• Step 3. How to optimize your circuit (not your code) for better timing?
• Step 4. Please try to refactor your circuit in pipeline.
27 October 2019 30
Verilog BasicsSection 1 Pro Plus
27 October 2019 31
Continue …11. Task & Function Block12. System Functions13. Compile-time Pre-processing14. Write a Simple Testbench
System Functions
• Print logs to your console.• $display/write(<format>, p0, p1, …);• $write(“LegBro is a flower, %h, %d, %m, %%.\nWoW”, 1, 2);• >> LegBro is a flower, 1, 2, the.path.of.this.module, %.
WoW
• Dump waveforms in the VCD format.• $dumpfile(“my_wave.vcd”);• $dumpvars(2, top.mymodule);• The VCD file size is very large, don’t dump all signals.
27 October 2019 32
System Functions
• Print logs in a file.• Open a file with: h = $fopen(<path>)• Remember close file with $fclose(h)• Log with $fdisplay, $fwrite, $fscanf• Multi-channel descriptor
• What does the value of fp1, fp2 and fp3 mean?
• fp1 = 32’b0000_0000_0000_0010• fp2 = 32’b0000_0000_0000_0100
27 October 2019 33
integer fp1, fp2, fp3;initial begin
fp1 = $fopen(“a0.log”);fp2 = $fopen(“a1.log”);fp3 = $fopen(“a2.log”);// print to fp1$fdisplay(fp1, “Hello”);// print to fp1 & fp2$fdisplay(fp1 | fp2, “Tim Cook”);// print to stdout & fp3$fdisplay(fp3 | 1, “Apple is awesome”);
end
System Functions
• Please guess the displayed result.
• The execution sequence of block statements is unknown. To avoid unexpected behavior, use $strobeinstead of $display.
• $strobe executes after other assignments at the same time are all done.
27 October 2019 34
reg a, b;always @(posedge clk) begin
b <= 1’b1;a <= b;
end
always @(posedge clk) begin$display(“a=%d %b=%d”, a, b);
end
System Functions
• Complete/stop the simulation.• $finish(2); • $stop;
• Get current time in a simulation.• $time; $realtime;
• Monitor some expressions or variables, and print information no matter when they changes.• $monitor(“var_x = %d var_y = %d”, x, y); • $monitor($time, , “a = %d”, a);
• Get a 32-bit random number, which is useful to generate test inputs.• always @(posedge clk) begin a <= $random % 5; end
27 October 2019 35
System Functions
• Initialize a 2-D vector with a file.• Binary -> $readmemb• Hexadecimal -> $readmemh
• The data file syntax• One line per data.
• Begin address is 0x0 by default.
• If you want to specify an address for the following lines, use “@<addr>”.
27 October 2019 36
// module btbreg [15:0] mem_a [0:1023];
// module tb_topinitial begin
$readmemh(“boys.txt”, cpu.btb.mem_a);end
// boys.txt@0dead -> mem_a[0]beaf -> mem_a[1]@160010 -> mem_a[16]0550 -> mem_a[17]…
• Define a macro
• Conditional compilation
27 October 2019 37
Compile-time Pre-processing
`define DATA_WIDTH 18reg [`DATA_WIDTH-1:0] mydata;
`define HUAWEI_MATE 30`ifdef IPHONE
`define RESOLUTION 1080`elsif HUAWEI_MATE
`define RESOLUTION 480`endif
`define CPU_AXI_BUSmodule my_cpu #(
parameter DBUS_WIDTH = 16)(
input wire clk,`ifndef CPU_AXI_BUS
// declare Tilelink bus ports hereinput wire [DBUS_WIDTH-1:0] dbus_in,
`else// declare AXI bus ports hereinput wire [DBUS_WIDTH-1:0] axi_rdata,
`endif);
Compile-time Pre-processing
• Include an external file.• `include “abc.vh”
• This method is equivalent to copy and paste your code here.
27 October 2019 38
// abc.vh`define DATA_WIDTH = 16;
// adder.v`include “abc.vh”module adder(
input wire [`DATA_WIDTH-1:0] a,input wire [`DATA_WIDTH-1:0] b,output wire [`DATA_WIDTH-1:0] c
);// …
endmodule
// mul.vmodule mul(
input wire [`DATA_WIDTH-1:0] a,);
WARNING`include will introduce serious inter-file macro pollution.
Quiz 2 – Finite State Machine
• Let’s try to code JTAG TAP. (Two-stage vs Three-stage FSM)
27 October 2019 39
SystemVerilog for DesignSection 3
27 October 2019 40
1. Logic2. Always Block3. Package4. Enumeration and Structure5. Typedef
Logic
• In SystemVerilog, use logic as signal type instead of reg & wire.• It is confusing to construct combinational
circuit with type reg.
• With one exception, use wire to connect two inout ports.
27 October 2019 41
`timescale 1ns/1ns
module myalu(
input logic clk,
input logic [3:0] a,
input logic [3:0] b,
output logic [3:0] c,
input logic mode
);
logic [3:0] p;
logic [3:0] q;
always @(posedge clk) p <= a + b;
mymul mymul0 (a, b, q);
assign c = mode == 0 ? p : q;
endmodule // myalu
Always Block
• The always block in Verilog can be synthesized to combinational circuit, latches or registers, according to your coding style. • Use always_comb / always_latch for combinational circuit and latches. We don’t
have need to write sensitive event list.
27 October 2019 42
always_comb begin
if (&a == 1’b1) begin
c = b + 3’d1;
end
else begin
c = b;
end
end
always_latch begin
if (&a == 1’b1) begin
c = b + 3’d1;
end
end
always_ff @(posedge clk) begin
if (&a == 1’b1) begin
c <= b + 3’d1;
end
else begin
c <= b;
end
end
Always Block
• The always block in Verilog can be synthesized to combinational circuit, latches or registers, according to your coding style. • Use always_ff for registers.
27 October 2019 43
Package
• Don’t use `include to import configuration parameters, because we have a much better solution in SystemVerilog—package.
27 October 2019 44
// adder.vmodule adder
import pkg_abc::*; #(parameter OTHER_PARAM = 3
)(input wire [DATA_WIDTH-1:0] a,input wire [DATA_WIDTH-1:0] b,output wire [DATA_WIDTH-1:0] c
);endmodule
// mul.vmodule mul(input wire [DATA_WIDTH-1:0] a,
);
// pkg_abc.svpackage pkg_abc;
parameter DATA_WIDTH = 16;parameter logic [2:0] MAT_PAT = 3’b101;
// typedef
endpackage
Enumeration & Structure
• Enumeration• Widely used as FSM states.
• Structure• Bundle multiple signals into one.
27 October 2019 45
enum logic [2:0] {STATE_IDLE = 3’b001,STATE_RX = 3’b010,STATE_TX = 3’b100
} state, state_next;
always_ff @(posedge clk) beginif (rst) state <= STATE_IDLE;else state <= state_next;
end
struct {logic [3:0] kernel_hori;logic [3:0] kernel_vert;logic [2:0] stride;logic [7:0] channel;
} conv_kernel;
always_ff @(posedge clk) beginconv_kernel.stride <= 3’d1;
end
assign sth_new = conv_kernel.channel;
Typedef
• Use keyword typedef to construct your own types.
• Hint: Combine typedef with enum/struct in packages.
27 October 2019 46
// conv.vmodule conv
import pkg_abc::*; #(parameter OTHER_PARAM = 3
)(input logic din_stream,input CONV_KERNEL_t kernel,output logic dout_stream
);endmodule
// pkg_abc.svpackage pkg_abc;
typedef struct {logic [3:0] kernel_hori;logic [3:0] kernel_vert;logic [2:0] stride;logic [7:0] channel;
} CONV_KERNEL_t;
endpackage
More to Explore
• Multi-dimension Array
• Packed & unpacked array / structure
• Interface
• Implicit Signal Connection
27 October 2019 47
Further Reading & Study
• Mohit Arora, 硬件架构的艺术
• Cliff Cummings, http://www.sunburst-design.com/papers/
• Stuart Sutherland, Verilog & SystemVerilog 101 Gotchas
•韩军, 专用集成电路讲座(Recommended)
•王明宇, ASIC courses
• Chisel, construct hardware with Scala
• Don’t spend too much time on language itself. Dive into practical projects!
27 October 2019 48