Skocz do zawartości

Verilog 2 VHDL Translator


FlyingDutch

Pomocna odpowiedź

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):

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:

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:

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):

-- 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.

UART.zip

Link do komentarza
Share on other sites

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 🤣

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

Link do komentarza
Share on other sites

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ń ^^

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.