ghdl / ghdl-yosys-plugin

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

Exiting with Found error in internal cell ($pmux) #129

Closed pstrueb closed 4 years ago

pstrueb commented 4 years ago

Here is another issue regarding type conversion in an multiplexer:

My minimal example is:

use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity test is
    port(
        sel:            in std_logic;
        inp:            in unsigned(7 downto 0);
        outp:           out integer range 0 to 255
        );
end;

architecture a of test is

begin
    with sel select outp <= to_integer(inp) when '1', 0 when others;        
end;    

Running this with

yosys -m ghdl -p 'ghdl ./Design/dec_dp40_E_TIKI.vhd -e test'

gives:

-- Running command `ghdl ./Design/test_mux.vhd -e test' --

1. Executing GHDL.
Importing module test.
ERROR: Found error in internal cell \test.\5 ($pmux) at kernel/rtlil.cc:973:
  cell $pmux \5
    parameter \S_WIDTH 1
    parameter \WIDTH 8
    connect \Y $auto$ghdl.cc:696:import_module$2
    connect \S $auto$ghdl.cc:696:import_module$1
    connect \B { 23'00000000000000000000000 \inp }
    connect \A 8'00000000
  end

While running with ghdl --synth ./Design/test_mux.vhd -e test Gives no error. if i put the integer conversion output with statement and put it into an intermediate signal, the synthesis is working.

Edit: I could trace the issue a bit further. It seems to be a ghdl --synth issue. Synthesizing the example gives

  signal wrap_sel: std_logic;
  signal wrap_inp: std_logic_vector (7 downto 0);
  signal wrap_outp: std_logic_vector (7 downto 0);
  signal n1_o : std_logic_vector (30 downto 0);
  signal n3_o : std_logic;
  signal n5_o : std_logic_vector (7 downto 0);
begin
  wrap_sel <= sel;
  wrap_inp <= std_logic_vector(inp);
  outp <= to_integer (unsigned (wrap_outp));
  wrap_outp <= n5_o;
  -- ./test/test_mux.vhd:20:32
  n1_o <= "00000000000000000000000" & wrap_inp;  --  uext
  -- ./test/test_mux.vhd:20:48
  n3_o <= '1' when wrap_sel = '1' else '0';
  -- ./test/test_mux.vhd:20:8
  with n3_o select n5_o <=
    n1_o when '1',
    "00000000" when others;
end rtl;

So what we see here is the assignment of signal n1_o which is a 31 bit vector to n5_o which is 8 bit broad (as it should be).