quartus how convert four input to two inputs in block? - vhdl

how can i convert entity of bloch which takes 4 inputs to 2 inputs?
http://dl.dropbox.com/u/2879760/sample.PNG
A you see here i use three the same mux :( how to take in etykieta2 only two inputs?
code:
library ieee;
use ieee.std_logic_1164.all;
library work; --domyslnie zawieta moj pakiet
use work.mux_package.all;
entity glowny is
generic(
n : integer := 4;
k : integer := 2
);
port(
a, b, c, d,e,f,g,h : in std_logic_vector(n-1 downto 0);
s : in std_logic_vector(1 downto 0);
t : in std_logic_vector (1 downto 0);
y, x, z : out std_logic_vector(n-1 downto 0)
);
end glowny;
architecture multiplekser of glowny is
signal xx,yy,zz : std_logic_vector(n-1 downto 0);
for etykieta: mux use entity work.mux(arch_mux5);
for etykieta1: mux use entity work.mux(arch_mux6);
for etykieta2: mux use entity work.mux(arch_mux3);
begin
etykieta:
mux generic map (n=>n) port map (a=> a, b=>b, c=>c, d=>d,s=>s, y=>xx);
etykieta1:
mux generic map (n=>n) port map (a=> e, b=>f, c=>g, d=>h,s=>s,y=>yy);
etykieta2:
mux generic map (n=>n) port map (a=> yy , b=>yy, c=> xx, d=>xx, s=>t ,y=>zz);
end multiplekser;
packages
library ieee;
use ieee.std_logic_1164.all;
entity mux is
generic(
n : integer := 4
);
port(
a, b, c, d : in std_logic_vector(n-1 downto 0);
s : in std_logic_vector(1 downto 0);
y : out std_logic_vector(n-1 downto 0)
);
end mux;
-- przypisanie podstawowe - concurrent signal assigment
architecture arch_mux1 of mux is
begin
y(0) <= (a(0) and not(s(1)) and not(s(0)))
or (b(0) and not(s(1)) and s(0))
or (c(0) and s(1) and not(s(0)))
or (d(0) and s(1) and s(0));
y(1) <= (a(1) and not(s(1)) and not(s(0)))
or (b(1) and not(s(1)) and s(0))
or (c(1) and s(1) and not(s(0)))
or (d(1) and s(1) and s(0));
y(2) <= (a(2) and not(s(1)) and not(s(0)))
or (b(2) and not(s(1)) and s(0))
or (c(2) and s(1) and not(s(0)))
or (d(2) and s(1) and s(0));
y(3) <= (a(3) and not(s(1)) and not(s(0)))
or (b(3) and not(s(1)) and s(0))
or (c(3) and s(1) and not(s(0)))
or (d(3) and s(1) and s(0));
end arch_mux1;
-- przypisanie warunkowe - conditional signal assigment
architecture arch_mux2 of mux is
begin
with s select
y <= a when "00",
b when "01",
c when "10",
d when others;
end arch_mux2;
-- przypisanie selektywne - selected signal assigment
architecture arch_mux3 of mux is
begin
y <= a when (s = "00") else
b when (s = "01") else
c when (s = "10") else
d;
end arch_mux3;
architecture arch_mux4 of mux is
begin
pr_if: process(a,b,c,d,s) --lista czulosci
begin
case s is
when "00" => y <= a; -- czytamy y :=
when "01" => y <= b;
when "10" => y <= c;
--when "11" => y <= d;
y <= (others => '0');
when others => y <= d;
end case;
end process;
end arch_mux4;
architecture arch_mux5 of mux is
begin
pr_if: process(a,b,c,d,s) --lista czulosci
begin
if s ="00" then
y <= a;
elsif s="01" then
y <=b;
elsif s="10" then
y <=c;
else
y <=d;
end if;
end process;
end arch_mux5;
architecture arch_mux6 of mux is
begin
pr_if: process(a,b,c,d,s) --lista czulosci
begin
y<=(others=>'0');
if s ="00" then
y <= a;
end if;
if s ="01" then
y <= b;
end if;
if s ="10" then
y <= c;
end if;
-- if s ="11" then
-- y <= d;
-- end if;
end process;
end arch_mux6;
architecture arch_mux7 of mux is
begin
pr_if: process(a,b,c,d,s) --lista czulosci
begin
--w procesie jak najbardziej jest to prawidlowe, tylko warningi sa (LACHE - pamieci)
if s = "00" then
y <= a;
else
y <=(others => '0');
end if;
if s = "01" then
y <= b;
else
y <=(others => '0');
end if;
if s = "10" then
y <= c;
else
y <=(others => '0');
end if;
if s = "11" then -- zadziala tylko ten if bo jest sekwencyjnie ywkonywane i albo da 'd' albo 0000
y <= d;
else
y <=(others => '0');
end if;
end process;
end arch_mux7;
-- configuration conf_mux of mux is
--for arch_mux6
--end for;
--end conf_mux;

how can i convert entity of bloch
which takes 4 inputs to 2 inputs?
Do you mean make your input a to h and output x,y,z 2 bits wide rather than 4?
Just change the relevant generic, surely!

Related

why my component doesn't work for inputs that given in vhdl

I am new to VHDL and I have an assignment about it. I have to make a register that can save the value of Y based on the value of the last 2 bits of X. But before that, there is a process to determine Y value to be used, based on a bit of "field", and this process is in the "initial" component. The "initial" component can work as expected but the "Regis" component, which has to save the value of Y, didn't work at all. And I don't know what's the problem, why my "Regis" component doesn't work as I expect. Would you help me to figure out the problem?
this is my top level module vhdl :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity part1 is
Port ( X : in INTEGER;
Y : in INTEGER;
field : in STD_LOGIC;
Z : out INTEGER);
end part1;
architecture Behavioral of part1 is
component initial
Port ( X : in INTEGER;
Y : in INTEGER;
FIELD : in STD_LOGIC;
Y1 : out UNSIGNED(7 DOWNTO 0));
end component;
component regis
Port ( y : in INTEGER;
x : in UNSIGNED(7 DOWNTO 0);
yout : out INTEGER);
end component;
signal yi, xr : unsigned(7 downto 0);
signal yr, yo : integer;
begin
beginone : initial port map (X => X, Y => Y, FIELD => field, Y1 => yi);
xr <= to_unsigned (X, xr'length);
yr <= to_integer(unsigned(yi));
regY : regis port map (y => yr, x => xr, yout => yo);
Z <= yo;
end Behavioral;
"initial" component listing :
signal xb, yb : unsigned(7 downto 0);
begin
xb <= to_unsigned(X, xb'length);
yb <= to_unsigned(Y, yb'length);
initial : process(FIELD, xb, by)
variable ys : unsigned(7 downto 0);
begin
if (FIELD = '1') then
ys := yb;
else ys := xb xor yb;
end if;
Y1 <= ys;
end process;
end Behavioral;
"regis" component listing :
begin
process(x(1), x(0))
begin
if (x(1) = '0' and x(0) = '0') then yout <= 0;
elsif (x(1) = '0' and x(0) = '1') then yout <= y;
elsif (x(1) = '1' and x(0) = '0') then yout <= 2*y;
elsif (x(1) = '1' and x(0) = '1') then yout <= 3*y;
else yout <= y;
end if;
end process;
end Behavioral;
and this is the testbench of the top level module :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity part1_tb is
-- Port ( );
end part1_tb;
architecture Behavioral of part1_tb is
component part1
Port ( X : in INTEGER;
Y : in INTEGER;
field : in STD_LOGIC;
Z : out INTEGER);
end component;
signal x, y : integer;
signal field : std_logic;
signal z : integer;
begin
uut : part1 port map (x => X, y => Y, field => field, z => Z);
stim_proc : process
begin
wait for 100 ns;
x <= 1;
wait for 100 ns;
y <= 2;
wait for 100 ns;
field <= '1';
wait;
end process;
end Behavioral;
if the program runs correctly, it will produce an output value of z = 2 according to the input being tested. but when the testbench simulated results z = 0.
Thanks all.

VHDL Getting a simulation fatal error in the loading design in modelsim

(Yes I know there's an easier way, yes my professor is asking for the long way.)
The following is the code for my 1 bit adder/subtractor.
library ieee;
use ieee.std_logic_1164.all;
entity FA1Bit is
port(x,y,Cin: in std_logic;
op: in std_logic;
S, Cout: out std_logic);
end FA1Bit;
architecture FA1Bit_arch of FA1Bit is
begin
behavior : PROCESS(op,x,y,Cin)
begin
if op = '0' then --if we're adding the bits;
if Cin = '0' then
if x = y then
S <= '0';
if (x= '1' and y = '1') then
Cout <= '1';
else --if x = 0 and y = 0;
Cout <= '0';
end if;
else --if x not equal to y;
S <= '1';
Cout <= '0';
end if;
else --if Cin = 1 then;
if x = y then
S <= '1';
if (x= '1' and y = '1') then
Cout <= '1';
else --if x = 0 and y = 0;
Cout <= '0';
end if;
else --if x not equal to y;
S <= '0';
Cout <= '1';
end if;
end if;
else -- if we're subtracting bits (op = 1);
if Cin = '0' then
if x = y then
Cout <= '0';
S <= '0';
elsif (x ='1' and y = '0') then
Cout <= '0';
S <= '1';
else --if x not equal to y;
S <= '1';
Cout <= '1';
end if;
else --if Cin = 1 then;
if x = y then
Cout <= '1';
S <= '1';
elsif (x ='1' and y = '0') then
Cout <= '0';
S <= '0';
else --if x not equal to y;
S <= '0';
Cout <= '1';
end if;
end if;
end if;
end PROCESS;
end FA1Bit_arch;
Now I use this component in my 4 bit adder/subtractor in this code:
library IEEE;
use IEEE.std_logic_1164.all;
entity FA4Bit is
port (
X : in STD_LOGIC_VECTOR(3 downto 0);
Y : in STD_LOGIC_VECTOR(3 downto 0);
C0: in STD_LOGIC;
S : out STD_LOGIC_VECTOR(3 downto 0);
C4: out STD_LOGIC;
OP1: in STD_LOGIC_VECTOR(3 DOWNTO 0));
end FA4Bit;
architecture FA4Bit_arch of FA4Bit is
component FA1bit
port ( X: in STD_LOGIC; Y: in STD_LOGIC; CIN : in STD_LOGIC;
SI : out STD_LOGIC; COUT: out STD_LOGIC;
OPA : in STD_LOGIC);
end component;
signal C : std_logic_vector(1 to 3);
begin
U1: FA1bit port map (X=>X(0), Y=>Y(0), CIN=> C0, SI=>S(0), COUT=>C(1), OPA => OP1(0));
U2: FA1bit port map (X=>X(1), Y=>Y(1), CIN=> C(1), SI=>S(1), COUT=>C(2), OPA => OP1(1));
U3: FA1bit port map (X=>X(2), Y=>Y(2), CIN=> C(2), SI=>S(2), COUT=>C(3), OPA => OP1(2));
U4: FA1bit port map (X=>X(3), Y=>Y(3), CIN=> C(3), SI=>S(3), COUT=>C4, OPA => OP1(3));
end FA4Bit_arch;
Everything compiles perfectly same goes for the following testbench.
library ieee;
use ieee.std_logic_1164.all;
entity FA4Bit_tb is
end ;
architecture arch of FA4Bit_tb is
component FA4Bit
port ( X1 : in std_logic_vector(3 downto 0);
Y : in std_logic_vector(3 downto 0);
C0 : in std_logic;
S : out std_logic_vector(3 downto 0);
C4 : out std_logic;
OP1: in std_logic_vector(3 downto 0));
end component;
signal X : std_logic_vector(3 downto 0) := "0000";
signal Y : std_logic_vector(3 downto 0) := "0000";
signal C0 : std_logic := '0';
signal opa: std_logic_vector(3 downto 0) := (others=>'0');
signal S : std_logic_vector(3 downto 0);
signal C4 : std_logic;
begin
UUT : FA4Bit
port map (X1 => X, Y => Y, C0 => C0, S => S, C4 => C4, OP1=> opa);
X <= not X after 5 ns;
Y <= not Y after 7 ns;
opa <= not opa after 9 ns;
end arch;
However, I'm receiving a FATAL ERROR in the loading design.
# ** Fatal: (vsim-3817) Port "X" of entity "fa4bit" is not in the component being instantiated.
# Time: 0 ns Iteration: 0 Instance: /fa4bit_tb/UUT File: C:/Users/Omar/Desktop/320 PROJECT 3ANJAD HAL MARRA/FA4Bit.vhd Line: 5
# FATAL ERROR while loading design
# Error loading design
This is one reason why I hate component instantiations. In your component instantiation, the port is called X1, not X. Renaming to X should fix this issue. Then you have a couple of similar ones to fix (OP and S on FA1bit).
If you use entity instantiations, then a lot of problems like this go away.

Why do I get "Found '0' definitions of operator "+"" when adding bit_vectors? Are Delta Delays a factor?

I'm in the process of coding a 3-bit ALU. The problem I'm running into is in the multiplier, when Opcode = "001". I'm trying to add 3 bit_vectors(5 downto 0), and it's throwing the error "Found '0' definitions of operator "+"". I've looked around and found some links found '0' definitions of operator "+" in VHDL, but adding any packages doesn't seem to fix the error for me.
Also, I read somewhere that since you're coding hardware in VHDL, it's wise to keep in mind delta delays. Since i'm assigning values to a signal in a process, will it actually work to output the final product? Or will the delta delays cause the signals to not be updated until the process is suspended.
The error occurs on line 67, "Z <= t4 + t5 + t6", in the block where Opcode = "001". Thank you to anyone who can give a little advice.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU is
PORT(
X,Y : IN BIT_VECTOR(2 downto 0);
Opcode : IN BIT_VECTOR(2 downto 0);
Z : OUT BIT_VECTOR(5 downto 0);
CLK : IN BIT
);
end ALU;
architecture Behavioral of ALU is
COMPONENT adder3 is
PORT (
A1 ,A2, A3, B1, B2, B3, Cin : IN BIT ;
Sum1 ,Sum2, Sum3, Cout : OUT BIT );
END COMPONENT;
SIGNAL adder_output: BIT_VECTOR(3 downto 0);
SIGNAL temp: BIT_VECTOR(2 downto 0);
SIGNAL t1,t2,t3: BIT_VECTOR(2 downto 0);
SIGNAL t4,t5,t6: BIT_VECTOR(5 downto 0);
begin
ADD3: adder3 PORT MAP(
A1 => X(0),
B1 => Y(0),
A2 => X(1),
B2 => Y(1),
A3 => X(2),
B3 => Y(2),
Cin => '0',
Sum1 => adder_output(0),
Sum2 => adder_output(1),
Sum3 => adder_output(2),
Cout => adder_output(3)
);
PROCESS(X, Y, CLK, Opcode)
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
IF Opcode = "000" THEN
Z <= adder_output;
ELSIF Opcode = "001" THEN
IF Y(0) = '1' THEN
t1 <= X;
ELSE
t1 <= "000";
END IF;
IF Y(1) = '1' THEN
t2 <= X;
ELSE
t2 <= "000";
END IF;
IF Y(2) = '1' THEN
t3 <= X;
ELSE
t3 <= "000";
END IF;
t4 <= "000"&t1;
t5 <= "00"&t2&"0";
t6 <= "0"&t3&"00";
Z <= t4+t5+t6;
ELSIF Opcode = "010" THEN
Z <= X AND Y;
ELSIF Opcode = "011" THEN
Z <= X OR Y;
ELSIF Opcode = "100" THEN
Z <= X XOR Y;
ELSIF Opcode = "101" THEN
temp <= NOT X;
Z <= "000"&temp;
ELSIF Opcode = "110" THEN
IF Y = "000" THEN
Z <= "000"&X(2 downto 0);
ELSIF Y = "001" THEN
Z <= "00"&X(2 downto 0)&"0";
ELSIF Y = "010" THEN
Z <= "0"&X(2 downto 0)&"00";
ELSIF Y = "011" THEN
Z <= X(2 downto 0)&"000";
ELSIF Y = "100" THEN
Z <= X(1 downto 0)&"0000";
ELSIF Y = "101" THEN
Z <= X(0)&"00000";
ELSE
Z <= "000000";
END IF;
ELSE
IF Y = "000" THEN
Z <= "000"&X(2 downto 0);
ELSIF Y = "001" THEN
Z <= "0000"&X(2 downto 1);
ELSIF Y = "010" THEN
Z <= "00000"&X(2);
ELSE
Z <= "000000";
END IF;
END IF;
END IF;
END PROCESS;
end Behavioral;
If you want to do unsigned arithmetic with bit_vector, you need to use the numeric_bit_unsigned library that is part of the VHDL 2008 spec. For signed arithmetic, you need to use unsigned or signed types from either numeric_std or numeric_bit (the only difference is the base type).

VHDL multiplexing and two outputs

I need your help. I have a VHDL with nested condition and I would like to redraw it into a schematic. I think I should use one 2bit mux and 4bit mux. Is there anyone who can help me please? I tried google it but I didn't find anything that can help me.
process (a,b,c,d) begin
y <= '0';
z <= b;
if d='1' then
y <= b;
if a = '0' then
y <= c;
end if;
z <= '1';
else
y <= '1';
z <= d;
end if;
end process;
a,b,c,d are std_logic in
z, y are std_logic out
This a code for a 4-bit mux you can easily modify to make 2 bit
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY mux_4_1 IS
PORT (
a : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
s : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
b : OUT STD_LOGIC);
END ENTITY;
ARCHITECTURE behavioural OF mux_4_1 IS
BEGIN
PROCESS (a, s)
BEGIN
IF s = "00" THEN
b <= a(0);
ELSIF s = "01" THEN
b <= a(1);
ELSIF s = "10" THEN
b <= a(2);
ELSE
b <= a(3);
END IF;
END PROCESS;
END ARCHITECTURE;

VHDL : False Results in 4-Bit Adder and Subtractor

I want to make a 4-Bit Adder and Subtractor with VHDL
I have created 1-Bit Full-Adder , XOR Gate ( for Subtract ) and a 4-Bit Adder as shown below :
Full-Adder :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY FullAdder_1_Bit IS
PORT(
X, Y : IN STD_LOGIC;
CIn : IN STD_LOGIC;
Sum : OUT STD_LOGIC;
COut : OUT STD_LOGIC
);
END FullAdder_1_Bit;
ARCHITECTURE Behavier OF FullAdder_1_Bit IS
BEGIN
Sum <= X XOR Y XOR CIn;
COut <= (X AND Y) OR (X AND CIn) OR (Y AND CIn);
END Behavier;
XOR Gate :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY XORGate IS
PORT(
X1, X2 : IN STD_LOGIC;
Y : OUT STD_LOGIC
);
END XORGate;
ARCHITECTURE Declare OF XORGate IS
BEGIN
Y <= X1 XOR X2;
END Declare;
4-Bit Adder :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY Adder_4_Bit IS
PORT(
A, B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Mode : IN STD_LOGIC;
Sum : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COut : OUT STD_LOGIC
);
END Adder_4_Bit;
ARCHITECTURE Structure OF Adder_4_Bit IS
COMPONENT FullAdder_1_Bit IS
PORT(
X, Y : IN STD_LOGIC;
CIn : IN STD_LOGIC;
Sum : OUT STD_LOGIC;
COut : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT XORGate IS
PORT(
X1, X2 : IN STD_LOGIC;
Y : OUT STD_LOGIC
);
END COMPONENT;
SIGNAL COut_Temp : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL XB : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
B_0 : XORGate PORT MAP(Mode, B(0), XB(0));
B_1 : XORGate PORT MAP(Mode, B(1), XB(1));
B_2 : XORGate PORT MAP(Mode, B(2), XB(2));
B_3 : XORGate PORT MAP(Mode, B(3), XB(3));
SUM_0 : FullAdder_1_Bit
PORT MAP (A(0), XB(0), Mode, Sum(0), COut_Temp(0));
SUM_1 : FullAdder_1_Bit
PORT MAP (A(1), XB(1), COut_Temp(0), Sum(1), COut_Temp(1));
SUM_2 : FullAdder_1_Bit
PORT MAP (A(2), XB(2), COut_Temp(1), Sum(2), COut_Temp(2));
SUM_3 : FullAdder_1_Bit
PORT MAP (A(3), XB(3), COut_Temp(2), Sum(3), COut);
END;
and in my Main Codes , i have used those ( like Test-Bench ! ) :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.ALL;
ENTITY Add_AND_Sub IS
END Add_AND_Sub;
ARCHITECTURE Declare OF Add_AND_Sub IS
COMPONENT Adder_4_Bit IS
PORT(
A, B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Mode : IN STD_LOGIC;
Sum : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COut : OUT STD_LOGIC
);
END COMPONENT;
SIGNAL A, B : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL Mode : STD_LOGIC;
SIGNAL As, Bs, E, AVF : STD_LOGIC;
SIGNAL XA, XB, Sum : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
Add : Adder_4_Bit
PORT MAP(XA, XB, Mode, Sum, E);
PROCESS(A, B, Mode)
BEGIN
As <= A(4);
Bs <= B(4);
XA <= A(3 DOWNTO 0);
XB <= B(3 DOWNTO 0);
CASE Mode IS
WHEN '0' =>
IF ((As XOR Bs) = '1') THEN
Mode <= '1';
XA <= Sum;
AVF <= '0';
IF (E = '1') THEN
IF (XA = "0000") THEN
As <= '0';
END IF;
ELSE
XA <= (NOT XA) + "0001";
As <= NOT As;
END IF;
ELSE
XA <= Sum;
END IF;
WHEN '1' =>
IF ((As XOR Bs) = '1') THEN
Mode <= '0';
XA <= Sum;
AVF <= E;
ELSE
AVF <= '0';
XA <= Sum;
IF (E = '1') THEN
IF (XA = "0000") THEN
As <= '0';
END IF;
ELSE
XA <= (NOT XA) + "0001";
As <= NOT As;
END IF;
END IF;
WHEN Others =>
--
END CASE;
END PROCESS;
END Declare;
The main scenario is to Model this algorithm :
but now i want to have output in XA and As
I Should use registers shown in algorithm such as "E" and "AVF"
there is one question :
we know port maps are continuously connected , so when i change Mode Value , Result ( Sum ) must change , is it True ?!
I have tried this code but i cant get output in XA , and there is no True result for sum values , i know there is some problem in my main code ( Process ) , but i cant find problems
please check that codes and tell me what goes wrong !
Edit :
Im using ModelSim and its simulation for testing my code , first i force values of "A", "B" and "Mode" then run to get result and wave
thanks ...
Your testbench add_and_sub makes no assignments to it's a and b, they're default values are all 'U's.
What do you expect when your inputs to adder_4_bit are undefined?
Look at the not_table, or_table, and_table and xor_table in the body of the std_logic_1164 package.
Also to be a Minimal, Complete, and Verifiable example your readers need both expected and actual results.
If you're actually simulating the testbench I'd expect it consume no simulation time and after some number of delta cycles during initialization show sum and e chock full of 'U's.
I haven't personally modified your testbench to determine if your adder_4_bit works, but if you provide it with valid stimulus you can debug it. It can be helpful to consume simulation time and use different input values.
Adding a monitor process to add_and_sub:
MONITOR:
process (sum)
function to_string(inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
-- report "image_str = " & image_str;
return image_str;
end;
begin
report "sum = " & to_string(sum);
end process;
gives:
fourbitadder.vhdl:174:10:#0ms:(report note): sum = uuuu
one event on sum.
Add a process to cause events on a and 'b`:
STIMULUS:
process
begin
a <= "00000" after 10 ns;
b <= "00000" after 10 ns;
wait for 20 ns;
wait;
end process;
and we get:
(clickable)
We find we get an event on a and b but sum didn't change.
And the reason why is apparent in the case statement in the process. The default value of mode is 'U', and the case statement has choices for 0, 1 and:
when others =>
--
end case;
And the others choice results in no new value in mode.
Why nothing works can be discovered by reading the source of the body for package std_logic_1164, the xor_table, and_table, or_table. With mode = 'U' all your combinatorial outputs will be 'U'.
And to fix this you can assign a default value to mode where it is declared in the testbench:
signal mode : std_logic := '0';
With mode defined as a valid choice resulting in some action we note xa is now never defined causing the same issue:
(clickable)
And this is a problem in the process:
process(a, b, mode)
begin
as <= a(4);
bs <= b(4);
xa <= a(3 downto 0);
xb <= b(3 downto 0);
case mode is
when '0' =>
if ((as xor bs) = '1') then
mode <= '1';
xa <= sum;
avf <= '0';
if (e = '1') then
if (xa = "0000") then
as <= '0';
end if;
else
xa <= std_logic_vector(unsigned(not xa) + unsigned'("0001"));
as <= not as;
end if;
else
xa <= sum;
end if;
when '1' =>
if ((as xor bs) = '1') then
mode <= '0';
xa <= sum;
avf <= e;
else
avf <= '0';
xa <= sum;
if (e = '1') then
if (xa = "0000") then
as <= '0';
end if;
else
xa <= std_logic_vector(unsigned(not xa) + unsigned'("0001"));
as <= not as;
end if;
end if;
when others =>
--
end case;
Notice there are three places where xa is assigned, with no simulation time between them. There's only one projected output waveform value for any simulation time. A later assignment in the same process will result in the later value being assigned, in this case sum, which is all 'U's.
So how do you solve this conundrum? There are two possibilities. First you could not try and do algorithmic stimulus generation, assigning input to add explicitly with wait statements between successive assignments of different values. You can also insert delays between successive assignments to the same signal in the existing process, which requires a substantial re-write.
On a positive note the adder_4_bit and full_adder_1bit look like they should work. The problem appears to be all in the testbench.
I made some changes
I made a ALU unit as :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE ieee.std_logic_unsigned.ALL;
ENTITY ALU IS
PORT(
--Clk : IN STD_LOGIC;
A, B : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
Sel : IN STD_LOGIC;
AOut : OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
AsO : OUT STD_LOGIC
);
END ALU;
ARCHITECTURE Declare OF ALU IS
COMPONENT Adder_4_Bit IS
PORT(
A, B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Mode : IN STD_LOGIC;
Sum : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
COut : OUT STD_LOGIC
);
END COMPONENT;
SIGNAL As, Bs, E, AVF : STD_LOGIC;
SIGNAL XA, XB, Sum : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Mode : STD_LOGIC;
BEGIN
Add : Adder_4_Bit
PORT MAP(XA, XB, Mode, Sum, E);
PROCESS
BEGIN
As <= A(4);
Bs <= B(4);
XA <= A(3 DOWNTO 0);
XB <= B(3 DOWNTO 0);
CASE Sel IS
WHEN '0' =>
IF ((As XOR Bs) = '1') THEN
Mode <= '1';
AVF <= '0';
WAIT ON Sum;
IF (E = '1') THEN
IF (Sum = "0000") THEN
As <= '0';
END IF;
ELSE
Sum <= (NOT Sum) + "0001";
As <= NOT As;
END IF;
ELSE
Mode <= '0';
WAIT ON Sum;
END IF;
AOut <= Sum;
AsO <= As;
WHEN '1' =>
IF ((As XOR Bs) = '1') THEN
Mode <= '0';
WAIT ON Sum;
AVF <= E;
ELSE
Mode <= '1';
WAIT ON Sum;
AVF <= '0';
IF (E = '1') THEN
IF (Sum = "0000") THEN
As <= '0';
END IF;
ELSE
Sum <= (NOT Sum) + "0001";
As <= NOT As;
END IF;
END IF;
AOut <= Sum;
AsO <= As;
WHEN Others =>
--
END CASE;
END PROCESS;
END Declare;
and A Test Bench like this :
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE ieee.std_logic_unsigned.ALL;
ENTITY ALU_Test_Bench IS
END ALU_Test_Bench;
ARCHITECTURE Declare OF ALU_Test_Bench IS
COMPONENT ALU IS
PORT(
--Clk : IN STD_LOGIC;
A, B : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
Sel : IN STD_LOGIC;
AOut : OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
AsO : OUT STD_LOGIC
);
END COMPONENT;
SIGNAL Xs, S : STD_LOGIC;
SIGNAL X, Y, O : STD_LOGIC_VECTOR(4 DOWNTO 0);
BEGIN
ALU_PM : ALU PORT MAP(X, Y, S, O, Xs);
Main_Process : PROCESS
BEGIN
WAIT FOR 100 ns;
X <= "00010";
Y <= "11011";
S <= '0';
WAIT FOR 30 ns;
S <= '1';
WAIT FOR 30 ns;
WAIT FOR 100 ns;
X <= "01110";
Y <= "10011";
S <= '0';
WAIT FOR 30 ns;
S <= '1';
WAIT FOR 30 ns;
WAIT FOR 100 ns;
X <= "10011";
Y <= "11111";
S <= '0';
WAIT FOR 30 ns;
S <= '1';
WAIT FOR 30 ns;
END PROCESS;
END Declare;
As i say , i want to model the algorithm i posted in first post
there is some problem ...
for example when i simulate and run test bench , there is no output value in O and Xs !
I know the problem is in ALU and Test Bench
I changed ALU many times and tested many ways but all times some things goes wrong !
If you want to code that algorithm , which units you will create or at all what will you create ?! and how will you code that ?!
thanks for your help ...

Resources