Está en la página 1de 41

Functional Verification

Functional verification, in electronic design automation, is the task of verifying that the logic
design conforms to specification. In everyday terms, functional verification attempts to answer
the question "Does this proposed design do what is intended?" This is a complex task, and takes
the majority of time and effort in most large electronic system design projects.
Functional verification is very difficult - it is equivalent to program verification, and is NP-
hard or even worse - and no solution has been found that works well in all cases. However, it
can be attacked by many methods. None of them are perfect, but each can be helpful in certain
circumstances:

 Logic simulation simulates the logic before it is built.


 Simulation acceleration applies special purpose hardware to the logic simulation
problem.
 Emulation builds a version of system using programmable logic. This is expensive, and
still much slower than the real hardware, but orders of magnitude faster than simulation. It
can be used, for example, to boot the operating system on a processor.
 Formal verification attempts to prove mathematically that certain requirements (also
expressed formally) are met, or that certain undesired behaviors (such as deadlock) cannot
occur.
 Intelligent verification uses automation to adapt the testbench to changes in
the register transfer level code.
 HDL-specific versions of lint, and other heuristics, are used to find common problems.
Simulation based verification (also called 'dynamic verification') is widely used to "simulate" the
design, since this method scales up very easily. Stimulus is provided to exercise each line in the
HDL code. A test-bench is built to functionally verify the design by providing meaningful
scenarios to check that given certain input, the design performs to specification.
A simulation environment is typically composed of several types of components:

 The generator[disambiguation needed] (or irritator) generates input vectors. Modern generators
generate random, biased, and valid stimuli. The randomness is important to achieve a high
distribution over the huge space of the available input stimuli. To this end, users of these
generators intentionally under-specify the requirements for the generated tests. It is the
role of the generator to randomly fill this gap. This mechanism allows the generator to
create inputs that reveal bugs not being searched for directly by the user. Generators also
bias the stimuli toward design corner cases to further stress the logic. Biasing and
randomness serve different goals and there are tradeoffs between them, hence different

1|Page
generators have a different mix of these characteristics. Since the input for the design must
be valid (legal) and many targets (such as biasing) should be maintained, many generators
use theConstraint satisfaction problem (CSP) technique to solve the complex testing
requirements. The legality of the design inputs and the biasing arsenal are modeled. The
model-based generators use this model to produce the correct stimuli for the target design.
 The drivers translate the stimuli produced by the generator into the actual inputs for the
design under verification. Generators create inputs at a high level of abstraction, namely, as
transactions or assembly language. The drivers convert this input into actual design inputs
as defined in the specification of the design's interface.
 The simulator produces the outputs of the design, based on the design’s current state
(the state of the flip-flops) and the injected inputs. The simulator has a description of the
design net-list. This description is created by synthesizing the HDL to a low gate level net-
list.
 The monitor converts the state of the design and its outputs to a transaction abstraction
level so it can be stored in a 'score-boards' database to be checked later on.
 The checker validates that the contents of the 'score-boards' are legal. There are cases
where the generator creates expected results, in addition to the inputs. In these cases, the
checker must validate that the actual results match the expected ones.
 The arbitration manager manages all the above components together.
Different coverage metrics are defined to assess that the design has been adequately exercised.
These include functional coverage (has every functionality of the design been exercised?),
statement coverage (has each line of HDL been exercised?), and branch coverage (has each
direction of every branch been exercised?).
Functional Verification Tools

 Avery Design Systems: SimCluster (for parallel logic simulation) and Insight (for formal
verification)
 Cadence Design Systems
 EVE/ZeBu
 Mentor Graphics
 Nusym Technology
 Obsidian Software
 Synopsys

2|Page
Test Bench
A test bench is a virtual environment used to verify the correctness or soundness of a design or
model (e.g., a software product).
The term has its roots in the testing of electronic devices, where an engineer would sit at a lab
bench with tools of measurement and manipulation, such as oscilloscopes, multimeters,
soldering irons, wire cutters, and so on, and manually verify the correctness of the device under
test.
In the context of software or firmware or hardware engineering, a test bench refers to an
environment in which the product under development is tested with the aid of a collection of
testing tools. Often, though not always, the suite of testing tools is designed specifically for the
product under test.
A test bench or testing workbench has four components.
1.INPUT: The entrance criteria or deliverables needed to perform work
2.PROCEDURES TO DO: The tasks or processes that will transform the input into the output
3.PROCEDURES TO CHECK: The processes that determine that the output meets the standards.
4.OUTPUT: The exit criteria or deliverables produced from the workbench

First create an empty folder in desktop to keep all your files and name it as “exercise”

The following is the path for opening ModelSim SE:

Start  All Programs  ModelSim SE 6.6c  ModelSim

3|Page
Now change your working directory to “exercise” folder

File  Change Directory

Browse for exercise folder which is on desktop

Click ok

4|Page
To create a new project, go to

File New  Project

Enter project name as “basic” and click ok

Give name as file name “counter” and click ok

5|Page
Observe there is one project tab added, in which your project name is counter

6|Page
Double click counter.v, and start coding for counter in open space

Click library tab, work is default working library of modelsim. It is empty because we have not yet
compiled our counter code.

Now add test bench to our project

Click project tab, select counter.v

Right click counter.v Add to Project  New File

7|Page
Click New File, name counter_test and type as “Verilog” and click ok

Double click counter_test.v and start typing test bench

8|Page
Now select both files counter.v and counter_test.v ( use ctrl key to select both files)

To compile, go to compile  Compile All

After compilation check if your code is having any errors

Now simulate your design

Select top entity of your project i.e. counter_test.v

9|Page
Simulate Start Simulation

In the design tab, select test_counter

Disable “Enable optimization” or uncheck and click ok

10 |
Page
11 |
Page
All the waves in design are added to the waveform window.

Click on Simulate button , all the input vectors written in testbench are applied to the dut and
waveforms are displayed in the window aas shown below.

After doing basic simulation, click on view and select dataflow. This option is useful for
debugging porpose.

12 |
Page
Once, we add a signal to wave, following wizard pops up. This is helpful for debugging. If any of
the output is X, then by using dataflow command the backtrace can be done and the source that
causes X can be found.

Code coverage

This is useful for any design which helps the verification engineer to apply all cases to the DUT
and check whether all lines of code is covered or not. There are different types of code coverages
like Statement Coverage, Line Cloverage, Expression Coverage etc.

13 |
Page
Compile all the files in design.

14 |
Page
Click Start Simulation

15 |
Page
Enable Code Coverage

16 |
Page
Again run simulation with the selected coverage directives.

All the coverages can be found with 0% covered because we did not apply he inpu stimulus till
now.

17 |
Page
Once we run simulation, alll the coverage directives will be displayed.

18 |
Page
Synsthesis
After Functional verification is done, we now do synthesis.

In electronics, logic synthesis is a process by which an abstract form of desired circuit behavior
(typically register transfer level (RTL)) is turned into a design implementation in terms oflogic
gates. Common examples of this process include synthesis of HDLs, including VHDL and Verilog.
Some tools can generate bitstreams for programmable logic devices such asPALs or FPGAs,
while others target the creation of ASICs. Logic synthesis is one aspect of electronic design
automation.

History of logic synthesis

The roots of logic synthesis can be traced to the treatment of logic by George Boole (1815 to
1864), in what is now termed Boolean algebra. In 1938, Claude Shannon showed that the two-
valued Boolean algebra can describe the operation of switching circuits. In the early days, logic
design involved manipulating the truth table representations as Karnaugh maps. The Karnaugh
map-based minimization of logic is guided by a set of rules on how entries in the maps can be
combined. A human designer can typically only work with Karnaugh maps containing up to four
to six variables.

The first step toward automation of logic minimization was the introduction of the Quine–
McCluskey algorithm that could be implemented on a computer. This exact minimization
technique presented the notion of prime implicants and minimum cost covers that would
become the cornerstone of two-level minimization. Nowadays, the much more
efficient Espresso heuristic logic minimizer has become the standard tool for this operation.
Another area of early research was in state minimization and encoding of finite state
machines (FSMs), a task that was the bane of designers. The applications for logic synthesis lay
primarily in digital computer design. Hence, IBM and Bell Labs played a pivotal role in the early
automation of logic synthesis. The evolution from discrete logic components to programmable
logic arrays (PLAs) hastened the need for efficient two-level minimization, since minimizing
terms in a two-level representation reduces the area in a PLA.

However, two-level logic circuits are of limited importance in a very-large-scale


integration (VLSI) design; most designs use multiple levels of logic. As a matter of fact, almost
any circuit representation in RTL or Behavioural Description is a multi-level representation. An
early system that was used to design multilevel circuits was LSS from IBM. It used local
transformations to simplify logic. Work on LSS and the Yorktown Silicon Compiler spurred rapid
research progress in logic synthesis in the 1980s. Several universities contributed by making
their research available to the public, most notably SIS from University of California, Berkeley,
19 |
Page
RASP from University of California, Los Angeles and BOLD from University of Colorado, Boulder.
Within a decade, the technology migrated to commercial logic synthesis products offered by
electronic design automation companies.

High-level synthesis or behavioral synthesis

With a goal of increasing designer productivity, research efforts on the synthesis of circuits
specified at the behavioral level have led to the emergence of commercial solutions in 2004[1],
which are used for complex ASIC and FPGA design. These tools automatically synthesize circuits
specified at C level to a register transfer level (RTL) specification, which can be used as input to
a gate-level logic synthesis flow.[1] Today, high-level synthesis, also known as ESL synthesis and
behavioral synthesis, essentially refers to circuit synthesis from high level Languages like ANSI
C/C++ or SystemC etc., whereas Logic Synthesis refers to synthesis from structural or functional
description to RTL.

Multi-level logic minimization

Typical practical implementations of a logic function utilize a multi-level network of logic


elements. Starting from an RTL description of a design, the synthesis tool constructs a
corresponding multilevel Boolean network.

Next, this network is optimized using several technology-independent techniques before


technology-dependent optimizations are performed. The typical cost function during
technology-independent optimizations is total literal count of the factored representation of
the logic function (which correlates quite well with circuit area).

Finally, technology-dependent optimization transforms the technology-independent circuit into


a network of gates in a given technology. The simple cost estimates are replaced by more
concrete, implementation-driven estimates during and after technology mapping. Mapping is
constrained by factors such as the available gates (logic functions) in the technology library, the
drive sizes for each gate, and the delay, power, and area characteristics of each gate.

Commercial tool for logic synthesis

1. Software tools for logic synthesis targeting ASICs

 Design Compiler by Synopsys

 Encounter RTL Compiler by Cadence Design Systems

 BuildGates, an older product by Cadence Design Systems, humorously named


after Bill Gates

20 |
Page
 TalusDesign by Magma Design Automation

 BooleDozer: Logic synthesis tool by IBM (internal IBM EDA tool)

2. Software tools for logic synthesis targeting FPGAs

 Encounter RTL Compiler by Cadence Design Systems

 LeonardoSpectrum and Precision (RTL / Physical) by Mentor Graphics

 Synplify (PRO / Premier) by Synplicity

 BlastFPGA by Magma Design Automation

 Quartus II integrated Synthesis by Altera

 XST (delivered within ISE) by Xilinx

 DesignCompiler Ultra and IC Compiler by Synopsys

 IspLever by Lattice Semiconductor

21 |
Page
To start Precision follow this path.

Go to Start  All Programs  Precision  Precision RTL

Following window pops up, where we can create new project or open an existing project.

22 |
Page
To crate a new project, click new project

Enter project name and browse the path, where it should be saved.

23 |
Page
Now a new project is created named Techlabs_synthesis.

To add new .v or .vhd files, right click on input files and select add input files.

24 |
Page
We need to add only design files , no need to add test bench files here.

Next set up design as shown below.

25 |
Page
Click on synthesis design.

After synthesis, many files are added to the output files as shown below.

26 |
Page
All the information in the output files can be viewed by double clicking on the file.

Following is the example of RTL schematic.

Technology Schematic.

27 |
Page
Area Report.

No of output files that can be viewed is shown below.

28 |
Page
All the options that can be accessed under each category is listed below.

To create new implementation of the same design

29 |
Page
After running the process one can view all the files of different implementations for same project.

30 |
Page
Programs
adder_8bit.v

module adder_8bit ( a, b, cin , sum, cout);


//inputs
input [7:0] a;
input [7:0] b;
input cin;

//outputs
output [7:0] sum;
output cout;

//wires
wire [7:0] a;
wire [7:0] b;
wire cin;

adder_1bit a1 ( a[0] , b[0] , cin , sum[0] , c1);


adder_1bit a2 ( a[1] , b[1] , c1 , sum[1] , c2);
adder_1bit a3 ( a[2] , b[2] , c2 , sum[2] , c3);
adder_1bit a4 ( a[3] , b[3] , c3 , sum[3] , c4);
adder_1bit a5 ( a[4] , b[4] , c4 , sum[4] , c5);
adder_1bit a6 ( a[5] , b[5] , c5 , sum[5] , c6);
adder_1bit a7 ( a[6] , b[6] , c6 , sum[6] , c7);
adder_1bit a8 ( a[7] , b[7] , c7 , sum[7] , cout);
endmodule

adder_1bit.v
module adder_1bit ( a , b, cin , sum, cout );

//inputs
input a , b , cin;

//outputs
output sum, cout;

31 |
Page
assign sum = a ^ b ^cin;
assign cout = cin(a^b) + ab;

endmodule

test_adder.v
// test bench for 8-bit adder

module test_adder();
reg [7:0] a;
reg [7:0] b;
reg cin;

wire [7:0] sum;


wire [7:0] cout;

//instantiate the adder


adder_8bit dut( a, b, cin , sum, cout);

initial begin

a = 8'b00000000;
b = 8'b00000000;
cin = 1'b0;

#10 a = 8'b00001111 ; b = 8'b11110000; cin = 1'b1;

#20 a = 8'b11110000; b = 8'b00001111; cin = 1'b1;

#30 a = 8'b00001111; b = 8'b11110000; cin = 1'b0;

#100 $finish;
end
endmodule

32 |
Page
address_decoder.v
module decoder_using_case (
binary_in , // 4 bit binary input
decoder_out , // 16-bit out
enable // Enable for the decoder
);
input [3:0] binary_in ;
input enable ;
output [15:0] decoder_out ;

reg [15:0] decoder_out ;

always @ (enable or binary_in)


begin
decoder_out = 0;
if (enable) begin
case (binary_in)
4'h0 : decoder_out = 16'h0001;
4'h1 : decoder_out = 16'h0002;
4'h2 : decoder_out = 16'h0004;
4'h3 : decoder_out = 16'h0008;
4'h4 : decoder_out = 16'h0010;
4'h5 : decoder_out = 16'h0020;
4'h6 : decoder_out = 16'h0040;
4'h7 : decoder_out = 16'h0080;
4'h8 : decoder_out = 16'h0100;
4'h9 : decoder_out = 16'h0200;
4'hA : decoder_out = 16'h0400;
4'hB : decoder_out = 16'h0800;
4'hC : decoder_out = 16'h1000;
4'hD : decoder_out = 16'h2000;
4'hE : decoder_out = 16'h4000;
4'hF : decoder_out = 16'h8000;
endcase
end
end

endmodule
33 |
Page
test_decoder.v

module test_decoder;
reg [3:0] binary_in;
reg enable;
wire [15:0] decoder_out;

decoder_using_case dut (binary_in, decoder_out,enable);

initial begin

binary_in = 4'h0;enable = 0;
#10
enable = 1;
#10
binary_in = 4'h1;
#10
binary_in = 4'h7;
#10
binary_in = 4'hA;
#10
binary_in = 4'hF;
#10
binary_in = 4'h3;
end

endmodule

mux using if
module mux_4to1_using_if (a, b, c, d, s, o);
input a,b,c,d;
input [1:0] s;
output o;

reg o;

always @(a or b or c or d or s)

34 |
Page
begin
if (s == 2'b00)
o = a;
else if (s == 2'b01)
o = b;
else if (s == 2'b10)
o = c;
else
o = d;
end

endmodule

test_mux.v
module test_mux;
reg a, b, c, d;
reg [1:0] s;
wire o;

mux_4to1_using_if dut (a, b, c, d, s, o);

initial begin
a=1;b=1;c=0;d=0;
s=00;
#20
s=01;
#20
s=10;
#20
s=11;
end

endmodule

Multiplier
module multiplier_4bit( a , b , out);
//inputs
input [3:0] a;
35 |
Page
input [3:0] b;
//output
output [8:0] out;

//wires
wire [3:0] a;
wire [3:0] b;

assign out = a * b;

endmodule

Test_Multiplier
module test_multiplier;

reg [3:0] a;

reg [3:0] b;

wire [8:0] out;

multiplier_4bit dut( a , b , out);

initial begin

a=4'b0000, b=4'b0000;

#20
a=4'b0001, b=4'b0011;

#20
a=4'b1111, b=4'b1111;

end

endmodule

36 |
Page
Accumulator

module accumulator (clk, clr, d, q);


input clk, clr;
input [3:0] d;
output [3:0] q;
reg [3:0] tmp;

always @(posedge clk or posedge clr)


begin
if (clr)
tmp = 4'b0000;
else
tmp = tmp + d;
end
assign q = tmp;
endmodule

test_accumulator
module test_acc;

reg clk, clr;


reg [3:0] d;

wire [3:0] q;

accumulator dut (clk, clr, d, q);

initial begin
forever begin
clk <= 0;
#5
clk <= 1;
#5
clk <= 0;
end
end
37 |
Page
initial begin

clr = 0;

#20
clr = 1;data = 0001;

#20
clr = 0; data = 0010;

#20
data = 0011;

#20 clr = 1

end
endmodule

Counter
module up_counter (
out , // Output of the counter
enable , // enable for counter
clk , // clock Input
reset // reset Input
);
//----------Output Ports--------------
output [7:0] out;
//------------Input Ports--------------
input enable, clk, reset;
//------------Internal Variables--------
reg [7:0] out;
//-------------Code Starts Here-------
always @(posedge clk)
if (reset) begin
out <= 8'b0 ;
end else if (enable) begin
38 |
Page
out <= out + 1;
end

endmodule

Test bench for up counter

module test_upcounter;
reg clk, reset,enable ;
wire [7:0] out;

up_counter dut (out, enable, clk ,reset);

initial begin
forever begin
clk <= 0;
#5
clk <= 1;
#5
clk <= 0;
end
end

initial begin

reset = 1;
#20
reset = 0;enable = 1;

#100
enable = 0;

#150
reset = 0;

end
endmodule

39 |
Page
PRBS Generator

module prbs (rand, clk, reset);

//inputs
input clk, reset;

//outputs
output rand;

//wires
wire rand;

//internal registors
reg [3:0] temp;

//always @ (posedge reset) begin


//temp <= 4'hf;
//end

always @ (posedge clk)

begin
if (reset)

temp <= 4'h1;

else
temp <= {temp[0]^temp[1],temp[3],temp[2],temp[1]};

end

assign rand = temp;

endmodule

40 |
Page
Test Bench for PRBS

module main;

reg clk, reset;

wire rand;

prbs pr (rand, clk, reset);

initial begin
forever begin
clk <= 0;
#5
clk <= 1;
#5
clk <= 0;
end
end

initial begin
reset = 1;
#12
reset = 0;
#90
reset = 1;
#12
reset = 0;
end
endmodule

41 |
Page

También podría gustarte