BugHunter Pro and the VeriLogger Simulators

Appendix C: VHDL2Verilog Translation Reference

Appendix C: VHDL2Verilog Translation Reference

Previous topic This is the last topic  

Appendix C: VHDL2Verilog Translation Reference

Previous topic This is the last topic  

VHDL2Verilog translates input VHDL to Verilog. This release supports a subset of VHDL (see Appendix A for comprehensive listing).

The rest of the chapter is organized as follows: For every construct supported by VHDL2Verilog, the general translation rules 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.

Entities and Architectures

The basic design unit in VHDL is the ENTITY and ARCHITECTURE pair. An entity and architecture pair is translated to a Verilog MODULE description. An entity can have multiple architectures. Multiple architectures per entity are translated to multiple modules. VHDL2Verilog creates module names based on the following criteria:

Module name is the same as the entity name in input VHDL file.

Module name is the concatenation of the entity and architecture name in input VHDL file. For e.g., if an entity aha has two architectures, structural and behavioral, the Verilog modules are aha_structural and aha_behavioral.

Example

VHDL

Verilog

library ieee;

use ieee.std_logic_1164.all

 

entity test is

port(a : in std_logic;

     b : out std_logic)

end entity;

 

architecture behave of test is

begin

end behave;

module test(a,b);

  input a;

  output b;

 

endmodule

Special Note: Verilog files can be imported for VHDL Entity and Architecture pairs by using tool-specific attribute VHDL2V_MODULE in the entity declaration. See Importing (parts of) Verilog files for detailed explanation.

Packages and Package Bodies

Most VHDL designs reference one or more PACKAGEs through USE statements. These packages can contain pre-defined constants, types, components, or subprograms (functions or procedures). VHDL2Verilog will translate the packages if they are used, and includes this translation either in the output file, or in one or more separate files.

Example

VHDL

Verilog

package my_package is

  constant width : integer := 16;

end my_package;

 

use ieee.my_package.all;

entity test is

  port(a : in std_logic;

       b : out std_logic);

end entity;

 

architecture behave of test is

begin

end behave;

module test(a,b);

  parameter width = 16;

  input a;

  output b;

endmodule

The translated package can also be included in a separate file using the -Include Package files switch. In that case VHDL2Verilog will produce a file called:

<package>_package.v

If there are components in the package, and the corresponding entity - architecture pairs of the components have been read in as well, another file will be produced called:

<package>_modules.v

Both files are included in the Verilog code with an `include statement.

NOTE: Subprograms in the package get translated only when they are used in the design and when Function mapping and translation has been activated.

Data Types

VHDL has three classes of data objects: SIGNAL, VARIABLE and CONSTANT. Verilog does not make any such distinction in its two data types: NETS and REGISTERS. Verilog NETS are used for driving signals, and REGISTERS are an abstraction of the hardware register. VHDL2Verilog translates VHDL objects to Verilog NETS or REGISTERS based on the following rules:

1.If the signal is an input, it is translated to an implicitly declared WIRE.

2.Signals corresponding to output ports get translated to Verilog REGISTERS.

3.If a signal is used as the target in a VHDL concurrent assignment or an actual designator in the port mapping of a component instantiation, the Verilog translation of VHDL signal is a WIRE. Note that in this particular case, outputs get declared as WIRES.

Example

VHDL

Verilog

library ieee;

use ieee.std.logic_1164.all;

 

entity test is

port(a : in std_logic;

     b : out std_logic;

     c : out std_logic)

end entity;

 

architecture behave of test is

begin

  b <= '1';

end behave;

module test(a,b,c);

  input a;

  output b;

  output c;

 

  wire b;

  reg c;

  assign b = 1;

endmodule;

Generics

VHDL GENERICs are used to construct parameterized components. Verilog offers similar capabilities in the form of parameter declarations. VHDL generics are translated to Verilog parameters.

Example

VHDL

 

Verilog

library ieee;

use ieee.std_logic_1164.all;

entity test is

  generic(gen_a : in natural := 20;

          datapath : in integer := 11);

port(a : in std_logic;

     b : out std_logic_vector(datapath downto 0);

     c : out std_logic);

end entity

 

architecture behave of test is

begin

end behave;

module test(a,b,c);

 

  parameter gen_a = 20;

  parameter datapath = 11;

 

  input a;

  output [datapath:0[ b;

  output c;

 

  wire [datapath:0] b;

  reg c;

 

endmodule;

Sequential Statements

VHDL sequential statements occur in VHDL PROCESS or SUBPROGRAM bodies. These statements execute in the order they appear. VHDL2Verilog translates sequential statements outlined in the following sections.

Wait Statements (Sequential Statement)

The WAIT statement is used to suspend the execution of a process or subprogram body. The VHDL LRM defines three types of WAIT statements:

4.Wait with sensitivity clause

5.Wait with condition clause 3. Wait with timeout clause

The current version of VHDL2Verilog supports WAITs with timeout clauses. WAITs with sensitivity clauses are supported only if appearing as the first (or last) item of the sequential body.

Example

VHDL

Verilog

process_l : process

  constant tpd  : std_logic := '1';

  constant tpd1 : std_logic := '0';

begin

  wait on a, enable;

  if (enable = '0') then

    q <= '0';

  elsif a'event and a'last_value = 0 then

    q <= d;

    q <= '1' after 2ns;

    q <= '0';

  end if;

end process process_1;

always @(posedge a or negedge enable)

  parameter tpd  = 'b1;

  parameter tpd1 = 'b0;

 

if (enable == 'b0)

  q <= 'b0;

else

  begin

  q <= d;

  q <= #2 'b1;

  q <= 'b0;

  end

end

Signal Assignments (Sequential Statement)

SIGNAL ASSIGNMENTs are used to modify the output waveform of the target. Verilog signal assignments (known as PROCEDURAL ASSIGNMENTS) can be of two types:

1.BLOCKING procedural assignment: A blocking procedural assignment MUST be executed before the execution of the statements that follow.

2.NON-BLOCKING procedural assignment: Verilog non-blocking procedural assignments allow scheduling of assignments without blocking the procedural flow. Typically, they are used when multiple assignments need to be made in the same simulation cycle.

All VHDL signal assignments are translated to Verilog NON-BLOCKING procedural assignments.

Example

VHDL

Verilog

architecture diffeq of diffeq is

begin

 

p0 : process

begin

  Xoutport <= 0;

  Youtport <= 0;

  Uoutport <= 0;

  wait;

end process p0;

 

p1 : process(Aport,DXport,Xinport,

             Yinport,Uinport)

  variable x_var, y_var, u_var : std_logic;

begin

  Xoutport <= x_var after 2 ns;

  Youtport <= transport y_var; //will occur

  Xoutport <= u_var after 5ns;

  -- above will cancel prev assignment

end process P1;

module diffeq;

 

 

initial

begin : p0

  Xoutport <= 0;

  Youtport <= 0;

  Uoutport <= 0;

end

 

 

always @(Aport or DXport or Xinport or

         Yinport or Uinport)

begin : p1

  reg x_var, y_var, u_var;

 

  Xoutport <= #2 x_var;

  Youtport <= y_var; //fully non-blocking

  Xoutport <= #5 u_var;

  // above will not cancel prev assignment

end

NOTE: Verilog non-blocking assignments differ from VHDL signal assignments in one important respect. Verilog non-blocking assignments ALWAYS occur. However, VHDL signal assignments with INERTIAL delay generate projected events which can be cancelled by future events. Verilog non-blocking assignments execute without cancelling a previous non-blocking assignment to the same register. Therefore, delays in Verilog non-blocking assignments are handled as TRANSPORT delays. If the delay type in VHDL signal assignments were specified to be TRANSPORT, then it would be equivalent to Verilog non-blocking assignment.

Variable Assignments (Sequential Statement)

VARIABLE ASSIGNMENTS are used to replace the current value of the variable with the new value specified on the right hand side of the assignment without any delay. They are mapped to Verilog non-blocking register assignments.

Example

VHDL

Verilog

process_2 : process(dummy)

  variable q_1 : std_logic_vector(3 downto 0);

  variable q_2 : std_logic_vector(3 downto 0);

begin

  if (dummy = '1') then

    q_1 := "0001"

  end if;

end process process_2;

always @(dummy)

begin : process_2

  reg [3:0] q_1;

  reg [3:0] q_2;

  if (dummy == 'b1)

    q_1 = 'b0001;

end

If Statements (Sequential Statements)

The IF statement chooses to execute one (or none) of many sequence of statements based on the value of corresponding condition. The semantics of the Verilog IF statement are the same, barring the VHDL requirement that an IF (ELSIF) expression be boolean. VHDL IFs are mapped to Verilog IFs.

Example

VHDL

Verilog

process_1 : process

begin

  wait on a,enable;

  if (enable = '0') then

    q <= '0'

  elsif a = '0' then

    q <= d;

    q <= '1' after 2 ns;

    q <= 0;

  end if;

end process process_1;

always @(a or enable)

begin : process_1;

if (enable == 'b0)

  q <= 'b0;

else if (a == 'b0)

  begin

  q <= d;

  q <= #2 'b1;

  q <= 'b0;

  end

end

Case Statements (Sequential Statements)

CASE statements in VHDL have the same semantics as CASE statements in Verilog and are mapped to the same.

Example

VHDL

Verilog

process

begin

  wait on sel_output;

  V2V_d_en <= '0';

  case sel_output is

    when(B"000")=> x <= B"00000001" after 2 ns;

    when(B"001")=> x <= B"00000010";

    when(B"010")=> x <= B"00000011";

    when(B"011")=> x <= B"00000100";

    when(B"100")=> x <= B"00000101";

    when(B"101")=> x <= B"00000110";

    when(B"110")=> x <= B"00000111";

    when(B"111")=> x <= B"00001000";

    when others => x <= "ZZZZZZZZ";

  end case;

end process;

always @(sel_output)

begin

 

  V2V_d_en <= 'b0;

case (sel_output)

  'b000 : x <= #2 'b00000001;

  'b001 : x <= 'b00000010;

  'b010 : x <= 'b00000011;

  'b011 : x <= 'b00000100;

  'b100 : x <= 'b00000101;

  'b101 : x <= 'b00000110;

  'b110 : x <= 'b00000111;

  'b111 : x <= 'b00001000;

  default : x <= 'bzzzzzzzz;

endcase

end

Loop Statements (Sequential Statements)

VHDL defines LOOP statements, that are a collection of sequential statements. The execution is specified by the iteration scheme (e.g FOR, WHILE) used. Loop statements without iteration schemes are equivalent to Verilog FOREVER statements, iteration scheme FOR is translated to Verilog FOR loop and VHDL WHILE iteration scheme is translated to Verilog WHILE loop.

Example

VHDL

Verilog

process

begin

  wait until a'event;

  i1 <= 0;

  wait for 0 ns;

 

  while i1 < reg_dummy + 1 loop

  v2v_b(3 downto 0) <= a(3 downto 0);

  i1 <= i1 + 1;

  wait for 0 ns;

  end loop;

 

for cnt in 4 downto 1 loop

  v2v_b(i = "00000001") <= a(i);

end loop;

 

len <= '8'

wait for 0 ns;

 

loop

  v2v_b(i - "00000001") <= a;

end loop;

 

end process;

always @(a)

begin

  i1 <= 0;

  #0

 

while (i1 < reg_dummy + 1)

begin

  v2v_b[3:0] <= a[3:0];

  i1 <= i1 + 1;

  #0;

end

 

for (cnt = 4; cnt >= 1; cnt = cnt - 1)

  v2v_b[i - 'b00000001] <= a[i];

 

 

len <= 'b8

#0

 

forever

  v2v_b[i - 'b00000001] <= a;

 

 

end

NULL Statements (Sequential Statements)

A NULL statement performs no action and is equivalent to the Verilog ``;'' statement.

Example

VHDL

Verilog

null;

;

Assert Statements (Sequential Statements)

The Assert statement shows a pre-defined message when the assertion fails. The severity is made part of the message. Furthermore, in the Verilog translation the time when the assertion was activated is shown.

Example

VHDL

Verilog

variable status : boolean;

 

assert status = false

report "Some message"

severity note;

reg status

 

if (!(status==`false))

  begin

  $write("note: ");

  $display("Some message");

  $display("Time: ",$time);

end

Procedure Call Statements (Sequential Statements)

A VHDL Procedure call is translated into a Verilog task enable when the -Support Subprogram Calls switch has been selected.

Example

VHDL

Verilog

architecture cpu of cpu

use work.mypackage.all; --defines ProcCall

 

begin

  p0 : process(s)

  begin

    ProcCall(s,s_out);

  end process;

 

end;

module cpu;

always @(s)

begin : p0

  ProcCall(s,s_out);

end

 

//include file with called functions/tasks

`include "cpu_cpu.v"

 

endmodule

Concurrent Statements

VHDL concurrent statements occur in VHDL Architectures. These statements execute in concurrently, as there name suggests. VHDL2Verilog translates concurrent statements outlined in the following sections.

Block Statements (Concurrent Statement)

In VHDL it is possible to group statements together in a BLOCK. Declarations made in the Block have a local scope. In verilog there is no concepts of Blocks. VHDL2Verilog translates blocks by moving all its contents into the enclosing scope. Local declarations are renamed (the label of the block is prepended) and are also moved into the enclosing scope.

Example

VHDL

Verilog

architecture foo of aha is

begin

 

b0: block

  constant a : boolean = true;

begin

  s <= a and b and c;

end block;

 

b1: block

  constant a : boolean = false;

begin

  co <= (a and b) or (a and c) or (b and c);

end block

 

end foo;

module aha;

 

  parameter B0_a = `true;

  parameter B1_a = `false;

 

  // begin BLOCK B0

  assign s =  B0_a & b & c;

  // end BLOCK B0

 

  // begin BLOCK B1

  assign co = B1_a & b | B1_a & c | b & c;

  // end BLOCK B1

 

endmodule

Process Statements (Concurrent Statement)

VHDL and Verilog have constructs that allow blocks of sequential statements to execute concurrently. In VHDL, these statements are PROCESS statements. PROCESS statements in VHDL are mapped to Verilog ALWAYS statements. If the VHDL process will execute only once during the simulation run (possible if the process sequential body has an infinite WAIT as its last item), then the process is mapped to the Verilog INITIAL statement.

VHDL2Verilog follows specific rules for mapping signal edges (RISING EDGE, FALLING EDGE) to Verilog. These rules apply only to processes with the following characteristics:

Process should have

1.Sensitivity signals or wait statement, and

2.Single IF (optional ELSIF) statement, and

3.IF (optional ELSIF) expression equivalent to Verilog POSEDGE or NEGEDGE. The IEEE Std_logic_1 164 package functions RISING_EDGE and FALLING_EDGE are identified by VHDL2Verilog as POSEDGE and NEGEDGE respectively.

In this case, the edge controls are moved to the ALWAYS sensitivity list, and the IF (ELSIF) expressions are modified to be equivalent to the VHDL description. Process PROCESS_DFF in the example below illustrates this concept.

Example

VHDL

Verilog

architecture diffeq of diffeq is

begin

 

p0 : process

begin

  Xoutport <= 0;

  Youtport <= 0;

  Uoutport <= 0;

  wait;

end process p0;

 

p1 : process(Aport,DXport,Xinport,

             Yinport,Uinport)

  variable x_var, y_var, u_var : std_logic;

begin

  Xoutport <= x_var after 2 ns;

  Youtport <= transport y_var; //will occur

  Xoutport <= u_var after 5ns;

  -- above will cancel previous assignment

end process P1;

 

module diffeq;

 

 

initial

begin : p0

  Xoutport <= 0;

  Youtport <= 0;

  Uoutport <= 0;

end

 

 

always @(Aport or DXport or 

         Yinport or Uinport)

begin : p1

  reg x_var, y_var, u_var;

 

  Xoutport <= #2 x_var;

  Youtport <= y_var; //fully non-blocking

  Xoutport <= #5 u_var;

  //above will not cancel prev assignment

end

Concurrent Signal Assignments (Concurrent Statement)

Concurrent Signal Assignments are used to drive signals continuously throughout the simulation run. Verilog CONTINUOUS ASSIGNMENTS provide the same capability. All VHDL concurrent signal assignments are translated to Verilog continuous assignments.

Example

VHDL

Verilog

 

architecture VeriArch of aha is

  signal s : std_logic;

  signal co : std_logic;

begin

  s <= a and b and c after 2 ns;

  co <= (a and s) or (a and c);

end VeriArch;

 

*********** DAN FIX THIS *********************

module aha(a,b,c,s,co);

 

  wire V2V_s;

  wire V2V_co;

 

assign #2 V2V_s = a & b & c;

assign V2V_co = a & V2v_s | a & c | b &c;

 

assign a  = V2v_s;

assign co = V2V_co;

 

endmodule

Component Instantiations (Current Statement)

Both VHDL and Verilog are hierarchical languages and provide module instantiation capabilities. Additionally, values of generics can be changed during the process of module instantiation. Generic maps in VHDL component instantiations are translated to Verilog DEFPARAM statements.

Example

VHDL

Verilog

component inbuf

    generic (len : integer := 2)

    port(pad : in std_logic_vector(len downto 1);

         y : out std_logic_vector(len downto 1));

end component;

 

for all : inbuf use entity work.inbuf;

begin

 

  comp_1 :inbuf

  generic map(len=>2);

  port map (pad(1)=>a(1),

            y(1) => z(1),

            pad(2)=>a(2), 

            y(2)>=>z(2) );

 

comp_2: inbuf

  generic map(len->2)

  port map( pad=>a, y=>z);

 

comp_3: inbuf

  generic map(len=>2)

  port map(a,z);

 

end rtl;

 

************ DLN FIX THIS

module inbuf(pad,y);

parameter len = 2;

 

input [len:1] pad;

output [len:0] y;

 

assign y = pad;

endmodule

 

defparam comp_1.len = 2;

inbuf comp_1

        (

        .pad({a[2],a[1]}),

        .y({z[2],z[1]}) 

        );

 

inbuf comp_2

        (.pad(a), .y(z));

 

inbuf comp_3(a,z);

    

Generate Statements (Concurrent Statement)

VHDL GENERATE statements are useful when regular structures need to be modeled. In Verilog however, there is no comparable construct. VHDL2Verilog therefore elaborates the generate statement, and then translates the result into Verilog.

Example

VHDL

Verilog

Bit2: block

  constant ks :

     integer := BitW + BitW;

  constant kc : integer := BitW - 1;

  constant i : integer := 2;

  signal in1ANDin2 :std_ulogic_vector

                     (0 to BitW-2);

begin

NextRow:for j in 0 TO BitW-2 generate

  in1ANDin2(j) <= ARR_MUL1in1(i) and

                    ARR_MUL1in2(j);

 

  NextRow1: IF j < (BitW-2) generate

    xx : fullxxx port map

         (in1ANDin2(j),

          carry(kc-BitW+1+j),

          carry(kc+j));

  end generate NextRow1;

 

  NextRow2: IF j = (BitW-2) generate

  pxx : partialfullxxx port map

          (in1ANDin2(j),

           carry(kc-BitW+1+j),

           carry(kc+j));

  end generate NextRow2;

 

end generate;

end block Bit2;

// begin BLOCK Bit2

parameter Bit2_ks = BitW + BitW;

parameter Bit2_kc = BitW - 1;

parameter Bit2_i = 2;

 

wire [0:BitW - 2] Bit2_in1ANDin2;

 

assign Bit2_in1ANDin2[0] =

     ARR_MUL1in1[Bit2_i] & ARR_MUL1in2[0];

assign Bit2_in1ANDin2[1] =

     ARR_MUL1in1[Bit2_i] & ARR_MUL1in2[1];

assign Bit2_in1ANDin2[2] =

     ARR_MUL1in1[Bit2_i] & ARR_MUL1in2[2];

 

fullxxx xx_Bit2_NextRow1_0 (

                    Bit2_in1ANDin2[0],

                    carry[Bit2_kc - BitW+1+0],

                    carry[Bit2_kc + 0]);

 

fullxxx xx_Bit2_NextRow1_1 (

                    Bit2_in1ANDin2[1],

                    carry[Bit2_kc - BitW+1+1],

                    carry[Bit2_kc + 1]);

 

partialfullxxx pxx_Bit2_NextRow2_2 (

                    Bit2_in1ANDin2[2],

                    carry[Bit2_kc - BitW+1+2],

                    carry[Bit2_kc + 2]);

// end BLOCK Bit2