I am trying to design an ALU in VHDL with a 4 bit and a 3 bit unsigned inputs. But my attempts at resizing the input are failing, and thus the addition operation is giving 'X' as output.
This is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity alu_bv is
Port ( a : in unsigned (3 downto 0);
b : in unsigned (2 downto 0);
ch : in STD_LOGIC_VECTOR (2 downto 0);
y : out unsigned (3 downto 0));
end alu_bv;
architecture Behavioral of alu_bv is
signal c : unsigned (3 downto 0);
begin
process(a,b,ch)
begin
c <= unsigned('0' & b);
case ch is
when "000" => y <= a + c;
when "001" => y <= a - c;
when "010" => y <= a + 1;
when "011" => y <= a - 1;
when "100" => y <= a and c;
when "101" => y <= a or c;
when "110" => y <= not a;
when "111" => y <= a xor c;
when others => NULL;
end case;
end process;
end Behavioral;
I have tried without typecasting when assigning to c c <= ('0' & b);
And I have tried the resize function c <= resize(b, a'length);
This was the output waveform when I ran behavioral simulation:
Hexadecimal radix:
Binary radix:
Could you suggest a solution to this problem?
Edit: Someone asked to add the test bench I have used:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity alu_tb is
-- Port ( );
end alu_tb;
architecture Behavioral of alu_tb is
component alu_bv is
Port ( a : in unsigned (3 downto 0);
b : in unsigned (2 downto 0);
ch : in STD_LOGIC_VECTOR (2 downto 0);
y : out unsigned (3 downto 0));
end component;
signal a1: unsigned (3 downto 0):="1100";
signal b1: unsigned (2 downto 0):="001";
signal ch: STD_LOGIC_VECTOR (2 downto 0):="000";
signal y1: unsigned(3 downto 0);
begin
uut:alu_bv port map(a=>a1,b=>b1,ch=>ch,y=>y1);
stim_proc: process
begin
wait for 125 ns;
ch <= "001";
wait for 125 ns;
ch <= "010";
wait for 125 ns;
ch <= "011";
wait for 125 ns;
ch <= "100";
wait for 125 ns;
ch <= "101";
wait for 125 ns;
ch <= "110";
wait for 125 ns;
ch <= "111";
wait;
end process;
end Behavioral;
Edit - Solution:
@RuudHelderman's suggestion (Adding c
to rhe senstivity list) or even replacing b
with c
in the sensitivity works, giving the correct output
process(a,c,ch)
Updated simulation waveform :
I have a follow-up question:
Since I am only assigning values to a
and b
once in the testbench and not updating them again, couldn't I remove them from the sensitivity list and keep only ch
if I assign c
before beginning process
This is what I mean
architecture Behavioral of alu_bv is
signal c : unsigned (3 downto 0);
begin
c <= ('0' & b);
process(ch)
begin
...
I tried this and it still gives me X
as output for a + c
X
only appears at the start, subsequent events are fine. That is because c
is updated too late to be picked up by the very first execution of y <= a + c
, as explained here.
Try adding c
to the sensitivity list, it will trigger the event that is necessary to update y
with the latest value of c
.