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;
Related
I am currently trying to implement a state machine with 5 different states. Basically, I want to stay in one state, wait for some time, move on to the next state, wait for a different amount of time, get into the next state etc....
For now I implemented a counter which generates a 1s signal from a 1ms signal that I create in the testbench. I created one process that determines the next state and one that upgrades the current state from the next state. The signal which does not behave as I expected is: next_stateHS which should upgrade stateHS. The code in question is in the process called "hsNextState". What I also can't explain is that the signal "startCounter" behaves as expected. This signal receives a new value in the same else - case as the signal "next_StateHS"
I will now add the code for the state machine and the test bench and a picture of the simulated waveform.
State machine:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity ampel is
port
(
clk : in std_ulogic;
reset : in std_ulogic;
enable : in std_ulogic;
haupt : out std_ulogic_vector(2 downto 0);
neben : out std_ulogic_vector(2 downto 0)
);
end ampel;
architecture ampel_behave of ampel is
--Codierung
-- idle = 000
-- gruen = 001
-- gelb = 010
-- rot = 011
-- rot_gelb = 100
signal stateHS, stateNS : std_ulogic_vector(2 downto 0) := (others => '0');
signal next_stateHS, next_stateNS : std_ulogic_vector(2 downto 0) := (others => '0');
signal startCounter : std_ulogic := '0';
signal counter : unsigned(9 downto 0) := (others => '0'); --für clk = 1ms im Testbench
signal count_seconds : unsigned(3 downto 0) := (others => '0');
begin
counterProcess : process(clk, reset, enable, startCounter)
begin
if enable = '0' or reset = '1' or startCounter = '0' then
counter <= (others => '0');
count_seconds <= (others => '0');
elsif rising_edge(clk) then
if counter < "1111101000" then
counter <= counter + 1;
else
counter <= (others => '0');
count_seconds <= count_seconds + 1;
end if;
end if;
end process counterProcess;
outputProcessHS : process(stateHS, reset, enable)
begin
if enable = '0' or reset = '1' then
haupt <= "000";
else
case (stateHS) is
when "000" =>
haupt <= "000";
when "001" =>
haupt <= "001";
when "010" =>
haupt <= "010";
when "011" =>
haupt <= "011";
when "100" =>
haupt <= "100";
when others =>
haupt <= "000";
end case;
end if;
end process outputProcessHS;
outputProcessNS : process(stateNS, reset, enable)
begin
if enable = '0' or reset = '1' then
neben <= "000";
else
case (stateNS) is
when "000" =>
neben <= "000";
when "001" =>
neben <= "001";
when "010" =>
neben <= "010";
when "011" =>
neben <= "011";
when "100" =>
neben <= "100";
when others =>
neben <= "000";
end case;
end if;
end process outputProcessNS;
hsNextState : process(reset, enable, stateHS, count_seconds)
begin
if enable = '0' or reset = '1' then
next_stateHS <= "000";
else
case (stateHS) is
when "000" =>
next_stateHS <= "001";
startCounter <= '1';
when "001" =>
if count_seconds < "1110" then
next_stateHS <= "001";
else
next_stateHS <= "010";
startCounter <= '0';
end if;
when "010" =>
next_stateHS <= "011";
when "011" =>
next_stateHS <= "100";
when "100" =>
next_stateHS <= "001";
when others =>
next_stateHS <= "000";
end case;
end if;
end process hsNextState;
hsState : process(reset, enable, next_stateHS, count_seconds)
begin
if enable = '0' or reset = '1' then
stateHS <= "000";
else
stateHS <= next_stateHS;
end if;
end process hsState;
-- nsStateProcess : process(reset, enable, stateNS, count_seconds)
-- begin
-- if enable = '0' or reset = '1' then
-- next_stateNS <= idle;
-- else
-- case (stateNS) is
-- when idle =>
-- next_stateNS <= gruen;
-- when gruen =>
-- next_stateNS <= gelb;
-- when gelb =>
-- next_stateNS <= rot;
-- when rot =>
-- next_stateNS <= rot_gelb;
-- when rot_gelb =>
-- next_stateNS <= gruen;
-- when others =>
-- next_stateNS <= idle;
-- end case;
-- end if;
-- stateNS <= next_stateNS;
-- end process nsStateProcess;
end ampel_behave;
Test Bench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity ampel_tb is
end ampel_tb;
architecture test of ampel_tb is
component ampel
port
(
clk : in std_ulogic;
reset : in std_ulogic;
enable : in std_ulogic;
haupt : out std_ulogic_vector(2 downto 0);
neben : out std_ulogic_vector(2 downto 0)
);
end component;
signal clk : std_ulogic := '0';
signal reset : std_ulogic := '0';
signal enable : std_ulogic := '1';
signal haupt, neben : std_ulogic_vector(2 downto 0);
signal count_cycles : unsigned (19 downto 0) := (others => '0');
begin
ampel_1 : ampel port map
(
clk => clk,
reset => reset,
enable => enable,
haupt => haupt,
neben => neben
);
clock_signal : process
begin
if count_cycles < "0011100000000000000" then
clk <= '0';
wait for 500 us;
clk <= '1';
wait for 500 us;
count_cycles <= count_cycles + 1;
else
wait;
end if;
end process clock_signal;
end test;
I'm trying to follow an example on my VHDL book. Its name is FPGA Prototyping by VHDL Examples, Pong Chu. It has a Divider Circuit example in Chapter 6, Listing 5. I understood the general idea of a division operation. To verify the module I wrote a testbench and I saw that it doesn't work properly. If anyone could explain to me where the problem is, I would be very appreciated.
Here are the codes of module and testbench.
Module:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Divider is
generic(W: integer := 8;
CBIT: integer := 4 );
Port ( clk, reset : in STD_LOGIC;
start : in STD_LOGIC;
dvsr, dvnd : in STD_LOGIC_VECTOR (W-1 downto 0);
ready, done_tick : out STD_LOGIC;
quo, rmd : out STD_LOGIC_VECTOR (W-1 downto 0));
end Divider;
architecture Behavioral of Divider is
type state_type is (idle, op, last, done);
signal state_reg, state_next: state_type;
signal rh_reg, rh_next: UNSIGNED(W-1 downto 0) := (others => '0');
signal rl_reg, rl_next: STD_LOGIC_VECTOR(W-1 downto 0) := (others => '0');
signal rh_temp: UNSIGNED(W-1 downto 0) := (others => '0');
signal d_reg, d_next: UNSIGNED(W-1 downto 0) := (others => '0');
signal n_reg, n_next: UNSIGNED(CBIT-1 downto 0) := (others => '0');
signal q_bit: STD_LOGIC;
begin
-- FSMD State and Data Registers
process(clk, reset)
begin
if reset = '1' then
state_reg <= idle;
rh_reg <= (others => '0');
rl_reg <= (others => '0');
d_reg <= (others => '0');
n_reg <= (others => '0');
elsif rising_edge(clk) then
state_reg <= state_next;
rh_reg <= rh_next;
rl_reg <= rl_next;
d_reg <= d_next;
n_reg <= n_next;
end if;
end process;
-- FSMD Next-State Logic and Data Path Logic
process(state_reg, n_reg, rh_reg, rl_reg, d_reg, start, dvsr, dvnd, q_bit, rh_temp, n_next)
begin
ready <= '0';
done_tick <= '0';
state_next <= state_reg;
rh_next <= rh_reg;
rl_next <= rl_reg;
d_next <= d_reg;
n_next <= n_reg;
case state_reg is
when idle =>
ready <= '1';
if start = '1' then
rh_next <= (others => '0');
rl_next <= dvnd; -- Dividend
d_next <= UNSIGNED(dvsr); -- Divisor
n_next <= TO_UNSIGNED(W+1, CBIT); -- Index
state_next <= op;
end if;
when op =>
--Shift rh and rl left
rl_next <= rl_reg(W-2 downto 0) & q_bit;
rh_next <= rh_temp(W-2 downto 0) & rl_reg(W-1);
--Decrease index
n_next <= n_reg - 1;
if(n_next = 1) then
state_next <= last;
end if;
when last =>
rl_next <= rl_reg(W-2 downto 0) & q_bit;
rh_next <= rh_temp;
state_next <= done;
when done =>
state_next <= idle;
done_tick <= '1';
end case;
end process;
-- Compare and Subtract
process(rh_reg, d_reg)
begin
if rh_reg <= d_reg then
rh_temp <= rh_Reg - d_reg;
q_bit <= '1';
else
rh_temp <= rh_reg;
q_bit <= '0';
end if;
end process;
-- Output
quo <= rl_reg;
rmd <= STD_LOGIC_VECTOR(rh_reg);
end Behavioral;
Testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_Divider is
-- Port ( );
end tb_Divider;
architecture Behavioral of tb_Divider is
signal clk, reset, start, ready, done: STD_LOGIC;
signal dvsr, dvnd: STD_LOGIC_VECTOR(7 downto 0);
signal quo, rmd: STD_LOGIC_VECTOR(7 downto 0);
component Divider is
port( clk, reset : in STD_LOGIC;
start : in STD_LOGIC;
dvsr, dvnd : in STD_LOGIC_VECTOR (7 downto 0);
ready, done_tick : out STD_LOGIC;
quo, rmd : out STD_LOGIC_VECTOR (7 downto 0));
end component Divider;
begin
UUT: Divider port map( clk => clk, reset => reset, start => start, dvsr => dvsr, dvnd => dvnd,
ready => ready, done_tick => done, quo => quo, rmd => rmd);
process
begin
clk <= '0';
wait for 10 ns;
clk <= '1';
wait for 10 ns;
end process;
process
begin
start <= '0';
dvnd <= x"00";
dvsr <= x"00";
wait for 100 ns;
start <= '1';
dvnd <= x"C8";
dvsr <= x"0A";
wait for 10 us;
end process;
end Behavioral;
Result of Testbench:
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
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).
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