ghdl / ghdl-yosys-plugin

VHDL synthesis (based on ghdl)
GNU General Public License v3.0
295 stars 32 forks source link

Error building ghdl plugin for yosys #168

Open minghungumich opened 2 years ago

minghungumich commented 2 years ago

First I cannot build ghdl locally, so I use the latest release from fpga-tool-chain. And I am able to run binary ghdl, but when I try to build ghdl plugin for yosys. It displays the following error.

[kevinchen@instance-5 ghdl-yosys-plugin]$ make
yosys-config --exec --cxx -c --cxxflags -o ghdl.o src/ghdl.cc -fPIC -DYOSYS_ENABLE_GHDL -I/home/kevinchen/fpga-toolchain/include -O -DGHDL_VER_HASH="\"c9b05e4\""
src/ghdl.cc:19:10: fatal error: kernel/yosys.h: No such file or directory
   19 | #include "kernel/yosys.h"
      |          ^~~~~~~~~~~~~~~~
compilation terminated.
make: *** [ghdl.o] Error 1

Then I try to add include directory for yosys in Makefile manually. It still companies about xxx was not declared in this scope like this

[kevinchen@instance-5 ghdl-yosys-plugin]$ make
yosys-config --exec --cxx -c --cxxflags -o ghdl.o src/ghdl.cc -fPIC -DYOSYS_ENABLE_GHDL  -I/home/kevinchen/fpga-toolchain/share/yosys/include -I/home/kevinchen/fpga-toolchain/include -O -DGHDL_VER_HASH="\"c9b05e4\""
src/ghdl.cc: In function ‘void add_attributes_from_instance(Yosys::RTLIL::AttrObject&, GhdlSynth::Instance)’:
src/ghdl.cc:385:35: error: ‘get_instance_first_attribute’ was not declared in this scope
  385 |         add_attributes_chain(obj, get_instance_first_attribute (inst));
      |                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ghdl.cc: In function ‘bool has_attribute_gclk(GhdlSynth::Net)’:
src/ghdl.cc:633:26: error: ‘get_instance_first_attribute’ was not declared in this scope
  633 |         Attribute attr = get_instance_first_attribute (inst);
      |                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ghdl.cc: In function ‘void import_module(Yosys::RTLIL::Design*, GhdlSynth::Module)’:
src/ghdl.cc:680:53: error: ‘get_input_port_first_attribute’ was not declared in this scope
  680 |                         add_attributes_chain(*wire, get_input_port_first_attribute(m, idx));
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ghdl.cc:690:53: error: ‘get_output_port_first_attribute’ was not declared in this scope
  690 |                         add_attributes_chain(*wire, get_output_port_first_attribute(m, idx));
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ghdl.cc:713:45: error: ‘get_input_port_first_attribute’ was not declared in this scope
  713 |                 add_attributes_chain(*wire, get_input_port_first_attribute(m, idx));
      |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ghdl.cc:730:45: error: ‘get_output_port_first_attribute’ was not declared in this scope
  730 |                 add_attributes_chain(*wire, get_output_port_first_attribute(m, idx));
      |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ghdl.cc:1216:45: error: ‘get_output_port_first_attribute’ was not declared in this scope
 1216 |                 add_attributes_chain(*wire, get_output_port_first_attribute(m, idx));
      |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/ghdl.cc: At global scope:
src/ghdl.cc:372:13: warning: ‘void add_attributes_chain(Yosys::RTLIL::AttrObject&, GhdlSynth::Attribute)’ defined but not used [-Wunused-function]
  372 | static void add_attributes_chain(RTLIL::AttrObject &obj, Attribute attr)
      |             ^~~~~~~~~~~~~~~~~~~~
make: *** [ghdl.o] Error 1
minghungumich commented 2 years ago

@mithro @msaligane Now I think it is a feasible solution for me to synthesize vhdl file. But I stuck at building plugin.

msaligane commented 2 years ago

Can you check with @antonblanchard how he synthesized Microwatt (VHDL)

umarcor commented 2 years ago

@minghungumich how do you want to build the ghdl-yosys-plugin? As a module (https://github.com/ghdl/ghdl-yosys-plugin#build-as-a-module-shared-library) or built into yosys (https://github.com/ghdl/ghdl-yosys-plugin#build-as-part-of-yosys-not-recommended)?

Note that on Windows, the second (non recommended) approach needs to be used, because Yosys cannot load plugins dynamically on that platform.

umarcor commented 2 years ago

@msaligane I believe that @antonblanchard uses containers with GHDL, Yosys and the plugin already available. See https://github.com/antonblanchard/microwatt/blob/master/Makefile#L37-L49. Containers from ghdl/docker are used for simulation, and containers from hdl/containers are used for synthesis. In those containers, the plugin is built as a module. See also https://github.com/ghdl/ghdl-yosys-plugin/blob/master/ci.sh#L37-L82.

umarcor commented 2 years ago

Now I think it is a feasible solution for me to synthesize vhdl file.

@minghungumich, note that the regular GHDL executable allows to "synthesize" VHDL >= 2008 to either VHDL 1993 or Verilog 2005. That's done through ghdl synth, without the plugin or Yosys. See http://ghdl.github.io/ghdl/using/Synthesis.html#cmdoption-ghdl-out. I believe that strategy is used by microwatt, edalize, and others.

minghungumich commented 2 years ago

@minghungumich how do you want to build the ghdl-yosys-plugin? As a module (https://github.com/ghdl/ghdl-yosys-plugin#build-as-a-module-shared-library) or built into yosys (https://github.com/ghdl/ghdl-yosys-plugin#build-as-part-of-yosys-not-recommended)?

Note that on Windows, the second (non recommended) approach needs to be used, because Yosys cannot load plugins dynamically on that platform.

@umarcor I want to build it as a module and use it as a plugin loaded into yosys. Then I can either use this to convert into verilog or read_vhdl directly.

minghungumich commented 2 years ago

Now I think it is a feasible solution for me to synthesize vhdl file.

@minghungumich, note that the regular GHDL executable allows to "synthesize" VHDL >= 2008 to either VHDL 1993 or Verilog 2005. That's done through ghdl synth, without the plugin or Yosys. See http://ghdl.github.io/ghdl/using/Synthesis.html#cmdoption-ghdl-out. I believe that strategy is used by microwatt, edalize, and others.

@umarcor I try to use this way, but the release package I found from fpga-tool-chain looks like this latest version did not support --out=verilog options.

umarcor commented 2 years ago

Then, we should probably start with using a version of GHDL which is not coming from fpga-toolchain. As you found out, it's archived and outdated. Can you get any other version of GHDL? Either from your system package manager, using containers or building it yourself? What's you host OS?

minghungumich commented 2 years ago

My host OS is CentOS7, and I also see lots of problem built in the same platform from GitHub issue. I think container should be the most promising way for me.

minghungumich commented 2 years ago

@umarcor Now I am able to convert some vhdl file to verilog file. I will try to synthesize and see if it has any problem.

minghungumich commented 2 years ago

@umarcor I found although the input output port will be kept. But the parameter definition will be gone.

For example, in one of the vhd file, I have parameter RATIO for signal counter.

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;

entity slib_clock_div is
    generic (
        RATIO       : integer := 4      -- Clock divider ratio
    );
    port (
        CLK         : in std_logic;     -- Clock
        RST         : in std_logic;     -- Reset
        CE          : in std_logic;     -- Clock enable input
        Q           : out std_logic     -- New clock enable output
    );
end slib_clock_div;

architecture rtl of slib_clock_div is
    -- Signals
    signal iQ       : std_logic;                  -- Internal Q
    signal iCounter : integer range 0 to RATIO-1; -- Counter

begin
    -- Main process
    CD_PROC: process (RST, CLK)
    begin
        if (RST = '1') then
            iCounter <= 0;
            iQ       <= '0';
        elsif (CLK'event and CLK='1') then
            iQ <= '0';
            if (CE = '1') then
                if (iCounter = (RATIO-1)) then
                    iQ <= '1';
                    iCounter <= 0;
                else
                    iCounter <= iCounter + 1;
                end if;
            end if;
        end if;
    end process;

    -- Output signals
    Q <= iQ;

end rtl;

But in the output verilog file, it just directly converts to the fixed number of bits.

/* Generated by Yosys 0.17+33 (git sha1 335b4888c, clang 11.0.1-2 -fPIC -Os) */

module slib_clock_div(CLK, RST, CE, Q);
  wire _0_;
  wire [31:0] _1_;
  wire _2_;
  wire [1:0] _3_;
  wire _4_;
  reg _5_;
  wire [1:0] _6_;
  reg [1:0] _7_;
  input CE;
  wire CE;
  input CLK;
  wire CLK;
  output Q;
  wire Q;
  input RST;
  wire RST;
  wire [1:0] icounter;
  wire iq;
  assign _2_ = _0_ ? 1'h1 : 1'h0;
  assign _3_ = _0_ ? 2'h0 : _1_[1:0];
  assign _4_ = CE ? _2_ : 1'h0;
  always @(posedge CLK, posedge RST)
    if (RST) _5_ <= 1'h0;
    else _5_ <= _4_;
  assign _6_ = CE ? _3_ : icounter;
  always @(posedge CLK, posedge RST)
    if (RST) _7_ <= 2'h0;
    else _7_ <= _6_;
  assign _0_ = { 30'h00000000, icounter } == 32'd3;
  assign _1_ = { 30'h00000000, icounter } + 32'd1;
  assign iq = _5_;
  assign icounter = _7_;
  assign Q = iq;
endmodule
tgingold commented 2 years ago

Well, that's expected. You are doing a synthesis and the output is a netlist.