VHDL : False Results in 4-Bit Adder and Subtractor - logic

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 ...

Related

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.

3-bit serial input bubble sort in VHDL not sorting

I am trying to design a 3-bit serial input bubble sort and have not been able to get the output to actually sort.
Unfortunately, I am not very familiar with VHDL, or programming in general.
I have read that a potential problem of mine is the way I am using signals and assigning them within my process. However, when I tried correcting that and got it to compile, my output was broken.
There was another question about bubble sort in VHDL using arrays that I also tried to base mine off of, but was also unsuccessful. The main thing I tried from that was the for i in ___ to ___ loop process.
Below is my code and test bench that I have most recently been using.
Any advice or explanations would be greatly appreciated!
library ieee;
use ieee.std_logic_1164.all;
entity bubble_sort_bs is
generic (
width : integer := 3);
port (
X0, X1, X2 : in std_logic;
Y0, Y1, Y2 : out std_logic;
clk, enable : in std_logic);
end entity bubble_sort_bs;
architecture bubble_sort_bs_behav of bubble_sort_bs is
signal comb_out : std_logic;
signal inp : std_logic_vector((width-1) downto 0);
signal inp1 : std_logic_vector((width-1) downto 0);
signal inp2 : std_logic_vector((width-1) downto 0);
signal pass_in, pass_out : std_logic_vector((width-1) downto 0);
signal outp : std_logic_vector((width-1) downto 0); --trash
signal x_vector : std_logic_vector((width-1) downto 0);
begin
x_vector <= X0 & X1 & X2;
Y0 <= pass_out(2);
Y1 <= pass_out(1);
Y2 <= pass_out(0);
Output : process(all)
begin
if rising_edge(clk) then
if enable <= '1' then
inp1 <= x_vector;
inp2 <= pass_in;
end if;
end if;
if inp1 > inp2 then --x_vector
comb_out <= '1';
outp <= inp1;
pass_in <= inp2;
elsif inp2 > inp1 then --x_vector
comb_out <= '0';
outp <= inp2;
pass_in <= inp1;
----inp2 <= inp1;
elsif inp2 = inp1 then
comb_out <= '0';
outp <= inp2;
pass_in <= inp1;
end if;
pass_out <= outp;
end process Output;
end architecture bubble_sort_bs_behav;
Testbench:
library ieee;
use ieee.std_logic_1164.all;
entity bubble_sort_bs_tb is
end entity bubble_sort_bs_tb;
architecture tb_behav of bubble_sort_bs_tb is
component bubble_sort_bs
generic (
width : integer);
port (
X0, X1, X2 : in std_logic;
Y0, Y1, Y2 : out std_logic;
clk, enable : std_logic
);
end component;
constant bit_width : integer := 3;
signal inp, outp : std_logic_vector((bit_width-1) downto 0);
signal t_clk, t_enable : std_logic := '0';
begin
U1 : bubble_sort_bs
generic map (bit_width)
port map (
X0 => inp(0),
X1 => inp(1),
X2 => inp(2),
Y0 => outp(0),
Y1 => outp(1),
Y2 => outp(2),
clk => t_clk,
enable => t_enable
);
t_clk <= not t_clk after 5 ns;
test_process : process
begin
inp <= "001";
t_enable <= '1';
wait for 20 ns;
inp <= "100";
t_enable <= '1';
wait for 20 ns;
inp <= "111";
t_enable <= '1';
wait for 20 ns;
inp <= "000";
t_enable <= '1';
wait for 20 ns;
wait;
end process;
end tb_behav;
Okay there are multiple things wrong with your code.
First of all your mapping from input to x_vector has the bits reversed, which you also do at your output.
Next pass_in will never get a value, resulting in that your first comparison inp1 > inp2 always is true. So what your actually doing is giving an input signal comparing it with nothing and then returning it a clock cycle later. See Picture.
To do a bubble sort you at least need to have two inputs in the beginning.
As said by others try some tutorials to get more familiar with VHDL before continuing. I can recommend the asic-world tutorial.
Good luck!

Vhdl error 10344 dont know what to do

I am trying to make set&load d-flip flop code(synch) but it keeps giving me count <= '0' & d; it has 2 elements but must have 9 elements error.Thanks in advance
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity syn is
port (
clk : in std_logic;
rst_n : in std_logic;
d : in std_logic;
ld : in std_logic;
q : out std_logic_vector(7 downto 0);
co : out std_logic);
end syn;
architecture rtl of syn is
signal count : std_logic_vector(8 downto 0);
begin
co <= count(8);
q <= count(7 downto 0);
process (clk)
begin
if (clk'event and clk = '1') then
if (rst_n = '0') then
count <= (others => '0'); -- sync reset
elsif (ld = '1') then
count <= '0' & d; -- sync load
else
count <= count + 1; -- sync increment
end if;
end if;
end process;
end rtl;
Input d is std_logic, so '0' & d is 2 bit vector. Count is std_logic_vector of length 9, so you can't make assignment like this.
I'm not entirely sure what you are trying to achieve. If you want to assign '0' & d to some part of a vector, you can write for example
count(1 downto 0) <= '0' & d
If d is supposed to be equal size of counter, then change it's size in entity declaration.

VHDL code error

I have this code for a Serial Adder in VHDL. I am trying to get it to work, but I keep on getting an error that says:
Errors found in VHDL File -
Line : 17, Error : Index constraint expected in the subtype indication
This error is referring to the line:
signal state, next_state : integer range 0 to 3;
I'm not sure why this is happening. Any help? Please find the full code below.
library ieee;
use ieee.std_logic_1164.all;
entity adder is
port(
start : in std_logic;
clk : in std_logic;
a_out : out std_logic_vector(3 downto 0)
);
end adder;
architecture behave of adder is
signal a, b : std_logic_vector(3 downto 0);
signal shift : std_logic;
signal Cin, Cout : std_logic;
signal sum_in : std_logic;
signal state, next_state : integer range 0 to 3;
begin
sum_in <= a(0) xor b(0) xor Cin;
Cout <= (Cin and a(0))or(Cin and b(0))or(a(0) and b(0));
a_out <= a;
process(state, start)
begin
case state is
when 0 =>
if start = '1' then shift <= '1'; next_state <= 1;
else shift <= '0'; next_state <= 2; end if;
when 1 => shift <= '1'; next_state <= 2;
when 2 => shift <= '1'; next_state <= 3;
when 3 => shift <= '1'; next_state <= 0;
end case;
end process;
process(clk)
begin
if clk'event and clk = '0' then
state <= next_state;
if shift = '1' then
a <= sum_in & a(3 downto 1);
b <= b(0) & b(3 downto 1);
Cin <= Cout;
end if;
end if;
end process;
end behave;
Try to replace your line in which you are getting error by:
signal state, next_state : integer is range 0 to 3;
If you are specifying range then you should use is range instead of range

VHDL : 'X' value in result of Adder

I have created a 4-Bit Adder , now I want to add and sub 2 registers as sign-magnitude values
so , there is two register named A and B , two bits named As and Bs have sign bits of values in A and B , one XOR Gate for making 2-complement of B in subtraction and at the end result should store in A and As ( value and Sign ) and overflow bit in a register named AVF
this is a simple diagram :
Mode = 1 => Sub; Mod = 0 => Add
I have written this codes :
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;
FSum : 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;
ALU :
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;
C : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
D : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Cs : IN STD_LOGIC;
Ds : IN STD_LOGIC;
Mode_ALU : IN STD_LOGIC;
Sum_ALU : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
AVF : 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 E, Temp_Cs, Temp_Ds : STD_LOGIC;
SIGNAL Temp_S : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
Add : Adder_4_Bit PORT MAP(C, D, Mode_ALU, Temp_S, E);
-- Sum_ALU <= Temp_S;
-- Temp_Cs <= Cs;
-- Temp_Ds <= Ds;
PROCESS
BEGIN
WAIT FOR 30 ns;
Sum_ALU <= Temp_S;
Temp_Cs <= Cs;
Temp_Ds <= Ds;
END PROCESS;
PROCESS(C, D, Cs, Ds, Mode_ALU)
BEGIN
CASE Mode_ALU IS
WHEN '0' =>
IF ((Cs XOR Ds) = '1') THEN
AVF <= '0';
IF (E = '1') THEN
IF (Temp_S = "0000") THEN
Temp_Cs <= '0';
END IF;
ELSE
Sum_ALU <= (NOT Temp_S) + "0001";
Temp_Cs <= NOT Cs;
END IF;
ELSE
AVF <= E;
END IF;
WHEN '1' =>
IF ((Cs XOR Ds) = '1') THEN
AVF <= E;
ELSE
AVF <= '0';
IF (E = '1') THEN
IF (Temp_S = "0000") THEN
Temp_Cs <= '0';
END IF;
ELSE
Sum_ALU <= (NOT Temp_S) + "0001";
Temp_Cs <= NOT Cs;
END IF;
END IF;
WHEN Others =>
--
END CASE;
END PROCESS;
END Declare;
Test Bench :
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;
C : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
D : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Cs : IN STD_LOGIC;
Ds : IN STD_LOGIC;
Mode_ALU : IN STD_LOGIC;
Sum_ALU : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
AVF : OUT STD_LOGIC
);
END COMPONENT;
SIGNAL Xs, Ys, M, Av : STD_LOGIC;
SIGNAL X, Y, O : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
ALU_PM : ALU PORT MAP(X, Y, Xs, Ys, M, O, Av);
Mode_Process : PROCESS
BEGIN
M <= '1';
WAIT FOR 10 ns;
M <= '0';
WAIT FOR 10 ns;
END PROCESS;
Calc_Process : PROCESS
BEGIN
X <= "0010";
Y <= "1011";
Xs <= '0';
Ys <= '1';
WAIT FOR 20 ns;
X <= "0110";
Y <= "0011";
Xs <= '1';
Ys <= '1';
WAIT FOR 20 ns;
X <= "0010";
Y <= "1011";
Xs <= '0';
Ys <= '1';
WAIT FOR 20 ns;
END PROCESS;
END Declare;
when I run test bench , the result value filled with 'X' :
I know the problem is in ALU , but I can`t find the problem.
There is no problem in 4-Bit Adder , I have tested.
Another problem is calc sign bit of the result , Is the PROCESSes I have written correct ?
At all what I should do to Code the diagram above ?
thanks ...
You have multiple drivers on signals Sum_ALU, Temp_Cs and Temp_Ds in file alu.vhd.
PROCESS
BEGIN
WAIT FOR 30 ns;
Sum_ALU <= Temp_S;
Temp_Cs <= Cs;
Temp_Ds <= Ds;
END PROCESS;
PROCESS(C, D, Cs, Ds, Mode_ALU)
BEGIN
CASE Mode_ALU IS
WHEN '0' =>
IF ((Cs XOR Ds) = '1') THEN
AVF <= '0';
IF (E = '1') THEN
IF (Temp_S = "0000") THEN
Temp_Cs <= '0';
END IF;
ELSE
Sum_ALU <= (NOT Temp_S) + "0001";
Temp_Cs <= NOT Cs;
END IF;
ELSE
AVF <= E;
END IF;
WHEN '1' =>
IF ((Cs XOR Ds) = '1') THEN
AVF <= E;
ELSE
AVF <= '0';
IF (E = '1') THEN
IF (Temp_S = "0000") THEN
Temp_Cs <= '0';
END IF;
ELSE
Sum_ALU <= (NOT Temp_S) + "0001";
Temp_Cs <= NOT Cs;
END IF;
END IF;
WHEN Others =>
--
END CASE;
END PROCESS;
Whenever you assign a signal in multiple process, as you did here, it yields multiple drivers. If the drivers don't agree on the value (one drives '1' and the other '0' for example), the result is undefined ('X'). You will have to solve the issue yourself, as I'm not sure what is the correct behaviour. However, if you remove the first process, no undefined signal appears in the simulation.
Furthermore, you should be aware that the statement wait for 30 ns; is not synthesizable. The synthesizer may either fail or simply ignore the wait statement. If your goal was to simulate routing delay, then your usage is fine, otherwise you should change the logic if your goal is synthesis.
Finally, your second process would generate latches if synthesized. Latches are memory element which are known to break circuits when used improperly. They are the main reason why circuit behaviour do not match simulations, and should be removed. Latches appears whenever a signal you assign in a combinational process is not assign in every path of the process. That means Temp_Cs and Sum_ALU needs an assignment every time the process is evaluated (AVF is fine as is); every if must have an else, and all signals must be assigned. One simple way to deal with this is to give default values at the beginning of the process, so that every signal has an assignments. If a signal is assigned multiple times in the evaluation of the process, then only the last assignation will be effective. For example:
PROCESS(C, D, Cs, Ds, Mode_ALU)
BEGIN
Temp_Cs <= Cs;
Sum_ALU <= Temp_S;
CASE Mode_ALU IS
While making assignations in the others branch of the case is not necessary, I would recommend it nevertheless. You can assign all signals to 'X' for example.

Resources