Process doesn't work due simulation - vhdl

I wrote this code to understand process in vhdl but strangely I saw the simulation that doesn't work properly
my code :
entity test is
port(
i1 : in std_logic;
i2 : in std_logic;
r : out std_logic
);
end test;
architecture Behavioral of test is
signal g : std_logic;
begin
process(i1)
begin
if i1 = '1' then
g <= '1';
else
g <= '0';
end if;
end process;
process(i2)
begin
if i2 = '1' and g = '0' then
r <= '1';
else
r <= '0';
end if;
end process;
end Behavioral;
and this is my result :
enter image description here
when i process i1 so g should be 1 in the first period so r should be 0 but r is 1 after i2 is 1

Your are using g in the second process but it is not in the process sensitivity list.
process(i2,g)
begin
if i2 = '1' and g = '0' then
...

Related

Unable to assign counter signal to output (FSM)

I'm working on an FSM for a quadrature encoder counter, to be used on the Arty A7 35 --- this is my first VHDL project, so I apologize if I am missing something very basic. I have an internal count signal that I decrement or increment in the FSM, but when I try to assign that signal via COUNT_OUT <= count, COUNT_OUT stays at zero, even though I have been able to observe the state changing. I do this assignment at the very end of the FSM process.
simulation outputs
Further, I am not able to observe "state", "next state", or "count" in simulation --- I would appreciate help on this as well as would be very useful. These signals do not show up in the "objects" window beside the scope either
My entity declaration is as follows:
entity GPIO_demo is
Port ( BTN : in STD_LOGIC;
z : in STD_LOGIC;
A : in STD_LOGIC;
B : in STD_LOGIC;
LED : out STD_LOGIC;
CLK : in STD_LOGIC;
UART_TXD : out STD_LOGIC;
COUNT_OUT : out unsigned(11 downto 0)
);
end GPIO_demo;
I define these relevant signals in architecture:
type state_type is (S00, S01, S10, S11);
signal state, next_state: state_type;
signal count: unsigned(11 downto 0) := (others=>'0');
My FSM is as follows:
SYNC_PROC: process(CLK)
begin
if rising_edge(CLK) then
if ( z='1' ) then
state <= S00;
count <= "000000000000";
else
state <= next_state;
end if;
end if;
end process;
NEXT_STATE_DECODE: process(state, A, B)
begin
case state is
when S00 =>
if(A = '0' and B = '1') then
count <= "000000000000";
next_state <= S01;
elsif(A = '1' and B = '0') then
count <= "000000000000";
next_state <= S10;
end if;
when S01 =>
if(A = '1' and B = '1') then
count <= "100000000000";
next_state <= S11;
elsif(A = '0' and B = '0') then
count <= "100000000000";
next_state <= S00;
end if;
when S11 =>
if(A = '1' and B = '0') then
count <= count - 1;
next_state <= S10;
elsif(A = '0' and B = '1') then
count <= count + 1;
next_state <= S01;
end if;
when S10 =>
if(A = '0' and B = '0') then
count <= count - 1;
next_state <= S00;
elsif(A = '1' and B = '1') then
count <= count + 1;
next_state <= S11;
end if;
end case;
COUNT_OUT <= count;
end process;
Any idea on why this output does not update?

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 go through multiple input combinations with a for loop in a testbench VHDL?

I'm new to VHDL and I'm writing a test bench for an XNOR gate. The simple solution was to manually go through each combination of the two inputs but with more inputs this will take too long. How can I write this as a for loop in VHDL?
process
begin
p0 <= '1';
p1 <= '0';
wait for 1 ns;
if (pout = '1') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '1';
p1 <= '1';
wait for 1 ns;
if (pout = '0') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '0';
p1 <= '1';
wait for 1 ns;
if (pout = '1') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '0';
p1 <= '0';
wait for 1 ns;
if (pout = '0') then
error <= '1';
end if;
wait for 200 ns;
end process;
If p0 and p1 are inputs to the device under test and their base type is compatible with the element type of type unsigned:
library ieee;
use ieee.std_logic_1164.all;
entity xnor2 is
port (
p0: in std_logic;
p1: in std_logic;
pout: out std_logic
);
end entity;
architecture foo of xnor2 is
begin
pout <= not (p0 xor p1);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity inputs is
end entity;
architecture foo of inputs is
signal p0, p1, pout: std_logic;
signal error: std_logic := '0';
begin
DUT:
entity work.xnor2
port map (
p0 => p0,
p1 => p1,
pout => pout
);
process
use ieee.numeric_std.all; -- for example, if not already visible
variable elements: unsigned (1 downto 0);
begin
elements := (others => '0');
for i in 0 to 2 ** elements'length - 1 loop
p0 <= elements(0);
p1 <= elements(1);
wait for 1 ns;
report LF & "i = " & integer'image(i) &
LF & HT & "p0 = " & std_ulogic'image(p0) &
" p1 = " & std_ulogic'image(p1) &
" error = " & std_ulogic'image(error);
if pout = '0' then
error <= '1';
end if;
wait for 200 ns;
elements := elements + 1;
end loop;
wait;
end process;
end architecture;
Which reports:
ghdl -r inputs
inputs.vhdl:45:13:#1ns:(report note):
i = 0
p0 = '0' p1 = '0' error = '0'
inputs.vhdl:45:13:#202ns:(report note):
i = 1
p0 = '1' p1 = '0' error = '0'
inputs.vhdl:45:13:#403ns:(report note):
i = 2
p0 = '0' p1 = '1' error = '1'
inputs.vhdl:45:13:#604ns:(report note):
i = 3
p0 = '1' p1 = '1' error = '1'
Where we also see error has no obvious meaning.
Without providing a minimal, complete, and verifiable example in the question there's some risk an answer may have one or more errors and future readers can't as easily verify the solution.
The idea here is to use a binary representing counter with as many bits (elements) as inputs and assign the value of bits (elements) to respective inputs in each loop iteration.
That binary value can also be provided directly from the integer value of the loop parameter. See How to easily group and drive signals in VHDL testbench which also uses aggregate assignment:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity agg_assign is
end entity;
architecture foo of agg_assign is
signal A, B, C: std_logic;
begin
process
begin
wait for 10 ns;
for i in 0 to 7 loop
(A, B, C) <= std_logic_vector(to_unsigned(i, 3));
wait for 10 ns;
end loop;
wait;
end process;
end architecture;
You can also create a record subtype to mix element and array assignments:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity aggr_rec_assign is
end entity;
architecture foo of aggr_rec_assign is
signal A, B, C: std_logic;
signal D: std_logic_vector (2 downto 0);
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;
return image_str;
end function;
begin
process
type inputs_rec is
record
A: std_logic;
B: std_logic;
C: std_logic;
D: std_logic_vector (2 downto 0);
end record;
variable elements: unsigned (5 downto 0);
begin
wait for 10 ns;
for i in 0 to 2 ** elements'length - 1 loop
elements := to_unsigned(i, elements'length);
(A, B, C, D) <=
inputs_rec'(
elements(5),
elements(4),
elements(3),
std_logic_vector(elements(2 downto 0))
);
wait for 10 ns;
report LF & HT & "i = "& integer'image(i) & " (A, B, C, D) = " &
std_ulogic'image(A) & " " &
std_ulogic'image(B) & " " &
std_ulogic'image(C) & " " &
to_string(D);
end loop;
wait;
end process;
end architecture;
where in both cases the aggregate assignment would be the place to select the order inputs are extracted from the binary value.

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;

How to send a bit sequence at every clock to a std_logic signal in VHDL?

I have a project submission that requires me to design a pattern detector that detects and counts the occurrence of '11100' in the given input sequence. I have 2 codes. One is the actual code to generate the pattern and count it. the 2nd code is a testbench. I have very little experience with VHDL so please guide me.
I am trying to send a '11100' such that it goes in bit by bit automatically.
pattern_recogniser.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--Sequence detector for detecting the sequence "11100".
--Non overlapping type.
entity pattern_recogniser is
port( clk : in std_logic; --clock signal
reset : in std_logic; --reset signal
data : in std_logic; --serial bit sequence
-- det_vld : out std_logic; --A '1' indicates the pattern "1011" is detected in the sequence.
count : out integer);
end pattern_recogniser;
architecture Behavioral of pattern_recogniser is
type state_type is (A,B,C,D,E); --Defines the type for states in the state machine
signal state : state_type := A; --Declare the signal with the corresponding state type.
signal ct : integer;
begin
process(clk)
begin
if( reset = '0' ) then --resets state and output signal when reset is asserted.
-- det_vld <= '0';
ct <= 00000000;
state <= A;
elsif ( rising_edge(clk) ) then --calculates the next state based on current state and input bit.
case state is
when A => --when the current state is A.
-- det_vld <= '0';
if ( data = '0' ) then
state <= A;
else
state <= B;
end if;
when B => --when the current state is B.
if ( data = '0' ) then
state <= A;
else
state <= C;
end if;
when C => --when the current state is C.
if ( data = '0' ) then
state <= A;
else
state <= D;
end if;
when D => --when the current state is C.
if ( data= '0' ) then
state <= E;
else
state <= D;
end if;
when E => --when the current state is D.
if ( data = '0' ) then
state <= A;
-- det_vld <= '1';
ct <= ct + 1;
else
state <= B;
--Output is asserted when the pattern "11100" is found in the sequence.
end if;
when others =>
NULL;
end case;
end if;
end process;
process (ct)
begin
if(ct >=99) then
count <= 99; -- the count must show a "--" on the 7 segment display after it exceeds 99.
else
count <= ct;
end if;
end process;
end Behavioral;
and the second: testbench.vhd:
library ieee;
use ieee.std_logic_1164.all;
entity testbench is
port(count_t: out integer);
end testbench;
architecture behav of testbench is
component testset
port( ck : out std_logic;
rst : out std_logic;
dout : out std_logic);
end component;
component pattern_recogniser
port( clk : in std_logic; --clock signal
reset : in std_logic; --reset signal
data : in std_logic; --serial bit sequence
count : out integer);
end component;
signal clk_1 : std_logic := '0';
signal reset_1 : std_logic := '0';
signal data_1 : std_logic := '1';
signal count_s : integer := 0;
begin
--tb: testset port map (ck => clk_1, rst => reset_1, dout => data_1);
pat_rec : pattern_recogniser port map (clk => clk_1, reset => reset_1, data => data_1, count => count_s);
process(clk_1)
begin
clk_1 <= not clk_1 after 100 ps;
end process;
process is
begin
wait for 600 ps;
data_1 <= '0';
wait for 400 ps;
end process;
count_t <= count_s;
end behav;
I am not able to generate this sequence automatically using the ifs in the testbench. I have to generate it 110 times, then perform a rest and then 50 times more. How do I achieve this? Any help would be highly appreciated!!!

Resources