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.
Related
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!
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.
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 ...
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.
I'm new to VHDL and I'm making a 4bit adder using 4 Full Adders. I created a test bench to see if the adder is working and in the ans I'm getting values of UUUU. From what I read is that the process is not being executed. I have no idea how to fix this, any help would be appreciated.
Here is the TestBench
ENTITY Adder4_Test IS
END Adder4_Test;
ARCHITECTURE behavior OF Adder4_Test IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT Adder4
PORT(
X : IN STD_LOGIC_vector(3 downto 0);
Y : IN STD_LOGIC_vector(3 downto 0);
Ans : OUT STD_LOGIC_VECTOR(3 downto 0);
Cout : OUT STD_LOGIC
);
END COMPONENT;
--Inputs
signal X : STD_LOGIC_vector(3 downto 0) := (others => '0');
signal Y : STD_LOGIC_vector(3 downto 0) := (others => '0');
--Outputs
signal Ans : STD_LOGIC_vector(3 downto 0);
signal Cout : STD_LOGIC;
-- No clocks detected in port list. Replace <clock> below with
-- appropriate port name
--constant <clock>_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Adder4 PORT MAP (
X,
Y,
Ans,
Cout
);
-- Clock process definitions
--<clock>_process :process
--begin
--<clock> <= '0';
--wait for <clock>_period/2;
--<clock> <= '1';
--wait for <clock>_period/2;
--end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
--wait for 100 ns;
--wait for <clock>_period*10;
-- insert stimulus here
-- Case 1 that we are testing.
X <= "0000";
Y <= "0000";
wait for 10 ns;
assert ( Ans = "0000" )report "Failed Case 1 - Ans" severity error;
assert ( Cout = '0' ) report "Failed Case 1 - Cout" severity error;
wait for 40 ns;
-- Case 2 that we are testing.
X <= "1111";
Y <= "1111";
wait for 10 ns;
assert ( Ans = "1110" )report "Failed Case 2 - Ans" severity error;
assert ( Cout = '1' ) report "Failed Case 2 - Cout" severity error;
wait for 40 ns;
wait;
end process;
END;
Here is the Adder4
entity Adder4 is
Port ( X : in STD_LOGIC_vector (3 DOWNTO 0);
Y : in STD_LOGIC_vector (3 DOWNTO 0);
Ans: out STD_LOGIC_vector (3 DOWNTO 0);
Cout: out STD_LOGIC);
end Adder4;
architecture Structure of Adder4 is
component FullAdder is
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC);
end component;
signal c0, c1, c2, c3: STD_LOGIC;
begin
c0 <='0';
b_adder0: FullAdder port map (X(0), Y(0), c0, Ans(0), c1);
b_adder1: FullAdder port map (X(1), Y(1), c1, Ans(1), c2);
b_adder2: FullAdder port map (X(2), Y(2), c2, Ans(2), c3);
b_adder3: FullAdder port map (X(3), Y(3), c3, Ans(3), Cout);
end Structure;
Here is the FullAdder
entity FullAdder is
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Cin : in STD_LOGIC;
Sum : out STD_LOGIC;
Cout : out STD_LOGIC);
end FullAdder;
architecture Behavioral of FullAdder is
component Xor_Model is
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
C : in STD_LOGIC;
Z : out STD_LOGIC);
end component;
begin
Cout <= ((X and Y) or (Y and Cin) or (X and Cin));
Sum <= (X AND (NOT Y) AND (NOT Cin)) OR ((NOT X) AND Y AND (NOT Cin)) OR
((NOT X) AND (NOT Y) AND Cin) OR (X AND Y AND Cin) after 5ns;
xorLabel: Xor_Model
Port Map ( A => X, B => Y, C => Cin, Z => Sum);
end Behavioral;
After adding context clauses you didn't supply, separating 5ns into 5 ns and insuring the entities needed in Addr4 were analyzed in the right order, I tried to run a simulation using ghdl where I promptly got an error message"
Adder4.vhdl:28:1:warning: component instance "xorlabel" is not bound
Adder4.vhdl:12:15:warning: (in default configuration of fulladder(behavioral))
This for the FullAdder. Seeing it was a 3 input XOR, I added one:
library ieee;
use ieee.std_logic_1164.all;
entity Xor_model is
Port (A: in std_logic;
B: in std_logic;
C: in std_logic;
Z: out std_logic
);
end entity;
architecture behavioral of Xor_model is
begin
Z <= A xor B xor C;
end behavioral;
There were 'U's on ans until 5 ns, from the Sum assignment delay in FullAdder.
I got 'X's at 50 ns on ans cleared 5 ns later from the same delayed assignment. Notice the LSB is '0' due to a short circuit logical operator.
Adding FF to FF got FE (correct without regards to carryout which showed up correctly as '1').
Getting rid of the initial 'U's could be done one of two ways. Either assign a known value to Sum as a default value instead of relying on the default, or removing the delay in the assignment to Sum.
The 'X's are dependent on Sum from the FullAdders as well, there are transitions on inputs while waiting for 5 ns.
In a behavioral combinatoric model delays aren't particularly expressive, in particular when you don't use delays for sub terms. If you delay contributing signals all along then signal path for a particular net based on gate delays, Sum would show up at the correct cumulative delay time. You could also use an intermediary Sum (with a different signal name) generated without delay and assign it to the output port Sum after a delay, eliminating the 'X's. Move the after 5 ns from FullAdder to Adder4:
In FullAdder:
((NOT X) AND (NOT Y) AND Cin) OR (X AND Y AND Cin) ; --after 5 ns;
In Adder4:
architecture Structure of Adder4 is
signal sum: std_logic_vector(3 downto 0);
b_adder0: FullAdder port map (X(0), Y(0), c0, sum(0), c1);
b_adder1: FullAdder port map (X(1), Y(1), c1, sum(1), c2);
b_adder2: FullAdder port map (X(2), Y(2), c2, sum(2), c3);
b_adder3: FullAdder port map (X(3), Y(3), c3, sum(3), Cout);
And add delay assigning sum to the ans:
Ans <= sum after 5 ns;
And where if you set a default value of '0's on Ans in the Adder4 port:
Ans: out STD_LOGIC_vector (3 DOWNTO 0) := (others => '0');
You can get rid of the initial 'U's:
And to clarify the 'U's are there until there is a transaction on the output (Ans) following the after 5 ns delay. It might be more proper to use (others => 'X')