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 `nonboolean' 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 nonboolean `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
|