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).
Related
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;
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
I have a 4x3 keypad, i wrote this FSM for interfacing it with my Nexys2 board, trouble I am having here is
When I run the code, the LEDs glow without any key pressed, it shows random combinations automatically
When I press a key it shows that particular combination then goes on to the next condition of ROW without any key pressed. And sometimes it does not even respond if i press a key.
What is happening? What is wrong with this code? I am clueless. Can someone point out the mistakes and suggest some solution? Here is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity keypad_3x4 is
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
ROW : in STD_LOGIC_VECTOR (3 downto 0);
COL : out STD_LOGIC_VECTOR (2 downto 0);
LED : out STD_LOGIC_VECTOR (3 downto 0)
);
end keypad_3x4;
architecture Behavioral of keypad_3x4 is
architecture Behavioral of keypad_3x4 is
TYPE STATE_TYPE is
( RESET_ST,
S1,
S2,
S3,
S4,
S5,
S6
);
signal state: STATE_TYPE;
begin
process (CLK, RESET)
begin
if (RESET = '1') then
state <= RESET_ST;
elsif (CLK'event and CLK = '1') then
case (state) is
WHEN RESET_ST =>
LED <= (others => '0');
COL <= (others => '0');
state <= S1;
WHEN S1 =>
COL <= "001"; --C1 selected
LED <= (others => '0');
state <= S2;
WHEN S2 =>
if ROW <= "0001" then
led <= "0001"; --1
elsif ROW <= "0010" then
led <= "0100"; --4
elsif ROW <= "0100" then
led <= "0111"; --7
elsif ROW <= "1000" then
led <= "1111"; --*
else
LED <= (others => '0');
state <= S3;
end if;
WHEN S3 =>
COL <= "010"; --C2 selected
LED <= (others => '0');
state <= S4;
WHEN S4 =>
if ROW <= "0001" then
led <= "0010"; --2
elsif ROW <= "0010" then
led <= "0101"; --5
elsif ROW <= "0100" then
led <= "1000"; --8
elsif ROW <= "1000" then
led <= "0000"; --0
else
LED <= (others => '0');
state <= S5;
end if;
WHEN S5 =>
COL <= "100"; --C3 selected
LED <= (others => '0');
state <= S6;
WHEN S6 =>
if ROW <= "0001" then
led <= "0011"; --3
elsif ROW <= "0010" then
led <= "0110"; --6
elsif ROW <= "0100" then
led <= "1001"; --9
elsif ROW <= "1000" then
led <= "1111"; --#
else
LED <= (others => '0');
state <= RESET_ST;
end if;
WHEN others =>
state <= RESET_ST;
END case;
END if;
END process;
end Behavioral;
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
I am a beginner so please excuse my code logic. I am trying to diplay 20 values on a 7 segment through a counter. When the value is greater than 9 the second segment is selected. When I run this code my first segment flickers very fast and the second one goes off. I know I have done some mistake with the case where i have assigned values to the segment. What am i missing here? My prescaled value is 48Hz. any ideas?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity counter is
Port ( clk : in STD_LOGIC;
segment : out STD_LOGIC_VECTOR (6 downto 0);
anode: out std_logic_vector (3 downto 0) );
end counter;
architecture Behavioral of counter is
constant prescaler: STD_LOGIC_VECTOR(16 downto 0) := "00000000000110000";
signal prescaler_counter: STD_LOGIC_VECTOR(16 downto 0) := (others => '0');
signal counter: std_logic_vector (19 downto 0):= (others => '0');
signal r_anode: std_logic_vector (3 downto 0):= (others => '0');
begin
process (clk) begin
if (clk'event and clk = '1') then
prescaler_counter <= std_logic_vector (unsigned(prescaler_counter) + 1);
if(prescaler_counter = prescaler) then
counter <= std_logic_vector (unsigned(counter)+1);
end if;
end if;
end process;
anode <= r_anode;
process (counter) begin
if (counter > "00000000000000001001") then
r_anode <= "1110";
else
r_anode <= "1101";
end if;
case counter is
when "00000000000000000000" => segment <= "0000001"; --0
when "00000000000000000001" => segment <= "1001111"; --1
when "00000000000000000010" => segment <= "0010010"; --2
when "00000000000000000011" => segment <= "0000110"; --3
when "00000000000000000100" => segment <= "1001100"; --4
when "00000000000000000101" => segment <= "0100100"; --5
when "00000000000000000110" => segment <= "0100000"; --6
when "00000000000000000111" => segment <= "0001111"; --7
when "00000000000000001000" => segment <= "0000000"; --8
when "00000000000000001001" => segment <= "0000100"; --9
when others => segment <= "1111111";
end case;
end process;
end Behavioral;
48Hz still seems pretty fast to cycle through 10 values for a digit, but if that's what you want... (if you slowed it down, the problem might become more obvious, by the way)
The problem is a combination of your count process, how you're setting r_anode, and your case statement to determine the value of segment, possibly among other things.
Your count process goes from 1 to, well, a lot, and you only want to go to 20, as I understand it. You may want to consider adding a wraparound condition. That depends on how you do the following, though.
r_anode is "1110" for 10 clocks and then "1101" for the rest of the 2^20 cycles. I don't think this is what you want. By the way, with numeric_std, you can just write unsigned(counter) > 9 - I'm not sure what you have written should even compile (you were using std_logic_unsigned before, I gather?).
This is the main problem. You seem to want the values for both of your digits to depend on this one counter, but you are comparing the entire 20-bit counter value, so segments are only active for 10 clocks out of 2^20, and only on for the first digit, since you're explicitly checking only values 0 through 9. What you need is some sort of a modulus operation (or separate counters for each digit, or something).
You may also need to think about how you are driving the two displays, but that depends on how you fix the other issues.
I was in the middle of getting this ready to display when fru1bat answered. It may provide illumination:
Note I used a 10 ns clock for sake of expediency.
The first digit goes through it's counts (seen on segment) then switches to the other digit, who's segments show the others choice):
process (counter)
begin
if (counter > "00000000000000001001") then
r_anode <= "1110";
else
r_anode <= "1101";
end if;
case counter is
when "00000000000000000000" => segment <= "0000001"; --0
when "00000000000000000001" => segment <= "1001111"; --1
when "00000000000000000010" => segment <= "0010010"; --2
when "00000000000000000011" => segment <= "0000110"; --3
when "00000000000000000100" => segment <= "1001100"; --4
when "00000000000000000101" => segment <= "0100100"; --5
when "00000000000000000110" => segment <= "0100000"; --6
when "00000000000000000111" => segment <= "0001111"; --7
when "00000000000000001000" => segment <= "0000000"; --8
when "00000000000000001001" => segment <= "0000100"; --9
when others => segment <= "1111111";
end case;
end process;
From that we can imagine you'll see every segment in the 'fast' digit flicker, followed by a long interval waiting for counter to roll over, then flicker again.
Both the prescaler counter and counter seem too long.
You want to switch through enabled anodes, meaning the switch should be between one digit and the other. That should be a bit faster than 48 Hz more than likely. (LCD or LED?).
You want the counter that drives segment to be much slower. Start out with 48 Hz to switch anode values between the two display digits using counter's LSB. Use bits from toward the other end of counter to drive the seven segement conversion. You want the digits to change slow enough to see. Also note that because counter isn't a BCD counter (now there's an idea), there will be blank displayed times for any four bits when those are greater than 9 as an aggregate.
You could always drive 0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F (by modifying your case statement). This will allow you to pick a prescaler value that gives you minimum flicker.
I don't recommend simply simulating your design, I did it to make the same points fru1bat covered. I wanted the picture. I stopped it about 1/10th of the way through (was going to run for 2 seconds, got 186 MB of clock transitions as it is).
I posted this code and I figured out my errors thanks to #fru1bat and #David. Yes I was using a 20 bit counter which was really dumb of me so i used a 5 bit counter and slowed my clock with this delay code.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity delay is
Port ( clk : in STD_LOGIC;
a : in STD_LOGIC_VECTOR (31 downto 0);
flag : out STD_LOGIC);
end delay;
architecture Behavioral of delay is
signal count :integer:=0;
begin
process(clk) begin
if(clk'event and clk='1') then
count <= count +1; --increment counter.
end if;
--see whether counter value is reached,if yes set the flag.
if(count = to_integer (unsigned(a))) then
count <= 0;
flag <='1';
else
flag <='0';
end if;
end process;
end Behavioral
And then I used this code in my 7 segment code, which for now turns on only one segment, it starts form 0 and goes till 9, after reaching 9 the counter resets. Now my question is how should I display two digits? Should I use the double dabble algorithm here? Or what? My basic issue of flickering is gone now I need to turn on the second segment to display two digits using this same code. How should i modify my code? Any ideas? Here is my final one digit code!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity counter is
Port ( clk : in STD_LOGIC;
segment : out STD_LOGIC_VECTOR (6 downto 0);
anode: out std_logic_vector (3 downto 0) );
end counter;
architecture Behavioral of counter is
component delay
Port ( clk : in STD_LOGIC;
a : in STD_LOGIC_VECTOR (31 downto 0);
flag : out STD_LOGIC);
end component;
signal flag : std_logic :='0';
signal delay_needed : std_logic_vector(31 downto 0);
constant countvalue: STD_LOGIC_VECTOR (4 downto 0) := "01001";
signal counter: std_logic_vector (4 downto 0):= (others => '0');
signal r_anode: std_logic_vector (3 downto 0):= (others => '0');
begin
delay_needed <= "00000001011111010111100001000000"; --25000000 in binary
inst_delay : delay port map(clk,delay_needed,flag);
process (flag) begin
if (flag'event and flag = '1') then
counter <= std_logic_vector (unsigned(counter)+1);
if (counter = countvalue) then
counter <= (others => '0');
end if;
end if;
end process;
anode <= r_anode;
r_anode <= "1110";
process (counter, r_anode) begin
case r_anode is
when "1110" => case counter is
when "00000" => segment <= "0000001"; --0
when "00001" => segment <= "1001111"; --1
when "00010" => segment <= "0010010"; --2
when "00011" => segment <= "0000110"; --3
when "00100" => segment <= "1001100"; --4
when "00101" => segment <= "0100100"; --5
when "00110" => segment <= "0100000"; --6
when "00111" => segment <= "0001111"; --7
when "01000" => segment <= "0000000"; --8
when "01001" => segment <= "0000100"; --9
when others => segment <= "1111111";
end case;
when others => segment <= "1111111";
end case;
end process;
end Behavioral;