I was implementing a multiplexer, but and gate returning "x" for no reason, pls help. As you can see in screenshot, result just became "x" from "1". i did a testbench for and gate, it works fine on its own. It should have been a 3 bit 4:1 multiplexer. this is the problem
This is source, i am using ghdl.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY mux41 IS
PORT (
i1 : IN std_logic_vector(2 DOWNTO 0);
i2 : IN std_logic_vector(2 DOWNTO 0);
i3 : IN std_logic_vector(2 DOWNTO 0);
i4 : IN std_logic_vector(2 DOWNTO 0);
sel : IN std_logic_vector(1 DOWNTO 0);
y : OUT std_logic_vector(2 DOWNTO 0)
);
END mux41;
ARCHITECTURE rtl OF mux41 IS
COMPONENT andgate
PORT (
input1 : IN std_logic;
input2 : IN std_logic;
input3 : IN std_logic;
and_output : OUT std_logic
);
END COMPONENT;
COMPONENT orgate
PORT (
input1 : IN std_logic;
input2 : IN std_logic;
input3 : IN std_logic;
input4 : IN std_logic;
or_output : OUT std_logic
);
END COMPONENT;
signal not_sel : std_logic_vector(1 DOWNTO 0);
signal and_result : std_logic_vector(3 DOWNTO 0);
signal or_result : std_logic_vector(2 DOWNTO 0);
BEGIN
not_sel <= not sel;
and_gate_assignment : for i in 0 to 2 generate
and_output1: andgate port map(input1=>i1(i), input2=>not_sel(1), input3=>not_sel(0), and_output=>and_result(0));
and_output2: andgate port map(input1=>i2(i), input2=>not_sel(1), input3=>sel(0), and_output=>and_result(1));
and_output3: andgate port map(input1=>i3(i), input2=>sel(1), input3=>not_sel(0), and_output=>and_result(2));
and_output4: andgate port map(input1=>i4(i), input2=>sel(1), input3=>sel(0), and_output=>and_result(3));
or_output: orgate port map(input1=>and_result(0), input2=>and_result(1), input3=>and_result(2), input4=>and_result(3), or_output=>or_result(i));
end generate and_gate_assignment;
y <= or_result;
END rtl;
Here is the and gate;
library ieee;
use ieee.std_logic_1164.all;
entity andgate is
port (
input1 : in std_logic;
input2 : in std_logic;
input3 : in std_logic;
and_output : out std_logic
);
end andgate;
architecture rtl of andgate is
signal and1 : std_logic;
signal and2 : std_logic;
begin
and1 <= input1 and input2;
and2 <= and1 and input3;
and_output <= and2;
end rtl;
there is not much to this really, could this be a timing issue?
Adding orgate's entity and architecture
and a testbench
allows you readers to replicate your problem. Adding more signals may help to understand the problem:
'X's come from driver conflict. Here there are multiple drivers connected to and_result(3 downto 0) across the generated blocks. When all the drivers are '0' the signal is resolved to '0'. When there is a conflict there's an 'X'.
The solution is to move the and_result declaration to the generate statement block declarative region (with a following begin separating declarations from statements):
And that gives you
the intended result.
The generate statement represents zero or more block statements in elaboration. Here each of the three block statement contains a 4 to 1 multiplexer for a std_logic element of a slice.
An individual multiplexer has signal nets connecting the output of each of four andgate instantiations to an orgate instantiation. By relying on a common declaration for
and_result
you've shorted the andgate outputs together across all three blocks.Moving the
and_result
declaration into the generate statement block declarative region results in it being replicated for each generated block statement. Because a block statement is a declarative region those three declarations ofand_result
aren't visible outside each generated block due to scope and visibility rules which match them being local to each block in a hierarchical block diagram - the threeand_result
elements are no longer connected to all three blocks. This eliminates multiple drivers.