why is the output of JK flip flop red in simulation? - vhdl

I am posting a Code for JK Flip flop in VHDL language. the code is correct according to the JK flip flop circuit. but i got output as red line. can any one tell me the what is the problem with only JK flip flop only.
Programme: JK Flip Flop
----------=======NAnd Gate with three inputs=====---------------
library ieee;
use ieee.std_logic_1164.all;
entity nand_gate3 is port(
A, B, C : in std_logic;
F : out std_logic);
end nand_gate3 ;
architecture nandfunc3 of nand_gate3 is
signal x : std_logic ;
begin
x <= A nand B ;
F <= x nand C ;
end nandfunc3;
------====== END NANd GATE with three inout ======--------
----=========NANd Gate with Two inputs==========------------
library ieee;
use ieee.std_logic_1164.all;
entity nand_gate2 is port(
A, B : in std_logic;
F : out std_logic );
end nand_gate2;
architecture nandFunc2 of nand_gate2 is
begin
F <= A nand B ;
end nandFunc2;
------====== END NANd GATE with three inout ======-
library ieee;
use ieee.std_logic_1164.all;
ENTITY JK_flipflop IS PORT (
clk , J, K : IN std_logic;
Q , Q_bar : OUT std_logic );
END JK_flipflop ;
architecture JK_structure OF JK_flipflop IS
----===Compnents
COMPONENT nand_gate3 IS PORT (
A, B ,C : IN std_logic ;
F : OUt std_logic );
End Component ;
COMPONENT nand_gate2 IS PORT (
A, B : IN std_logic ;
F : OUt std_logic );
End Component ;
Signal X, Y , Qback ,Qbar_back: std_logic ;
----== Structure
Begin
U1: nand_gate3 PORT MAP ( J, clk, Qbar_back, X );
U2: nand_gate3 PORT MAP ( K, clk, Qback ,Y );
U3: nand_gate2 PORT MAP ( X, Qbar_back ,Qback);
U4: nand_gate2 PORT MAP ( Y, Qback ,Qbar_back);
Q <= Qback;
Q_bar <= Qbar_back;
END JK_structure ;
--------------------Test Bench for JK flip flop----===
library ieee;
use ieee.std_logic_1164.all;
entity jk_flipflop_tb is
end jk_flipflop_tb ;
architecture tb of jk_flipflop_tb is
---====Jk_flipflop
component JK_flipflop is port(
clk,J , K : in std_logic;
Q, Q_bar : out std_logic);
end component;
---===signals
signal clk,J ,K , Q, Q_bar : std_logic;
begin
mapping: JK_flipflop port map(clk, J, K, Q, Q_bar);
-------=========Process for Clcok ===========---------------
process
begin
clk <= '1';
wait for 5 ns;
clk <= '0';
wait for 5 ns;
end process;
--------===========Process for j,k inputs values=======--------------
process
begin
-------===TEST 1
J <= '0';
K <= '1';
wait for 20 ns;
-------====TEST 2
J <= '1';
K <= '1';
wait for 20 ns;
-------====TEST 3
J <= '1';
K <= '0';
wait for 20 ns;
-------====TEST 4
J <= '0';
K <= '0';
wait for 20 ns;
end process;
end tb;
--------------------------------------------
configuration cfg_tb of jk_flipflop_tb is
for tb
end for;
end cfg_tb;
---------======------

JK flip flops must have a reset port to initialize outputs, Otherwise because outputs (Q , Qbar) are set by themselves (feedback), if they don't have any initial value, they are always undefined. Then you should add a reset port to your design.
You can use the following code to get the correct result :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity JK_FF is
port(
Reset : in std_logic;
Clock : in std_logic;
J,K : in std_logic;
Q,Qbar : out std_logic
);
end JK_FF;
architecture Behavioral of JK_FF is
signal temp : std_logic;
begin
process (Clock)
begin
if rising_edge(Clock) then
if Reset='1' then
temp <= '0';
else
if (J='0' and K='0') then
temp <= temp;
elsif (J='0' and K='1') then
temp <= '0';
elsif (J='1' and K='0') then
temp <= '1';
elsif (J='1' and K='1') then
temp <= not (temp);
end if;
end if;
end if;
end process;
Q <= temp;
Qbar <= not temp;
end Behavioral;

Your logic seems to be faulty. The right logic is:
Q = (J and Qbar_back) nand clk nand Qbar_back
Qbar = (K and Q_back) nand clk nand Q_back
The and operation is a nand operation in your logic.

Related

VHDL And or Invert Circuit, Output undetermined for first 5 ns during simulation. Internal signals also not showing on waveform

I am trying to show simulation results for a simple And or Invert circuit. I have been struggling to get to the bottom of this for a while now. The code compiles correctly although the simulation does not show the results I expected. The output signal shows as undefined for 5ns then shows a correct signal while the internal signals stated in my design do not show up at all during simulation.
Can anyone check my code for me? Thanks.
Design
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity AOI is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
D : in STD_LOGIC;
F : out STD_LOGIC);
end AOI;
architecture V1 of AOI is
begin
F <= (A and B) nor (C and D);
end V1;
architecture V3 of AOI is
signal I1, I2, I3 : std_logic;
begin
F <= not I3 after 1 ns;
I3 <= I1 or I2 after 2 ns;
I1 <= A and B after 2 ns;
I2 <= C and D after 2 ns;
end V3;
Testbench
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity andorinvertTB is
end;
architecture TB1 of andorinvertTB is
component AOI_component
port(A,B,C,D : in std_logic;
F : out std_logic);
end component;
signal A,B,C,D,F : std_logic;
for G1: AOI_component use entity work.AOI(V3);
begin
stimuli: process
begin
A <= '0'; B <= '0'; C <= '0'; D <= '0'; wait for 10 NS;
A <= '0'; B <= '1'; C <= '0'; D <= '1'; wait for 10 NS;
A <= '1'; B <= '0'; C <= '1'; D <= '0'; wait for 10 NS;
A <= '1'; B <= '1'; C <= '1'; D <= '1'; wait for 10 NS;
wait;
end process;
G1: AOI_component port map ( A=>A, B=>B, C=>C, D=>D, F=>F );
end;
Image of simulation results - Output F undefined at the start and missing internal singals I1, I2 and I3

How to create a pseudo-random sequence with a 16 bit LFSR

I am trying to generate a random sequence of 16 bit.
The problem is that the output is getting undefined state. I feel that this is due to parallel processing in those xor statements. So I have put in delays but it still doesn't work.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity random_data_generator is
port (
por : in STD_LOGIC;
sys_clk : in STD_LOGIC;
random_flag : in STD_LOGIC;
random_data : out STD_LOGIC_vector (15 downto 0)
);
end random_data_generator;
architecture Behavioral of random_data_generator is
signal q : std_logic_vector(15 downto 0);
signal n1,n2,n3 : std_logic;
begin
process(sys_clk)
begin
if(por='0') then
q<= "1001101001101010";
elsif(falling_edge(sys_clk)) then
if(random_flag='1') then
n1<= q(15) xor q(13);
n2<= n1 xor q(11) after 10 ns;
n3<= n2 xor q(10) after 10 ns;
q<= q(14 downto 0) & n3 after 10 ns;
end if;
end if;
end process;
random_data <= q;
end Behavioral;
Making some small structural changes to your LFSR:
library ieee;
use ieee.std_logic_1164.all;
entity random_data_generator is
port (
por: in std_logic;
sys_clk: in std_logic;
random_flag: in std_logic;
random_data: out std_logic_vector (15 downto 0)
);
end entity random_data_generator;
architecture behavioral of random_data_generator is
signal q: std_logic_vector(15 downto 0);
signal n1, n2, n3: std_logic;
begin
process (por, sys_clk) -- ADDED por to sensitivity list
begin
if por = '0' then
q <= "1001101001101010";
elsif falling_edge(sys_clk) then
if random_flag = '1' then
-- REMOVED intermediary products as flip flops
q <= q(14 downto 0) & n3; -- REMOVED after 10 ns;
end if;
end if;
end process;
-- MOVED intermediary products to concurrent signal assignments:
n1 <= q(15) xor q(13);
n2 <= n1 xor q(11); -- REMOVED after 10 ns;
n3 <= n2 xor q(10); -- REMOVED after 10 ns;
random_data <= q;
end architecture behavioral;
These changes remove the n1, n2, and n3 flip flops by promoting those assignments to concurrent signal assignment statements. The fundamental issue generating 'U's is that these flip flops were not initialized. They were flip flops because their assignment was inside the if statement with an elsif condition on the falling edge of sys_clk.
Adding a testbench:
library ieee;
use ieee.std_logic_1164.all;
entity rng_tb is
end entity;
architecture foo of rng_tb is
signal por: std_logic;
signal sys_clk: std_logic := '0';
signal random_flag: std_logic;
signal random_data: std_logic_vector (15 downto 0);
begin
DUT:
entity work.random_data_generator
port map (
por => por,
sys_clk => sys_clk,
random_flag => random_flag,
random_data => random_data
);
CLOCK:
process
begin
wait for 5 ns;
sys_clk <= not sys_clk;
if now > 2800 ns then
wait;
end if;
end process;
STIMULI:
process
begin
por <= '1';
random_flag <= '0';
wait until falling_edge(sys_clk);
por <= '0';
wait until falling_edge(sys_clk);
wait for 1 ns;
por <= '1';
wait until falling_edge(sys_clk);
random_flag <= '1';
wait;
end process;
end architecture;
Analyzing both, elaborating and simulating the testbench gives:
Showing a pseudo-random sequence with a length longer than 16 using a 16 bit Linear Feedback Shift Register (LFSR).

How to put desired inputs for VHDL simulation (force Command)

The Following is the VHDL code for a counter using D flip-flops. Here we are assuming the flip-flops are positive edge triggered.
Inside the architecture, I declared Q (present state) and D as a 4-Bit logic vector.
I assigned all the outputs (Z0 to Z7) and D signal values to match the logic expressions determined by the minimum input equations for the counter and flip-flops respectively.
At the end of the code a process is called to simulate the behavior of clear (ClrN) and clock (CLK)
My Question:
The code works properly but I am facing an issue with the Simulation of the test bench.
In the simulation we need to show circuit started out with the state 1000 and it then goes through each state in the correct order.
In Short: How do i show the signals Q and D in the simulation.
This is the part i am not sure on how to do.
I was told to use the force commands to set the desired inputs.
For Example:
force ClrN 0 0, 1 20
force CLK 1000 0
force CLK 0 0, 1 40 -repeat 80
But i am not sure where and how to use it.
Below is the VHDL Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity counter is
port (CLK, ClrN : in std_logic;
Z0 : out std_logic;
Z1 : out std_logic;
Z2 : out std_logic;
Z3 : out std_logic;
Z4 : out std_logic;
Z5 : out std_logic;
Z6 : out std_logic;
Z7 : out std_logic);
end counter;
architecture Behavioral of counter is
signal Q: std_logic_vector(0 to 3);
signal D: std_logic_vector(0 to 3);
begin
u1: process(Q)
begin
Z0 <= Q(0) and not Q(1) and not Q(3);
Z1 <= Q(0) and Q(1);
Z2 <= not Q(0) and Q(1) and not Q(2);
Z3 <= Q(1) and Q(2);
Z4 <= not Q(1) and Q(2) and not Q(3);
Z5 <= Q(2) and Q(3);
Z6 <= not Q(0) and not Q(2) and Q(3);
Z7 <= Q(0) and Q(3);
D(0) <= not Q(1) and not Q(2);
D(1) <= not Q(2) and not Q(3);
D(2) <= not Q(0) and not Q(3);
D(3) <= not Q(0) and not Q(1);
end process u1;
u2: process(CLK,ClrN)
begin
if ClrN = '0' then
Q <= "1000";
elsif Rising_Edge (CLK) then
Q <= D;
end if;
end process u2;
end Behavioral;
The following is my VHDL test bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
COMPONENT counter
PORT(
CLK : IN std_logic;
ClrN : IN std_logic;
Z0 : OUT std_logic;
Z1 : OUT std_logic;
Z2 : OUT std_logic;
Z3 : OUT std_logic;
Z4 : OUT std_logic;
Z5 : OUT std_logic;
Z6 : OUT std_logic;
Z7 : OUT std_logic
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal ClrN : std_logic := '0';
--Outputs
signal Z0 : std_logic;
signal Z1 : std_logic;
signal Z2 : std_logic;
signal Z3 : std_logic;
signal Z4 : std_logic;
signal Z5 : std_logic;
signal Z6 : std_logic;
signal Z7 : std_logic;
-- Clock period definitions
constant CLK_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: counter PORT MAP (
CLK => CLK,
ClrN => ClrN,
Z0 => Z0,
Z1 => Z1,
Z2 => Z2,
Z3 => Z3,
Z4 => Z4,
Z5 => Z5,
Z6 => Z6,
Z7 => Z7
);
-- Clock process definitions
CLK_process :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- -- hold reset state for 10 ns.
wait for 10 ns;
ClrN <= '1';
wait;
end process;
END;
Where and how do I add the Q and D signals to my test bench in order to get the simulation that shows the circuit started out with the state 1000 and it then goes through each state in the correct order.
and do i even use force command?
One way to document what happens in the simulation (in addition to the waveform) is to write the desired signals into output (like printf in c) or to file (like fprintf).
To do this, first include textio package:
use std.textio.all;
use ieee.std_logic_textio.all;
and then amend you process:
u2: process(CLK,ClrN)
file f0 : text is out "output.txt";
begin
if ClrN = '0' then
Q <= "1000";
elsif Rising_Edge (CLK) then
--pragma translate_off
write(output, "Q:" & to_string(Q) & " D:" & to_string(D) & lf);
write(f0, "Q:" & to_string(Q) & " D:" & to_string(D) & lf);
--pragma translate_on
Q <= D;
end if;
end process u2;
The pragmas are not absolutely necessary, but they are a good habit to add to whatever non-synthesizable code inside a module that is meant for synthesis.
In your example, force should be used not.

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.

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