How can I test bench a VHDL 24 hour Clock? - vhdl

I'm having a bit of problem when trying to test bench my VHDL.
I'm using a fpga Baysis 2 to run my code, and it is working pretty well on the hardware, but when I use the program Isim to simulate my code, it doesn't show any behavior for my out pins, only the letter U.
I'm looking through the internet and couldn't find a solution, can someone help me on this one?
Here follows the last part of my code (probably the one with the something wrong). Before that the code simply had a process to divide the clock to measure 1 second another to divide in 1/200 of a second to quickly turn on and off the led's on the fpga's display, and counted the seconds to make the 24 hour clock work, of course.
contador: process(clk200)
variable flag : std_logic_vector (1 downto 0);
-- ledplex is the mux that controls which display should be on
-- Segm is the 7 segments display
-- mu md hu hd are the signals with the time information
begin
if(clk200'event and clk200='1') then
if (flag = "00") then
ledplex <= "1110";
case mu is
when 0 => segm <= "1000000";
when 1 => segm <= "1111001";
when 2 => segm <= "0100100";
when 3 => segm <= "0110000";
when 4 => segm <= "0011001";
when 5 => segm <= "0010010";
when 6 => segm <= "0000011";
when 7 => segm <= "1111000";
when 8 => segm <= "0000000";
when 9 => segm <= "0011000";
when others => segm <= "1111111";
end case;
flag := "01";
elsif (flag = "01") then
ledplex <= "1101";
case md is
when 0 => segm <= "1000000";
when 1 => segm <= "1111001";
when 2 => segm <= "0100100";
when 3 => segm <= "0110000";
when 4 => segm <= "0011001";
when 5 => segm <= "0010010";
when others => segm <= "1111111";
end case;
flag := "10";
elsif (flag = "10") then
ledplex <= "1011";
case hu is
when 0 => segm <= "1000000";
when 1 => segm <= "1111001";
when 2 => segm <= "0100100";
when 3 => segm <= "0110000";
when 4 => segm <= "0011001";
when 5 => segm <= "0010010";
when 6 => segm <= "0000011";
when 7 => segm <= "1111000";
when 8 => segm <= "0000000";
when 9 => segm <= "0011000";
when others => segm <= "1111111";
end case;
flag := "11";
elsif (flag = "11") then
ledplex <= "0111";
case hd is
when 0 => segm <= "1000000";
when 1 => segm <= "1111001";
when 2 => segm <= "0100100";
when others => segm <= "1111111";
end case;
flag := "00";
end if;
end if;
end process contador;
and here follows the test bench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY t_b IS
END t_b;
ARCHITECTURE behavior OF t_b IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT hora
PORT(
clk25m : IN std_logic;
segm : OUT std_logic_vector(6 downto 0);
ledplex : OUT std_logic_vector(3 downto 0);
x : out std_logic
);
END COMPONENT;
signal clk_tb : std_logic := '0';
signal segm_tb : std_logic_vector(6 downto 0);
signal ledplex_tb : std_logic_vector(3 downto 0);
signal x_tb : std_logic;
BEGIN
CUT: hora port map( clk25m => clk_tb,
segm => segm_tb,
ledplex => ledplex_tb,
x => x_tb);
Test_Vector: process
begin
clk_tb <= '1';
wait for 40 ns;
clk_tb <= '0';
wait for 40 ns;
end process;
END behavior;

You did not initialize your variable flag. Without this your variable may be undefined, hence U. Use the following:
variable flag : std_logic_vector (1 downto 0) := "00"; -- initialize variable

Related

VHDL Code For Numbers 0000 to 0099 on 7-Segment Display

I'm a beginner to VHDL, trying to write a code that counts from 0000 to 0099 on my board (BASYS-3) depending on which switches I press. Problem is, I need one switch for shutting the program on and off, 4 switches for showing the far right decimal digit and 4 other for showing the "tens" (like the 1 in 17).
There are more switches on the board (in total 16) but I thought 4 is most logical because of the binary codings of decimals (like 9 = 1001 in binary is the largest).
I have no idea on what gates to use so the work I've done is very limited, sorry about that.
process(bcd_display)
begin
case bcd_display is
when "0000" => LED <= "0000001";
when "0001" => LED <= "1001111";
when "0010" => LED <= "0010010";
when "0011" => LED <= "0000110";
when "0100" => LED <= "1001100";
when "0101" => LED <= "0100100";
when "0110" => LED <= "0100000";
when "0111" => LED <= "0001111";
when "1000" => LED <= "0000000";
when "1001" => LED <= "0000100";
end case;
end process;
PS: https://www.youtube.com/watch?v=H7a56D4rczU
The last 30 seconds or so shows what I'm trying to do. English is not my first language so I'm putting this in case my description was hard to understand.
For future reference, you are going to want to add full code & the testbench you are using. I still wrote out what I think will work for you.
For below. You will want to assign each switch to (bcd_display_0 & bcd_display_1). For resetting the program, assign that switch to (rst) and you will need to assign a clock to (clk). Then assign each the seven segment displays to (LED_0 & LED_1). Hopefully this gets you going. I have also attached a test bench for you.
-- BCD Entity
library ieee;
use ieee.std_logic_1164.all;
entity Display_Test is
port (
clk : in std_logic;
rst : in std_logic;
bcd_display_0 : in std_logic_vector(3 downto 0);-- assign to first set of switches
bcd_display_1 : in std_logic_vector(3 downto 0);-- assign to second set of switches
LED_0 : out std_logic_vector(6 downto 0);-- assign to first 7-segment display
LED_1 : out std_logic_vector(6 downto 0) -- assign to second 7-segment display
);
end Display_Test;
architecture behav of Display_Test is
use ieee.numeric_std.all;
begin
p : process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
LED_0 <= (others => '0');
LED_1 <= (others => '0');
else
case to_integer(unsigned(bcd_display_0)) is
when 0 => LED_0 <= "0000001";
when 1 => LED_0 <= "1001111";
when 2 => LED_0 <= "0010010";
when 3 => LED_0 <= "0000110";
when 4 => LED_0 <= "1001100";
when 5 => LED_0 <= "0100100";
when 6 => LED_0 <= "0100000";
when 7 => LED_0 <= "0001111";
when 8 => LED_0 <= "0000000";
when 9 => LED_0 <= "0000100";
when others => LED_0 <= "0000000";
end case;
case to_integer(unsigned(bcd_display_1)) is
when 0 => LED_1 <= "0000001";
when 1 => LED_1 <= "1001111";
when 2 => LED_1 <= "0010010";
when 3 => LED_1 <= "0000110";
when 4 => LED_1 <= "1001100";
when 5 => LED_1 <= "0100100";
when 6 => LED_1 <= "0100000";
when 7 => LED_1 <= "0001111";
when 8 => LED_1 <= "0000000";
when 9 => LED_1 <= "0000100";
when others => LED_1 <= "0000000";
end case;
end if;
end if;
end process;
end behav;
--TestBench
entity tb_bcd is
end tb_bcd;
library ieee;
use ieee.std_logic_1164.all;
architecture behav of tb_bcd is
signal clk : std_logic := '1';
signal rst : std_logic := '1';
signal bcd_display_0 : std_logic_vector(3 downto 0);
signal bcd_display_1 : std_logic_vector(3 downto 0);
signal LED_0 : std_logic_vector(6 downto 0);
signal LED_1 : std_logic_vector(6 downto 0);
begin
clk <= not clk after 50 ns;
rst <= '0' after 200 ns;
bcd_display_0 <= "0110" after 250 ns;
bcd_display_1 <= "0010" after 280 ns;
Display_Test_inst : entity work.Display_Test
port map (
clk => clk,
rst => rst,
bcd_display_0 => bcd_display_0,
bcd_display_1 => bcd_display_1,
LED_0 => LED_0,
LED_1 => LED_1
);
end behav;

Problem with CLK in implementing counter in VHDL

I am trying to implement counter which gives as output values from one to six, which I want to later put on 7 segment display on fpga. The problem is with CLK, process doesn't see value of CLK changing and simulation gives as output always set of values "1001111".
library ieee;
use ieee.std_logic_1164.all;
entity projekt is
generic ( half_period : time := 10ms);
port(Q : out std_logic_vector(6 downto 0));
end projekt;
architecture a1 of projekt is
signal CLK : std_logic := '0';
begin
CLK <= not CLK after half_period;
process(CLK)
variable tmpQ : integer range 0 to 7 := 1;
begin
if ( CLK = '1' and CLK'event ) then
tmpQ := tmpQ + 1;
if tmpQ = 7 then
tmpQ := 1;
end if;
end if;
case tmpQ is
when 1 => Q <= "1001111";
when 2 => Q <= "0010010";
when 3 => Q <= "0000110";
when 4 => Q <= "1001100";
when 5 => Q <= "0100100";
when 6 => Q <= "0100000";
when others => Q <= "1111111";
end case;
end process;
end a1;
Is it CLK not changing or program never enters if statement?

Can't assign value to integer signal in VHDL

I am using a programmable-logic to decode a sequence of long or short impulses into latin letters according to morse code. I am using VHDL to describe our design, to be precise I'm using Quartus Prime for the design and ModelSim for the simulations. My CPLD is an ALTERA MAX-V 5M160ZE64C5.
Here is my code :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all ;
use ieee.std_logic_arith.all;
entity SauvezLesMorses is
port
(
-- Input ports
clk : in std_logic;
message : in std_logic;
display : in std_logic;
start : in std_logic;
-- Output ports
seg14 : out std_logic_vector (13 downto 0);
lengthLED : out std_logic := '0'
);
end entity SauvezLesMorses;
architecture SauvezLesMorses_arch of SauvezLesMorses is
type state_t is (A, B, C);
signal state : state_t;
signal count : integer range 0 to 4 := 0;
signal clk_cnt : integer range 0 to 21 := 0;
signal morse : std_logic_vector (3 downto 0);
begin
process (clk, start)
variable vectorDummy : std_logic_vector (3 downto 0);
begin
if (start = '1') then
state <= A;
count <= 0;
seg14 <= "00000010001000";
morse <= "0000";
lengthLED <= '0';
elsif (rising_edge(clk)) then
case state is
-- Idle, listening
when A =>
if (display = '0') then
if (message = '1' and count < 4) then
state <= B;
seg14 <= "00000010001000";
count <= count;
morse <= morse;
lengthLED <= '0';
clk_cnt <= 0;
else
state <= A;
seg14 <= "00000010001000";
count <= count;
morse <= morse;
lengthLED <= '0';
end if;
else
state <= C;
count <= count;
morse <= morse;
lengthLED <= '0';
seg14 <= "00000010001000";
end if;
-- Measuring impulse length
when B =>
if (display = '0') then
if (message = '1') then
state <= B;
count <= count;
morse <= morse;
seg14 <= "00000010001000";
if (clk_cnt < 20) then
clk_cnt <= (1 + clk_cnt);
lengthLED <= '0';
else
clk_cnt <= 21;
lengthLED <= '1';
end if;
else
state <= A;
if (clk_cnt < 21) then
morse <= morse;
else
case count is
when 0 => vectorDummy := "1000";
when 1 => vectorDummy := "0100";
when 2 => vectorDummy := "0010";
when 3 => vectorDummy := "0001";
when others => vectorDummy := "0000";
end case;
morse <= morse or vectorDummy;
end if;
count <= count + 1;
lengthLED <= '0';
seg14 <= "00000010001000";
end if;
else
state <= C;
count <= count;
morse <= morse;
lengthLED <= '0';
seg14 <= "00000010001000";
end if;
-- Displaying converted character to user
when C =>
if (display = '0') then
state <= A;
count <= 0;
seg14 <= "00000010001000";
lengthLED <= '0';
morse <= "0000";
else
state <= C;
count <= count;
morse <= morse;
lengthLED <= '0';
if(count = 1) then
case morse is
when "0000" => seg14 <= "10011110001000"; --E
when "1000" => seg14 <= "10000000100010"; --T
when others => seg14 <= "11111111111111"; --unknown character
end case;
elsif(count = 2) then
case morse is
when "0100" => seg14 <= "11101110001000"; --A
when "1000" => seg14 <= "01101101000100"; --N
when "1100" => seg14 <= "01101101010000"; --M
when "0000" => seg14 <= "00000000100010"; --I
when others => seg14 <= "11111111111111"; --unknown character
end case;
elsif(count = 3) then
case morse is
when "0000" => seg14 <= "10110110001000"; --S
when "0010" => seg14 <= "01111100000000"; --U
when "0100" => seg14 <= "11001110001100"; --R
when "0110" => seg14 <= "01101100000101"; --W
when "1000" => seg14 <= "11110000100010"; --D
when "1010" => seg14 <= "00001110010100"; --K
when "1100" => seg14 <= "10111100001000"; --G
when "1110" => seg14 <= "11111100000000"; --O
when others => seg14 <= "11111111111111"; --unknown character
end case;
elsif(count = 4) then
case morse is
when "0000" => seg14 <= "01101110001000"; --H
when "0001" => seg14 <= "00001100010001"; --V
when "0010" => seg14 <= "10001110001000"; --F
when "0100" => seg14 <= "00011100000000"; --L
when "0110" => seg14 <= "11001110001000"; --P
when "0111" => seg14 <= "01111000000000"; --J
when "1000" => seg14 <= "11110000101010"; --B
when "1001" => seg14 <= "00000001010101"; --X
when "1010" => seg14 <= "10011100000000"; --C
when "1011" => seg14 <= "00000001010010"; --Y
when "1100" => seg14 <= "10010000010001"; --Z
when "1101" => seg14 <= "11111100000100"; --Q
when others => seg14 <= "11111111111111"; --unknown character
end case;
else
seg14 <= "11111111111111";
end if ;
end if;
end case;
end if;
end process;
end architecture SauvezLesMorses_arch ;
A modelsim simulation with parameters
force -freeze sim:/sauvezlesmorses/clk 1 0, 0 {25000000000 ps} -r {50 ms}
force -freeze sim:/sauvezlesmorses/display 0 0, 1 {9000000000000 ps} -r {18 sec}
force -freeze sim:/sauvezlesmorses/message 0 0, 1 {3200000000000 ps} -r {6.4 sec}
force -freeze sim:/sauvezlesmorses/start 1 0 -cancel {0.5 sec}
run 40 sec
which yields :
Modelsim Simulation
clearly shows that :
clk_cnt never increases but rather remains zero for 40 seconds
count is neither set to 0 by the activation of start nor from the desactivation of display (i.e. the transition of state from C to A).
Would you have any idea why?
P.S. I know that I am positively not running a proper testbench. So even if I should, please do not remind it to me unless you know it is part of the answer to my question.
A force updating a signal value doesn't generate an event.
See IEEE Std 1076-2008 14.7.3.4 Signal update, para 3
... If updating a signal causes the current value of that signal to change, then an event is said to have occurred on the signal, unless the update occurs by application of the vhpi_put_value function with an update mode of vhpiDeposit or vhpiForce to an object that represents the signal. ...
Likely the same mechanism used by Modelsim's force or FLI.
With a testbench:
library ieee;
use ieee.std_logic_1164.all;
entity slm_tb is
end entity;
architecture foo of slm_tb is
-- Input ports
signal clk: std_logic := '1';
signal message: std_logic := '0';
signal display: std_logic := '0';
signal start: std_logic := '1';
-- Output ports
signal seg14: std_logic_vector (13 downto 0);
signal lengthLED: std_logic;
begin
DUT:
entity work.sauvezlesmorses
port map (
clk => clk,
message => message,
display => display,
start => start,
seg14 => seg14,
lengthLED => lengthLED
);
-- force -freeze sim:/sauvezlesmorses/clk 1 0, 0 {25000000000 ps} -r {50 ms}
-- force -freeze sim:/sauvezlesmorses/display 0 0, 1 {9000000000000 ps} -r {18 sec}
-- force -freeze sim:/sauvezlesmorses/message 0 0, 1 {3200000000000 ps} -r {6.4 sec}
-- force -freeze sim:/sauvezlesmorses/start 1 0 -cancel {0.5 sec}
-- run 40 sec
-- stimulus generators:
CLOCK:
process
begin
wait for 25 ms;
clk <= not clk;
if now > 40 sec then
wait;
end if;
end process;
DISP:
process
begin
wait for 9 sec;
display <= not display;
if now > 35 sec then -- stop simulation at 40 sec
wait;
end if;
end process;
MSG:
process
begin
wait for 3.2 sec;
message <= not message;
if now > 35 sec then
wait;
end if;
end process;
ST:
process
begin
wait for 0.5 sec;
start <= 'U';
wait;
end process;
end architecture;
You do get events:

VHDL code not running properly on Nexys2

This code selects either the leds or the 7 segment display to show it's 8-bit data that i feed in through the switches. I select the led or the 7 segment through a push button. When I try to run it on my nexys2 board the led part works fine but as i press the pushbutton the selected 7segment glows and changes its value with the led glowing as well. Also the 7 segment changes it's value only when i press the pushbuton again. I am a newbie and i think I am having trouble making a good logic or what is the issue? any help would be appreciated!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity selector is
Port ( clk: in STD_LOGIC;
sel : in STD_LOGIC;
comb : in STD_LOGIC_VECTOR (7 downto 0);
segment : out STD_LOGIC_VECTOR (3 downto 0);
number : out STD_LOGIC_VECTOR (6 downto 0);
led: out STD_LOGIC_VECTOR (7 downto 0));
end selector;
architecture Behavioral of selector is
begin
process (clk, comb, sel) begin
if (clk'event and clk = '1') then
if sel = '1' then
segment <= "1110";
case (comb) is
when "00000000" => number <= "0000001"; --0
when "00000001" => number <= "1001111"; --1
when "00000010" => number <= "0010010"; --2
when "00000011" => number <= "0000110"; --3
when "00000100" => number <= "1001100"; --4
when "00000101" => number <= "0100100"; --5
when "00000110" => number <= "0100000"; --6
when "00000111" => number <= "0001111"; --7
when "00001000" => number <= "0000000"; --8
when "00001001" => number <= "0000100"; --9
when others => number <= "1111111"; -- off
end case;
elsif sel = '0' then
case (comb) is
when "00000000" => led <= "00000000"; --0
when "00000001" => led <= "00000001"; --1
when "00000010" => led <= "00000011"; --2
when "00000011" => led <= "00000111"; --3
when "00000100" => led <= "00001111"; --4
when "00000101" => led <= "00011111"; --5
when "00000110" => led <= "00111111"; --6
when "00000111" => led <= "01111111"; --7
when "00001000" => led <= "11111111"; --8
when others => led <= "00000000"; -- off
end case;
end if;
end if;
end process;
end Behavioral;
You are not changing the value for the output that is not selected, so it remains in the state it has been assigned last.
Also, your code your code will only ever have an effect on the rising edge of the clock, so the sensitivity list can be reduced to (clk) (at which point, clk'event is implied).

How to resolve this coding error

Here is my code for writing two decimal numbers on 7 segment. I have used AN0 and AN1. I am getting this really weird error I don't know how to resolve it, is there any problem with my case structure? What does this error mean? any help would be appreciated
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity twosegments is
Port ( clk : in STD_LOGIC;
dig0: in std_logic_vector (3 downto 0);
dig1: in STD_LOGIC_VECTOR (3 downto 0);
segment : out STD_LOGIC_VECTOR (6 downto 0);
anode : out STD_LOGIC_VECTOR (3 downto 0));
end twosegments;
architecture Behavioral of twosegments is
constant prescaler: STD_LOGIC_VECTOR(16 downto 0) := "00000000110010000";
signal prescaler_counter: STD_LOGIC_VECTOR(16 downto 0) := (others => '0');
signal sel: STD_LOGIC_VECTOR (1 downto 0);
signal r_anode: STD_LOGIC_VECTOR (3 downto 0);
begin
anode <= r_anode;
process (clk) begin
if (clk'event and clk = '1') then
prescaler_counter <= prescaler_counter + 1;
if(prescaler_counter = prescaler) then
sel <= sel+1;
prescaler_counter <= (others => '0');
end if;
end if;
end process;
process (sel, dig0,dig1) begin
case sel is
when "00" => r_anode <= "1110";
when "01" => r_anode <= "1101";
--when "10" => r_anode <= "1110";
--when "11" => r_anode <= "1101";
when others => r_anode <= "1111";
end case;
case r_anode is
when "1110" => case "dig0" is
when "0000" => segment <= "0000001"; --0
when "0001" => segment <= "1001111"; --1
when "0010" => segment <= "0010010"; --2
when "0011" => segment <= "0000110"; --3
when "0100" => segment <= "1001100"; --4
when "0101" => segment <= "0100100"; --5
when "0110" => segment <= "0100000"; --6
when "0111" => segment <= "0001111"; --7
when "1000" => segment <= "0000000"; --8
when "1001" => segment <= "0000100"; --9
when others => segment <= "1111111";
end case;
when "1101" => case "dig1" is
when "0000" => segment <= "0000001"; --0
when "0001" => segment <= "1001111"; --1
when "0010" => segment <= "0010010"; --2
when "0011" => segment <= "0000110"; --3
when "0100" => segment <= "1001100"; --4
when "0101" => segment <= "0100100"; --5
when "0110" => segment <= "0100000"; --6
when "0111" => segment <= "0001111"; --7
when "1000" => segment <= "0000000"; --8
when "1001" => segment <= "0000100"; --9
when others => segment <= "1111111"; --off
end case;
when others => segment <= "1111111";
end case;
end process;
end Behavioral;
This is the weird error
FATAL_ERROR:HDLParsers:vhpcstr.c:2040:$Id: vhpcstr.c,v 1.64 2008/12/03 00:28:13 sandeepd Exp $:200 - INTERNAL ERROR... while parsing "E:/Xilinx Projects/twosegs/twosegments.vhd" line 62. Contact your hot line. Process will terminate. For technical support on this issue, please open a WebCase with this project attached at http://www.xilinx.com/support.
There is a syntax error with quotes around dig0 and dig1 signal identifiers, so try to change case "dig0" is to case dig0 is, and case "dig1" is to case dig1 is.
But anyway, the Xilinx parser is not robust enough since it crashes, so it is a good habit to create a WebCase for issues like this, so Xilinx can improve in the future.
I would follow the error message directions. Specifically:
For technical support on this issue, please open a WebCase with this
project attached at http://www.xilinx.com/support

Resources