vhdl_to_sv

16
VHDL to SystemVerilog Guide 1.0 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

Upload: bhargava0867335

Post on 27-Dec-2015

14 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: VHDL_to_SV

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

Page 2: VHDL_to_SV

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;

Page 3: VHDL_to_SV

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)

Page 4: VHDL_to_SV

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;

Page 5: VHDL_to_SV

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

Page 6: VHDL_to_SV

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

Page 7: VHDL_to_SV

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;

Page 8: VHDL_to_SV

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

Page 9: VHDL_to_SV

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

Page 10: VHDL_to_SV

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

Page 11: VHDL_to_SV

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

Page 12: VHDL_to_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...

Page 13: VHDL_to_SV

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

Page 14: VHDL_to_SV

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

Page 15: VHDL_to_SV

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...

Page 16: VHDL_to_SV

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