You are on page 1of 99

Accelerating Systems with

Programmable Logic Components


Lecture 08 Verification I
Basic concepts and methods of Verification

1DT109 ASPLOC
2022 VT1-VT2

Yuan Yao, yuan.yao@it.uu.se

2022-09-19 1
Agenda
• Introduction to Verification
• Verification model
• Verification abstraction
• Verification task
• Introduction to SystemVerilog
• Basic building blocks
• Delta delay

2022-09-19 2
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 3
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 4
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy
• Expensive to build

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 5
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy
• Expensive to build
• Spans shorter range

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 6
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy
• Expensive to build
• Spans shorter range
• Collapse in 1907
and 1916, twice!

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 7
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy
• Expensive to build
• Spans shorter range
• Collapse in 1907
and 1916, twice!

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 8
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy
• Expensive to build
• Spans shorter range
• Collapse in 1907
and 1916, twice!

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 9
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy
• Expensive to build
• Spans shorter range
• Collapse in 1907
and 1916, twice!
• Due to flaws in
blueprint verification

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 10
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build
• Spans shorter range
• Collapse in 1907
and 1916, twice!
• Due to flaws in
blueprint verification

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 11
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range
• Collapse in 1907
and 1916, twice!
• Due to flaws in
blueprint verification

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 12
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range • Spans longer range
• Collapse in 1907
and 1916, twice!
• Due to flaws in
blueprint verification

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 13
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range • Spans longer range
• Collapse in 1907 • Was the longest
and 1916, twice! suspension
• Due to flaws in bridge in the
blueprint verification world!

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 14
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range • Spans longer range
• Collapse in 1907 • Was the longest
and 1916, twice! suspension
• Due to flaws in bridge in the
blueprint verification world!
• Stands since 1970

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 15
The Quebec Bridge and Pierre Laporte Bridge

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range • Spans longer range
• Collapse in 1907 • Was the longest
and 1916, twice! suspension
• Due to flaws in bridge in the
blueprint verification world!
• Stands since 1970

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 16
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range • Spans longer range
• Collapse in 1907 • Was the longest
and 1916, twice! suspension
• Due to flaws in bridge in the
blueprint verification world!
• Stands since 1970

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 17
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range • Spans longer range
• Collapse in 1907 • Was the longest
and 1916, twice! suspension
• Due to flaws in bridge in the
blueprint verification world!
• Stands since 1970

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 18
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Suspension
Cantilever bridge
bridge

• Heavy • Light weight


• Expensive to build • Cheap to build
• Spans shorter range • Spans longer range
• Collapse in 1907 • Was the longest
and 1916, twice! suspension
• Due to flaws in bridge in the
blueprint verification world!
• Stands since 1970

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 19
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 20
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 21
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose
• Hard and tedious to
build

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 22
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose
• Hard and tedious to
build
• Provide limited test
cases

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 23
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose
• Hard and tedious to
build
• Provide limited test
cases
• Waveform eyeing

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 24
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose
• Hard and tedious to
build
• Provide limited test
cases
• Waveform eyeing
• Ad-hoc

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 25
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to
build
• Provide limited test
cases
• Waveform eyeing
• Ad-hoc

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 26
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build
• Provide limited test
cases
• Waveform eyeing
• Ad-hoc

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 27
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build • Powerful in test
• Provide limited test strength
cases
• Waveform eyeing
• Ad-hoc

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 28
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build • Powerful in test
• Provide limited test strength
cases • Coverage
• Waveform eyeing
• Ad-hoc

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 29
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build • Powerful in test
• Provide limited test strength
cases • Coverage
• Waveform eyeing • Constraints
• Ad-hoc

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 30
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build • Powerful in test
• Provide limited test strength
cases • Coverage
• Waveform eyeing • Constraints
• Ad-hoc • Randomization

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 31
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build • Powerful in test
• Provide limited test strength
cases • Coverage
• Waveform eyeing • Constraints
• Ad-hoc • Randomization
• And many more

Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette
2022-09-19 32
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build • Powerful in test
• Provide limited test strength
cases • Coverage
• Waveform eyeing • Constraints
• Ad-hoc • Randomization
• And many more
• Formal methods to
Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette verify the results
2022-09-19 33
The Quebec Bridge and Pierre Laporte Bridge
Case-based testbench Verification

Case-based
Verification
testbench

• Verbose • Concise
• Hard and tedious to • Easy to build
build • Powerful in test
• Provide limited test strength
cases • Coverage
• Waveform eyeing • Constraints
• Ad-hoc • Randomization
• And many more
• Formal methods to
Source: https://www.wikiwand.com/en/Quebec_Bridge#/google_vignette verify the results
2022-09-19 • True industry34
standard
Intel’s Pentium FDIV bug
• A hardware bug affecting
the floating-point unit (FPU)
• Discovered in 1994
• Caused Intel about $ 0.5
billion to recall all flaw
processors in 1995.
• Roughly speaking $ 0.5 billion
in 1995 is worth $ 0.9 billion
today
• ~7.4 billion SEK
• Ericsson full-year sales in Source: https://en.wikipedia.org/wiki/Pentium_FDIV_bug

2020: ~70 billion SEK


worldwide
2022-09-19 35
Intel’s Pentium FDIV bug
• A hardware bug affecting
the floating-point unit (FPU)
• Discovered in 1994

Does this bug affect OS kernel space


• Caused Intel about $ 0.5
billion to recall all flaw

• Roughly speaking such


$ 0.5 billion as Linux?
processors in 1995.

in 1995 is worth $ 0.9 billion


today
• ~7.4 billion SEK
• Ericsson full-year sales in Source: https://en.wikipedia.org/wiki/Pentium_FDIV_bug

2020: ~70 billion SEK


worldwide
2022-09-19 36
More recently – Meltdown and Spectre
• A hardware bug affecting
branch prediction and
speculative execution in
modern CPU.
• Discovered in 2018
• Affecting almost all
modern processors:
• Intel x86 microprocessors
• IBM POWER processors
• ARM-based
microprocessors
• Not on AMD processors*
2022-09-19
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability) 37
More recently – Meltdown and Spectre
• A hardware bug affecting
branch prediction and
speculative execution in
modern CPU.
Does this bug affect OS kernel space
• Discovered in 2018
• Affecting almost all
such as Linux?
modern processors:
• Intel x86 microprocessors
• IBM POWER processors
• ARM-based
microprocessors
• Not on AMD processors*
2022-09-19
* https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability) 38
Verification, validation, testing
• In hardware design domain
• Verification = a process in which a design is tested (or verified) against a given
design specification before tape-out.
• Validation = a process in which the manufactured design (chip) is tested for all
functional correctness in a lab setup.
• Testing = screening manufactured chips for faults or random defects, reliability,
functional defects and electrical characterization before volume shipment.

Testing
Verification (this lecture)
Validation

Volume
Chip design and development life cycle shipment

Specifications
Prototype
Architecture RTL Design Physical Design Tapeout
(Chip back from fab)
Microarchitecture
2022-09-19 39
The Embedded SoC engineering pie

2022-09-19 40
The Embedded SoC engineering pie

System design
Implementation
Verification

2022-09-19 41
The Embedded SoC engineering pie

System design
Implementation
Verification

2022-09-19 42
The Embedded SoC engineering pie

System design
Implementation
Verification

2022-09-19 43
What to verify – the reconvergence model
Requirements
• Remember that the
purpose of the System design team’s
verification process is interpretation
to ensure that the (SystemC)

functionality of a logic
is as intended.
Specification
• The reconvergence
model is a conceptual Verification Team’s
Interpretation
Design Team’s
Interpretation
representation of what (SystemVerilog) (Verilog)

to verify.
Implementation

2022-09-19 44
What to verify – the reconvergence model
Requirements
• Remember that the
purpose of the System design team’s

Independence of interpretation by
verification process is
to ensure that the
interpretation
(SystemC)

design and verification teams is


functionality of a logic
is as intended.
expensive but essential.
Specification
• The reconvergence
model is a conceptual Verification Team’s
Interpretation
Design Team’s
Interpretation
representation of what (SystemVerilog) (Verilog)

to verify.
Implementation

2022-09-19 45
What to verify – the reconvergence model
Requirements
• Remember that the
purpose of the System design team’s

Independence of interpretation by
verification process is
to ensure that the
interpretation
(SystemC)

design and verification teams is


functionality of a logic
is as intended.
expensive but essential.
Specification
• The reconvergence
model is a conceptual Verification Team’s Design Team’s

Do not fight.
representation of what
Interpretation
(SystemVerilog)
Interpretation
(Verilog)

to verify.
Implementation

2022-09-19 46
Verification models
• Black-box model
• The verification team has access to input and output only
• White-box model
• The verification team has access to the internal logic
• Grey-box model
• The verification team has access to the internal logic that is specifically
designed to aid debug

2022-09-19 47
Verification abstraction
• Function/system level
• Operations ordered by functionality
• Example: DSP systems modeled in Matlab
• Transaction level
• Operations ordered by transmission protocol
• Example: AXI data transfer
• RTL/cycle accurate level
• Operations ordered by clock signal
• Example: FSM state transition
• Gate/Transistor level
• Operations ordered by physical signal
• Example: Bit change in gate with manufactural delays
2022-09-19 48
Verification abstraction
• Function/system level
• Operations ordered by functionality
• Example: DSP systems modeled in Matlab

Higher
• Operationsabstraction
• Transaction level
level = greater
ordered by transmission protocol
efficiency
• Example: AXI data transfer
• RTL/cycle accurate level
but less control
• Operations ordered by clock signal
• Example: FSM state transition
• Gate/Transistor level
• Operations ordered by physical signal
• Example: Bit change in gate with manufactural delays
2022-09-19 49
Verification abstraction
• Function/system level
• Operations ordered by functionality
• Example: DSP systems modeled in Matlab

Higher
• Operationsabstraction
• Transaction level
level = greater
ordered by transmission protocol
efficiency
• Example: AXI data transfer
• RTL/cycle accurate level
but less control
• Operations ordered by clock signal
• Example: FSM state transition
• Gate/Transistor level
• Operations ordered by physical signal
• Example: Bit change in gate with manufactural delays
2022-09-19 50
Verification abstraction
• Function/system level
• Operations ordered by functionality
• Example: DSP systems modeled in Matlab

Higher
• Operationsabstraction
• Transaction level
level = greater
ordered by transmission protocol
efficiency
• Example: AXI data transfer
• RTL/cycle accurate level
but less control
• Operations ordered by clock signal We mainly
• Example: FSM state transition
focus here
• Gate/Transistor level
• Operations ordered by physical signal
• Example: Bit change in gate with manufactural delays
2022-09-19 51
Verification tasks
In each of the verification hierarchy, checking the
following
• Function and performance
o Function: A piece of HW/SW that transforms input to output
o Performance: How well does the function perform in terms of figures of merits
• Timing and interface
o The logic timing which specifies when the input and output should appear/be
valid/be active, especially in relation to each other.
• Address/Location/Amount
o The amount of data that is read/input and the location from which it is read.
o The amount of data that is written/output and the location to which it is written.
• Structure/configuration
o IPs/Sub-systems are connected and configured properly
2022-09-19 52
The verification space
Model

Abstraction

Task
2022-09-19 53
Why SystemVerilog
• Verilog lacks
• Constrained random generation
• Functional coverage
• Assertions
• Specman E/Vera
• Used with VHDL and Verilog for constrained random generation and
functional coverage
• Property specification language (PSL)
• For assertion
• Learning 1 language (SystemVerilog) is better than learning 2
(Specman E/Vera and PSL)
• Even as a verification engineer, one should have enough knowledge
on HDL and system design language such as SystemC
2022-09-19 54
More than just a verification tool
• SystemVerilog rapidly getting accepted as the next
generation HDL for
• System design
• RTL design and synthesis
• Verification
• Easy bridging up different design teams.
• It is strongly practiced by the industries such as Ericsson.
• There are many properties and features in SV (can be
enough for another full course).
• We will only cover a small set of useful ones for writing
testbench in this course.
2022-09-19 55
More than just a verification tool
• SystemVerilog rapidly getting accepted as the next
generation HDL for
• System design
In this course, we use Verilog for RTL
• RTL design and synthesis
• Verification
modeling
• Easy bridgingand SV design
up different onlyteams.
for verification.
• It is strongly practiced by the industries such as Ericsson.
• There are many properties and features in SV (can be
enough for another full course).
• We will only cover a small set of useful ones for writing
testbench in this course.
2022-09-19 56
Basic building blocks
• Basic data types
• Different always blocks
• Struct vs. Class
• Packed and unpacked array
• Associative array
• File

2022-09-19 57
bit [15:0] bus; //unsigned

Basic data types bit signed [11:0] i, q; // signed


shortint unsigned addr_unsigned;
• 2 valued data type logic [15:0] addr_logic;
• bit: 1 bit
string myName = “John Smith”;
• byte: 8 bit (char), signed
• shortint: 16 bit, signed byte c = “A”; // assign c “A”
• int: 32 bit, signed bit [3:0][7:0] s = “hello”; // assign s “ello”
• 4 valued data types
• reg/wire: 1 bit
$display("bus=%b", bus);
• logic: 1 bit, identical to reg
• integer: 32 bit, signed $display("i,q=%b", i);
$display("addr_unsigned=%b", addr_unsigned);
$display("addr_logic=%b", addr_logic);
$display("myName=%s", myName);
$display("c=%c", c);
$display("c=%b", c);
$display("s=%s", s);
2022-09-19 //demo_1 58
bit [15:0] bus; //unsigned

Basic data types bit signed [11:0] i, q; // signed


shortint unsigned addr_unsigned;
• 2 valued data type logic [15:0] addr_logic;
• bit: 1 bit
string myName = “John Smith”;
• byte: 8 bit (char), signed
• shortint: 16 bit, signed byte c = “A”; // assign c “A”
• int: 32 bit, signed bit [3:0][7:0] s = “hello”; // assign s “ello”
Choose
• 4 valued datathe types proper data type to use in
• reg/wire: 1 bit

the testbench.
$display("bus=%b", bus);
• logic: 1 bit, identical to reg
• integer: 32 bit, signed $display("i,q=%b", i);
$display("addr_unsigned=%b", addr_unsigned);
$display("addr_logic=%b", addr_logic);
$display("myName=%s", myName);
$display("c=%c", c);
$display("c=%b", c);
$display("s=%s", s);
2022-09-19 //demo_1 59
Different always blocks
• Comes in four flavors
• always module demo_2(
o The old Verilog legacy. input a,
• always_ff input b,
o Clocked synchronous body output c
);
o To infer DFF
reg c;
o The only case to use “<=”
• always _comb: always_ff
o To infer combinational logic if (b)
o Sensitivity list is inferred from c <= a;
signals involved in the RHS of
expressions. endmodule
• always_latch
o To infer latch
o Sensitivity list is inferred from Compilation error.
signals involved in the RHS of
2022-09-19
expressions. 60
Different always blocks
• Comes in four flavors
• always module demo_2(
o The old Verilog legacy. input a,
• always_ff input b,
o Clocked synchronous body output c
);
o To infer DFF
reg c;
o The only case to use “<=”
• always _comb: always_ff @ (a, b)
o To infer combinational logic if (b)
o Sensitivity list is inferred from c <= a;
signals involved in the RHS of
expressions. endmodule
• always_latch
o To infer latch
o Sensitivity list is inferred from Compilation error.
signals involved in the RHS of
2022-09-19
expressions. 61
Different always blocks
• Comes in four flavors
• always module demo_2(
o The old Verilog legacy. input a,
• always_ff input b,
o Clocked synchronous body output c
);
o To infer DFF
reg c;
o The only case to use “<=”
• always _comb: always_ff @ (a, b)
o To infer combinational logic if (b)
o Sensitivity list is inferred from c <= a;
signals involved in the RHS of
expressions. endmodule
• always_latch
o To infer latch Warning.
o Sensitivity list is inferred from Compilation
No DFFerror.
signals involved in the RHS of generated.
2022-09-19
expressions. 62
Different always blocks
• Comes in four flavors
• always module demo_2( module demo_2(
o The old Verilog legacy. input a, input a,
• always_ff input b, input b,
o Clocked synchronous body output c output c
); );
o To infer DFF
reg c; reg c;
o The only case to use “<=”
• always _comb: always_ff @ (a, b) always_comb
o To infer combinational logic if (b) if (b)
o Sensitivity list is inferred from c <= a; c = a;
signals involved in the RHS of
expressions. endmodule endmodule
• always_latch
o To infer latch Warning.
o Sensitivity list is inferred from Compilation
No DFFerror.
signals involved in the RHS of generated.
2022-09-19
expressions. 63
Different always blocks
• Comes in four flavors
• always module demo_2( module demo_2(
o The old Verilog legacy. input a, input a,
• always_ff input b, input b,
o Clocked synchronous body output c output c
); );
o To infer DFF
reg c; reg c;
o The only case to use “<=”
• always _comb: always_ff @ (a, b) always_comb
o To infer combinational logic if (b) if (b)
o Sensitivity list is inferred from c <= a; c = a;
signals involved in the RHS of
expressions. endmodule endmodule
• always_latch
o To infer latch Warning. Warning.
o Sensitivity list is inferred from Compilation
No DFFerror. No comb logic
signals involved in the RHS of generated. generated
2022-09-19
expressions. 64
Different always blocks
• Comes in four flavors
• always module demo_2( module demo_2( module demo_2(
o The old Verilog legacy. input a, input a, input a,
• always_ff input b, input b, input b,
o Clocked synchronous body output c output c output c
); ); );
o To infer DFF
reg c; reg c; reg c;
o The only case to use “<=”
• always _comb: always_ff @ (a, b) always_comb always_latch
o To infer combinational logic if (b) if (b) if (b)
o Sensitivity list is inferred from c <= a; c = a; c = a;
signals involved in the RHS of
expressions. endmodule endmodule endmodule
• always_latch
o To infer latch Warning. Warning.
o Sensitivity list is inferred from Compilation
No DFFerror. No comb logic
signals involved in the RHS of generated. generated
2022-09-19
expressions. 65
Different always blocks
• Comes in four flavors
• always module demo_2( module demo_2( module demo_2(
o The old Verilog legacy. input a, input a, input a,
• always_ff input b, input b, input b,
o Clocked synchronous body output c output c output c
); ); );
o To infer DFF
reg c; reg c; reg c;
o The only case to use “<=”
• always _comb: always_ff @ (a, b) always_comb always_latch
o To infer combinational logic if (b) if (b) if (b)
o Sensitivity list is inferred from c <= a; c = a; c = a;
signals involved in the RHS of
expressions. endmodule endmodule endmodule
• always_latch
o To infer latch Warning. Warning.
o Sensitivity list is inferred from Compilation
No DFFerror. No comb logic Correct.
signals involved in the RHS of generated. generated
2022-09-19
expressions. 66
Different always blocks
• Comes in four flavors
• always module demo_2( module demo_2( module demo_2(
o The old Verilog legacy. input a, input a, input a,
• always_ff input b, input b, input b,
o Clocked synchronous body output c output c output c
); ); );
o To infer DFF
Can be used for synthesis.
reg c; reg c; reg c;
o The only case to use “<=”
• always _comb: always_ff @ (a, b) always_comb always_latch
o To infer combinational logic if (b) if (b) if (b)
o Sensitivity list is inferred from c <= a; c = a; c = a;
signals involved in the RHS of
expressions. endmodule endmodule endmodule
• always_latch
o To infer latch Warning. Warning.
o Sensitivity list is inferred from Compilation
No DFFerror. No comb logic Correct.
signals involved in the RHS of generated. generated
2022-09-19
expressions. 67
Struct vs. Class

• Both are used to represent


information composed of
different types. typedef struct { class atm_pkt;
bit sign; bit [11:0] id;
• The example struct models bit [22:0] mantissa; bit [15:0] pw;
IEEE single-precision bit [ 7:0] exponent; bit [ 3:0] pri;
floating-point number. } ieee_sp_float; endclass: atm_ pkt
• The example class models
ATM info packet which is
Pay attention to the difference
fixed 4-byte of user data. of the semi-colon at the end

2022-09-19 68
Concept of struct
• A struct is an integral type, just like integer or reg.
• Whenever a “struct” type is declared, the necessary
number of bits is automatically allocated.
• If a struct variable is assigned to another or passed as
an argument to a function or task, all the bits are copied.
typedef struct {
bit sign;
bit [22:0] mantissa;
bit [ 7:0] exponent;
} ieee_sp_float_unpacked
2022-09-19 69
Concept of struct

• If a struct is declared typedef struct packed {


packed, the bits of the bit sign;
struct fields are laid out bit [22:0] mantissa;
consecutively in memory. bit [ 7:0] exponent;
} ieee_sp_float_packed
• We can thus define literal
value for a struct.
• This allows the struct to be
seamlessly converted to
Sign Mantissa Exponent
and from bit vectors.
31 30 6 5 0

2022-09-19 70
module demo_3;

More on struct function ieee_sp_float_packed abs (ieee_sp_float_packed v);


v.sign = 0;
abs = v;
endfunction: abs
• Concatenation assignment to
unpacked struct leads to initial begin
ieee_sp_float_packed v1, v2;
warning. ieee_sp_float_unpacked v3;

• Bit selection on unpacked v1 = {1'b1, 23'hf00000, 8'h0};


v2 = v1;
struct leads to compilation v1 = abs(v1);
error.
$display("v1 = %b, %b, %b", v1.sign, v1.mantissa, v1.exponent);
$display("v1 = %b, %b, %b", v1[31], v1[30:8], v1[7:0]);
$display("v2 = %b, %b, %b", v2[31], v2[30:8], v2[7:0]);

v3 = {1'b1, 23'hf00000, 8'h0};


$display("v3 = %b, %b, %b", v3.sign, v3.mantissa, v3.exponent);
$display("v3 = %b, %b, %b", v3[31], v3[30:6], v3[5:0]);

end
endmodule
2022-09-19 71
module demo_3;

More on struct function ieee_sp_float_packed abs (ieee_sp_float_packed v);


v.sign = 0;
abs = v;
endfunction: abs
• Concatenation assignment to
unpacked struct leads to initial begin
ieee_sp_float_packed v1, v2;
warning. ieee_sp_float_unpacked v3;

• Bit selection on unpacked v1 = {1'b1, 23'hf00000, 8'h0};


v2 = v1;
struct leads to compilation v1 = abs(v1);
error.
$display("v1 = %b, %b, %b", v1.sign, v1.mantissa, v1.exponent);
$display("v1 = %b, %b, %b", v1[31], v1[30:8], v1[7:0]);
$display("v2 = %b, %b, %b", v2[31], v2[30:8], v2[7:0]);

v3 = {1'b1, 23'hf00000, 8'h0};


$display("v3 = %b, %b, %b", v3.sign, v3.mantissa, v3.exponent);
$display("v3 = %b, %b, %b", v3[31], v3[30:6], v3[5:0]);

end Error
endmodule
2022-09-19 72
module demo_3;

More on struct function ieee_sp_float_packed abs (ieee_sp_float_packed v);


v.sign = 0;
abs = v;
endfunction: abs
• Concatenation assignment to
unpacked struct leads to initial begin
ieee_sp_float_packed v1, v2;
warning. ieee_sp_float_unpacked v3;

• Bit selection on unpacked v1 = {1'b1, 23'hf00000, 8'h0};


v2 = v1;
struct leads to compilation v1 = abs(v1);
error.
$display("v1 = %b, %b, %b", v1.sign, v1.mantissa, v1.exponent);
$display("v1 = %b, %b, %b", v1[31], v1[30:8], v1[7:0]);
$display("v2 = %b, %b, %b", v2[31], v2[30:8], v2[7:0]);
Warning
v3 = {1'b1, 23'hf00000, 8'h0};
$display("v3 = %b, %b, %b", v3.sign, v3.mantissa, v3.exponent);
$display("v3 = %b, %b, %b", v3[31], v3[30:6], v3[5:0]);

end Error
endmodule
2022-09-19 73
module demo_3;

More on struct function ieee_sp_float_packed abs (ieee_sp_float_packed v);


v.sign = 0;
abs = v;
endfunction: abs
• Concatenation assignment to
unpacked struct leads to initial begin
ieee_sp_float_packed v1, v2;
warning. ieee_sp_float_unpacked v3;

• Bit selection on unpacked v1 = {1'b1, 23'hf00000, 8'h0};


v2 = v1;
struct leads to compilation v1 = abs(v1);
error.
$display("v1 = %b, %b, %b", v1.sign, v1.mantissa, v1.exponent);
$display("v1 = %b, %b, %b", v1[31], v1[30:8], v1[7:0]);
$display("v2 = %b, %b, %b", v2[31], v2[30:8], v2[7:0]);
Warning
v3 = {1'b1, 23'hf00000, 8'h0};
$display("v3 = %b, %b, %b", v3.sign, v3.mantissa, v3.exponent);
$display("v3 = %b, %b, %b", v3[31], v3[30:6], v3[5:0]);

end Error
endmodule
2022-09-19 74
class atm_pkt; Variable
bit [11:0] id; By default, “public”
To use private var:
Concept of class bit [15:0] pw;
bit [ 2:0] pri; local bit [11:0] id

function new (bit [11:0] id = 12’hfff,


• In object-oriented programming bit [15:0] pw = 16’hffff);
this.id = id; Overridden
(OOP), a class is a structure this.pw = pw; constructor new
this.pri = 3’b0;
that encapsulates variables endfunction Call the overridden
and functions that process the new constructor
function atm_pkt copy ();
variables. copy = new;
Self-defined
• Some of the functions are pre- copy.id = this.id;
copy.pw = this.pw; function
defined implicitly but can be copy.pri = this.pri;
endfunction: copy
override by user explicitly. Self-defined
function display (); function
• All other functions should be $display (“ id = 0x%0h,
pw=0x%0h,
defined explicitly by user. pri=%0b",
this.id, this.pw, this.pri);
endfunction
2022-09-19 endclass: atm_pkt 75
Instantiation of class using new
module demo_4; class atm_pkt;
initial begin bit [11:0] id;
bit [15:0] pw;
atm_pkt u1, u2; bit [ 2:0] pri;
u1 = new;
u2 = new (12'h123, 16'h1234); function new (bit [11:0] id = 12’hfff,
u1.display(); bit [15:0] pw = 16’hffff);
u2.display(); this.id = id;
this.pw = pw;
end this.pri = 3’b0;
endmodule endfunction
...
function display ();
Output from Vivado $display (“ id = 0x%0h,
pw=0x%0h,
pri=%0b",
this.id, this.pw, this.pri);
endfunction
endclass: atm_pkt
2022-09-19 76
class atm_pkt;
...
function new (bit [11:0] id = 12’hfff,

More on class bit [15:0] pw = 16’hffff);


this.id = id;
this.pw = pw;
• A class is a dynamic type. this.pri = 3’b0;
endfunction
• Whenever a class type is declared function atm_pkt copy ();
(using the new keyword), only a null copy = new;
pointer to a new instance of the class copy.id = this.id;
is created. copy.pw = this.pw;
copy.pri = this.pri;
• All info of the instance must be endfunction: copy

explicitly allocated. endclass: atm_pkt
• If a class variable is assigned to module demo_4
another or passed as an argument to Initial begin
a function or task, only the pointer is atm_pkt u1, u2, u3; // object instantiation
copied into another class instance. u1 = new;
u1.id = 12’h123;
u2 = u1; // u1 & u2 refer to same
// instance
u3 = u2.copy(); // u2 & u3 differ
// but have same content
u2.id = 12’h456; // only u1 and u2 will
// change
2022-09-19 end 77
Difference between struct & class
• A class can be converted to and from bit vectors by using user
defined packing and unpacking functions.
• The biggest difference between struct and class is that the
class is the only type in SystemVerilog that supports the object-
oriented programming model.
• Encapsulation
• Inheritance
• Polymorphism
• Use struct for writing synthesizable design.
• Packed struct is very similar to bit-vectors
• Use class when writing testbenches.
2022-09-19 78
Difference between struct & class
• A class can be converted to and from bit vectors by using user
defined packing and unpacking functions.
• The biggest difference between struct and class is that the
class is the only type in SystemVerilog that supports the object-
oriented programming model.
• Encapsulation
• Inheritance
• Polymorphism
• Use struct for writing synthesizable design.
• Packed struct is very similar to bit-vectors
• Use class when writing testbenches.
2022-09-19 79
Packed and unpacked array
• Packed arrays can only be • Unpacked arrays can be of
made of single-bit types and any type.
their dimensions are specified
to the left of the variable • They are declared with their
name. dimensions specified to the
• Packed arrays are implemented right of the variable name.
as consecutive bits and can be • Each element of an unpacked
implicitly used as signed or array is an individual value.
unsigned integer values.

bit [ 7:0] a_byte; bit eight_bits[8];


logic [ 3:0] [ 7:0] q_quadword; logic sixteen_bits[4][4];
ieee_sp_float [31:0] scoreboard; // INVALID ieee_sp_float scoreboard[32]; // VALID

2022-09-19 80
More on unpacked array
• Which should be used to model a general-purpose array?
• Packed or unpacked?
• A dynamic array is an unpacked array with an unspecified
dimension size.
• The actual size of the array is specified and allocated at runtime.
• 1-D or multi-dimensional.
ieee_sp_float_packed array_1d [ ]; //demo_5 ieee_sp_float_packed array_2d [ ][ ];
bit [22:0] rand_vec;
array_1d = new [32]; // 32 elements array_2d = new [32]; Observe how the
array_1d = new [64] (array_1d); // resize foreach (array_2d [i]) array_2d is indexed.
No need to declare I,j
array_1d.delete(); // Delete array array_2d[i] = new [32];
foreach (array_2d [i, j])
Call the SV operator new to allocate rand_vec = $urandom();
memory for the array dynamically. array_2d[i][j] = {1'b1, rand_vec, 8'h0};
2022-09-19 81
Not a constructor!
Multi-dimensional class pixel;
bit [7:0] red;

dynamic array of class bit [7:0] green;


bit [7:0] blue;

• Multi-dimensional dynamic endclass: pixel


/*******************************/
arrays can be emulated by using class line;
pixel pixels[];
a dynamic array of classes function new (input int unsigned n);
containing a dynamic array. this.pixels = new[n];

• Since this multi-dimensional


array is composed of
endfunction: new
independent one-dimensional endclass: line
arrays, the size and number of /*******************************/
each dimension can vary. class picture;
line lines[];
function new (input int unsigned x,y);
this.lines = new [x];
foreach (this.lines[i]) begin
this.lines[i] = new(y);
end
endfunction: new
endclass: picture
2022-09-19 82
Multi-dimensional class pixel;
bit [7:0] red;

dynamic array of class bit [7:0] green;


bit [7:0] blue;

• Multi-dimensional dynamic endclass: pixel


/*******************************/
arrays can be emulated by using class line;
pixel pixels[];
a dynamic array of classes function new (input int unsigned n);
containing a dynamic array. this.pixels = new[n]; Problem?

• Since this multi-dimensional


array is composed of
endfunction: new
independent one-dimensional endclass: line
arrays, the size and number of /*******************************/
each dimension can vary. class picture;
line lines[];
function new (input int unsigned x,y);
this.lines = new [x];
foreach (this.lines[i]) begin
this.lines[i] = new(y);
end
endfunction: new
endclass: picture
2022-09-19 83
Multi-dimensional class pixel;
bit [7:0] red;

dynamic array of class bit [7:0] green;


bit [7:0] blue;

• Multi-dimensional dynamic endclass: pixel


/*******************************/
arrays can be emulated by using class line;
pixel pixels[];
a dynamic array of classes function new (input int unsigned n);
containing a dynamic array. this.pixels = new[n]; Problem?

• Since this multi-dimensional


array is composed of Need to call
endfunction: new new()!
independent one-dimensional endclass: line Otherwise, only
arrays, the size and number of /*******************************/ nulls exist in
each dimension can vary. class picture;
line lines[];
pixels
function new (input int unsigned x,y);
this.lines = new [x];
foreach (this.lines[i]) begin
this.lines[i] = new(y);
end
endfunction: new
endclass: picture
2022-09-19 84
Multi-dimensional class pixel;
bit [7:0] red;

dynamic array of class bit [7:0] green;


bit [7:0] blue;

• Multi-dimensional dynamic endclass: pixel


/*******************************/
arrays can be emulated by using class line;
pixel pixels[];
a dynamic array of classes function new (input int unsigned n);
containing a dynamic array. this.pixels = new[n]; Problem?
foreach (this.pixels[i])
• Since this multi-dimensional this.pixels[i] = new();
array is composed of Need to call
endfunction: new new()!
independent one-dimensional endclass: line Otherwise, only
arrays, the size and number of /*******************************/ nulls exist in
each dimension can vary. class picture;
line lines[];
pixels
function new (input int unsigned x,y);
this.lines = new [x];
foreach (this.lines[i]) begin
this.lines[i] = new(y);
end
endfunction: new
endclass: picture
2022-09-19 85
Multi-dimensional class pixel;
bit [7:0] red;

dynamic array of class bit [7:0] green;


bit [7:0] blue;

• Multi-dimensional dynamic endclass: pixel


/*******************************/
arrays can be emulated by using class line;
pixel pixels[];
a dynamic array of classes function new (input int unsigned n);
containing a dynamic array. this.pixels = new[n]; Problem?
foreach (this.pixels[i])
• Since this multi-dimensional this.pixels[i] = new();
array is composed of Need to call
endfunction: new new()!
independent one-dimensional endclass: line Otherwise, only
arrays, the size and number of /*******************************/ nulls exist in
each dimension can vary. class picture;
line lines[];
pixels
function new (input int unsigned x,y);
module demo_3; this.lines = new [x];
initial begin foreach (this.lines[i]) begin
picture vga = new(480, 640); this.lines[i] = new(y);
pixel center = vga.lines[240].pixels[320]; end
endfunction: new
end
endclass: picture
endmodule
2022-09-19 86
Multi-dimensional class pixel;
bit [7:0] red;

dynamic array of class bit [7:0] green;


bit [7:0] blue;

• Multi-dimensional dynamic endclass: pixel


/*******************************/
arrays can be emulated by using class line;
pixel pixels[];
a dynamic array of classes function new (input int unsigned n);
containing a dynamic array. this.pixels = new[n]; Problem?
foreach (this.pixels[i])
• Since this multi-dimensional this.pixels[i] = new();
array is composed of Need to call
endfunction: new new()!
independent one-dimensional endclass: line Otherwise, only
arrays, the size and number of /*******************************/ nulls exist in
each dimension can vary. class picture;
line lines[];
pixels
function new (input int unsigned x,y);
module demo_3; this.lines = new [x];
initial begin foreach (this.lines[i]) begin
picture vga = new(480, 640); this.lines[i] = new(y);
pixel center = vga.lines[240].pixels[320]; end
endfunction: new
end
endclass: picture
endmodule
2022-09-19 87
Associative array
• Associative arrays are used for non-ordinal or non-consecutive
indexing operations.
• The elements in an associative array are not considered ordered from index 0
through index N-1.
• They are randomly stored based on an efficient indexing mechanism that can
use any type — even a string or class reference — as indexing value.
• The concept is close to the “map” data structure
• One of the best applications of an associative array is to model a
large memory.

16GB 0
Allocated
2022-09-19 region 88
More on associative array
class sparse_memory;
local logic [7:0] mem [bit [63:0]];
/********************************/
function logic [7:0] read(input bit [63:0] addr); module demo_7;
read = 8’hxx; sparse_memory mem = new();
if (this.mem.exists(addr)) begin bit [63:0] addr;
read = this.mem[addr]; bit [7:0] data;
end
endfunction: read initial begin
/********************************/ $display(“Method 1 Init. memory by random writing”);
function void write(input bit [63:0] addr, repeat (10) begin
input logic [ 7:0] data); addr = { $urandom(), $urandom() };
this.mem[addr] = data; data = $urandom();
endfunction: write mem.write(addr, data);
/********************************/ $display("0x%h, 0x%h", addr, mem.read(addr));
function void display(); end
foreach (mem[i]) mem.display();
$display("Addr: 0x%h, data: 0x%h", i, mem[i]); end
endfunction: display endmodule
endclass: sparse_memory
2022-09-19 89
More on associative array
class sparse_memory;
local logic [7:0] mem [bit [63:0]];
/********************************/
function logic [7:0] read(input bit [63:0] addr); module demo_7;
read = 8’hxx; sparse_memory mem = new();
bit [63:0] addr; $random()/$urandom()
if (this.mem.exists(addr)) begin
read = this.mem[addr]; bit [7:0] data; only return 32-bit
end random number
endfunction: read initial begin
/********************************/ $display(“Method 1 Init. memory by random writing”);
function void write(input bit [63:0] addr, repeat (10) begin
input logic [ 7:0] data); addr = { $urandom(), $urandom() };
this.mem[addr] = data; data = $urandom();
endfunction: write mem.write(addr, data);
/********************************/ $display("0x%h, 0x%h", addr, mem.read(addr));
function void display(); end
foreach (mem[i]) mem.display();
$display("Addr: 0x%h, data: 0x%h", i, mem[i]); end
endfunction: display endmodule
endclass: sparse_memory
2022-09-19 90
More on associative array
class sparse_memory;
local logic [7:0] mem [bit [63:0]];
/********************************/
function logic [7:0] read(input bit [63:0] addr); module demo_7;
read = 8’hxx; sparse_memory mem = new();
bit [63:0] addr; $random()/$urandom()
if (this.mem.exists(addr)) begin
read = this.mem[addr]; bit [7:0] data; only return 32-bit
end random number
endfunction: read initial begin
/********************************/ $display(“Method 1 Init. memory by random writing”);
function void write(input bit [63:0] addr, repeat (10) begin
input logic [ 7:0] data); addr = { $urandom(), $urandom() };
this.mem[addr] = data; data = $urandom();
endfunction: write mem.write(addr, data);
/********************************/ $display("0x%h, 0x%h", addr, mem.read(addr));
function void display(); end
foreach (mem[i]) mem.display();
$display("Addr: 0x%h, data: 0x%h", i, mem[i]); end
endfunction: display endmodule
endclass: sparse_memory
2022-09-19 91
File
• SystemVerilog can both open file for read and write using the
$fopen() system task.
• The task will return a 32-bit integer handle called a file
descriptor. This handle should be used to read and write to the
file until closed.
• Close a file by using the $fclose() system task.
• File is another way to initialization memory content.

2022-09-19 92
More on File
class sparse_memory; // demo_7
local logic [7:0] mem [bit [63:0]];
/********************************/
function void loadimage();
$display("Loading mem image...");
fd = $fopen("mem_image.txt", "r");
if (fd) begin
while (!$feof(fd)) begin
bit [63:0] addr;
bit [7:0] data;
string line;
$fgets(line, fd);
$sscanf(line, "%h %h", addr, data);
this.write(addr, data);
end
$fclose(fd);
end else
$display("Error in opening memory image file.");
endfunction: loadimage
endclass: sparse_memory
2022-09-19 93
More on File
class sparse_memory; // demo_7
local logic [7:0] mem [bit [63:0]];
/********************************/
function void loadimage();
$display("Loading mem image...");
fd = $fopen("mem_image.txt", "r");
if (fd) begin
while (!$feof(fd)) begin
bit [63:0] addr; Remember to import
bit [7:0] data; the file to Vivado as
string line; “Simulation Sources”
$fgets(line, fd);
$sscanf(line, "%h %h", addr, data);
this.write(addr, data);
end
$fclose(fd);
end else
$display("Error in opening memory image file.");
endfunction: loadimage
endclass: sparse_memory
2022-09-19 94
More on File
class sparse_memory; // demo_7
local logic [7:0] mem [bit [63:0]];
/********************************/
function void loadimage();
$display("Loading mem image...");
fd = $fopen("mem_image.txt", "r");
if (fd) begin
while (!$feof(fd)) begin
bit [63:0] addr; Remember to import
bit [7:0] data; the file to Vivado as
string line; “Simulation Sources”
$fgets(line, fd);
$sscanf(line, "%h %h", addr, data);
this.write(addr, data);
end
$fclose(fd);
end else
$display("Error in opening memory image file.");
endfunction: loadimage
endclass: sparse_memory
2022-09-19 95
More on File
class sparse_memory; // demo_7
local logic [7:0] mem [bit [63:0]];
/********************************/
function void loadimage(); File content
$display("Loading mem image...");
fd = $fopen("mem_image.txt", "r");
if (fd) begin
while (!$feof(fd)) begin
bit [63:0] addr; Remember to import
bit [7:0] data; the file to Vivado as
string line; “Simulation Sources”
$fgets(line, fd);
$sscanf(line, "%h %h", addr, data);
this.write(addr, data);
end
$fclose(fd);
end else
$display("Error in opening memory image file.");
endfunction: loadimage
endclass: sparse_memory
2022-09-19 96
More on File
class sparse_memory; // demo_7
local logic [7:0] mem [bit [63:0]];
/********************************/
function void loadimage(); File content
$display("Loading mem image...");
fd = $fopen("mem_image.txt", "r");
if (fd) begin
while (!$feof(fd)) begin
bit [63:0] addr; Remember to import
bit [7:0] data; the file to Vivado as module demo_7;
string line; “Simulation Sources” sparse_memory mem = new();
$fgets(line, fd); bit [63:0] addr;
$sscanf(line, "%h %h", addr, data); bit [7:0] data;
this.write(addr, data);
end initial begin
$fclose(fd); $display(“Method 2 Load memory by reading file”);
end else mem.loadimage();
$display("Error in opening memory image file."); mem.display();
endfunction: loadimage end
endclass: sparse_memory endmodule
2022-09-19 97
More on File
class sparse_memory; // demo_7
local logic [7:0] mem [bit [63:0]];
/********************************/
function void loadimage(); File content
$display("Loading mem image...");
fd = $fopen("mem_image.txt", "r");
if (fd) begin
while (!$feof(fd)) begin
bit [63:0] addr; Remember to import
bit [7:0] data; the file to Vivado as module demo_7;
string line; “Simulation Sources” sparse_memory mem = new();
$fgets(line, fd); bit [63:0] addr;
$sscanf(line, "%h %h", addr, data); bit [7:0] data;
this.write(addr, data);
end initial begin
$fclose(fd); $display(“Method 2 Load memory by reading file”);
end else mem.loadimage();
$display("Error in opening memory image file."); mem.display();
endfunction: loadimage end
endclass: sparse_memory endmodule
2022-09-19 98
Questions?

2022-09-19 99

You might also like