FlyingDutch Napisano Styczeń 10, 2018 Udostępnij Napisano Styczeń 10, 2018 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 Cytuj Link do komentarza Share on other sites More sharing options...
JTyburski Styczeń 10, 2018 Udostępnij Styczeń 10, 2018 Ja to mimo wszystko ze sceptycyzmem podchodzę do takich rozwiązań (automatycznie konwertuje, ale nie zawsze w zoptymalizowany sposób ^^) Cytuj Link do komentarza Share on other sites More sharing options...
FlyingDutch Styczeń 11, 2018 Autor tematu Udostępnij Styczeń 11, 2018 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 Cytuj Link do komentarza Share on other sites More sharing options...
JTyburski Styczeń 11, 2018 Udostępnij Styczeń 11, 2018 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ń ^^ Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
Pomocna odpowiedź
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!