BugHunter Pro and the VeriLogger Simulators

Appendix B: Verilog2VHDL Translation Reference

Appendix B: Verilog2VHDL Translation Reference

Previous topic Next topic  

Appendix B: Verilog2VHDL Translation Reference

Previous topic Next topic  

Verilog2VHDL translates Verilog to VHDL using a combination of IEEE and tool-specific packages. The tool provides support for comprehensive modeling styles and maintains hierarchy during the translation. In this chapter, various supported constructs are discussed.

The rest of the chapter is organized as follows: For every construct supported by Verilog2VHDL, the general Verilog and VHDL semantics are given, followed by an example illustrating the construct in both languages. Special notes are given when required. The user is advised to refer to the VHDL LRM and Verilog LRM for detailed explanations.

Objects and Types

Verilog has the following types defined:

Register

Net

Integer, real and time variables

In VHDL, three classes of objects (as outlined below) are defined, each of which can be a scalar, composite, access or file type:

Signal

Variable

Constant

Verilog2VHDL translates registers, integer, real and wire variables (henceforth referred to as Verilog objects) declared in Verilog to VHDL objects of a specific class based on the following criteria:

1.If a Verilog object is declared inside a task or function, the corresponding VHDL object class is VARIABLE.

2.If a Verilog object is declared as a parameter, the VHDL object class is CONSTANT.

3.All others Verilog object declarations get the VHDL object class SIGNAL.

Verilog and VHDL are based on the same 4-level logic system (0,1 ,X,Z). Verilog2VHDL uses the IEEE standard 9-level std_ulogic type to translate the logic-levels. The logic levels in Verilog translate to the VHDL std_logic_1 164 package 9-level system in the following way:

Logic Level Mapping

Verilog

VHDL

0

0

1

1

X

X

Z

Z

 

U,H,L

The basic Verilog data type wire is equivalent to the VHDL resolved type std_logic. Similarly, a vector in Verilog is equivalent to the VHDL resolved type std_logic_vector.

Module

The primary design unit in Verilog is the module. The equivalent representation in VHDL is an entity and architecture declaration. The standard Verilog and VHDL syntax for design unit declaration and an example illustrating the concept are shown below:

Example:

Verilog

VHDL

module Verilog2VHDL_example(

   Verilog2VHDL_a,  

   Verilog2VHDL_b, 

   Verilog2VHDL_c);

 

 

input Verilog2VHDL_a;

input Verilog2VHDL_b;

output Verilog2VHDL_c;

 

endmodule

entity Verilog2VHDL_example is 

 port(Verilog2VHDL_a : in std_logic;

 Verilog2VHDL_b : in std_logic;

 Verilog2VHDL_c : out std_logic);

end entity;

 

architecture VeriArch of Verilog2VHDL_example is

begin

 

 

end VeriArch;

Parameter Declaration

Constants can be declared in Verilog using the parameter declaration. The corresponding VHDL declaration is a generic in the entity declaration.

Example

Verilog

VHDL

parameter a = 10;

parameter b = 5;

parameter c = 1.5;

generic(CONSTANT a : integer := 10;

CONSTANT b : integer := 5;

CONSTANT c : real := 1.5 );

Register and Net Declaration

There are two main types of data types in Verilog: Registers and Nets. Registers are a data type to model data storage. They can hold their value until the next assignment. Nets, on the contrary, do not store any value (except trireg), and instead take the value of the driving gate or assignment. They are primarily used to represent connections between structural entities. VHDL models both registers and nets using the type signal. Signals in VHDL are used both for electrical connections and storing values.

Example

Verilog

VHDL

wire a;

wire [3:0] b;

reg c;

signal a : std_logic;

signal b : std_logic_vector( 3 downto 0);

signal c : std_logic register;

Special Note: Register declarations and other Verilog declarations inside user defined tasks and functions are modeled as VHDL variables.

Memory Declaration

Verilog HDL models memories as arrays of register variables. They are typically used to model Read only memories (ROM) or Random access memories (RAM). Translation of memory types to VHDL is straight forward. A special type is created for this purpose in output VHDL.

Example

Verilog

VHDL

reg [255:0] a[7:0]; 

 

 

type memory_0 is array(7 downto 0) of

           std_logic_vector(255 downto 0);

signal a : memory_0 register;

Integer Declaration

One of the types allowed in Verilog is the Integer type. Integer types in Verilog are translated to a resolved subtype of the pre-defined integer type in VHDL.

Example

Verilog

VHDL

integer a;

integer b[3:0]

 

use Verilog.v2v_types.all;

 

signal a : v2v_integer register;

signal b : integer_array(3 downto 0);

Special Note: The resolved subtype v2v_integer, and type integer_array are declared in the v2v_types package available in the types.vhd file.

Real Declaration

Types allowed in Verilog include the real type. Real types in Verilog are translated to the pre-defined real type in VHDL.

Verilog

VHDL

real a;

 

 

use Verilog.v2v_types.all;

signal a : real;

Module Instantiation

Both Verilog and VHDL are hierarchical description languages, and allow modules to be embedded inside other modules. This process is also known as module instantiation. Higher level modules instantiate modules, and communicate with them through the ports on the instantiated module. The functionality of module instantiation is equivalent in both languages.

Example

Verilog

VHDL

wire a, b;

reg c;

 

df df_instance1(a,b,c);

 

df df_instance(.in1(a), 

               .in2(b), 

               .in3(c) );

architecture arch_name of

  signal a,b,c : std_logic;

begin

  df_instance1 df port map(a,b,c);

 

  df_instance2 df port map(in1 => a,

                           in2 => b,

                           out => c);

Gate Instantiation

Verilog is a rich language for modeling at low levels of abstraction. It has built-in primitives like n-input nand gates and buffers. VHDL, on the other hand, is more suited for modeling at higher levels. Though it is possible to create entities corresponding to Verilog gates, Verilog2VHDL translates a gate instantiation for almost all gates into equivalent VHDL concurrent signal assignments.

Example

Verilog

VHDL

`timescale 1ns/1ns;

wire a,b,c;

wire d,e,f;

wire g,h,i;

 

nand(a,b,c);

nor #3 (d,b,c,e,f);

not #2(g,b);

not (h,i,c);

 

signal a,b,c : std_logic;

signal d,e,f : std_logic;

signal g,h,i : std_logic;

 

a <= b nand c;

d <= (((b nor c) nor e) nor f) after 3 ns;

g <= b after 2 ns;

h <= c;

i <= c;

Always Statement

Example

Verilog

VHDL

reg b;

reg a;

always @(negedge clock)

begin

  if (a == 1)

    b = 1;

  else

    b = 0;

end

 

 

USE Verilog.timing.all;

signal a,b : std_logic;

process

begin

  wait until negedge(clock);

  if (a = '1')

    b = '1';

  else

    b = '0'

  else if;

end process;

Special Note: `negedge' is a library function provided in the timing package (file timing.vhd ).

Initial Statement

The initial statement is similar to the always statement, except that it executes only once during the entire simulation run. It is functionally equivalent to a VHDL process with an infinite wait statement at the end of the sequential body.

Register initialization in initial statements without event control are handled as a special case. If the register initialization is the first statement in the initial block without event control (precedes ALL wait statements), the statement is mapped to a signal initialization statement in VHDL. The following example shows this special case for register `a'.

Example

Verilog

VHDL

reg a;

 

initial

begin

  a = 0;l

  #10 b = 0;

  c = 1;

  d = 1;

end

signal a : std_logic register := 0;

 

process

begin

  wait for 10 ns;

  b <= '0';

  c <= '1';

  d <= '1';

  wait;

end process;

Conditional if-else-if Statement

Both languages support the conditional `if statement' and the translation is mostly straightforward, with a few exceptions. In Verilog, the result of an `if expression' can be (0,1,X,Z). In VHDL, the `if expression' has to decode to the boolean type in VHDL (FALSE, TRUE). All Verilog expressions do not map directly to VHDL. A typical example is the following `if expression' (this type of expression will be referred to a `non­boolean' expression in ensuing discussion) :

if (a)

There is no direct equivalent in VHDL, because the above `if expression' tests if `a' is `1', in the case `a' is a register data type, or if `a' has a value other than `0', if `a' is an integer type. To preserve logical equality during translation, Verilog2VHDL translates a non­boolean `if expression' in Verilog to a boolean expression. A negation test is applied to the scalar or vector instead, to preserve the logic. An example illustrates the translation below. In the example, the first `if expression' is not a boolean expression by itself. Hence, Verilog2VHDL maps the `if expression' in Verilog to VHDL by first applying the std_logic_1 164 package translation function `To_Bit' to the register variable and then testing for a non-zero value. The translation function `To_Bit' is required to discard cases involving unknowns.

Example

Verilog

VHDL

always @(a)

begin

  if (a)

    b = 1;

  else

    b = 0;

end

process

begin

  wait on a;

  if To_bit(a) /= '0' then

    b <= '1';

else

    b <= '0';

end if;

end process;

Special Note: The library function `To_bit' is available in the Std_logic_1164 package.

Conditional 'case' Statement

The case statement uses the same reasoning in both languages; both are multi-way decision statements which test for a matching expression and branch accordingly. There are, however, some limitations in VHDL, which does not have direct equivalent statements for `casex' and `casez'. The translation of ` casex' and `casez' statements is detailed in the next section.

Example

Verilog

VHDL

always @(select)

begin

  case (select)

    3'b000 : dec_out = 8'b00000001;

    3'b001 : dec_out = 8'b00000001;

    3'b010 : dec_out = 8'b00000001;

    3'b011 : dec_out = 8'b00000001;

    3'b100 : dec_out = 8'b00000001;

    3'b101 : dec_out = 8'b00000001;

    3'b110 : dec_out = 8'b00000001;

    3'b111 : dec_out = 8'b00000001;

  endcase

end

 

process

begin

wait on select;

  case select is

    when "000" => dec_out <= "00000001";

    when "001" => dec_out <= "00000001";

    when "010" => dec_out <= "00000001";

    when "011" => dec_out <= "00000001";

    when "100" => dec_out <= "00000001";

    when "101" => dec_out <= "00000001";

    when "110" => dec_out <= "00000001";

    when "111" => dec_out <= "00000001";

   end case;

end process;

Conditional 'casex' and 'casez ' Statement

`casex' and `casez' statements are special purpose case routines provided in the Verilog language for `dontcare' comparison. VHDL has no direct equivalent, but Verilog2VHDL writes out the equivalent VHDL for a `casex' or `casez' statement. Each of these statements is translated to an equivalent VHDL `if' statement and the sequential statements are updated accordingly.

Example

Verilog

VHDL

always @(select)

begin

casex (select)

  3'b0?0 : dec_out = 8'b00000001;

  3'b?01 : dec_out = 8'b00000010;

  default : dec_out = 8'bz;

endcase

end

 

 

 

 

always @(select)

begin

casez (select)

  0 : dec_out = 8'b00000001;

  1 : dec_out = 8'b00000010;

  default: dec_out = 8'bz;

endcase

end

process

begin

  wait on selct;

  if casex(select,"0Z0") then

    dec_out <= "000000001";

  elsif casex(select,"Z01")

    dec_out <= "00000010";

  else

    dec_out <= "ZZZZZZZZ";

  end if;

end process;

 

process

begin

  wait on select

  if casez(select,0) then

    dec_out <= "00000010";

  elsif casez(select,1) then

    dec_out <= "00000010";

  else

    dec_out <= "ZZZZZZZZ";

  end if;

end process;

Special Note: `casex' and `casez' are library functions available in the utils package (file utils.vhd).

Looping Statements

Looping, or iteration schemes found in Verilog can be easily translated to VHDL. Verilog2VHDL supports `for', `repeat', `while' and `forever' statements.

Example

Verilog

VHDL

for (i = 0; i < 4; i = i + 1)

  b = b + 2;

 

 

 

 

while (i < 5)

  b = b + 2;

 

 

repeat (5)

loop

  b = b + 2;

 

forever

  b = b + 2;

i := 0;

while (i < 4) loop

  b := b + 1;

  i := i + 1;

end loop;

 

while (i<5) loop

  b := b + 2;

end loop;

 

for V2V_repeat in 5 downto 1

  b := b + 2;

end loop;

 

loop

  b := b + 2;

end loop;

Special Note: The Verilog `for' statement is equivalent to the VHDL `for' statement only when the Verilog `for' has static bounds, and the loop variable (`i' in the example above) is incremented by one (i = i + 1) or decremented by one (i = i - 1). The loop variable `i' is not available as a signal in VHDL, and hence cannot be accessed when used as the target for assignments, other than incrementing (decrementing) by one. For this reason, the Verilog `for' is mapped to the VHDL `WHILE' loop. In doing so, we also gain access to the loop variable `i'.

Continuous Assignments

A continuous assignment in Verilog is a statement that executes every time the right hand side of the an assignment changes. This is wholly equivalent to the concurrent signal assignment in VHDL with inertial delays.

Example

Verilog

VHDL

`timescale 1ns/1ns

assign #10 a = b & c;

a <= b and c after 10 ns;

 

Procedural Assignments

Procedural assignments are used to assign values to register, integers, real or time variables. These types of assignments are normally present in always/initial statements, tasks and functions. Procedural assignments can have delay, event or repeat control. All cases are translated correctly to functionally equivalent VHDL.The subtle differences when translating a Verilog procedural assignment to a VHDL assignment are shown below.

Example

Verilog

VHDL

timescale 1ns/1ps;

reg a,b;

always @(clk)

begin

  a = #10 1;

 

 

 

  a = @(posedge clk) b;

 

 

 

  a = repeat (5) @(posedge clk) b;

 

 

 

 

 

  #5 b <= 0;

 

  #5 b = 1;

 

end

signal a,b : std_logic;

shared variable V2V_a : std_logic;

process

begin

  wait on clk;

  a <= '1' after 10 ns;

  wait for 10 ns;

 

  V2V_a := b;

  wait until posedge(clk);

  a <= V2V_a;

 

  V2V_a := b;

  for V2V_repeat in 5 downto 1

    wait until posedge(clk);

  end loop;

  a <= V2V_a;

 

  wait for 5 ns;

  b < = transport '0';

 

  wait for 5 ns;

  b <= '1';

  wait for 0 ns;

 

end process;

Special Note: Explanation follows about the `wait for 0 ns' statements in the VHDL code corresponding to a Verilog blocking assignment without timing control. In Verilog, events due to blocking assignments always occur. Statements following the blocking assignments occur only after the blocking assignment has taken effect. In VHDL, however, simulation time advances only after a wait statement, and assignments take effect when simulation time advances. For this reason, it is necessary to insert a `wait for 0 ns' after a sequential signal assignment in VHDL for cases where no delay in specified.

Non-blocking Procedural Assignment

The non-blocking Verilog procedural is a way to model transport delays in signal assignments; i.e it does not matter what order you make the assignments in a procedural dataflow. VHDL assignments are inherently non-blocking, and hence it is easy to translate Verilog non-blocking assignments.

Example

Verilog

VHDL

`timescale 1ns/1ps;

always @(posedge clk)

begin

  a <= #10 1;

 

 

  #5 b <= 0;

end

process

begin

  wait until posedge(clk);

  a <= transport '1' after 10 ns;

 

  wait for 5 ns;

  b <= transport '0';

end process;

Special Note: `posedge' function is available in the timing package.

Compiler Directives

Verilog supports numerous compiler directives. In this version of Verilog2VHDL, only the `timescale and `define compiler directives are supported. `define compiler directives are translated as system - wide generic declarations i.e. all modules following the `define statement have a generic interface list corresponding to the `define statement. The time unit specified with the `timescale directive is used as the time unit for VHDL.

Example

Verilog

VHDL

 

`define TRUE 1

`define FALSE 0

`define foo "some people"

`define all_zs 8'bz

 

 

 

`timescale 10ns/1ns;

reg a,b;

 

always @(posedge clk)

begin

  a = #10 1;

  #5 b = 0;

end

entity verilog2vhdl is port

  (constant TRUE : integer := 1;

   constant FALSE : integer := 0;

   constant foo : string(1 to 10) := "some people";

   constant all_zs : std_logic_vector(8"ZZZZZZZZ");

 

 

 

process

begin

  wait until posedge(clk);

  a <= '1' after 100 ns;

  wait for 50 ns;

  b <= '0';

end process

User-Defined Tasks and Functions

User-defined tasks and functions are used extensively in behavioral Verilog. They encapsulate blocks of sequential statements and are invoked from within the module. Additionally, arguments can be passed and exchanged through these calls. Though VHDL has equivalent procedures known as `Subprograms', they differ from Verilog tasks and functions in the following ways:

1.To execute a signal assignment in a VHDL subprogram, it is necessary for the signal to be available in the list of interface elements of the subprogram. This is not a requirement in Verilog. Hence, Verilog2VHDL adds signals that are driven from within a Verilog task or function as interface elements to the corresponding VHDL subprogram.

2.In VHDL, it is not possible to read a signal inside a subprogram if it is an interface element of the subprogram of mode `OUT'. For this reason, an intermediate temporary signal is created in the VHDL architecture.

The above points are further illustrated by the example below.

Example

Verilog

VHDL

`timescale 1ns/1ns;

module dummy(a,b,c)

  input a;

  input b;

  output c;

 

  reg temp;

 

  always @(a)

    update_output;

 

task update_output;

  temp = a or b;

  c = temp

endtask;

 

endmodule

entity ...end entity;

architecture VeriArch of dummy is

procedure update_output(

  signal temp : out std_logic;

  signal V2V_c : out std_logic register) is

begin

  temp <= a or b;

  wait for 0 ns;

  V2V_c = V2V_TEMP_temp;

  -- note the temporary signal

end procedure;

 

signal temp : std_logic;

signal V2V_c : std_logic;

signal V2V_TEMP_temp : std_logic;

signal guard : Boolean := true;

begin

  process

  begin

    wait on a;

    update_output(temp,c)

  end process;

end

 

c <= guarded V2V_c;

V2V_TEMP_temp <= guarded temp;

-- Note the concurrent assignments

 

end VeriArch;

`System Tasks and Functions

There are no direct VHDL equivalents to Verilog system tasks or functions, so the translation is done by automatically creating equivalent procedures in the VHDL output file. Of all Verilog system tasks and functions, Verilog2VHDL supports those associated with formatted output, and $time and $fopen functions.

System Functions

Verilog

VHDL

$time

NOW / <timeunit>

$fopen("filename.ext")

FILE F 1: text open

WRITE _MODE is "filename.ext"

$time function is translated into NOW function normalized by 1 ns (default) or by the timeunit specified with a `timescale directive.

Translation of $fopen("filename.ext") function results in a declaration of a file with the logical name "filename.ext". If $fopen function appears on the RHS of an assignment or as an argument to a task or a function, it is substituted by the channel descriptor number normally returned by a $fopen function call in Verilog (see assignment to file1 in the example below). As in Verilog, filechannel 1 is reserved for STDOUT ("/dev/tty" in VHDL). STDOUT channel is added automatically to the translation of a Verilog file with output system task calls.

System Tasks

Verilog

VHDL

$display $fdisplay $strobe $fstrobe

V2V_display

$write $fwrite

V2V_write

 

The number of parameters of V2V_display is adjusted automatically to translate $(f)display or $(f)strobe call with the greatest number of parameters. Similarly, the number of parameters of V2V_write is adjusted automatically to translate the $(f)write call with the greatest number of parameters.

Example

Verilog

VHDL

integer file1;

integer filechan;

 

file = $fopen("latch.list);

filechan = file1 | 1;

$fdisplay(filechan, , $time,

  "Change in qQuit=%b with data=%b",

  qOut, data);

signal filel : integer;

signal filechan : integer;

signal std_io : integer := 1;

file v2v_file_f2 : text open WRITE_MODE 

                   is "latch.list";

file v2v_file_f1 : text open WRITE_MODE 

                   is "dev/tty";

 

PROCEDURE writeline(filechannel : IN integer;

                    VARIABLE l  : INOUT line;

                    line_feed   : IN character := LF) IS

   VARIABLE unsigned_filechannel : unsigned(2 downto 1);

BEGIN

  unsigned_filechannel := TO_UNSIGNED(filechannel, 2);

  IF unsigned_filechannel(1) = '1' THEN

    write(V2V_FILE_F1, l.all & line_feed);        

  END IF;

  IF unsigned_filechannel(2) = '1' THEN

    write(V2V_FILE_F2, l.all & line_feed);        

  END IF;

  Deallocate(l);        

END;

 

PROCEDURE V2V_display (filechannel : IN integer;

                 message1 : IN string := "";

                 message2 : IN string := "";

                 message3 : IN string := "";

                 message4 : IN string := "";

                 message5 : IN string := "";

                 message6 : IN string := "") IS 

        VARIABLE l : LINE;        

BEGIN

        WRITE(l, message1, LEFT, 0);        

        WRITE(l, message2, LEFT, 0);        

        WRITE(l, message3, LEFT, 0);        

        WRITE(l, message4, LEFT, 0);        

        WRITE(l, message5, LEFT, 0);        

        WRITE(l, message6, LEFT, 0);        

        writeline(filechannel, l);        

END;

 

 filechan <= v2v_to_integer(file1 OR 1);        

 WAIT FOR 0 NS;

 V2V_display(filechan, 

             image(To_bitvector(filechan)), 

             image(now / 1 NS), 

             "Change in qQuit=", 

             image(To_bit(qOut)), 

             " with data=", 

             image(To_bit(data)));        

Verilog2VHDL Error Handling

Verilog2VHDL handles errors in the following way:

1.If a syntax error in encountered in the Verilog input file, the tool exits immediately after printing out the error message.

2.If an unsupported construct is encountered in the Verilog Input, a warning message is issued, and Verilog2VHDL continues processing.

3.If the unsupported construct is of the type `event', Verilog2VHDL exits after issuing appropriate error message.

Reserved words in Verilog2VHDL

It is important to note that VHDL is case-insensitive; and therefore `test' and `TEST' are the same. The user is advised not to use identifiers differing only in case in the Verilog file as this may result in incorrect VHDL.

Verilog2VHDL has a list of reserved words which are not allowed as identifiers in input Verilog code. When they appear in the input Verilog code, Verilog2VHDL creates legal VHDL names by modifying each reserved identifier to a VHDL extended identifier with the same name. For eg., VHDL reserved identifier `shared' would be modified to `\shared\'; all occurrences of `shared' will be changed to `\shared\'. Reserved identifiers follow below:

abs

access

after

alias

all

architecture

array

assert

attribute

block

body

buffer

bus

component

configuration

constant

disconnect

downto

elsif

entity

exit

FALSE

file

function

generate

generic

guarded

impure

in

inertial

inout

is

label

library

linkage

literal

loop

map

mod

nand

new

next

nor

not

of

on

open

others

out

package

port

postponed

procedure

process

pure

range

record

register

reject

rem

report

return

rol

ror

select

severity

signaland

sla

sll

sra

srl

subtype

then

to

transport

TRUE

type

unaffected

units

until

use

variable

wait

when

with

xnor

xor