I'm having trouble with something that seems as simple as it gets, alas even after reading about and trying many possible solutions I'm not getting success.
I have a simple entity:
entity periph_btn is
Port ( sel_i : in STD_LOGIC;
n_rd_i : in STD_LOGIC;
data_o : out STD_LOGIC_VECTOR (7 downto 0);
btns_i : in STD_LOGIC_VECTOR (3 downto 0)
);
end periph_btn;
The intended behavior is just as simple:
architecture Behavioral of periph_btn is
begin
data_o <= btns_i when n_rd_i = '0' and sel_i = '1' else (others => 'Z');
end Behavioral;
Now obviously as btns_i is only 4 bits and data_o is 8, something's missing. Question, how to define that the 4 MSB of data_o should be '0'?
Several of the solutions online worked perfectly as expected in a simple behavioral simulation, but when I run a post-implementation simulation (Vivado) those bits always show up as state 'U'
An example of what I've tried that gives this result, using the & operator:
architecture Behavioral of periph_btn is
signal data_s : STD_LOGIC_VECTOR (7 downto 0);
signal zeroes_s : STD_LOGIC_VECTOR (3 downto 0);
begin
zeroes_s <= (others => '0');
data_s <= zeroes_s & btns_i;
data_o <= data_s when n_rd_i = '0' and sel_i = '1' else (others => 'Z');
end Behavioral;
Both behavioral and post-implementation simulation of the system this is a component of are posted below. The behavioral simulation looks exactly as expected, but on the post-implementation one the last line that is of concern is getting 0xZA instead of 0x0A. As a result, data1_i of the component that receives this signal (Mux, data1_i) sees 0xUA.
In the end the top level signal's behavior (AD) is as desired, so maybe it's normal for the internal signals to do some mess and that can be ignored, it looks like implementation also simplifies some signals when they're not being looked at...
Note that the design could be simplified and the problem would disappear - but I'd rather learn something while I'm there.