Upload
bhargava0867335
View
14
Download
1
Embed Size (px)
Citation preview
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 1
VHDL to SystemVerilog Guide
ID tbd
Introduction
This document provides example code to assist engineers in the transition from VHDL to SystemVerilog.
Each topic shows pieces of code in each language, together with comments at the side. The main focus
is on synthesizable code, but there are also some examples which are testbench-related.
On subsequent pages there are three columns: notes, followed by VHDL code, then SystemVerilog code.
SystemVerilog provides features that are beyond those available in VHDL (for example interfaces). These
are covered in the final section, together with some non-synthesizable testbench related features.
Contents
VHDL to SystemVerilog Guide ........................................................................................ 1
Introduction .................................................................................................................. 1
Contents ....................................................................................................................... 1
Data Types ................................................................................................................... 2
Operators and Attributes .............................................................................................. 2
Modules / Design Entities ............................................................................................. 2
Generate ...................................................................................................................... 2
Processes / always ....................................................................................................... 2
Sequential Statements ................................................................................................. 2
Arithmetic ..................................................................................................................... 2
Packages and Scope ................................................................................................... 2
Interfaces ..................................................................................................................... 2
Test Fixture Code ......................................................................................................... 2
VHDL SystemVerilog
2 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Data Types
SystemVerilog logic is a four value
variable. SystemVerilog also allows
enumerated, record, and array types.
Array types may have both packed
and unpacked dimensions.
When declaring types that will be re-
used, it is convenient to use typedef.
Note that VHDL integer does not
support indexing (e.g. i(0)), whereas
the SystemVerilog 2-state types
(such as int) and 4-state types (logic,
integer) do.
SystemVerilog 2-state types are
intended to match C types when co-
simulating with C via the direct
programming interface (DPI).
-- intial value "UUUUUUUU"
SUBTYPE byte_t IS
std_logic_vector(7 downto 0);
TYPE rec_t IS
RECORD
-- VHDL integer synthesises to 32 bit
-- signed
i1 : integer;
s1 : byte_t;
END RECORD rec_t;
TYPE fsmstate_t is (IDLE, GO1, GO2);
TYPE mem_ is array (0 to 1023) of byte_t;
TYPE mem2T is array (natural range <>)
of byte_t;
-- signal s : byte_t;
s <= (others => '0'); -- VHDL aggregate
-- numeric_std unsigned/signed vectors
signal s1 : signed(7 downto 0);
// initial value "XXXXXXXX"
typedef logic [7:0] byte_t; // packed
// may also be declared packed
typedef struct
{
// int is a 2-state type (0, 1 only)
// int i1;
// integer is a 4 state type (0,1,X,Z)
integer i1; // 32 bits signed
byte_t s1;
} rec_t;
typedef enum {IDLE, GO1, GO2} fsmstate_t;
// unpacked – each byte_t element is not
// butted up adjacent to the next.
typedef byte_t mem_t [0:1023];
typedef byte_t mem_t[1024]; // also OK
// SystemVerilog does not have a simple
// equivalent to the VHDL unconstrained
// array type.
// Dynamic arrays and queues are similar,
// but are not synthesisable
// (and not shown here)
// byte_t s;
s = '{default:0}; // assignment pattern
// can declare signed – from Verilog 2001
logic signed [7:0] s1;
VHDL SystemVerilog
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 3
Operators and Attributes
SystemVerilog adds many more
operators.
There are also many built-in array
functions, similar to VHDL array
attributes.
Array attributes may be applied to
multi-dimensional arrays.
The attributes and query functions
shown here for arrays will
synthesize fine.
An example of declaring a 2-D array
is shown here.
Note: VHDL type attributes and
SystemVerilog type querying
functions (which are not shown
opposite) are generally not
synthesizable.
and or not xor xnor
and or not
-- array attributes
-- signal s : std_logic_vector(7 downto )
s'RANGE
s'REVERSE_RANGE
s'LENGTH
s'LEFT
S'RIGHT
S'LOW
S'HIGH
S'ASCENDING -- true if ascending
-- type twoDT array is
-- (0 to 1, 7 downto 0) of std_logic;
-- signal s2d : twoDT;
s2d'LENGTH(2) -- 8
& | ~ ^ (bitwise – no xnor)
&& || ! (logical)
// new operators (borrowed from C)
+= -= *= /= %= &=
|= ^= <<= >>= <<<= >>>=
++ --
// array query functions
// logic [7:0] s;
$size(s)
$left(s)
$right(s)
$low(s)
$high(s)
$increment(s) // -1 ascending,
// +1 descending
$dimensions(s) // 1
$unpacked_dimensions(s) // 0
-- typedef logic [0:1][7:0] twoDT;
-- twoDT s2d;
$size(s2d,2)
VHDL SystemVerilog
4 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Modules / Design Entities
SystemVerilog follows Verilog 2001
for module declarations.
There are additional features (e.g.
modules parameterised by type) but
these are not well-supported for
synthesis.
Like VHDL, SystemVerilog allows
abstract data types on ports – but for
synthesis it may make more sense to
use interfaces (see later).
The example here shows a simple
parameterized counter. There are
also two kinds of process, clocked
(with asynchronous reset) and
combinational (to generate the
output TC, terminal count).
Note that SystemVerilog introduces
new process keywords including
always_comb (to indicate a process
that generates combination logic, i.e.
should be sensitive to all it inputs)
and always_ff (to indicate a process
that produces clocked logic). These
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_std.all;
entity Counter is
generic (NBits : Positive;
MaxCount : Positive);
port (Enable, UpDn : in Std_logic;
Clock, Reset, Load : in std_logic;
Data : in
Std_logic_vector(NBits-1 downto 0);
Q : out
Std_logic_vector(NBits-1 downto 0);
TC : out Std_logic);
end;
architecture RTL of Counter is
signal Cnt: Unsigned(NBits-1 downto 0);
begin
process (Clock, Reset)
begin
if Reset = '1' then
Cnt <= (others => '0');
elsif Rising_edge(Clock) then
if Enable = '1' then
if Load = '1' then
Cnt <= Unsigned(Data);
elsif UpDn = '1' then
if Cnt = MaxCount then
Cnt <= (others => '0');
else
Cnt <= Cnt + 1;
end if;
else
if Cnt = 0 then
Cnt <=
TO_UNSIGNED(MaxCount,NBits);
`default_nettype none
module counter
#(parameter nbits = 8,
maxcount = 100)
(input logic clk, rstb,
enable, load, updn,
input logic [nbits-1:0] data,
output logic [nbits-1:0] q,
output logic tc);
always_ff @(posedge clk or
negedge rstb)
if (rstb == 1'b0)
q <= {nbits{1'b0}};
else // not !rstb
if (enable == 1'b1)
if (load == 1'b1)
q <= data;
else // not load
if (updn == 1'b1)
if (q == maxcount)
q <= 0;
else
// Note q++ would result in
// a blocking assignment
q <= q + 1;
else // not updn
if (q == 0)
q <= maxcount;
else
q <= q - 1;
always_comb
if ( (q == maxcount && updn) ||
(q == 0 && ~updn))
tc = 1;
VHDL SystemVerilog
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 5
help reduce the chance of an
unintentional simulation / synthesis
mismatch.
always_comb also checks for (does
not allow) assignments to variables
from parallel processes; and will run
at time zero after normal initial and
always blocks, which ensures
outputs reflect the inputs correctly at
time 0.
Note Q++ in SystemVerilog would
result in a blocking assignment. Of
itself this is OK in certain contexts,
but it is bad to mix blocking and non-
blocking assignments to the same
variable (Q) (in fact it will not
synthesize).
The code opposite shows the
instantiation of the counter design.
Note the use of .* in SystemVerilog –
this automatically matches ports to
variables by name. (.* can make
your code less readable though).
.* is not applicable to parameters
(generics).
else
Cnt <= Cnt - 1;
end if;
end if;
end if;
end if;
end process;
Q <= Std_logic_vector(Cnt);
TC <= Enable when
Cnt = MaxCount and UpDn = '1' else
Enable when
Cnt = 0 and UpDn = '0' else
'0';
end architecture RTL;
// Instantiation from the testbench
uut: entity work.Counter
generic map (NBits => 4, MaxCount => 9)
port map (
Clock => Clock,
Reset => Reset,
Enable => Enable,
Load => Load,
UpDn => UpDn,
Data => Data,
Q => Q,
TC => TC
);
else
tc = 0;
endmodule : counter
// Instantiation from the testbench
// counter #(.nbits(4), .maxcount(9))
// uut (.*);
// PMC preferred
counter #(.nbits(4), .maxcount(9))
uut (.clk, .rstb, .enable, .load, .updn,
.data, .q, .tc);
// variables must match port names
VHDL SystemVerilog
6 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Generate
The VHDL generate statement is
very powerful for writing re-usable
code. Engineers have avoided the
Verilog generate statement in favour
of arrays of instances, partly due to
the difficulty of generating arrays of
wires/nets in Verilog.
With SystemVerilog, generate works
fine – and of course array ports are
possible as shown in the example
opposite.
The keywords generate/endgenerate
are optional, though you should
check tool support.
Note the slight difference in the use
of data types in the package,
because of VHDL's ability to declare
unconstrained arrays.
library IEEE;
use IEEE.Std_logic_1164.all;
package BCDPack is
type BCDCountT is array
(NATURAL range <> ) of
Std_logic_vector(3 downto 0);
end package BCDPack;
library IEEE;
use IEEE.Std_logic_1164.all;
use WORK.BCDPack.all;
entity BCDCounter is
generic (NDigits : Positive := 4);
port (Clock,
Reset, Enable: in Std_logic;
Count: out
BCDCountT(NDigits-1 downto 0));
end entity BCDCounter;
architecture Gen of BCDCounter is
signal TCn :
Std_logic_vector(NDigits downto 0);
begin
G1: for I in 0 to NDigits-1 generate
C1: entity work.Counter
generic map (4,9)
port map (Clock => Clock,
Reset => Reset, Enable => TCn(I),
Load => '0', UpDn => '1',
Data => "0000", Q => Count(I),
TC => TCn(I+1));
end generate;
TCn(0) <= Enable;
end architecture Gen;
package bcdpack;
typedef logic [3:0] nibble_t;
endpackage : bcdpack
module bcdounter
#(parameter ndigits = 4)
( input logic clk, rstb, enable,
output bcdpack::nibble_t
count [ndigits-1:0]);
logic [ndigits:0] tcn;
genvar i; // must use a genvar
generate // optional
for (i = 0; i < ndigits; i++)
begin : g1 // optional
counter #(.nbits(4),.maxcount(9)) c1
(.enable(tcn[i]),
.load (1'b0),
.updn (1'b0),
.data ({4{1'b0}}),
.q (count[i]),
.tc (TCn[i+1]),
.*); // connect others by name
end
endgenerate // optional
assign tcn[0] = enable;
endmodule : bcdcounter
VHDL SystemVerilog
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 7
Processes / always
Some simple VHDL and Verilog
equivalents are shown. Some key
features of SystemVerilog:
local variables are possible
without a named block
always_comb means
"combinational logic" i.e.
automatic complete sensitivity
list
always_ff means "synchronous
logic" i.e. one clock and a reset
allowed, edge triggered flip-flops
will be generated
always_latch means "this is a
transparent latch" – but
transparent latches are generally
avoided by most experienced
designers.
The last examples create an infinite
loop as there is no sensitivity! A
good reason to prefer always_comb.
optionalLabel: process
begin
-- statements
wait;
end process;
comb: process(a,b,c)
begin
f <= a or b or c;
end process;
-- identical in VHDL to concurrent signal
-- assignment
f <= a or b or c;
-- synchronous logic with async reset
process (Clk, Rstb)
begin
if Rstb = '0' then
Q <= '0';
else
Q <= D;
end if;
end process;
-- don't do this...
process
begin
a <= b;
end process;
initial
begin : optionalLabel
// statements
end
// always_comb preferred
always @*
f = a | b | c;
// continuous assignment
assign f = a | b | c;
// synchronous logic with async reset
always @(posedge clk or negedge rstb)
if (rstb == 1'0)
Q <= 0;
else
Q <= D;
// new in SystemVerilog – and preferred
always_comb
f = a | b | c;
always_ff @(posedge clk or negedge rstb)
if (rstb == 1'b0)
Q <= 0;
else
Q <= D;
// don't do this
always
a = b;
VHDL SystemVerilog
8 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Sequential Statements
Traditional Verilog has a source of
potential simulation / synthesis
mismatch in the use of synthesis
directives to indicate full / parallel
behaviour in case statements.
A full case statement means that
something will definitely be assigned
(there will be no latches).
A parallel case statement means that
only one branch will be taken (no
priority logic should be created).
SystemVerilog adds the unique and
priority keywords for both if and case
statements – this allows both
simulation and synthesis to
understand designer intent.
unique and priority both imply no
latches should be inferred. unique
also implies no priority logic.
Verilog has "don't care" casez and
casex (casex is prohibited by PMC
guidelines). The VHDL equivalent is
to use an if statement.
process(Op)
begin
case Op is
when Add =>
f <= a + b;
when Sub =>
f <= a – b;
when others =>
f <= (others => 'X');
end case;
end process;
-- must use an if statement for VHDL
if S = "01" then
State <= State1;
elsif S = "10" then
State <= State2;
else
State <= Idle; -- no simulation warning
end if; -- if latches inferred
always_comb
case (op)
ADD: f = a + b;
SUB: f = a – b;
default: f = 'bx;
endcase
// new in SystemVerilog
// Simulator will warn if contents of
// State are not one-hot
unique case (1'b1)
state[0]: ... // state is 3'b001
state[1]: ... // state is 3'b010
state[2]: ... // state is 3'b100
endcase
// conditions are matched in order. For
// instance, 01 has priority over 11.
priority case (S)
2'b01 : state = STATE1;
2'b10 : state = STATE2;
default: state = IDLE;
endcase
// Note: unique if not shown, as it may
// not synthesize
VHDL SystemVerilog
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 9
Other sequential statements are
shown here – loops and simple
functions.
Note SystemVerilog allows the
declaration of the loop variable within
the loop.
Also SystemVerilog allows local
variables within an un-named block
(this was only allowed in named
blocks in Verilog).
There is also a simple example of a
function. Of course this can be best
implemented in SystemVerilog using
the reduction operators!
Note that the use of automatic
functions (in both SystemVerilog and
VHDL) incurs a simulation overhead,
as the functions are created at run-
time ("dynamically elaborated" in
VHDL jargon). Nevertheless, when
using functions in SystemVerilog you
should declare them automatic, to
avoid potential problems with shared
local variables (race hazards).
-- simple function
function parity(s : std_logic_vector)
return std_logic is
variable V : std_logic;
begin
V := 0;
for i in s'range loop
V := xor s(i);
end loop;
return v;
end function parity;
f <= parity(A);
process (A, B)
variable V : std_logic;
begin
V := '0';
for i in A'RANGE loop
F(i) <= A(i) xor B(i);
V = V xor A(i);
end loop;
G <= V;
end process;
`default_nettype none
function automatic logic parity
( input logic [7:0] s);
logic v;
v = 0;
for (int i = 0; i < 7; i++)
v = v ^ s[i];
parity = v;
endfunction
module floop
(input logic [7:0] a,
input logic [7:0] b,
output logic [7:0] f,
output logic g, h);
always_comb
f = parity(.s(a));
always_comb
begin // no name required in SV
logic v;
v = 0;
for (int i = 0; i < $size(a); i++)
begin
f[i] <= a[i] ^ b[i];
v = v ^ a[i];
end
g <= v;
end
assign h = ^ a; // reduction operator
endmodule : floop
VHDL SystemVerilog
10 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Arithmetic
VHDL arithmetic may be done using
integer types, or overloaded
operators on vectors. Typically the
package IEEE.numeric_std is used,
which provides the vector types
signed and unsigned.
SystemVerilog includes the
improvements of Verilog 2001,
including the ability to declare signed
variables.
So in fact most examples on this
page are really Verilog 2001...
Note that a part select [n:m] of a
signed variable is unsigned.
The new SystemVerilog types
longint, int, shortint, byte all
synthesize as signed.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.Numeric_std.all;
entity Arith is
port (a : std_logic_vector(7 downto 0);
b : std_logic_vector(7 downto 0);
f : std_logic_vector(8 downto 0));
end entity arith;
architecture RTL of arith is
signal a1, b1 : signed(a'RANGE);
signal f1 : signed(f'RANGE);
begin
a1 <= SIGNED(a);
b1 <= SIGNED(b);
f1 <= RESIZE(a1, f'LENGTH) + b1;
f <= std_logic_vector(f1);
end architecture RTL;
-- or in one line
f <= std_logic_vector(
signed(resize(a, f'length) +
signed(b) );
`default_nettype none
module arith
(input logic [7:0] a,
input logic [7:0] b,
output logic [8:0] f);
// automatic sign extension
assign f = $signed(a) + $signed(b);
endmodule : arith
//
// various "gotchas"
//
// unsigned signed
logic [7:0] l; logic signed [7:0] r;
r[7:0] r
'd1 1
4'b1001 4'sb1001
$unsigned() $signed()
bit
longint
int
shortint
byte
VHDL SystemVerilog
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 11
Packages and Scope
SystemVerilog introduces packages,
similar in many ways to VHDL
packages.
In VHDL, a package must be
explicitly declared where it is needed
– in particular in front of entities,
packages, and configurations.
VHDL architectures can
automatically "see" what was made
visible in front of their parent entity.
Package bodies similarly have
visibility of packages made visible in
front of their parent package.
In SystemVerilog, declarations in a
particular compilation unit (often a
single file) are put in a kind of
invisible package called $unit.
A declaration in a package may be
explicitly referred to using a
"resolved name". It is also possible
to use a wildcard import, which
makes all declarations candidates for
import – but they are only actually
imported if they are used.
--
-- all declarations in std_logic_1164 are
-- made visible in the following package
--
library IEEE;
use IEEE.std_logic_1164.all;
package mypack is
subtype Byte_T is
std_logic_vector(7 downto 0);
end package mypack;
--
-- library work is always declared
--
use work.mypack; -- package name visible
entity myEntity is
port ( a, b : in mypack.Byte_T;
f : out mypack.Byte_T;
end entity myEntity;
--
-- alternatively make all names visible in
-- the following design unit
--
use work.mypack.all;
`default_nettype none
package mypack;
typedef logic [7:0] byte_t;
endpackage : mypack
//
// now can explicitly refer to each name
//
module myentity
( input a, b : mypack::byte_t,
output f : mypack::byte_t);
//
// alternatively wildcard import – names
// are potentially visible
//
import mypack::*;
// What is a compilation unit?
// It might be a single file, or a
// group of files
// Cadence incisive – multiple files
// implies one compilation unit
irun a.sv b.sv
// questasim
qverilog –mfcu a.sv b.sv
VHDL SystemVerilog
12 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Interfaces
SystemVerilog introduces a way to
group a set of connections into a
single object – an interface. It is
possible to achieve some limited
functionality in VHDL using records,
but it is much less powerful because
a VHDL record on a port cannot
have a mixture of in and out
fields
any connected entity can see all
the fields of the record
a record cannot contain helper
functions or procedures.
All the above are possible with
SystemVerilog interfaces. This
section contains a very simple
introduction based on APB (Amba
Peripheral Bus). See also
http://www.doulos.com/knowhow/sys
verilog
The SystemVerilog example shows
the declaration of an interface
subtype addr_T is
std_logic_vector(15 downto 0);
subtype data_T is
std_logic_vector(31 downto 0);
-- inputs
type APBInrecT is
record
PADDR : addr_T;
PWDATA : data_T;
PWRITE : std_logic;
PENABLE : std_logic;
PSEL : std_logic;
end record
--outputs
type APBOutRec_T is
record
PREADY : std_logic;
PRDATA : data_T;
end record APBOutRec_T;
-- to use on entity
entity APB_peripheral is
port (PCLK : in std_logic;
Ins : in APBInRec_T;
Outs : out APBOutRec_T)
end entity APB_Peripheral;
-- instantiation
signal Ins : APBInRec_T;
signal Outs : APBOutRec_T;
signal Clk : std_logic;
begin
uut: entity work.APB_peripheral
port map (PCLK => Clk, Ins => Ins,
Outs => Outs);
typedef logic [15:0] addr_t;
typedef logic [31:0] data_;
interface apb;
logic pclk, psel, penable, pwrite;
addrT paddr;
dataT pwdata;
dataT prdata;
// the view from a Master
modport Master (output pclk, psel,
penable, pwrite, paddr, pwdata,
input prdata);
// the view from a Slave
modport slave (input pclk, psel,
penable, pwrite, paddr, pwdata,
output prdata);
endinterface : apb
module apb _Master (apb.Master bus);
bus.penable = 1;
// ...
endmodule : apb _master
module apb _slave (apb.slave bus);
always_comb
if (bus.penable == 1)
// ...
endmodule : apb _slave
// continued on next page...
VHDL SystemVerilog
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 13
containing two modports. A modport
creates a particular "view" of an
interface from the point of view of the
connecting module. So for a slave,
the modport says that PRDATA is an
output (because it is driven by the
slave). For a master, the modport
says that PRDATA is an input.
Opposite you see the instantiation
and binding of the interface.
Note you don't have to mention the
modport both in the interface and in
the port map – but if you do, the
names must match.
So in the "master" instance, the port
is bound using "theBus.Master",
while in the "slave" instance, the port
is bound using "theBus". This is
possible because the port in the
slave was declared as "bus.Slave"
rather than just "bus".
Interfaces will synthesize – tools
"explode" the interconnect captured
in the interface, declaring individual
signals in the enclosing module. You
will need to check the use of
interfaces in your tool flow.
// instantiation
module design (...);
// interface instance
apb the_bus ();
// connect the master port to the
// master modport
apb_master master (
.bus(the_bus.master), ...);
// connect the slave port to the slave
// modport.
apb_slave slave (
.bus(the_bus),
...);
endmodule : design
VHDL SystemVerilog
14 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Test Fixture Code
Here we see some examples of non-
synthesizable code.
Simple assertions allow checks on
data values (for instance actual vs.
expected data). As well as $error,
one can use $info, $warning, and
$fatal. If you use $display, the
default severity is $error.
SystemVerilog also contains a
complete assertion language, but
that is beyond the scope of an
introduction.
File I/O in SystemVerilog is
essentially unchanged from Verilog
2001. There is a simple example
opposite.
Note the use of the immediate
assert, which can print messages for
both pass and fail (VHDL only prints
messages on failure).
-- assert
assert expected = actual
report "data mismath" severity ERROR;
-- file I/O
library IEEE;
use std.textio.all;
use ieee.std_logic_textio.all;
filereader: process
file F : text;
variable L : line;
variable OK : boolean;
variable status : file_open_status;
variable hex :
std_logic_vector(7 downto 0);
begin
file_open(status, F, "vectors.txt",
READ_MODE);
assert status = OPEN_OK
report "File prob" severity FAILURE;
while not ENDFILE(F) loop
READLINE(F, L);
HREAD(L, Hex, OK);
assert OK report "file read prob"
severity FAILURE;
-- ...
end loop;
FILE_CLOSE(F);
wait;
end process filereader;
// immediate assertion - %m returns the
// instance path of the module
assert (expected === actual) "OK" else
$error("%m Mismatch");
// file I/O
initial begin : fileReader
integer f;
logic [7:0] hex;
const static int EOF = -1;
f = $fopen( "vectors.txt", "r" );
fileok: assert (f != 0)
$display ("Opened vectors.txt");
else begin
$error ( "Could not open file" );
$stop;
end
forever begin : readfile
integer count;
count = $fscanf(f, "%2h", hex);
notEOF: assert (count != EOF) else
begin
$warning("End of file");
break;
end
one_item_ok: assert (count == 1) else
begin
$error("Expecting 1 item");
break;
end;
$display("Read value %2h", hex);
end : readfile
$fclose (f);
end : filereader
VHDL SystemVerilog
VHDL to SystemVerilog Guide 1.0 Copyright © 2010 by Doulos Ltd. All Rights Reserved 15
SystemVerilog has a built-in std
package, which contains some
classes, and also a randomize
function. The use of the randomize
function is shown opposite. Full
(class-based) constrained random
verification is beyond the scope of
this guide.
SystemVerilog introduces a very
simple and usable way of calling C
functions functions directly from
SystemVerilog code, the DPI (Direct
Programming Interface).
There is a very simple example
opposite.
--
-- randomization
--
use IEEE.math_real.all;
use IEEE.numeric_std.all;
process
variable seed1, seed2 : POSITIVE;
variable rand : REAL;
begin
-- generate a random real value between
-- 0.0 and just less than 1.0
uniform(seed1, seed2, rand);
addr <= std_logic_vector(
to_unsigned(
integer(rand), addr'LENGTH));
--
-- C interface
--
-- either proprietary, or use
-- IEEE 1076-2007C (incorporated into
-- IEEE 1076-2008) VHDL Programming
-- Interface, VHPI.
--
-- Too complex to show in a small space!
//
// randomization
//
// Note: you don't have to declare package
// std, it exists for free.
package std;
class semaphore; ...
class mailbox; ...
class process; ...
function int randomize(...);
endpackage : std
always begin
bit ok;
// randomize a list of variables
// don't need to write std::randomize,
// std:: is imported for you.
ok = randomize(addr, data);
assert (ok)
else $error("randomize failed");
// DPI-C
// function hello.c
#include <stdio.h>
int hello ( int num_repeats )
{
int i;
const char what_to_say[] = "Hello";
for ( i = 0; i < num_repeats; i++ )
printf( "%s\n", what_to_say );
return 0;
}
// continued on next page...
VHDL SystemVerilog
16 Copyright © 2010 by Doulos Ltd. All Rights Reserved VHDL to SystemVerilog Guide 1.0
Finally there are whole areas of
SystemVerilog which are simply not
available in VHDL including
classes and objects, supporting
randomization and (single)
inheritance
temporal assertions (SVA,
SystemVerilog Assertions)
similar to the Property
Specification Language (PSL)
interfaces including interface
tasks (procedures)
synchronization and clocking
blocks (to assist with verification
environments)
dynamic data types (queues,
arrays)
... and more!
// sayhello.sv
module sayhello;
// Import the C function "hello", so it
// can be called from SystemVerilog
// It could be imported either as a task
//or as a function returning void
import "DPI-C" task hello (input int i);
//import "DPI-C" function
// void hello (input int i);
initial
begin
$display("About to say ...\n");
// Call the C function "hello" here
hello(2);
$display("\nSaid it. Goodbye");
end
endmodule