How can we assign different signals to a single integer value? - vhdl

I'm writing VHDL test bench for full adder
in Simulation i have tried this and getting the correct result
begin
A <= '0';
B <= '0';
C <= '0';
wait for 10 ns;
A <= '0';
B <= '0';
C <= '1';
wait for 10 ns;
A <= '0';
B <= '1';
C <= '0';
wait for 10 ns;
A <= '0';
B <= '1';
C <= '1';
wait for 10 ns;
A <= '1';
B <= '0';
C <= '0';
wait for 10 ns;
A <= '1';
B <= '0';
C <= '1';
wait for 10 ns;
A <= '1';
B <= '1';
C <= '0';
wait for 10 ns;
A <= '1';
B <= '1';
C <= '1';
wait for 10 ns;
wait;
end process;
but i don't want to write all this i just want to use for loop like in verilog
for i in 0 to 7 loop
{A,B,C} <= i;
wait for 10 ns;
end loop;
I Know assigning A, B, C to i is not right in VHDL?
how do we do that what are the correct syntax?

Yes you can - VHDL 2008 allows aggregate assignments.
use ieee.numeric_std_unsigned.all;
for i in 0 to 7 loop
(A,B,C) <= to_slv(i, 3);
wait for 10 ns;
end loop;

This work under VHDL93 with Vivado 2018.1:
loop1: for i in 0 to 7 loop
(a,b,c) <= std_logic_vector(to_unsigned(i,3));
wait for 10ns;
end loop;
You will not need the library use ieee.numeric_std_unsigned.all; (which I do not know)
But you will need the standard ieee library:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
Here is the testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library work;
entity test_tb is
end entity;
architecture Behavioral of test_tb is
signal clk : std_logic;
signal a : std_logic;
signal b : std_logic;
signal c : std_logic;
begin
clkpr : process
begin
clk <='1';
wait for 10ns;
clk <= '0';
wait for 10ns;
end process;
test_pr : process
begin
loop: for i in 0 to 7 loop
(a,b,c) <= std_logic_vector(to_unsigned(i,3));
wait for 10ns;
end loop;
wait;
end process;
end Behavioral;

You can try this :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; -- To use integer and unsigned
...
signal stimuli : std_logic_vector(2 downto 0); -- Equivalent of A, B, C
...
inst_full_adder : full_adder
port map
(
i_a => stimuli(0),
i_b => stimuli(1),
i_carry => stimuli(2),
...
);
...
for i in 0 to 7 loop
stimuli <= std_logic_vector(to_unsigned(i,3)); -- Conversion of your integer in std_logic_vector (3 is the size of your vector)
wait for 10 ns;
end loop;

Related

How to add a parity bit to the input sequence VHDL

I am making a FSM Moore sequence detector on VHDL for a given input bit sequence (10100110) but now I also want to add an even parity bit to the input bit sequence as a new sequence. I know the logic behind it to use xor gate but im unable to implement it in the code.
This is my design code:
library IEEE;
use IEEE.std_logic_1164.all;
entity sequence_detector is
port(clock: in std_logic;
input_seq: in std_logic;
detector: out std_logic);
end sequence_detector;
architecture behaviour of sequence_detector is
type state is (init, s1, s2, s3, s4);
signal p_s, n_s : state;
begin
process
begin
wait until clock'event and clock = '1';
p_s <= n_s;
end process;
process (input_seq, p_s)
begin
case(p_s) is
when init =>
if(input_seq = '1') then
n_s <= s1;
detector <= '0';
else
n_s <= init;
detector <= '0';
end if;
when s1 =>
if(input_seq = '0') then
n_s <= s2;
detector <= '0';
else
n_s <= s1;
detector <= '0';
end if;
when s2 =>
if(input_seq = '0') then
n_s <= s3;
detector <= '0';
else
n_s <= s1;
detector <= '0';
end if;
when s3 =>
if(input_seq = '1') then
n_s <= s4;
detector <= '0';
else
n_s <= init;
detector <= '0';
end if;
when s4 => --here we decide if its overlapping or not
if(input_seq = '1') then
n_s <= s1;
detector <= '1';
else
n_s <= s2;
detector <= '0';
end if;
end case;
end process;
end behaviour;
This is my testbench:
library IEEE;
use IEEE.std_logic_1164.all;
entity testbench is
end testbench;
architecture behaviour of testbench is
component sequence_detector is
port(clock: in std_logic;
input_seq: in std_logic;
detector: out std_logic);
end component;
signal clock, input_seq : std_logic;
signal detector : std_logic;
constant clock_period: Time := 10 ns;
begin
DUT: sequence_detector port map(clock, input_seq, detector);
p_clock: process
begin
clock <= '0';
wait for clock_period/2;
clock <= '1';
wait for clock_period/2;
end process;
process
begin
input_seq <= '1';
wait for 10 ns;
input_seq <= '0';
wait for 10 ns;
input_seq <= '1';
wait for 20 ns;
input_seq <= '0';
wait for 20 ns;
input_seq <= '1';
wait for 20 ns;
input_seq <= '0';
wait;
end process;
end behaviour;
This is the output:
output graph

How to test bench VHDL signals and show them In GTKWAVE?

I emulated this VHDL code using GHDL in terminal, no errors occured, but when I imported .vcd file into GTKWAVE no signal shown up.
SCREENSHOT OF GTKWAVE
Desing Code:
Library ieee; Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
entity EXO is
port (CLK, EN: in bit; SORTIE: out bit);
end entity;
architecture EXXO of EXO is
signal compt : integer range 0 to 7 ;
signal etat : bit;
begin
process (CLK)
begin
if CLK'event and CLK = '1' then
if EN = '1' then
compt <= compt + 1;
case etat is
when '0' => if compt = 3 then compt <= 0; SORTIE <= '1'; etat <= '1'; end if;
when '1' => if compt = 2 then compt <= 0; SORTIE <= '0'; etat <= '0'; end if;
end case;
end if;
end if;
end process;
end architecture;
EDIT: I am new to VHDL, so please bear with me.
I am required to complete this
chronogram. The design code is given. I tried to create a Test bench for it, and here is the result:
GTKWAVE Screenshot 2 Which is obviously an utter failure (Failed to show compt, etat, SORTIE).
Test Bench:
Library ieee; Use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;
entity EXOtb is
end entity;
architecture EXXOtb of EXOtb is
component EXO
port (CLK, EN: in bit; SORTIE: out bit);
end component;
signal CLKtb, ENtb: bit;
signal SORTIEtb: bit;
begin
DUT: EXO port map (CLK => CLKtb, EN => ENtb, SORTIE => SORTIEtb );
STIMULUS: process
begin
CLKtb <= '0'; ENtb <= '0'; wait for 10 ns;
CLKtb <= '0'; ENtb <= '1'; wait for 10 ns;
CLKtb <= '1'; ENtb <= '1'; wait for 10 ns;
CLKtb <= '1'; ENtb <= '1'; wait for 10 ns;
assert false report "Reached End of test";
wait;
end process;
end architecture;
EDIT 3: Thanks to #user1155120's detailed answer, I believe I have solved the problem.
Instead of declaring CLK values manually, I have created a proper function for it.
For some reason, in order to show internal signals in GTKWAVE, You need to declare them as well in the test bench, honestly I don't know why.
By looking carefully into the design code, the input EN seems to refer to some enabling property, and the code runs only if EN is true, so in the test bench I gave it the value of 1. Also, that if EN = '1' then seems to be redundant and there is no need for since EN is always 1. I kept it as it is though.
The new Design Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity EX is
Port ( CLK : in STD_LOGIC;
EN : in STD_LOGIC;
SORTIE : out STD_LOGIC);
end EX;
architecture Behavioral of EX is
signal compt : integer range 0 to 7 ;
signal etat : bit;
begin -- Stimulus process
process (CLK)
begin
if CLK'event and CLK = '1' then
if EN = '1' then
compt <= compt + 1;
case etat is
when '0' => if compt = 3 then compt <= 0; SORTIE <= '1'; etat <= '1'; end if;
when '1' => if compt = 2 then compt <= 0; SORTIE <= '0'; etat <= '0'; end if;
end case;
end if;
end if;
end process;
end Behavioral;
Test Bench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY EXTB IS
END EXTB;
ARCHITECTURE behavior OF EXTB IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT EX
PORT(
CLK : IN std_logic;
EN : IN std_logic;
SORTIE : OUT std_logic
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal EN : std_logic := '1';
-- Inner
signal compt : integer range 0 to 7 ;
signal etat : bit;
--Outputs
signal SORTIE : std_logic;
-- Clock period definitions
constant CLK_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: EX PORT MAP (
CLK => CLK,
EN => EN,
SORTIE => SORTIE
);
-- 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
process (CLK)
begin
if CLK'event and CLK = '1' then
if EN = '1' then
compt <= compt + 1;
case etat is
when '0' => if compt = 3 then compt <= 0; SORTIE <= '1'; etat <= '1'; end if;
when '1' => if compt = 2 then compt <= 0; SORTIE <= '0'; etat <= '0'; end if;
end case;
end if;
end if;
end process;
END;
GTKWAVE result (All signals are shown as required in the homework)

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

VHDL testbench not changing output ALU 32bit

You see, I've already finished to describe an ALU on vhdl with modelsim, however the testbench seems to not update the solution, when I see the simulation the circuit 32 bit response always says "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU" I dont know what did i wrote wrong on the testbench also there is a warning on the compiler about the circuit response which says
** Warning: (vsim-8683) Uninitialized out port /alu_tb/ALU_test/res(32 downto 0) has no driver.
This port will contribute value (UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU) to the signal network.
and here is the testbench code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ALU_tb is
end ALU_tb;
architecture bhv_ALU_tb of ALU_tb is
component ALU
port(
a, b: in std_logic_vector(31 downto 0);
c: in std_logic;
s: in std_logic_vector(3 downto 0);
res: out std_logic_vector(32 downto 0));
end component;
signal a, b: std_logic_vector(31 downto 0);
signal c: std_logic;
signal s: std_logic_vector(3 downto 0);
signal re: std_logic_vector(32 downto 0);
begin
ALU_test: ALU port map (a => a, b => b, c => c, s => s, res => re);
process begin
b <= "00000000000010100111010100011110";
a <= "00000000011010000100110011101110";
c <= '0';
s <= "1111";
wait for 2 ns;
b <= "00000000000010100111010100011110";
a <= "00000000011010000100110011101110";
c <= '0';
s <= "0100";
wait for 2 ns;
s <= "0000";
wait for 2 ns;
s <= "0001";
wait for 2 ns;
s <= "0010";
wait for 2 ns;
s <= "0011";
wait for 2 ns;
s <= "0100";
wait for 2 ns;
s <= "0101";
wait for 2 ns;
s <= "0110";
wait for 2 ns;
s <= "0111";
wait for 2 ns;
s <= "1000";
wait for 2 ns;
s <= "1001";
wait for 2 ns;
s <= "1010";
wait for 2 ns;
s <= "1011";
wait for 2 ns;
s <= "1100";
wait for 2 ns;
s <= "1101";
wait for 2 ns;
s <= "1110";
wait for 2 ns;
s <= "1111";
wait for 2 ns;
end process;
end bhv_ALU_tb;
i know the mistake seems trivial "res isn't initialized" but I've been away from vhdl way too long and honestly dont know how to fix it, any ideas?
Firstly
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
Bad.. don't use. You don't even need them in this file.
If you ever need arithmentic, use numeric_std.
Then: the error is in the component ALU, becasue that should 'drive' res. But since you did not post the code of that, we cannot help you (yet).
p.s. currently you do not need to define a component in VHDL anymore. You could just write:
ALU_test: entity work.ALU port map

What is Simulator 45-1 Error in Xilinx Vivado?

I have been trying to make a generic sequence detector. When i try to simulate my design, I get a simulator 45-1 Fatal run time error. Can somebody please help me with this. Here is my Test bench and design.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Sequence_tb is
end Sequence_tb;
architecture Behavioral of Sequence_tb is
component sequence is
Generic(width: integer;
sequence: std_logic_vector);
Port(din,CLK,RST:in std_logic;
dout: out std_logic;
temp: buffer std_logic_vector(0 to width-1));
end component;
constant CLK_period: time := 10ns;
constant width: integer := 4;
constant sequence0: std_logic_vector(width-1 downto 0) := "1010";
signal din,CLK,RST,dout: std_logic := '0';
signal temp : std_logic_vector(0 to width-1) := (others=>'0');
begin
uut: sequence generic map(width=>width,sequence=>sequence0)
port map(din=>din,CLK=>CLK,RST=>RST,dout=>dout,temp=>temp);
CLK_proc: process
begin
CLK <= not CLK;
wait for CLK_period;
end process;
RST_proc: process
begin
RST <= '1';
wait for 20 ns;
RST <= '0';
wait;
end process;
din_proc: process
begin
din <= '1';
wait for 30 ns;
din <= '0';
wait for 10 ns;
din <= '1';
wait for 10 ns;
din <= '0';
wait for 10 ns;
din <= '1';
wait for 10 ns;
wait;
end process;
end Behavioral;
Design File:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Sequence is
Generic(width: integer;
sequence: std_logic_vector);
Port (din, CLK, rst: in std_logic;
dout: out std_logic;
temp: buffer std_logic_vector(0 to width-1));
end Sequence;
architecture Beh of Sequence is
subtype statetype is integer range 0 to width-1;
signal prstate,nxstate: statetype := 0;
begin
process(RST,CLK)
begin
if RST='1' then
temp <= (others => '0');
nxstate <= 0;
elsif CLK'event and CLK='1' then
temp(prstate) <= din;
for k in prstate downto 0 loop
if temp(k downto 0) = sequence(k downto 0) then
nxstate <= k;
exit;
else temp <= temp(1 to width-1) & '0';
end if;
end loop;
end if;
prstate <= nxstate;
end process;
dout <= '1' when prstate = width-1 and din = sequence(sequence'left) else '0';
end Beh;

Resources