Ta strona używa ciasteczek (plików cookies), dzięki którym może działać lepiej. Dowiedz się więcejRozumiem i akceptuję
Prowadniki kablowe dla robotów zaprojektowane do ruchów w trzech osiach!

Verilog 2 VHDL Translator

Autor Wiadomość
FlyingDutch 




Posty: 119
Pomógł: 1 raz
Otrzymał 6 piw(a)
Skąd: Bydgoszcz
Programuję w:
C++,Python
Wysłany: 10-01-2018, 15:51   Verilog 2 VHDL Translator

Cześć,

ponieważ lepiej znam język VHDL niż Verilog (i VHDL'a używam w swoich projektach) staram się aby cały kod projektu był napisany w jednym języku - VHDL. Czasami jednak, szukając rozwiązania jakiegoś problemu znajduję ciekawe rozwiązanie w Języku Verilog (tak. np było w przypadku implementacji UART w FPGA). Przykładowa realizacja UART wykonana w języku Verilog była prostsza(i bardziej dla mnie zrozumiała niż kod rozwiązań w VHDL). Teraz jednak chciałbym przetłumaczyć tą sprawdzoną praktycznie implementację na kod VHDL (i włączyć ją do innego projektu).

Przeszukiwałem fora dyskusyjne dot. układów programowalnych i istnieje kilka takich automatycznych translatorów Verilog na VHDL. Kilka komercyjnych narzędzi jest niedostępnych ze względu na licencję, a chyba niezłego darmowego:

http://www.edautils.com/vhdl2verilog.html

nie mogę wypróbować, bo nikt nie odpowiada na mojego maila z prośbą o hasło do ściągnięcia softu z ich strony.

Po kilku "podejściach" stwierdziłem, że chyba najlepiej z darmowych translatorów sprawdza się Icarus Verilog (oczywiście możecie się ze mną nie zgodzić i podać lepiej działające rozwiązania). Podaję linki do "Icarus Verilog":

http://iverilog.icarus.com/

http://bleyer.org/icarus/

http://iverilog.icarus.com/page/plug-ins

A tutaj linki do dokumentacji:

http://iverilog.wikia.com/wiki/User_Guide

https://www.swarthmore.edu/NatSci/mzucker1/e15_f2014/iverilog.html

http://manpages.ubuntu.com/manpages/wily/man1/iverilog.1.html

Po instalacji kompilatora z pakietu instalacyjnego Windows (64-bit):

Dodałem ścieżkę z plikami binarnymi programu do zmiennej PATH: z Windowsa (u mnie jest to D:\IcarusVerilog\bin). Podstawowa wersja wywołania kompilatora to (command line Windows):

Kod programu: Zaznacz cały

iverilog -o simple  simple.v


gdzie: iverilog - to program kompilatora
-o simple - plik wyjściowy (object z kompilatora C)
simple.v - plik wejściowy projektu w j. Verilog (może być ich wiele)

Dzięki dokumentacji po kilku próbach udało mi się wypracować z jakimi parametrami należy wywołać kompilator aby uzyskać źródła przetłumaczone na VHDL:

Kod programu: Zaznacz cały

iverilog -o UART -t vhdl txstr.v uart_tx.v baudgen_tx.v


Kluczowy jest tu parametr: -t vhd (target: VHDL)

Teraz w pliku UART będziemy mieć kod VHDL z opisami przetłumaczony z Verilog.
Można też podać dodatkowe parametry, aby mieć informację z procesu translacji Verilog2VHDL:

Kod programu: Zaznacz cały

D:\IcarusVerilog\_Projects\UART>iverilog -o UART -t vhdl -pdebug=1 -pdepth=3 txstr.v uart_tx.v baudgen_tx.v
[DEBUG] Initial visit to scope type txstr at depth 0
[DEBUG] Initial visit to scope type uart_tx at depth 1
[DEBUG] Initial visit to scope type baudgen_tx at depth 2
[DEBUG] Declaring signals in scope type txstr
[DEBUG] Declaring signals in scope type uart_tx
[DEBUG] Declaring signals in scope type baudgen_tx
[DEBUG] Declaring logic in scope type txstr
[DEBUG] Declaring logic in scope type uart_tx
[DEBUG] Declaring logic in scope type baudgen_tx
[DEBUG] Translating process in scope type baudgen_tx (baudgen_tx.v:45)
[DEBUG] Translating process in scope type baudgen_tx (baudgen_tx.v:47)
[DEBUG] Translating process in scope type uart_tx (uart_tx.v:62)
[DEBUG] Translating process in scope type uart_tx (uart_tx.v:75)
[DEBUG] Translating process in scope type uart_tx (uart_tx.v:91)
[DEBUG] Translating process in scope type uart_tx (uart_tx.v:103)
[DEBUG] Translating process in scope type uart_tx (uart_tx.v:121)
[DEBUG] Translating process in scope type uart_tx (uart_tx.v:128)
[DEBUG] Translating process in scope type txstr (txstr.v:26)
[DEBUG] Translating process in scope type txstr (txstr.v:46)
[DEBUG] Translating process in scope type txstr (txstr.v:62)
[DEBUG] Generated wait-for-0 for txstr.v:66
[DEBUG] Translating process in scope type txstr (txstr.v:81)
[DEBUG] Translating process in scope type txstr (txstr.v:89)
[DEBUG] Deallocated 860 VHDL syntax objects
[DEBUG] 83552 total bytes used for VHDL syntax objects

D:\IcarusVerilog\_Projects\UART>


Parametr: -pdepth=3 mówi ile poziomów zagłębień modułów Verilog ma być tłumaczonych.

A tutaj plik z wynikiej translacji Verilog 2 VHDL (generuje też komentarze):

Kod programu: Zaznacz cały

-- This VHDL was converted from Verilog using the
-- Icarus Verilog VHDL Code Generator 10.1 (stable) (v10_1_1)

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

-- Generated from Verilog module txstr (txstr.v:16)
--   BAUDRATE = 1250
--   INI = 0
--   NEXTCAR = 2
--   STOP = 3
--   TXCAR = 1
entity txstr is
  port (
    clk : in std_logic;
    rstn : in std_logic;
    tx : out std_logic
  );
end entity;

-- Generated from Verilog module txstr (txstr.v:16)
--   BAUDRATE = 1250
--   INI = 0
--   NEXTCAR = 2
--   STOP = 3
--   TXCAR = 1
architecture from_verilog of txstr is
  signal cena : std_logic;  -- Declared at txstr.v:43
  signal char_count : unsigned(2 downto 0);  -- Declared at txstr.v:42
  signal data : unsigned(7 downto 0);  -- Declared at txstr.v:27
  signal next_state : unsigned(1 downto 0);  -- Declared at txstr.v:78
  signal ready : std_logic;  -- Declared at txstr.v:25
  signal start : std_logic := '0';  -- Declared at txstr.v:26
  signal state : unsigned(1 downto 0);  -- Declared at txstr.v:77
 
  component uart_tx is
    port (
      clk : in std_logic;
      data : in unsigned(7 downto 0);
      ready : out std_logic;
      rstn : in std_logic;
      start : in std_logic;
      tx : out std_logic
    );
  end component;
  signal tx_Readable : std_logic;  -- Needed to connect outputs
begin
  tx <= tx_Readable;
 
  -- Generated from instantiation at txstr.v:33
  TX0: uart_tx
    port map (
      clk => clk,
      data => data,
      ready => ready,
      rstn => rstn,
      start => start,
      tx => tx_Readable
    );
  -- Removed one empty process
 
 
  -- Generated from always process in txstr (txstr.v:46)
  process (char_count) is
  begin
    case char_count is
      when "000" =>
        data <= Resize(unsigned("H"), 8);
      when "001" =>
        data <= Resize(unsigned("e"), 8);
      when "010" =>
        data <= Resize(unsigned("l"), 8);
      when "011" =>
        data <= Resize(unsigned("l"), 8);
      when "100" =>
        data <= Resize(unsigned("o"), 8);
      when "101" =>
        data <= Resize(unsigned("!"), 8);
      when "110" =>
        data <= Resize(unsigned("."), 8);
      when "111" =>
        data <= Resize(unsigned("."), 8);
      when others =>
        data <= Resize(unsigned("."), 8);
    end case;
  end process;
 
  -- Generated from always process in txstr (txstr.v:62)
  process is
  begin
    wait until rising_edge(clk);
    if (not rstn) = '1' then
      char_count <= "000";
    else
      if cena = '1' then
        wait for 0 ns;  -- Read target of blocking assignment (txstr.v:66)
        char_count <= char_count + "001";
      end if;
    end if;
  end process;
 
  -- Generated from always process in txstr (txstr.v:81)
  process (clk) is
  begin
    if rising_edge(clk) then
      if (not rstn) = '1' then
        state <= "00";
      else
        state <= next_state;
      end if;
    end if;
  end process;
 
  -- Generated from always process in txstr (txstr.v:89)
  process (state, ready, char_count) is
  begin
    next_state <= state;
    start <= '0';
    cena <= '0';
    case state is
      when "00" =>
        start <= '1';
        next_state <= "01";
      when "01" =>
        if ready = '1' then
          next_state <= "10";
        end if;
      when "10" =>
        cena <= '1';
        if Resize(char_count, 32) = X"00000007" then
          next_state <= "11";
        else
          next_state <= "00";
        end if;
      when others =>
        null;
    end case;
  end process;
end architecture;

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

-- Generated from Verilog module uart_tx (uart_tx.v:22)
--   BAUDRATE = 1250
--   IDLE = 0
--   START = 1
--   TRANS = 2
entity uart_tx is
  port (
    clk : in std_logic;
    data : in unsigned(7 downto 0);
    ready : out std_logic;
    rstn : in std_logic;
    start : in std_logic;
    tx : out std_logic
  );
end entity;

-- Generated from Verilog module uart_tx (uart_tx.v:22)
--   BAUDRATE = 1250
--   IDLE = 0
--   START = 1
--   TRANS = 2
architecture from_verilog of uart_tx is
  signal ready_Reg : std_logic;
  signal tx_Reg : std_logic;
  signal baud_en : std_logic;  -- Declared at uart_tx.v:45
  signal bitc : unsigned(3 downto 0);  -- Declared at uart_tx.v:38
  signal clk_baud : std_logic;  -- Declared at uart_tx.v:35
  signal data_r : unsigned(7 downto 0);  -- Declared at uart_tx.v:41
  signal load : std_logic;  -- Declared at uart_tx.v:44
  signal next_state : unsigned(1 downto 0);  -- Declared at uart_tx.v:54
  signal shifter : unsigned(9 downto 0);  -- Declared at uart_tx.v:69
  signal state : unsigned(1 downto 0);  -- Declared at uart_tx.v:53
 
  component baudgen_tx is
    port (
      clk : in std_logic;
      clk_ena : in std_logic;
      clk_out : out std_logic;
      rstn : in std_logic
    );
  end component;
begin
  ready <= ready_Reg;
  tx <= tx_Reg;
 
  -- Generated from instantiation at uart_tx.v:108
  BAUD0: baudgen_tx
    port map (
      clk => clk,
      clk_ena => baud_en,
      clk_out => clk_baud,
      rstn => rstn
    );
 
  -- Generated from always process in uart_tx (uart_tx.v:62)
  process (clk) is
  begin
    if rising_edge(clk) then
      if ((unsigned'("0000000000000000000000000000000") & start) = X"00000001") and (Resize(state, 32) = X"00000000") then
        data_r <= data;
      end if;
    end if;
  end process;
 
  -- Generated from always process in uart_tx (uart_tx.v:75)
  process (clk) is
  begin
    if rising_edge(clk) then
      if (unsigned'("0000000000000000000000000000000") & rstn) = X"00000000" then
        shifter <= "1111111111";
      else
        if (unsigned'("0000000000000000000000000000000") & load) = X"00000001" then
          shifter <= data_r & "01";
        else
          if ((unsigned'("0000000000000000000000000000000") & load) = X"00000000") and ((unsigned'("0000000000000000000000000000000") & clk_baud) = X"00000001") then
            shifter <= '1' & shifter(1 + 8 downto 1);
          end if;
        end if;
      end if;
    end if;
  end process;
 
  -- Generated from always process in uart_tx (uart_tx.v:91)
  process (clk) is
  begin
    if rising_edge(clk) then
      if (not rstn) = '1' then
        bitc <= X"0";
      else
        if (unsigned'("0000000000000000000000000000000") & load) = X"00000001" then
          bitc <= X"0";
        else
          if ((unsigned'("0000000000000000000000000000000") & load) = X"00000000") and ((unsigned'("0000000000000000000000000000000") & clk_baud) = X"00000001") then
            bitc <= bitc + X"1";
          end if;
        end if;
      end if;
    end if;
  end process;
 
  -- Generated from always process in uart_tx (uart_tx.v:103)
  process (clk) is
  begin
    if rising_edge(clk) then
      tx_Reg <= shifter(0);
    end if;
  end process;
 
  -- Generated from always process in uart_tx (uart_tx.v:121)
  process (clk) is
  begin
    if rising_edge(clk) then
      if (not rstn) = '1' then
        state <= "00";
      else
        state <= next_state;
      end if;
    end if;
  end process;
 
  -- Generated from always process in uart_tx (uart_tx.v:128)
  process (state, start, bitc) is
  begin
    next_state <= state;
    load <= '0';
    baud_en <= '0';
    case state is
      when "00" =>
        ready_Reg <= '1';
        if (unsigned'("0000000000000000000000000000000") & start) = X"00000001" then
          next_state <= "01";
        end if;
      when "01" =>
        load <= '1';
        baud_en <= '1';
        ready_Reg <= '0';
        next_state <= "10";
      when "10" =>
        baud_en <= '1';
        ready_Reg <= '0';
        if Resize(bitc, 32) = X"0000000b" then
          next_state <= "00";
        end if;
      when others =>
        ready_Reg <= '0';
    end case;
  end process;
end architecture;

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

-- Generated from Verilog module baudgen_tx (baudgen_tx.v:30)
--   BAUDRATE = 1250
--   N = 17
entity baudgen_tx is
  port (
    clk : in std_logic;
    clk_ena : in std_logic;
    clk_out : out std_logic;
    rstn : in std_logic
  );
end entity;

-- Generated from Verilog module baudgen_tx (baudgen_tx.v:30)
--   BAUDRATE = 1250
--   N = 17
architecture from_verilog of baudgen_tx is
  signal tmp_s0 : unsigned(31 downto 0);  -- Temporary created at baudgen_tx.v:62
  signal tmp_s3 : unsigned(14 downto 0);  -- Temporary created at baudgen_tx.v:62
  signal tmp_s4 : unsigned(31 downto 0);  -- Temporary created at baudgen_tx.v:62
  signal tmp_s6 : std_logic;  -- Temporary created at baudgen_tx.v:62
  signal tmp_s8 : std_logic;  -- Temporary created at baudgen_tx.v:62
  signal divcounter : unsigned(16 downto 0) := "00000000000000000";  -- Declared at baudgen_tx.v:45
begin
  tmp_s0 <= tmp_s3 & divcounter;
  tmp_s6 <= '1' when tmp_s0 = tmp_s4 else '0';
  clk_out <= clk_ena when tmp_s6 = '1' else tmp_s8;
  tmp_s3 <= "000000000000000";
  tmp_s4 <= X"00000000";
  tmp_s8 <= '0';
  -- Removed one empty process
 
 
  -- Generated from always process in baudgen_tx (baudgen_tx.v:47)
  process (clk) is
  begin
    if rising_edge(clk) then
      if (not rstn) = '1' then
        divcounter <= "00000000000000000";
      else
        if clk_ena = '1' then
          if Resize(divcounter, 32) = X"000004e1" then
            divcounter <= "00000000000000000";
          else
            divcounter <= divcounter + "00000000000000001";
          end if;
        else
          divcounter <= "00000010011100001";
        end if;
      end if;
    end if;
  end process;
end architecture;



Plik został wygenerowany z plików projektu Verilog (uart_tx), w załączniku zamieszczam te pliki projektu Verilog spakowane zip.

Polecany artykuł » Serwisy o robotyce i majsterkowaniu, które warto znać - #2




UART.zip
Plik projektu Verilog -UART Tx.
Pobierz Plik ściągnięto 3 raz(y) 6.35 KB


Anioły to też demony - lepiej ich nie wkurzaj
Ostatnio zmieniony przez FlyingDutch 10-01-2018, 16:20, w całości zmieniany 8 razy  
Postaw piwo autorowi tego posta
 
 
JTyburski 



Posty: 33
Pomógł: 2 razy
Otrzymał 4 piw(a)
Skąd: Warszawa
Programuję w:
VHDL, Verilog
Wysłany: 10-01-2018, 23:27   

Ja to mimo wszystko ze sceptycyzmem podchodzę do takich rozwiązań (automatycznie konwertuje, ale nie zawsze w zoptymalizowany sposób ^^)

Postaw piwo autorowi tego posta
 
 
FlyingDutch 




Posty: 119
Pomógł: 1 raz
Otrzymał 6 piw(a)
Skąd: Bydgoszcz
Programuję w:
C++,Python
Wysłany: 11-01-2018, 08:45   

JTyburski napisał/a:
Ja to mimo wszystko ze sceptycyzmem podchodzę do takich rozwiązań (automatycznie konwertuje, ale nie zawsze w zoptymalizowany sposób ^^)


Cześć Jakub,

ja też, ale jeśli tłumaczę większą ilość kodu z Verilog'a na VHDL to zaoszczędzam sporo czasu (mam wygenerowany "szkielet" projektu, który trzeba w niektórych punktach ręcznie zmodyfikować. To mniej więcej jak z syntezą HLS, też musisz dopisać część kodu ręcznie).

BTW: już teraz mogę powiedzieć, że ten translator nie generuje optymalnego kodu i to w kilku aspektach. Przykład: zupełnie pomija konstrukcje parameter w modułach Veriloga, chociaż mógłby to z powodzeniem przetłumaczyć na generic w entity VHDL.
Niektóre konwersje przez niego wykonane są komiczne :lol:

Tutaj link pomagający konwertować podstawowe konstrukcje Verilog <-> VHDL:

ftp://ece.buap.mx/pub/Secretaria_Academica/SDC/Active_HDL_4.2_Student_Version_Installer/Doc/avhdl/Avh00213.htm

Pozdrawiam


Anioły to też demony - lepiej ich nie wkurzaj
Ostatnio zmieniony przez FlyingDutch 11-01-2018, 14:40, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
JTyburski 



Posty: 33
Pomógł: 2 razy
Otrzymał 4 piw(a)
Skąd: Warszawa
Programuję w:
VHDL, Verilog
Wysłany: 11-01-2018, 21:06   

Oooo i widzę, że się ze mną zgadzasz co do optymalności - i cieszę się, że nie odebrałeś tego jako krytyki (ufffff....). Domyślam się, że chodzi o to aby jakiś szkielet uzyskać z większych porcji kodów (a tym samym oszczędzić jak to ująłeś czas - to tak jak właśnie z byle językiem wyższego poziomu typu C i asemblerem, co się stało przełomem i doprowadziło do wykwitu różnorakich rozwiązań mikrokontrolerowych i mikroprocesorowych ze względu na szybkość - tylko tam to prosta sprawa bo zamieniasz wszystko na pojedyncze instrukcje, a tu musisz jedną konstrukcję w drugą zamienić i to jest kłopotliwe - a żeby się już połapać to już w ogóle, szczególnie przy rozbudowanych rzeczach, i żeby jeszcze przy tym zachować wymagają funkcjonalność w całości - to jest prawdziwy wyczyn już). Oczywiście to też nie jest krytyka, tylko wymiana spostrzeżeń ^^

Popularny artykuł » Kurs Arduino II - #2 - diody RGB (tradycyjne oraz WS2812)


Postaw piwo autorowi tego posta
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Wersja do druku

Skocz do:  

Nie rozwiązałeś swojego problemu? Zobacz podobne tematy: Programowanie układó... Realizacja pamięci p... [FPGA] Sterowanie se... Co, jak, dlaczego??J...
lub przeszukaj forum po wybranych tagach: translator, verilog, vhdl


Powered by phpBB modified by Przemo © 2003 phpBB Group
Popularne kursy: Arduinopodstawy elektroniki