ghdl-yosys-plugin
ghdl-yosys-plugin copied to clipboard
VHDL to Verilog conversion with yosys-ghdl-plugin -- how to perserve signal names
I have this VHDL design in a file spi_icebreaker.vhdl
:
-- A:
library ieee;
use ieee.std_logic_1164.all;
-- B:
entity spi_icebreaker is
port(
pcb_oscilator: in std_logic;
pcb_led: out std_logic;
pcb_button: in std_logic
);
end spi_icebreaker;
----------------------------------------------------------------------------------------------------
-- C:
architecture logic_001 of spi_icebreaker is
-- D:
signal sbclki: std_logic;
signal sbrwi: std_logic;
signal sbstbi: std_logic;
signal sbadri: std_logic_vector (7 downto 0);
signal sbdati: std_logic_vector (7 downto 0);
signal sbdato: std_logic_vector (7 downto 0);
signal sbacko: std_logic;
signal spiirq: std_logic;
signal spiwkup: std_logic;
signal mi: std_logic;
signal so: std_logic;
signal soe: std_logic;
signal si: std_logic;
signal mo: std_logic;
signal moe: std_logic;
signal scki: std_logic;
signal scko: std_logic;
signal sckoe: std_logic;
signal scsni: std_logic;
signal mcsno: std_logic_vector (3 downto 0);
signal mcsnoe: std_logic_vector (3 downto 0);
-- E:
component SB_SPI is
generic(
BUS_ADDR74: integer
);
port(
SBCLKI: in std_logic; -- System bus: System clock input
SBRWI: in std_logic; -- System bus: System read/write input
SBSTBI: in std_logic; -- System bus: Strobe signal
SBADRI0: in std_logic; -- System bus: control registers address
SBADRI1: in std_logic;
SBADRI2: in std_logic;
SBADRI3: in std_logic;
SBADRI4: in std_logic;
SBADRI5: in std_logic;
SBADRI6: in std_logic;
SBADRI7: in std_logic;
SBDATI0: in std_logic; -- System bus: System data input
SBDATI1: in std_logic;
SBDATI2: in std_logic;
SBDATI3: in std_logic;
SBDATI4: in std_logic;
SBDATI5: in std_logic;
SBDATI6: in std_logic;
SBDATI7: in std_logic;
SBDATO0: out std_logic; -- System bus: System data output
SBDATO1: out std_logic;
SBDATO2: out std_logic;
SBDATO3: out std_logic;
SBDATO4: out std_logic;
SBDATO5: out std_logic;
SBDATO6: out std_logic;
SBDATO7: out std_logic;
SBACKO: out std_logic; -- System bus: System acknowledgement
SPIIRQ: out std_logic; -- SPI: interrupt output
SPIWKUP: out std_logic; -- SPI: wake up from standby signal
MI: in std_logic; -- Master input --> from PAD
SO: out std_logic; -- Slave output --> to PAD
SOE: out std_logic; -- Slave output enable --> to PAD (active high)
SI: in std_logic; -- Slave input --> from PAD
MO: out std_logic; -- Master output --> to PAD
MOE: out std_logic; -- Master output enable --> to PAD (active high)
SCKI: in std_logic; -- Slave clock input --> from PAD
SCKO: out std_logic; -- Slave clock output --> to PAD
SCKOE: out std_logic; -- Slave clock output enable --> to PAD (active high)
SCSNI: in std_logic; -- Slave chip select input --> from PAD
MCSNO0: out std_logic; -- Master chip select output --> to PAD
MCSNO1: out std_logic;
MCSNO2: out std_logic;
MCSNO3: out std_logic;
MCSNOE0: out std_logic; -- Master chip select output enable --> to PAD (active high)
MCSNOE1: out std_logic;
MCSNOE2: out std_logic;
MCSNOE3: out std_logic
);
end component;
begin
-- F:
C1: SB_SPI
generic map(
BUS_ADDR74 => 2#00000#
)
port map(
SBCLKI => sbclki, -- System bus: clock input
SBRWI => sbrwi, -- System bus: read/write input
SBSTBI => sbstbi, -- System bus: strobe signal
SBADRI0 => sbadri(0), -- System bus: control registers address
SBADRI1 => sbadri(1),
SBADRI2 => sbadri(2),
SBADRI3 => sbadri(3),
SBADRI4 => sbadri(4),
SBADRI5 => sbadri(5),
SBADRI6 => sbadri(6),
SBADRI7 => sbadri(7),
SBDATI0 => sbdati(0), -- System bus: data input
SBDATI1 => sbdati(1),
SBDATI2 => sbdati(2),
SBDATI3 => sbdati(3),
SBDATI4 => sbdati(4),
SBDATI5 => sbdati(5),
SBDATI6 => sbdati(6),
SBDATI7 => sbdati(7),
SBDATO0 => sbdato(0), -- System bus: data output
SBDATO1 => sbdato(1),
SBDATO2 => sbdato(2),
SBDATO3 => sbdato(3),
SBDATO4 => sbdato(4),
SBDATO5 => sbdato(5),
SBDATO6 => sbdato(6),
SBDATO7 => sbdato(7),
SBACKO => sbacko, -- System bus: acknowledgement
SPIIRQ => spiirq, -- SPI interrupt output
SPIWKUP => spiwkup, -- SPI wake up from standby signal
MI => mi, -- Master input --> from PAD
SO => so, -- Slave output --> to PAD
SOE => soe, -- Slave output enable --> to PAD (active high)
SI => si, -- Slave input --> from PAD
MO => mo, -- Master output --> to PAD
MOE => moe, -- Master output enable --> to PAD (active high)
SCKI => scki, -- Slave clock input --> from PAD
SCKO => scko, -- Slave clock output --> to PAD
SCKOE => sckoe, -- Slave clock output enable --> to PAD (active high)
SCSNI => scsni, -- Slave chip select input --> from PAD
MCSNO0 => mcsno(0), -- Master chip select output --> to PAD
MCSNO1 => mcsno(1),
MCSNO2 => mcsno(2),
MCSNO3 => mcsno(3),
MCSNOE0 => mcsnoe(0), -- Master chip select output enable --> to PAD (active high)
MCSNOE1 => mcsnoe(1),
MCSNOE2 => mcsnoe(2),
MCSNOE3 => mcsnoe(3)
)
;
-- G:
sbclki <= pcb_oscilator;
-- H:
process_001: process (sbclki) begin
if pcb_button = '1' then
pcb_led <= '1';
elsif rising_edge(sbclki) then
pcb_led <= '0';
end if;
end process;
end architecture logic_001;
That I convert it to Verilog file spi_icebreaker.v
using this one-liner Linux command:
yosys -m ghdl -p "ghdl -fsynopsys spi_icebreaker.vhdl -e spi_icebreaker; write_verilog spi_icebreaker.v"
And get this output:
/----------------------------------------------------------------------------\
| |
| yosys -- Yosys Open SYnthesis Suite |
| |
| Copyright (C) 2012 - 2020 Claire Wolf <[email protected]> |
| |
| Permission to use, copy, modify, and/or distribute this software for any |
| purpose with or without fee is hereby granted, provided that the above |
| copyright notice and this permission notice appear in all copies. |
| |
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| |
\----------------------------------------------------------------------------/
Yosys 0.9+4052 (git sha1 UNKNOWN, clang 11.0.1-2 -fPIC -Os)
-- Running command `ghdl -fsynopsys spi_icebreaker.vhdl -e spi_icebreaker; write_verilog spi_icebreaker.v' --
1. Executing GHDL.
spi_icebreaker.vhdl:143:9:warning: instance "c1" of component "sb_spi" is not bound [-Wbinding]
C1: SB_SPI
^
spi_icebreaker.vhdl:58:14:warning: (in default configuration of spi_icebreaker(logic_001))
spi_icebreaker.vhdl:62:16:warning: signal "sbrwi" is never assigned and has no default value
signal sbrwi: std_logic;
^
spi_icebreaker.vhdl:63:16:warning: signal "sbstbi" is never assigned and has no default value
signal sbstbi: std_logic;
^
spi_icebreaker.vhdl:64:16:warning: signal "sbadri" is never assigned and has no default value
signal sbadri: std_logic_vector (7 downto 0);
^
spi_icebreaker.vhdl:65:16:warning: signal "sbdati" is never assigned and has no default value
signal sbdati: std_logic_vector (7 downto 0);
^
spi_icebreaker.vhdl:70:16:warning: signal "mi" is never assigned and has no default value
signal mi: std_logic;
^
spi_icebreaker.vhdl:73:16:warning: signal "si" is never assigned and has no default value
signal si: std_logic;
^
spi_icebreaker.vhdl:76:16:warning: signal "scki" is never assigned and has no default value
signal scki: std_logic;
^
spi_icebreaker.vhdl:79:16:warning: signal "scsni" is never assigned and has no default value
signal scsni: std_logic;
^
Importing module spi_icebreaker.
Importing module SB_SPI.
2. Executing Verilog backend.
Dumping module `\spi_icebreaker'.
End of script. Logfile hash: f35896d774, CPU: user 0.01s system 0.00s, MEM: 14.39 MB peak
Yosys 0.9+4052 (git sha1 UNKNOWN, clang 11.0.1-2 -fPIC -Os)
Time spent: 88% 1x ghdl (0 sec), 11% 2x write_verilog (0 sec)
Note: There are some warnings.
Verilog file looks like this:
/* Generated by Yosys 0.9+4052 (git sha1 UNKNOWN, clang 11.0.1-2 -fPIC -Os) */
module spi_icebreaker(pcb_oscilator, pcb_button, pcb_led);
wire _00_;
wire _01_;
wire _02_;
wire _03_;
wire _04_;
wire _05_;
wire _06_;
wire _07_;
wire _08_;
wire _09_;
wire _10_;
wire _11_;
wire _12_;
wire _13_;
wire _14_;
wire _15_;
wire _16_;
wire _17_;
reg _18_;
wire _19_;
wire _20_;
wire _21_;
wire _22_;
wire _23_;
wire _24_;
wire _25_;
input pcb_button;
output pcb_led;
input pcb_oscilator;
always @(posedge pcb_oscilator, posedge pcb_button)
if (pcb_button) _18_ <= 1'h1;
else _18_ <= 1'h0;
SB_SPI #(
.BUS_ADDR74(32'd0)
) c1 (
.MCSNO0(_09_),
.MCSNO1(_10_),
.MCSNO2(_12_),
.MCSNO3(_13_),
.MCSNOE0(_14_),
.MCSNOE1(_15_),
.MCSNOE2(_16_),
.MCSNOE3(_17_),
.MI(1'hx),
.MO(_05_),
.MOE(_06_),
.SBACKO(_25_),
.SBADRI0(1'hx),
.SBADRI1(1'hx),
.SBADRI2(1'hx),
.SBADRI3(1'hx),
.SBADRI4(1'hx),
.SBADRI5(1'hx),
.SBADRI6(1'hx),
.SBADRI7(1'hx),
.SBCLKI(pcb_oscilator),
.SBDATI0(1'hx),
.SBDATI1(1'hx),
.SBDATI2(1'hx),
.SBDATI3(1'hx),
.SBDATI4(1'hx),
.SBDATI5(1'hx),
.SBDATI6(1'hx),
.SBDATI7(1'hx),
.SBDATO0(_00_),
.SBDATO1(_11_),
.SBDATO2(_19_),
.SBDATO3(_20_),
.SBDATO4(_21_),
.SBDATO5(_22_),
.SBDATO6(_23_),
.SBDATO7(_24_),
.SBRWI(1'hx),
.SBSTBI(1'hx),
.SCKI(1'hx),
.SCKO(_07_),
.SCKOE(_08_),
.SCSNI(1'hx),
.SI(1'hx),
.SO(_03_),
.SOE(_04_),
.SPIIRQ(_01_),
.SPIWKUP(_02_)
);
assign pcb_led = _18_;
endmodule
It bothers me that signal names are completely different in the Verilog file compared to the VHDL file. For example this VHDL signal mo
is renamed to _05_
... Why? How can I keep the original names? Does it have anything to do with the warnings that I get when translating VHDL to Verilog?
I think the situation has improved recently: most of the signal names are now kept. For mo
, it is not. The reason is that this signal is not connected. So yes, it is related to the warning.
@71GA, if your target is just converting VHDL to Verilog, you might want to try ghdl synth --out=verilog
(http://ghdl.github.io/ghdl/using/Synthesis.html#cmdoption-ghdl-out).
In any of the two conversions, is it possible to convert vhdl generics -> verilog parameters? i.e. preserve the generics and don't fill them with their defaults?
@bluesceada the output of ghdl synth
or the one of the plugin is a post-elaboration result. Therefore, all the parameters are resolved by the time the ouput is generated. See http://ghdl.github.io/ghdl/internals/index.html.