Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16881 Discussions

Bug report: synthesis optimizes out the signal if data type is declared in generic package

Ivan00
Beginner
2,109 Views

When the data type is declared in the generic package, the synthesis tool removes the signal completely when array slice is used on the right side of the assignment. I have condensed it to the following minimal example. The output signal o_bug in this example does not have any driver:

 

package parallel_pixel_type_pkg is new work.chr3_pkg_generic
    generic map(PARALLEL_INPUT_CHANNELS => 1);

library ieee;
use ieee.std_logic_1164.all;
use work.parallel_pixel_type_pkg.all;

entity bug is
port(
    i      : in std_logic_vector(17 downto 0);
    o_bug  : out std_logic_vector(16 downto 0);
    o_ok   : out std_logic_vector(17 downto 0)
);
end entity;

architecture rtl of bug is
    signal sp : test_type_t;
begin
    sp.pixel_data(0) <= i;
    o_bug <= sp.pixel_data(0)(16 downto 0);   -- BUG: o_bug is not connected to i
    o_ok <= sp.pixel_data(0);                 -- OK 
end rtl;

 

Generic package looks like this:

 

-- 
library ieee;
use ieee.std_logic_1164.all;

package chr3_pkg_generic is
    generic(PARALLEL_INPUT_CHANNELS : integer);

    type spectrum_arr_t is array (integer range <>) of std_logic_vector(17 downto 0);
    
    type test_type_t is record
        pixel_data            : spectrum_arr_t(PARALLEL_INPUT_CHANNELS - 1 downto 0);
    end record;

end package chr3_pkg_generic;
--

 

 

bug.png

I am using Quartus Prime Pro 19.3 and 21.3 on Windows 10.  I am also attaching the project archive with the example.

0 Kudos
15 Replies
YEan
Employee
2,083 Views

Hi,

 

The bus length of o_bug was different with the input i. So, the o_bug was not connected. You may change the bus length of o_bug to (17 downto 0).

 

The entity will be:

--

entity bug is

generic(

G_MODULE_DISABLED : boolean := false;

G_ID : std_logic_vector(7 downto 0) := X"17"

);

port(

i : in std_logic_vector(17 downto 0);

o_bug : out std_logic_vector(17 downto 0);

o_ok : out std_logic_vector(17 downto 0)

);

end entity;

 

architecture rtl of bug is

signal sp : test_type_t;

begin

sp.pixel_data(0) <= i;

o_bug <= sp.pixel_data(0);

o_ok <= sp.pixel_data(0);

end rtl;

--

Thank you.

 

Regards,

Ean

0 Kudos
Ivan00
Beginner
2,075 Views

Hi Ean, 

i have chosen different output bus size in order to demonstrate the bug. The bug manifests itself when subscript is used on the right side.

 

When I resize the bus, the o_bug[16 downto 0] must be connected to i[16 downto 0], only bit 17 should be removed. Instead the whole connection is removed.

 

This happens only if the type test_type_t is defined in a generic package. 

 

Best regards,

Ivan

0 Kudos
YEan
Employee
2,056 Views

Hi Ivan,

 

If the bus length of input and output were different the Quartus will show error messages. You may consider to change the architecture in your design to fulfill your requirement.

 

Thanks,

Ean

0 Kudos
Ivan00
Beginner
2,051 Views

Hi Ean,

 

I want to connect 16 lower bits of the 17 bit signal to the external port, i.e.

 

signal a : std_logic_vector(16 downto 0);

signal b: std_logic_vector(15 downto 0);

 

b <= a(15 downto 0);

 

I have provided an example where it does not work.  The example is not from my working project, I have stripped it down in order to easily demonstrate the issue.

 

Can you see the problem here? 

b(15 downto 0) must be connected to a(15 downto 0), but it is removed.

 

Best regards,

Ivan 

 

0 Kudos
YEan
Employee
2,035 Views

Hi Ivan,

 

Yes, this option works fine when there are only one statement in the architecture. If there are two concurrent statements in the architecture as shown in the previous example, the most significant signal will be connected and the least significant signal will not be connected.

 

You may refer to this https://stackoverflow.com/questions/12144019/how-to-write-to-two-output-ports-from-inside-architecture-in-vhdl on how to connect one input to multiple outputs.

 

Thanks,

Ean

0 Kudos
Ivan00
Beginner
2,030 Views

Hi Ean,

 

the link to the stack overflow page does not apply here, it is completely different issue. 

I have simplified my example further, so that two ports do not mislead anybody. Now there is only one signal at the output, and it is still not connected.  I hope you can see the issue this time.

library ieee;
use ieee.std_logic_1164.all;
use work.parallel_pixel_type_pkg.all;

entity bug is
    port(
        i     : in  std_logic_vector(17 downto 0);
        o_bug : out std_logic_vector(16 downto 0)
	  );
end entity;

architecture rtl of bug is
    signal sp      : test_type_t;
begin
 sp.pixel_data(0) <= i;
 o_bug <= sp.pixel_data(0)(16 downto 0);
end rtl;

 

Ivan00_0-1644994867583.png

 

Best regards,

Ivan

 

0 Kudos
YEan
Employee
2,013 Views

Hi Ivan,

 

Noted. I have tried another way. Adding a 17 bits signal, sp2, to connect the input i and output o_bug.

 

--

architecture rtl of bug is
signal sp : test_type_t;
signal sp2 : std_logic_vector(16 downto 0);

begin

sp.pixel_data(0) <= i;
sp2 <= i(16 downto 0);
o_ok <= sp.pixel_data(0);
o_bug <=sp2;

end rtl;

--

 

Thanks,

Ean

0 Kudos
Ivan00
Beginner
2,007 Views

Hi Ean, 

 

yes, that would work. If you dont use test_type_t  in the o_bug signal, then o_bug is generated properly. 

The wrong behaviour shows only when a data type from the generic package is used. This is the subject of this thread:

"Bug report: synthesis optimizes out the signal if data type is declared in generic package"

 

Can i assume that you have reproduced the bug and there will be a fix in a future version of Quartus ?

 

Best regards,

Ivan

0 Kudos
YEan
Employee
1,992 Views

Hi Ivan,

 

The solution I provided is to connect the o_bug to i that you request for. Because I don't have the complete design so I can't said that I reproduced the bug. It was coding issues so it will not be fix in future version of Quartus. As I mentioned before, if the bus length(size) of input and output were different the Quartus will show error messages. You may consider to change the architecture in your design. 

 

Thanks,

Ean

0 Kudos
Ivan00
Beginner
1,986 Views

Dear Ean,

 

you have not provided a solution to the bug, you have provided a workaround.  By avoiding the use of generic package you have avoided the bug.

In the case I have presented, the Intel Quartus synthesis generates wrong design.  It does not produce any error messages. And I also do not want to consider changing my architecture, because the code I wrote is valid VHDL and I expect Quartus to produce correct results from it. It also simulates fine in Modelsim.

I also do not need a workaround.

I just wanted to report a bug in the synthesis tool and to get it fixed.

 

Let's try again. Below I have provided an example, where the synthesis tool wrongly removes the whole connection. No errors are generated in Quartus.
I can also simulate this file in Modelsim and the connection is there. 

 

Can you explain the behavior of the synthesis tool?   Why is the whole connection to o_bug removed in this case?

library ieee;
use ieee.std_logic_1164.all;
use work.parallel_pixel_type_pkg.all;

entity bug is
    port(
        i     : in  std_logic_vector(17 downto 0);
        o_bug : out std_logic_vector(16 downto 0)
	  );
end entity;

architecture rtl of bug is
    signal sp      : test_type_t;
begin
 sp.pixel_data(0) <= i;
 o_bug <= sp.pixel_data(0)(16 downto 0);
end rtl;

If you need any more information, let me know.

 

Best regards,

Ivan

0 Kudos
YEan
Employee
1,963 Views

Hi Ivan,

 

May I know how you view the connection in ModelSim? So, I'm able to understand your design more.

 

Thanks,

Ean

0 Kudos
Ivan00
Beginner
1,958 Views

Hi Ean,

 

I am feeding some data into the i port of the design and monitoring the o_bug port. As expected, the o_bug port is equal to the i port.

 

Here is the testbench:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity bug_tb is
end bug_tb;
architecture test of bug_tb is
    signal i:      std_logic_vector(17 downto 0);
    signal o_bug:  std_logic_vector(16 downto 0); 
begin
    stimuli : process
    begin
        for j in 0 to 10 loop
	    i <= std_logic_vector(to_unsigned(j, 18));
            wait for 1 ns;
        end loop;
    wait;
    end process;

    uut : entity work.bug port map(i => i, o_bug => o_bug);

end;

 Here is the result of the simulation.

Ivan00_0-1645524647114.png

As you can see, it works in simulation.

 

Best regards,

Ivan

 

P.S.  It has been almost two weeks that i am trying to prove you that such simple construct as A<=B does not work in this case. I have provided an VHDL example, the proof in the RTL view, now we are down to simulating the basic VHDL A<=B construct. This is really a very basic VHDL. You have multiple times sent me completely false and misleading information, which leads me to believe that you do not have experience with that language. Is there anybody in support with VHDL knowledge who might have a  look at it? Because realizing that the problem here is not due to "coding issues"(what does it even mean anyway?) should not take more then 10 min.

 

0 Kudos
YEan
Employee
1,923 Views

Noted, I will file this to the internal engineer and get back to you as soon as possible.

0 Kudos
Ivan00
Beginner
1,858 Views

Hi Ean, 

 

is there an update on the issue?

I would really like this VHDL-2008 feature to be supported in the future.

 

Best regards,

Ivan 

0 Kudos
YEan
Employee
1,852 Views

Hi Ivan,


I'm pending reply from them too. I will ask for update asap. But, this issue probably will be resolved in future version.


Thanks,

Ean


0 Kudos
Reply