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);
I've created this simple mod16 counter using basys3 board and something is not right with my clock. The code itself do works, however one count (changing from "1" to "2" etc.) last 40 seconds, instead of 1 second! I've tried to lower the "clk_vector" if condition to 1 but it didn't help either.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity mod_16_k is
Port ( switch : in STD_LOGIC_VECTOR (3 downto 0);
CLK1 : in STD_LOGIC;
reset : in STD_LOGIC;
led : out STD_LOGIC_VECTOR (15 downto 0));
end mod_16_k;
architecture Behavioral of mod_16_k is
signal clk_vector :integer;
signal clk_vec2 :std_logic_vector(15 downto 0);
begin
zegar_wew : process(CLK1)
begin
if(CLK1'event and CLK1 = '1') then
clk_vector <= clk_vector + 1;
if(clk_vector = 100000000) then
clk_vec2 <= std_logic_vector(unsigned(clk_vec2) + 1);
end if;
end if;
end process;
led <= clk_vec2;
end Behavioral;
The .XDC lines for clock are:
If we check the basys3 datasheet, the clock is connected to "W5" port.
Do you have any idea, what might be the problem in here? It might be connected with detecting the rising edge of an clk, however all of the changes (from 1 to 2 etc.) last ~40 seconds.
This is because you forget to reset clk_vector once it reaches 1 second. Because it is an integer, it is 32 bits, thus will count 2^32 instead of 100000000.
This should work:
If(CLK1'event and CLK1 = '1') then
if(clk_vector = 100000000-1) then
clk_vector <= 0;
clk_vec2 <= std_logic_vector(unsigned(clk_vec2) + 1);
else
clk_vector <= clk_vector + 1;
end if;
end if;
Also, notice that to count 1 second, you need to count up to 100000000-1, we start counting from zero!
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).
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.
I'm trying to get two outputs (pulse(0) and pulse(1)) to deliver a short one clock pulse. The latency between these pulses needs to be controlled by some input value. So 0x1 = 1 clock cycle etc.
At the moment, once the trigger switches on, it stays on
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
<...snip>
architecture rtl of trig_latency is
signal ack : std_logic;
signal s_level : unsigned(pulse'range);
signal s_level_d1 : std_logic;
signal bit_shift : std_logic_vector(addr_width downto 0);
signal latency: integer:=5;
begin
latency <= to_integer(unsigned(in_data(addr_width -1 downto 0))) when addr_width > 0 else 0;
process(clk)
begin
if rising_edge(clk) then
if ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write = '1' then
s_level <= s_level + 1;
s_level_d1<=s_level(s_level'left);
else
s_level<=(others=>'0);
end if;
bit_shift <= bit_shift(bit_shift'high-1 downto 0) & (s_level(s_level'left) and (not s_level_d1));
ipbus_out.ipb_rdata <= (others => '0');
ack <= ipbus_in.ipb_strobe and not ack;
pulse(0) <= s_level(s_level'left) and (not s_level_d1);
pulse(1)<=bit_shift(latency);
end if;
end process;
ipbus_out.ipb_ack <= ack;
ipbus_out.ipb_err <= '0';
end rtl;
Why can't you just shift your bits the whole way and ignore the fact that they go above N. The usual VHDL shifter uses the & to concatenate the shifted register with the new value:
bit_shift <= bit_shift(bit_shift'high-1 downto 0) & s_level;
That should produce your shift register just fine.
The pulse(1) <= bit_shift(N) ought to work fine.