I'm using target aggregates in VHDL 2008 and I found out, that Quartus (specifically "Quartus Prime Version 19.4.0 Build 64 12/04/2019 SC Pro Edition") fails to assign drivers to some of the target signals when they are std_logic_vector with the width of 1.
Here is an example code I tested it on:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity EXAMPLE is generic( WIDTH : natural := 8 ); port( IN_A : in std_logic_vector(WIDTH-1 downto 0); IN_B : in std_logic_vector(WIDTH-1 downto 0); OUT_A : out std_logic_vector(WIDTH-1 downto 0); OUT_B : out std_logic; OUT_C : out std_logic_vector(WIDTH-1 downto 0); OUT_D : out std_logic_vector(1-1 downto 0); OUT_E : out std_logic_vector(WIDTH/3-1 downto 0); OUT_F : out std_logic_vector(1-1 downto 0); OUT_G : out std_logic_vector(2-1 downto 0); OUT_H : out std_logic_vector(0-1 downto 0); OUT_I : out std_logic_vector((WIDTH+1)-(WIDTH/3+1+2+0)-1 downto 0) ); end entity; architecture FULL of EXAMPLE is signal result : unsigned(WIDTH+1-1 downto 0); begin my_process : process (all) begin result <= ("0" & unsigned(IN_A)) + ("0" & unsigned(IN_B)); (OUT_A, OUT_B) <= std_logic_vector(result); (OUT_C, OUT_D) <= std_logic_vector(result); (OUT_E, OUT_F, OUT_G, OUT_H, OUT_I) <= std_logic_vector(result); end process; end architecture;
Synthesizing this code leads to a warning:
Warning (13024): Output pins are stuck at VCC or GND Warning (13410): Pin "OUT_D" is stuck at GND File: example.vhd Line: 17 Warning (13410): Pin "OUT_F" is stuck at GND File: example.vhd Line: 20
meaning Quartus was unable to assign value to those parts of the aggregate, where the signal had a 1-bit width. You can see, that the bug does not occur, when the signal is a simple std_logic, but I have multiple cases where the width of the signal is determined by generics and it is possible for it to result as 1.
Are you saying it's done on purpose and you don't plan on fixing it?
Because it would be a much lesser complication even if it was the other way around and the expression didn't work for std_logic instead. Than I can imagine turning all std_logic signals that are used in aggregates into 1-bit vectors; but this way it cannot be done so easily, since a vector with generic width can sometimes by 1 bit wide and sometimes wider. So the only way to solve this would be creating a std_logic version of each std_logic_vector and switch between them in separated IF branches based on the vector width. And since there are N signals in the aggregate, it would mean up to 2**N different branches of code to solve this. That really makes the whole point of target aggregates being used for code simplification useless.
Well, this workaround fixes the non-working short aggregate assignment by not using the short aggregate assignment. I know how to do that, too. The point was to be able to assign multiple signals from one signal without having to explicitly write the width of each and every one of them and thus shorten the code and make it more clear and readable. I know I can make it work the same way without the aggregates. But it bugs me that it doesn't work in this specific case, even though it should.
I'm glad to see that someone was actually assigned to look into this, but this is not the result I was looking for, sadly. What I'm looking for is at least a hint suggesting that someone will try to fix the bug in the synthesis tool, even if it is in a version a year from now.
I also confirm this annoying bug. It's shame quartus is lacking such basic support of VHDL 2008 features. I took me a few days to find out why my design was not working. Today I also realized that conditional assignment in process VHDL 2008 feature is not working. Quartus simply synthesize logic away.
rx_pkt_len_proc : process(clk_avmm) is begin if rising_edge(clk_avmm) then ready <= '1'; ready <= '0' when ready = '1'; end if; end process;