smiley face of counter with d_flip flop - vhdl

I'm trying to write a code with VHDL for smiley face counter, with flip flop
but i got some errors that about "width mismatch" and i dont know exactly what's a problem.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Smiley_Faces is
Port ( Clk, Reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (3 downto 0));
end Smiley_Faces;
architecture Behavioral of Smiley_Faces is
signal NS, PS:std_logic_vector(5 downto 0):= (others => '0');
begin
--- Memory Component
D_ff:process(reset,clk)
begin
if(reset='1') then
ps <= "0000";
elsif(rising_edge(clk)) then
ps<=nS;
end if;
end process;
-- Combination Logic
NS <= "010000" when ps="000000" else
"000110" when ps="010000" else
"010110" when ps="000110" else
"001111" when ps="010110" else
"011111" when ps="001111" else
"101111" when ps="011111" else
"111111" when ps="101111" else
"000000" when ps="111111" else
"000000";
Q <= PS;
end Behavioral;
The pic attached about state machine of smiley face

Multiple things
You set PS with a bit width of 6 but your reset statement is only assigning it with 4 bits
if(reset='1') then
ps <= "0000";`
You are assigning Q with the value of PS, but they are not the same bit widths. Either you need to update Q to be 6 bits or edit the code to be:
Q <= PS(3 downto 0);

Related

Why is my debouncing/counter not working in VHDL?

i am currently trying to display a counter state on a 7-Segment.
If i push a button (physically) it should increase this counter state.
But in my case its displaying a random number, i think its a wrong debouncing/counter method.
I searched the web but i can´t fix this behaviour.
I would be very thankful if someone could help me!
EDIT: The 7-Segment-Display is working well i did a test with all numbers (0-9)
So it is definetly failing in my debounce or counter method.
//debouncer.vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
entity Debounce is
Port ( CLK100MHZ : in STD_LOGIC;
BTNU : in STD_LOGIC;
BTNU_I : out STD_LOGIC);
end Debounce;
architecture Behavioral of Debounce is
signal keydeb : std_logic := '0';
signal debcnt : integer range 0 to 63 := 0;
begin
process begin
wait until rising_edge(CLK100MHZ);
-- XOR
if (BTNU=keydeb) then debcnt <= 0;
else debcnt <= debcnt+1;
end if;
-- Latch
if (debcnt=63) then keydeb <= BTNU;
end if;
end process;
BTNU_I <= keydeb;
end Behavioral;
//main.vhdl
//declared ports
Port (
BTNU: in std_logic; //button
CPU_RESETN: in std_logic;
CLK100MHZ: in std_logic;
);
//declared signals
signal Qint10m: std_logic_vector(3 downto 0); //number which holds the number to display
signal BTNU_I: std_logic; //button debounced
signal testC: integer range 9 downto 0; //counter
BTNU_debounce: entity Work.Debounce port map(
CLK100MHZ => CLK100MHZ,
BTNU => BTNU,
BTNU_I => BTNU_I);
bcd_counttest: process(CPU_RESETN, CLK100MHZ, BTNU_I)
begin
if(CPU_RESETN='0') then
testC <= 0;
elsif( CLK100MHZ'event and CLK100MHZ = '1') then
if(BTNU_I = '1') then
if(testC = 8) then
testC <= 0;
else
testC <= testC+1 ;
end if;
end if;
end if;
end process bcd_counttest;
Qint10m <= std_logic_vector(to_unsigned(testC, Qint10m'length));
I did not check your code very well, but noticed a de-bounce counter of 63 on a 100MHz clock. That is 630 ns.
A button can easily bounces for several milliseconds (depending on the button type) . So I suggest you start with using a bigger counter.
p.s. I am not very familiar with VHDL but this:
wait until rising_edge(CLK100MHZ);
can not be synthesized in Verilog.
I suggest you have a good look at your whole debounce process as I also see no sensitivity list and a latch!

Programming Altera DE2 for displaying colors on LCM in VHDL

Hi, i'm coding the main program structure for my LCM, called DE2_LCM2(in vhdl).
Within the main structure, there is a clock divider calls PLL2 (in verilog) and a I2S_LCM_Config (in verilog).
My PLL2.v and I2S_LCM.v are given by vendor, except for my DE2_LCM.vhd, myself coded. Compile successful, but stimulation failed.
FYI:
Horizontal scan:
1 Horizontal Line, there are 1171 counts or cycles of DCLK. The LCM_HSYNC goes low during falling edge of DCLK for 1 cycle. For the first 152 cycle, the data on LCM_DATA bus are invalid, start valid from cycle 153 to 1112, and invalid from cycle 1112 to 1171.
Vertical scan (Non-interlace):
After the last cycle of a horizontal line, the vertical counter shall be incremented by one. This LCM got 262 vertical lines in total, but only line 15 to (15+240)=255 is displayed.
LCM_PLL.v:
This file helps to convert system clock 50MHz to 18.42MHz. the DCLK or LCM_DCLK will be used for horizontal and vertical counter.
Below is my DE2_LCM.vhd codes, can't find what is going wrong on my code. Some more my teacher is on leave.
library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity DE2_LCM2 is port(CLOCK_50 : in std_logic;
KEY0 : in std_logic;
SW : in std_logic_vector(1 downto 0);
LCM_DATA : out std_logic_vector(7 downto 0);
LCM_DCLK, LCM_HSYNC, LCM_VSYNC,LCM_SCLK,LCM_SDAT,LCM_SCEN,LCM_GRST,LCM_SHDB : out std_logic
);
end DE2_LCM2;
architecture rtl of DE2_LCM2 is
constant H_SYNC_CYC: integer:=1;
constant H_SYNC_BACK: integer:=152;
constant H_SYNC_ACT: integer:=960;
constant H_SYNC_FRONT: integer:=59;
constant H_SYNC_TOTAL: integer:=1171;
constant V_SYNC_CYC: integer:=1;
constant V_SYNC_BACK: integer:=14;
constant V_SYNC_ACT: integer:=240;
constant V_SYNC_FRONT: integer:=8;
constant V_SYNC_TOTAL: integer:=262;
signal H_Cont: std_logic_vector(10 downto 0);
signal V_Cont: std_logic_vector(10 downto 0);
signal MOD_CNT: std_logic_vector(1 downto 0);
signal Tmp_DATA1: std_logic_vector(11 downto 0);
signal CLK_18: std_logic;
signal mSEL: std_logic_vector(1 downto 0);
signal iRST_N: std_logic;
signal I2S_SDAT: std_logic;
component LCM_PLL2 port(inclk0: in std_logic;
c0: out std_logic);
end component;
component I2S_LCM_Config is port(iCLK: in std_logic;
iRST_N: in std_logic;
I2S_SCLK: out std_logic;
I2S_SDAT: inout std_logic;
I2S_SCEN: out std_logic);
end component;
begin
LCM_GRST<=KEY0;
LCM_DCLK<=not(CLK_18);
LCM_SHDB<='1';
iRST_N<=KEY0;
LCM_SDAT<=I2S_SDAT; --add on
process(SW,MOD_CNT )
begin
if(SW="00")then
if(MOD_CNT="00")then
LCM_DATA<="01111111";
else LCM_DATA<="00000000";
end if;
elsif(SW="01")then
if(MOD_CNT="01")then
LCM_DATA<="01111111";
else LCM_DATA<="00000000";
end if;
elsif(SW="10")then
if(MOD_CNT="10")then
LCM_DATA<="01111111";
else LCM_DATA<="00000000";
end if;
else LCM_DATA<="00000000";
end if;
end process;
u0:LCM_PLL2 port map(inclk0=>CLOCK_50,
c0=>CLK_18);
u1:I2S_LCM_Config port map(iCLK=>CLOCK_50,
iRST_N=>KEY0,
I2S_SCLK=>LCM_SCLK,
I2S_SDAT=>I2S_SDAT,
I2S_SCEN=>LCM_SCEN);
process(CLK_18,iRST_N)
begin
if(rising_edge(CLK_18))then
if iRST_N = '0'then
MOD_CNT <= "11";
H_Cont <= "00000000000";
LCM_HSYNC <= '0';
V_Cont <= "00000000000";
LCM_VSYNC <= '0';
else
if((H_Cont >= H_SYNC_BACK) and (H_Cont<(H_SYNC_TOTAL-H_SYNC_FRONT)))then
if(MOD_CNT < "10") then
MOD_CNT <= MOD_CNT + '1';
else
MOD_CNT <= "00";
end if;
else MOD_CNT <= "11";
end if;
if(H_Cont < (H_SYNC_TOTAL-1)) then
H_Cont <= H_Cont + '1';
else H_cont <= "00000000000";
end if;
if(H_Cont < H_SYNC_CYC)then
LCM_HSYNC <= '0';
else LCM_HSYNC <= '1';
end if;
if(V_Cont <(V_SYNC_TOTAL-1)) then
V_Cont <= V_Cont+'1';
else V_Cont <= "00000000000";
end if;
if(V_Cont < V_SYNC_CYC) then
LCM_VSYNC <= '0';
else LCM_VSYNC <= '1';
end if;
end if;
end if;
end process;
end rtl;
Should be my coding style that is not suitable for hardware programming. Do let me know if PLL2.v and I2S_LCM_Config.v are needed for your testing. I'll send u through email.
Thanks in advance:)
Without checking your PLL or I2C, the vertical counter appears to be counting clocks and not lines:
There needs to be an additional qualifier to only increment V_cont when H_Cont is the maximum count (1170).
Something along the lines of:
if H_Cont = std_logic_vector (to_unsigned (H_SYNC_TOTAL-1,11)) then
if V_Cont < std_logic_vector(to_unsigned (V_SYNC_TOTAL-1, 11)) then
V_Cont <= std_logic_vector(unsigned(V_Cont) + 1);
else
V_Cont <= (others => '0');
end if;
end if;
(Ya, I used package numeric_std, sue me. Reformatted the heck out of your code to make it readable too).
And that gives you something that looks more reasonable (but hasn't really been checked, after all it's your design):
And the next Vertical event:
I also don't see any reason you couldn't use range constrained integers for H_Cont and V_Cont.
addendum
Because the answer caused confusion:
sorry, to be frank, i do understand what r u trying to achieve but i
dont understand your codes. – user317130 13 hours ago
I figured I'd redo the solution using the Synopsys version of std_logic packages. It makes the changes simpler and easier to see.
First, I created a CLOCK process that generated CLK_18 locally. This could have been in the test bench and simply driving CLK_18 with CLK_50, I didn't want any name confusion. I also commented out the I2C and PLL as being not supplied/uninvolved:
signal CLK_18: std_logic := '0'; -- default value to allow not in CLOCK process to run
Removing the unsupplied components:
-- component LCM_PLL2 port(inclk0: in std_logic;
-- c0: out std_logic);
-- end component;
--
-- component I2S_LCM_Config is port(iCLK: in std_logic;
-- iRST_N: in std_logic;
-- I2S_SCLK: out std_logic;
-- I2S_SDAT: inout std_logic;
-- I2S_SCEN: out std_logic);
-- end component;
And:
--
-- u0:LCM_PLL2 port map(inclk0=>CLOCK_50,
-- c0=>CLK_18);
-- u1:I2S_LCM_Config port map(iCLK=>CLOCK_50,
-- iRST_N=>KEY0,
-- I2S_SCLK=>LCM_SCLK,
-- I2S_SDAT=>I2S_SDAT,
-- I2S_SCEN=>LCM_SCEN);
And yes that leaves some signals undriven. We'll drive CLK_18 locally:
-- Dummy up CLK_18:
CLOCK:
process
begin
wait for 27.15 ns;
CLK_18 <= not CLK_18;
if Now > 80 ms then
wait;
end if;
end process;
-- Here instead of the test bench, could have jumpered CLOCK_50 to CLK_18
80 ms was rather excessive (a simulation will run until no events occur, everything is driven off the clock). Took a substantial length of time to simulate and the waveform dump was big (32 MB). It can be pared in half at least.
The change in operating the vertical counter is a bit more obvious using Synopsys standard logic libraries:
if H_Cont = H_SYNC_TOTAL - 1 then
if(V_Cont <(V_SYNC_TOTAL-1)) then
V_Cont <= V_Cont+'1';
else V_Cont <= "00000000000";
end if;
end if;
It consists of only operating the V_Cont counter in the last count of H_Cont so the counter only operates once per scan line.
The added test bench:
library ieee;
use ieee.std_logic_1164.all;
entity LCM_TB is
end entity;
architecture foo of LCM_TB is
signal CLOCK_50: std_logic := 'H';
signal KEY0: std_logic := '0';
signal SW: std_logic_vector(1 downto 0) := "11";
signal LCM_DATA: std_logic_vector(7 downto 0);
signal LCM_DCLK,
LCM_HSYNC,
LCM_VSYNC,
LCM_SCLK,
LCM_SDAT,
LCM_SCEN,
LCM_GRST,
LCM_SHDB: std_logic;
begin
-- CLOCK process found in DUT
DUT:
entity work.de2_lcm2
port map (
CLOCK_50 => CLOCK_50,
KEY0 => KEY0,
SW => SW,
LCM_DATA => LCM_DATA,
LCM_DCLK => LCM_DCLK,
LCM_HSYNC => LCM_HSYNC,
LCM_VSYNC => LCM_VSYNC,
LCM_SCLK => LCM_SCLK,
LCM_SDAT => LCM_SDAT,
LCM_SCEN => LCM_SCEN,
LCM_GRST => LCM_GRST,
LCM_SHDB => LCM_SHDB
);
STIMULUS: -- Just a reset
process
begin
wait for 100 ns;
KEY0 <= '1';
wait;
end process;
end architecture;
The build process:
ghdl -a --ieee=synopsys -fexplicit de2_lcm2.vhdl
ghdl -e --ieee=synopsys -fexplicit lcm_tb
ghdl -r lcm_tb --wave=lcm_tb.ghw
And because this is a Mac open *.ghw, or after establishing a save file open *.gtkw.
(OS X claims suffixes like Windows, the open command tells it to...).
And all this gives the same answer as the version using package numeric_std:
From the horizontal scroll bar in GTKWave you can see the simulation was twice as long as needed.
And instead of using std_logic_vector values you could have used unsigned with IEEE standard compliant package numeric_std with some slight modifications or converted H_Cont and V_Cont to range constrained integers (which will synthesize just fine), not forgetting to convert "00000000000" to 0 and ... + '1' to + 1 where appropriate.
I would have gotten back quicker but am in timezone GMT-12 (It's tomorrow here).

Trying to show one cycle of 8 bit LFSR with VHDL

I'm trying to do a VHDL code with the objective to make a 8 bit LFSR and show all the random states, and after one cycle (when the last state be the same seed value) it stop. But I'm have a problems, keep saying: "loop must terminate within 10,000 iterations". I'm using Quartus II-Altera.
Code:
entity lfsr_8bit is
--generic ( n : integer := 2**8 );
port (
clk : in bit;
rst : in bit;
lfsr : out bit_vector(7 downto 0)
);
end lfsr_8bit;
architecture behaviour of lfsr_8bit is
--signal i : integer := 0;
--signal seed : bit_vector(7 downto 0) := "10000000";
signal rand : bit_vector(7 downto 0);
begin
ciclo : process (clk,rst)
begin
loop
if (rst='0') then
rand <= "10000000";
elsif (clk'event and clk='1') then
rand(0) <= rand(6) xor rand(7);
rand(7 downto 1) <= rand(6 downto 0);
end if;
-- wait until rand = "10000000" for 100 ns;
exit when rand = "10000000";
-- case rand is
-- when "10000000" => EXIT;
-- when others => NULL;
-- end case;
-- i <= i +1;
end loop;
lfsr <= rand(7 downto 0);
end process ciclo;
end behaviour;
Thank you for all help.
Get rid of that loop, that loop does not work the way you think it does! Stop thinking like a software designer and think like a hardware designer. Loops in hardware are used to replicate logic. So that loop of yours is literally trying to generate 10,000 LFSRs!
I don't believe that you need to be using that loop there at all. If you remove it your LFSR should work as intended. You may need to add a control signal to enable/disable the LFSR, but definitely do not use a loop.
Here's some example code demonstrating this. Change the default value of rand to something else or the LFSR will never run! It will immediately set the lfsr_done signal.
ciclo : process (clk,rst)
begin
if (rst='0') then
rand <= "10000000"; -- SET THIS TO SOMETHING DIFFERENT
lfsr_done <= '0';
elsif (clk'event and clk='1') then
if rand = "10000000" then
lfsr_done <= '1';
end if;
if lfsr_done = '0' then
rand(0) <= rand(6) xor rand(7);
rand(7 downto 1) <= rand(6 downto 0);
end if;
end if;

Random LED turning on and off in VHDL

I want to implement a random-number game on BASYS2. In this game there would be five LEDs chosen out of which one would turn on at random for a second or two (this time can be changed to increase or decrease the difficulty level of the game). Then the user is required to respond to this LED event by pressing the switch button behind it within the time that it is on. If he or she is able to do so successfully a point would be scored and it would be showed on the Seven Segment Display. If he or she fails no point would be scored. There would be 9 such events after which the game can be replayed.
Now following is my code (only for the random LED turning on). However, I am unable to fix it. Please somebody help. The FPGA I am using is BASYS2 SPARTAN 3E-100.
Thanks in advance to everyone.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.STD_LOGIC_arith.ALL;
entity random_number is
generic ( width : integer := 4 );
port (
clk : in std_logic;
reset : in std_logic;
random_num : out std_logic_vector (width-1 downto 0) --output vector
);
end random_number;
architecture Behavioral of random_number is
signal q: std_logic_vector(23 downto 0);
signal divided_clock: std_logic;
begin
process(clk, reset)
begin
if (reset = '1')then
q <= X"000000";
elsif(rising_edge(clk)) then
q <= q + 1;
end if;
end process;
divided_clock <= q(22);
process (divided_clock)
variable rand_temp : std_logic_vector(width-1 downto 0):=("1000");
variable temp : std_logic := '0';
begin
if(rising_edge(divided_clock)) then
temp := rand_temp(width-1) xor rand_temp(width-2);
rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0);
rand_temp(0) := temp;
end if;
random_num <= rand_temp;
end process;
end Behavioral;
I think the second process should even run with the main clk and the devided clock should be an enable.
signal divided_enable: std_logic;
process(clk, reset)
begin
if (reset = '1')then
q <= X"000000";
elsif(rising_edge(clk)) then
q <= q + 1;
end if;
if (q(22) = '1') then
--short pulse wenn q bit 22 is high
divided_enable <= '1';
q <= (others => '0');
end if;
end process;
process (clk)
variable rand_temp : std_logic_vector(width-1 downto 0):=("1000");
variable temp : std_logic := '0';
begin
if(rising_edge(clk)) then
if(divided_enable = '1') then
temp := rand_temp(width-1) xor rand_temp(width-2);
rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0);
rand_temp(0) := temp;
end if;
end if;
random_num <= rand_temp;
end process;
I don't know if this will fix all your problems. Please discribe compiler errors or errors in the behavior.

VGA VHDL Screen Moves when I refresh

I'm trying to make a grid on the screen using this VHDL.
I can make two lines now, but when I refresh the screen, the lines move.
I'm not sure where the error is, can someone help or offer any pointers?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_unsigned.all;
--use IEEE.std_logic_arith.all; --VVVVVVV
use IEEE.NUMERIC_STD.all; --^^^^^^^
entity SCRN is
port(
clk : in STD_LOGIC;
vga : OUT STD_LOGIC_VECTOR (7 downto 0);
Hsync : OUT STD_LOGIC;
Vsync : OUT STD_LOGIC
);
end SCRN;
architecture Behavioral of SCRN is
type PLC_HOLD is array (1 to 800, 1 to 525) of STD_LOGIC_VECTOR(7 downto 0);
signal scrn : PLC_HOLD;
signal s_clk : std_logic_vector (1 downto 0) := (others => '0');
signal xx_vga : std_logic_vector (7 downto 0);
signal xx_h : std_logic;
signal xx_v : std_logic;
signal X : std_logic_vector (9 downto 0) := (others => '1');
signal Y : std_logic_vector (9 downto 0) := (others => '1');
-- signal test : ieee.numeric_std.unsigned
-- test now works with mod
begin
NW_CLK: process (clk) is
begin
if rising_edge (clk) then
s_clk <= (s_clk + "01");
end if;
end process NW_CLK;
--###############################--
scrn_loc :
process (s_clk(1)) is
begin
if RISING_EDGE (s_clk(1)) then
X <= X + "0000000001";
if (X = "1100100000") then --if x = 800
X <= "0000000001";
Y <= (Y + "0000000001");
elsif (Y = 525) then -- if y = 525
X <= "0000000001";
Y <= "0000000001";
end if;
end if;
end process;
--###############################--
draw :
process (X,Y) is
-- h and v sync process
begin
if (X > 640) then -- and (X <= 752) then -- low for sync pulse at 656 to 752 -- 96 pixel
xx_h <= '0';
else
xx_h <= '1';
end if;
if (Y> 490) and (Y <= 492) then -- low for sync puls at 490 to 492
xx_v <= '0';
else
xx_v <= '1';
end if;
-- (CONV_INTEGER((X)) mod 10)
-- CONV_INTEGER(Y) mod 10
-- if X = 1 then
-- xx_vga <= "00111000";
---- elsif Y = 1 or Y = 480 then
---- xx_vga <= "11101011";
-- else
-- xx_vga <= "11100000";
-- end if;
end process;
--###############################--
scrn(CONV_INTEGER(X),CONV_INTEGER(Y)) <= "00111000" when X = 1 else
"11100101" when Y = 2 else
"00000111" when X = 640 else
"11001101";
Hsync <= xx_h;
Vsync <= xx_v;
vga <= scrn(CONV_INTEGER(X),CONV_INTEGER(Y));
end Behavioral;
Hmmm... What happens if you move the line where you assign to scrn(CONV_INTEGER(X),CONV_INTEGER(Y)) <= "00111000" when X = 1 else ... to somewhere inside your process?
Also there is no need to use binary literals in your code (e.g., if (X = "1100100000")). Just use integer literals, or decimal bit-string literals. Better yet, define all your numeric values as integers or naturals. As a bonus, your code will be cleaner because you won't need all those conversion functions.
You are creating a clock from a clock, which is a bad idea. It seems you are trying to divide by 4? Instead create an enable pulse:
NW_CLK: process (clk) is
variable divider : integer range 0 to 3;
begin
if rising_edge (clk) then
if divider = 3 then
divider := 0;
screen_process_enable <= '1';
else
divider := divider + 1;
screen_process_enable <= '0';
end if
end if;
end process NW_CLK;
Then in the screen process:
scrn_loc : process (clk) is
begin
if RISING_EDGE (clk) and screen_process_enable = '1' then
etc...
Not related to your question, but I'll comment on it here anyway: You seem to be trying to hold the entire screen in memory - that's quite a lot of storage you are asking for in a real chip (it'll be fine in simulation).
For producing a grid you can just do it on the fly, by assigning to the VGA output depending on the values of your x and y counters. Because you have both the assignment to scrn and vga outside of a process, the synthesiser is probably clever enough to figure out that you never make use of the memory storage you've asked for and has optimised it away. If at some future point you come to use scrn as a true framebuffer, you may run up against performance or resource limitations, depending on your device.
Check chapter 15 (VHDL Design of VGA Video Interfaces) of "Circuit Design and Simulation with VHDL", which shows detailed VGA theory followed by a number of experiments using VHDL and VGA monitors.

Resources