Converting VHDL to Verilog

Most open source tools don’t accept VHDL as an input, which is a real shame/annoyance if VHDL is your thing. What are the options?

Simple VHDL Test Code

I’ve got a small bit of test code for this article to show what’s going on.

-------------------------------------------------------------------------------
--
-- Copyright (c) 2022 Iain Waugh. All rights reserved.
-- 
-- This code is a sample and does not come with any warranty or guarantee of correctness.
-- Redistribution and use in source and binary forms (with or without
-- modification) is permitted.
--
-------------------------------------------------------------------------------
-- Project Name  : Test Project
-- Author(s)     : Iain Waugh
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity adder is
  port(
    -- Clock and Reset signals
    clk : in std_logic;
    rst : in std_logic;

    i_data_a : in unsigned(7 downto 0);
    i_data_b : in unsigned(7 downto 0);

    o_data   : out unsigned(7 downto 0)
    );
end adder;

architecture adder_rtl of adder is

begin -- adder_rtl

  process (clk)
  begin
    if rising_edge(clk) then
      if (rst = '1') then
        o_data <= (others => '0');
      else
        o_data <= i_data_a + i_data_b;
      end if;
    end if;
  end process;

end adder_rtl;

Convert With GHDL

I’ve covered the installation process for GHDL here.

Converting your code is a 2-step process. First, you compile it, then you convert it.

ghdl -a adder.vhd
# Creates a file called 'work-obj93.cf'
ghdl synth --out=verilog adder > adder_ghdl.v

The result is redirected to ‘adder_ghdl.v’ and it looks like this:

module adder
  (input  clk,
   input  rst,
   input  [7:0] i_data_a,
   input  [7:0] i_data_b,
   output [7:0] o_data);
  wire [7:0] n4_o;
  wire [7:0] n6_o;
  reg [7:0] n9_q;
  assign o_data = n9_q;
  /* adder.vhd:41:28  */
  assign n4_o = i_data_a + i_data_b;
  /* adder.vhd:38:7  */
  assign n6_o = rst ? 8'b00000000 : n4_o;
  /* adder.vhd:37:5  */
  always @(posedge clk)
    n9_q <= n6_o;
endmodule

No offence to GHDL, but this is pretty hard to trace and read. The comments have been stripped out, the signal names are scrambled and it’s quite hard to see the intent of the original code. Even this web page’s built-in code formatter gets 2 lines wrong; it thinks the ‘assign‘ statements are comments.

Convert With VHD2VL

This code was originally written by Enzo Ligouri from Ocean Logic, then it was updated a few times by a few people and now it lives on GitHub. Get the source code for this tool, build it and install it.

cd ~/Work/vlsi/tools && git clone https://github.com/ldoolitt/vhd2vl
cd vhd2vl/src
make
sudo cp vhd2vl /usr/local/bin

Converting your code is a 1-step process. You just run the converter:

vhd2vl adder.vhd > adder_vhd2vl.v

The result is redirected to ‘adder_vhd2vl.v’ and it looks like this:

// File adder.vhd translated with vhd2vl v3.0 VHDL to Verilog RTL translator
// vhd2vl settings:
//  * Verilog Module Declaration Style: 2001

// vhd2vl is Free (libre) Software:
//   Copyright (C) 2001 Vincenzo Liguori - Ocean Logic Pty Ltd
//     http://www.ocean-logic.com
//   Modifications Copyright (C) 2006 Mark Gonzales - PMC Sierra Inc
//   Modifications (C) 2010 Shankar Giri
//   Modifications Copyright (C) 2002-2017 Larry Doolittle
//     http://doolittle.icarus.com/~larry/vhd2vl/
//   Modifications (C) 2017 Rodrigo A. Melo
//
//   vhd2vl comes with ABSOLUTELY NO WARRANTY.  Always check the resulting
//   Verilog for correctness, ideally with a formal verification tool.
//
//   You are welcome to redistribute vhd2vl under certain conditions.
//   See the license (GPLv2) file included with the source for details.

// The result of translation follows.  Its copyright status should be
// considered unchanged from the original VHDL.

//-----------------------------------------------------------------------------
//
// Copyright (c) 2022 Iain Waugh. All rights reserved.
// 
// This code is a sample and does not come with any warranty or guarantee of correctness.
// Redistribution and use in source and binary forms (with or without
// modification) is permitted.
//
//-----------------------------------------------------------------------------
// Project Name  : Test Project
// Author(s)     : Iain Waugh
//-----------------------------------------------------------------------------
// no timescale needed

module adder(
input wire clk,
input wire rst,
input wire [7:0] i_data_a,
input wire [7:0] i_data_b,
output reg [7:0] o_data
);

// Clock and Reset signals




  // adder_rtl
  always @(posedge clk) begin
    if((rst == 1'b1)) begin
      o_data <= {8{1'b0}};
    end
    else begin
      o_data <= i_data_a + i_data_b;
    end
  end


endmodule

The carriage-returns get a bit verbose, but you can clearly see that this is pretty much the same as the original file, with whatever minor changes are needed for conversion.

vhd2vl Limitations

The biggest limitation with vhd2vl is that it doesn’t support generic “if” statements. It should be possible to add this, but whoever does it will need to learn flex/bison to do it.