I'm trying to use a LCD project in my own project but I don't really
understand this project fully especially with the counters e.g count1 and count2
I can provide the datasheet if needed!
I hope I can get a clarification to this, I understand what is going on when counter has reached a certain number but what I do not understand is what is that number is representing!
I think something is worth mentioning is the clock used in the FPGA is 50MHz
the code is as fellow
library ieee;
use ieee.std_logic_1164.all;
entity display is
port( clk : in std_logic;
rst : in std_logic;
byte_ready : in std_logic;
RS : out std_logic;
RW : out std_logic;
E : out std_logic;
DB : out std_logic_vector(7 downto 0);
rxdata : in std_logic_vector(7 downto 0) );
end entity display;
architecture rtl of display is
signal cnt : integer range 0 to 1000000; -- init counter
signal cnt2 : integer range 0 to 50000000; -- counter that resets every time byte i recieved
begin
clk_gen : process(clk, cnt, rst)
begin
if (rst = '0') then
cnt <= 0;
cnt2 <= 0;
else
if rising_edge(clk) and cnt < 1000000 then
cnt <= cnt + 1;
elsif rising_edge(clk) and cnt = 1000000 then
if (byte_Ready = '1') then
cnt2 <= 0;
end if;
if (cnt2 < 5000000) then
cnt2 <= cnt2 + 1;
end if;
end if;
end if;
end process clk_gen;
p_main : process(clk, rst)
begin
if (rst = '1') then
if rising_edge(clk) then
case cnt is -- INIT
when 100000 =>
RS <= '0';
RW <= '0';
E <= '1';
DB <= "00111000"; -- function set --kan ändras till 00111011 western eurpean #2
when 140000 =>
E <= '0';
when 150000 =>
E <= '1';
DB <= "00001011"; -- display off
when 190000 =>
E <= '0';
when 200000 =>
E <= '1';
DB <= "00000001"; -- display clear
when 300000 =>
E <= '0';
when 350000 =>
E <= '1';
DB <= "00000110"; -- entry mode
when 390000 =>
E <= '0';
when 400000 =>
E <= '1';
DB <= "00000010"; -- home command
when 440000 =>
E <= '0';
when 450000 =>
E <= '1';
DB <= "00001111"; -- display on
when 490000 =>
E <= '0';
when 500000 =>
RS <= '0';
E <= '1';
DB <= "00010000"; -- cursor shift left
when 550000 =>
E <= '0';
when 600000 =>
RS <= '1';
E <= '1';
DB <= "10100000"; -- output space
when 650000 =>
E <= '0';
when 700000 =>
RS <= '0';
E <= '1';
DB <= "00010000"; -- cursor shift left
when 750000 =>
E <= '0';
when others => null;
end case;
if (rxdata = "01111111") then -- if input is backspace
case cnt2 is
when 300000 =>
RS <= '0';
E <= '1';
DB <= "00010000"; -- cursor shift left
when 350000 =>
E <= '0';
when 400000 =>
RS <= '1';
E <= '1';
DB <= "10100000"; -- output space
when 450000 =>
E <= '0';
when 500000 =>
RS <= '0';
E <= '1';
DB <= "00010000"; -- cursor shift left
when 550000 =>
E <= '0';
when others => null;
end case;
elsif (rxdata = "00001101") then -- if input is enter
case cnt2 is
when 300000 =>
RS <= '0';
E <= '1';
DB <= "11000000"; -- go to second row
when 350000 =>
E <= '0';
when others => null;
end case;
else
case cnt2 is
when 300000 =>
RS <= '1';
E <= '1';
DB <= rxdata; -- output character
when 350000 =>
E <= '0';
when others => null;
end case;
end if;
end if;
end if;
end process p_main;
end architecture rtl;
Related
I'm trying to implement a testbench for the following fsm in created in vhdl. The problem is that currently, I'm not seeing any state transitions in the test bench. The simulation stays at state 0.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_Challenge is
Port ( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end FPGA_Challenge;
architecture Behavioral of FPGA_Challenge is
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x:std_logic;
signal y:std_logic;
signal count : integer:= 0;
--signal tmp: std_logic:= '1';
begin
process(clk_in, reset)
begin
if rising_edge(clk_in)then
if reset = '1'then -- Goes back to known state (state 0)
state <= s0;
count <= 0;
else
count <= count + 1;
case state is
-- Initial state- if button is pressed, then LED is lit and machine goes to state 2, if not it stays in state 1
when s0 =>
if (button <= '1') then
led <= '1';
state <= s1;
else
state <= s0;
led <= '0'; --is this necessary?
end if;
-- Beginning of preamble detection(states 1-17)
-- Count = ((freq in) / (freq out))/ 2 -1 = (100 MHz/ 2 MHz)/ 2 -1 = 50/2 - 1 (due to 50% duty cycle)
when s1=> -- do I need to put led = '1' in each state because it stays on ?
if (count = 25 -1) then
count <= 0;
if (data_line = '1')then
y <= '0';
-- led = '1';
state <= s2;
else
-- led = '1';
y <= '0';
state <= s1;
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s2 =>
if (count = 25-1) then
count <= 0;
if (data_line = '0')then
y <= '0';
-- led = '1';
state <= s3;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s3 =>
if (count = 25-1)then
count <= 0; ----reinitializes count
if (data_line <= '1')then
y <= '0';
-- led = '1';
state <= s4;
else
state <= s1;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s4 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s5;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s5 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s6;
else
state <= s4;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s6 =>
if (count= 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s7 =>
if (count = 25-1)then
count<= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s8 =>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
-- led = '1';
state <= s9;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s9 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s10;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s10=>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
--led = '1';
state <= s11;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s11 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s12;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s12 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s13;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s13 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s14;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s14 =>
if (count = 25-1)then
count <=0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s15;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s15 =>
if (count = 25-1)then
count <=0;
if (data_line <='0') then
y <= '0';
-- led = '1';
state <= s16;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s16 =>
if (count = 25-1) then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s17;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s17 =>
if (count = 25-1)then
count <= 0;
if (data_line ='1')then
y <= '1';
-- led = '1';
state <= s18;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s18 => -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s19;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s19=> -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s0;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when others=>
null;
end case;
end if;
end if;
end process;
end architecture;
The following is the testbench I have so far. I have internal signals such as y(output for each state), and count(counter for how long I'm in a state) that I probably should be using as drivers in the testbench. Any input is appreciated
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_tb is
-- Port ( );
end FPGA_tb;
architecture Behavioral of FPGA_tb is
component FPGA_Challenge is
Port( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end component;
signal led : STD_LOGIC;
signal clk_in : STD_LOGIC; -- 100 MHZ internal clock
signal reset : STD_LOGIC; -- is reset necessary
signal button : STD_LOGIC;
signal data_line : STD_LOGIC;
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x,y: std_logic;
signal count : integer:= 0;
begin
UUT: FPGA_Challenge
PORT MAP(
led => led,
clk_in => clk_in,
reset => reset,
button => button,
data_line => data_line
);
Testing: Process
begin
--wait until rising_edge(clk_in);
--wait until rising_edge(clk_in);
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '0';
button <= '1';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '1';
WAIT For 10ns;
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
end process;
end Behavioral;
Try this in the testbench to have a running clock and proper reset
signal clk_in : STD_LOGIC := '1'; -- 100 MHZ internal clock
signal reset : STD_LOGIC := '1'; -- is reset necessary
clk_in <=NOT clk_in after 10ns;
reset <= 0 after 30ns;
play with button after the reset. that is, from 40ns
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:
I am trying to simulate an elevator and as a result i get the error
ERROR:Xst:827 = Signal count cannot be synthesized, bad synchronous description
I am following the code from this source [https://www.youtube.com/watch?v=i03_-NMwmDs] since mine is very similar,(i have 7 floors and two more elevators). At first i am working with the code mentioned on the video and later i am going to implement two more elevators to work together in this simulation.
Thanks in advance.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity elevator is
port (clk: in std_logic;
sensors1: out std_logic:='0'; --sensors at each level for elevator 1
a1, a2, a3, a4, a5, a6, a7: out std_logic; -- for LED display at FPGA
insideopendoor, in1, in2, in3, in4, in5, in1up, in2up, in3up, in4up, in5up, in5down, in4down, in3down, in2down, in1down: std_logic; -- input request for each floor
opendoor: out std_logic; -- from inside elevator
closedoor: out std_logic); -- from inside elevator
end elevator;
architecture sequence of elevator is
constant timedoorclose: integer := 3;
constant timedoorclosed: integer := 2;
constant time_nx_state: integer :=4;
signal demand: std_logic_vector(0 to 4) := "00000";
signal direction_of_elevator : integer range 0 to 2 := 0;
signal updownpassenger : std_logic := '0';
signal signalstatus: std_logic := '1';
type status is (L1, L2, L3, L4, L5);
signal pr_state, nx_state: status;
begin
main: process (clk, insideopendoor, in1, in2, in3, in4, in5, in1up, in2up, in3up, in4up, in5up, in5down, in4down, in3down, in2down, in1down)
variable digit1 : std_logic_vector (6 downto 0);
variable count : integer range 0 to (time_nx_state + timedoorclose + timedoorclosed);
variable bufferopendoor : std_logic;
variable position : integer range 0 to 4;
variable tempup : integer range 1 to 2 := 1;
variable tempdown : integer range -4 to 4;
begin
if (clk'event and clk='1') then
demand(0) <= demand(0) or in1 or in1up or in1down;
demand(1) <= demand(1) or in2 or in2up or in2down;
demand(2) <= demand(2) or in3 or in3up or in3down;
demand(3) <= demand(3) or in4 or in4up or in4down;
demand(4) <= demand(4) or in5 or in5up or in5down;
case pr_state is
when L1 => position := 0;
when L2 => position := 1;
when L3 => position := 2;
when L4 => position := 3;
when L5 => position := 4;
end case;
for i in 1 to 4 loop
if demand(i) ='1' then
tempup := i - position;
else null;
end if;
end loop;
for i in 3 downto 0 loop
bufferopendoor := '1';
closedoor <= '0';
count := 0;
end loop; --
elsif (updownpassenger = '1') then
if (count < timedoorclose) then
opendoor <= '1';
bufferopendoor := '1';
elsif count < (timedoorclose + timedoorclosed) then
opendoor <= '0';
bufferopendoor := '0';
else
closedoor <= '0';
end if;
--else null; ------
--end if; ------
-----------part main-----------------
count := count +1;
if insideopendoor = '1' then
opendoor<='1';
bufferopendoor :='1';
closedoor <= '0';
count := 0;
elsif (updownpassenger ='1') then
if (count < timedoorclose) then
opendoor <= '1';
bufferopendoor := '1';
closedoor <= '0';
elsif (count < (timedoorclose + timedoorclosed)) then
opendoor <= '0';
bufferopendoor := '0';
closedoor <= '1';
else
closedoor <= '0';
pr_state <= nx_state;
if signalstatus = '1' then
signalstatus <= '0';
else
signalstatus <= '1';
end if;
count := 0;
end if;
else null; --
end if;--
case nx_state is
when L1 =>
digit1 := "1111001";
if demand(0) = '1' then
demand(0) <= '0';
else null;
end if;
when L2 =>
digit1 := "0100100";
if demand(1) = '1' then
demand(1) <= '0';
else null;
end if;
when L3 =>
digit1 := "0110000";
if demand(3) = '1' then
demand(3) <= '0';
else null;
end if;
when L4 =>
digit1 := "0011001";
if demand(3) = '1' then
demand(3) <= '0';
else null;
end if;
when L5 =>
digit1 := "0010010";
if demand(4) = '1' then
demand(4) <= '0';
else null;
end if;
when others => null;
end case;
a1 <= digit1(0);
a2 <= digit1(1);
a3 <= digit1(2);
a4 <= digit1(3);
a5 <= digit1(4);
a6 <= digit1(5);
a7 <= digit1(6);
end if;
end process main;
step: process (pr_state, signalstatus)
begin
case pr_state is
--end if;
when L1 =>
if (demand(0)='1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <=L2;
elsif direction_of_elevator = 2 then
nx_state <= pr_state;
else
nx_state <= pr_state;
end if;
end if;
when L2 =>
if (demand(1)= '1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L3;
elsif direction_of_elevator = 2 then
nx_state <= L1;
else
nx_state <= pr_state;
end if;
end if;
when L3 =>
if (demand(2)= '1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L4;
elsif direction_of_elevator = 2 then
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L5;
elsif direction_of_elevator = 2 then
end if;
end if;
end if;
when L5 =>
if (demand(4)='1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L4;
elsif direction_of_elevator = 2 then
nx_state <= L1;
else
nx_state <= pr_state;
end if;
end if;
when others => null;
end case;
end process step;
end sequence;
Your code seems very mixed up. There is a specific reason why it won't synthesise: think carefully when the code immediately following this line here
elsif (updownpassenger = '1') then
will be executed. It will be executed following a positive edge or negative edge on any input in the sensitivity list, apart from clk where it will be executed only following a negative edge. How would you design logic with such behaviour? Well, your synthesiser can't do it, either.
Basically, you need to refactor your code. You need to split it into sequential and combinational processes. (Combinational logic is logic whose output depends only on it's input and thus is logic that contains no latches or flip-flops. Sequential logic is logic that contains latches or flip-flops, but will also usually contain some gates too. Do not use latches - they are not synchronous design.) Whilst there are many ways to code such processes, it is wise to be consistent by sticking to a template. Here are three templates, which if followed, will give you everything you need and will keep your VHDL coding life simple:
Here is the template for sequential logic with an asynchronous reset, which all synthesis tools should understand:
process(clock, async_reset) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if async_reset ='1' then -- or '0' for an active low reset
-- set/reset the flip-flops here
-- ie drive the signals to their initial values
elsif rising_edge(clock) then -- or falling_edge(clock) or clk'event and clk='1' or clk'event and clk='0'
-- put the synchronous stuff here
-- ie the stuff that happens on the rising or falling edge of the clock
end if;
-- never put anything here
end process;
Here is the template for sequential logic without an asynchronous reset:
process(clock) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if rising_edge(clock) then -- or falling_edge(clock) or clk'event and clk='1' or clk'event and clk='0'
-- put the synchronous stuff here
-- ie the stuff that happens on the rising or falling edge of the clock
end if;
-- never put anything here
end process;
And here is the corresponding template for a combinational process:
process(all inputs in the sensitivity list) -- an 'input' is a signal either on the LHS of an assignment or a signal that is tested
begin
-- combinational logic (with complete assignment and no feedback)
end process;
My code is intended to be purely combinational. Only one element gives some synchronysm to simulation. it is a 4*4 led matrix where only 3*3 (starting on the top right) is valid. like:
-- LED matrix
-- rows\cols | A | B | C | D |
---------------------------------
-- 1 | 3 | 2 | 1 | 0 |
-- 2 | 7 | 6 | 5 | 4 |
-- 3 | 11 | 10| 9 | 8 |
-- 4 | 15 | 14| 13| 12| <- row not used
-- ^
-- |
-- column not used
---------------------------------
the following code compiles and simulates on an FPGA but not with the desired behaviour. The wanted behabiour is to iluminate a red led if one input is detected, 2 if 2, and if 3 are in a row in the matrix at the same time instead of 3 red led it should show 3 blue ones. no memory involved. The observed behaviour is explained as coments within the code.
entity mt is
PORT (
cD, cC, cB, cA : in std_logic; -- comparators for each column. cA is not necessary / not used.
row : inout std_logic_vector (3 downto 0) := (others => '0'); -- detection of each row.
led_R, led_G, led_B : out std_logic_vector (15 downto 0) := (others => '1') -- '1' indicates they are OFF. 12 to 15 will not be used (as well as 3, 7, 11 positions)
);
end mt;
I have 4 concurrent processes which depend on the signals explained:
architecture arc1 of mt is
signal led_R_in : std_logic_vector (15 downto 0) := (others => '1');
signal led_G_in : std_logic_vector (15 downto 0) := (others => '1'); -- don't think they are necessary
signal led_B_in : std_logic_vector (15 downto 0) := (others => '1'); -- don't think they are necessary
signal counter : std_logic_vector (1 downto 0) := "00";
begin
PROCESS (row, cD, cC, cB, cA) -- execute if any of these change
BEGIN
CASE row IS
WHEN "1000" => -- row 1 --
-- (LEDs are active at logic level 0)
CASE cD IS
WHEN '1' => led_R_in(0) <= '0'; led_G_in(0) <= '1'; led_B_in(0) <= '1';
WHEN OTHERS => led_R_in(0) <= '1'; led_G_in(0) <= '1'; led_B_in(0) <= '1';
END CASE;
CASE cC IS
WHEN '1' => led_R_in(1) <= '0'; led_G_in(1) <= '1'; led_B_in(1) <= '1';
WHEN OTHERS => led_R_in(1) <= '1'; led_G_in(1) <= '1'; led_B_in(1) <= '1';
END CASE;
CASE cB IS
WHEN '1' => led_R_in(2) <= '0'; led_G_in(2) <= '1'; led_B_in(2) <= '1';
WHEN OTHERS => led_R_in(2) <= '1'; led_G_in(2) <= '1'; led_B_in(2) <= '1';
END CASE;
CASE cA IS -- not necessary
WHEN '1' => led_R_in(3) <= '0'; led_G_in(3) <= '1'; led_B_in(3) <= '1';
WHEN OTHERS => led_R_in(3) <= '1'; led_G_in(3) <= '1'; led_B_in(3) <= '1';
END CASE;
WHEN "0100" => -- row 2 --
-- (LEDs are active at logic level 0)
CASE cD IS
WHEN '1' => led_R_in(4) <= '0'; led_G_in(4) <= '1'; led_B_in(4) <= '1';
WHEN OTHERS => led_R_in(4) <= '1'; led_G_in(4) <= '1'; led_B_in(4) <= '1';
END CASE;
CASE cC IS
WHEN '1' => led_R_in(5) <= '0'; led_G_in(5) <= '1'; led_B_in(5) <= '1';
WHEN OTHERS => led_R_in(5) <= '1'; led_G_in(5) <= '1'; led_B_in(5) <= '1';
END CASE;
CASE cB IS
WHEN '1' => led_R_in(6) <= '0'; led_G_in(6) <= '1'; led_B_in(6) <= '1';
WHEN OTHERS => led_R_in(6) <= '1'; led_G_in(6) <= '1'; led_B_in(6) <= '1';
END CASE;
CASE cA IS -- not necessary
WHEN '1' => led_R_in(7) <= '0'; led_G_in(7) <= '1'; led_B_in(7) <= '1';
WHEN OTHERS => led_R_in(7) <= '1'; led_G_in(7) <= '1'; led_B_in(7) <= '1';
END CASE;
WHEN "0010" => -- row 3 --
-- (LEDs are active at logic level 0)
CASE cD IS
WHEN '1' => led_R_in(8) <= '0'; led_G_in(8) <= '1'; led_B_in(8) <= '1';
WHEN OTHERS => led_R_in(8) <= '1'; led_G_in(8) <= '1'; led_B_in(8) <= '1';
END CASE;
CASE cC IS
WHEN '1' => led_R_in(9) <= '0'; led_G_in(9) <= '1'; led_B_in(9) <= '1';
WHEN OTHERS => led_R_in(9) <= '1'; led_G_in(9) <= '1'; led_B_in(9) <= '1';
END CASE;
CASE cB IS
WHEN '1' => led_R_in(10) <= '0'; led_G_in(10) <= '1'; led_B_in(10) <= '1';
WHEN OTHERS => led_R_in(10) <= '1'; led_G_in(10) <= '1'; led_B_in(10) <= '1';
END CASE;
CASE cA IS -- not necessary
WHEN '1' => led_R_in(11) <= '0'; led_G_in(11) <= '1'; led_B_in(11) <= '1';
WHEN OTHERS => led_R_in(11) <= '1'; led_G_in(11) <= '1'; led_B_in(11) <= '1';
END CASE;
WHEN OTHERS => Null; -- not necessary, although for avoiding latches creation I will have to assign them.
END CASE;
END PROCESS;
PROCESS (led_R_in) -- executes when led_R_in changes
BEGIN
-- leds are ON at '0' value
-- the problem is that, when initialising, the first row of leds will be blue, which means that
-- led_R_in 0, 1, 2 are 0, but they should be 1 as stated in their default values
-- the second and third row initialises correctly to green values, although the response to changes in the inputs are not only affecting them but also their neighbours, which I think it could be a problem of the FPGA pin assignment.
if (led_R_in(0)='0' AND ((led_R_in(1)='0' AND led_R_in(2)='0') OR (led_R_in(4)='0' AND led_R_in(8)='0') OR (led_R_in(5)='0' AND led_R_in(10)='0'))) then
led_B(0) <= '0';
led_R(0) <= '1';
led_G(0) <= '1';
else
led_R(0) <= led_R_in(0);
led_G(0) <= '0';
led_B(0) <= '1';
end if;
if (led_R_in(1)='0' AND ((led_R_in(0)='0' AND led_R_in(2)='0') OR (led_R_in(5)='0' AND led_R_in(9)='0'))) then
led_B(1) <= '0';
led_R(1) <= '1';
led_G(1) <= '1';
else
led_R(1) <= led_R_in(1);
led_G(1) <= '0';
led_B(1) <= '1';
end if;
if (led_R_in(2)='0' AND ((led_R_in(0)='0' AND led_R_in(1)='0') OR (led_R_in(10)='0' AND led_R_in(6)='0') OR (led_R_in(5)='0' AND led_R_in(8)='0'))) then
led_B(2) <= '0';
led_R(2) <= '1';
led_G(2) <= '1';
else
led_R(2) <= led_R_in(2);
led_G(2) <= '0';
led_B(2) <= '1';
end if;
if (led_R_in(4)='0' AND ((led_R_in(0)='0' AND led_R_in(8)='0') OR (led_R_in(5)='0' AND led_R_in(6)='0'))) then
led_B(4) <= '0';
led_R(4) <= '1';
led_G(4) <= '1';
else
led_R(4) <= led_R_in(4);
led_G(4) <= '0';
led_B(4) <= '1';
end if;
if (led_R_in(5)='0' AND ((led_R_in(2)='0' AND led_R_in(8)='0') OR (led_R_in(1)='0' AND led_R_in(9)='0') OR (led_R_in(0)='0' AND led_R_in(10)='0') OR (led_R_in(6)='0' AND led_R_in(4)='0'))) then
led_B(5) <= '0';
led_R(5) <= '1';
led_G(5) <= '1';
else
led_R(5) <= led_R_in(5);
led_G(5) <= '0';
led_B(5) <= '1';
end if;
if (led_R_in(6)='0' AND ((led_R_in(2)='0' AND led_R_in(10)='0') OR (led_R_in(5)='0' AND led_R_in(4)='0'))) then
led_B(6) <= '0';
led_R(6) <= '1';
led_G(6) <= '1';
else
led_R(6) <= led_R_in(6);
led_G(6) <= '0';
led_B(6) <= '1';
end if;
if (led_R_in(8)='0' AND ((led_R_in(2)='0' AND led_R_in(5)='0') OR (led_R_in(4)='0' AND led_R_in(0)='0') OR (led_R_in(9)='0' AND led_R_in(10)='0'))) then
led_B(8) <= '0';
led_R(8) <= '1';
led_G(8) <= '1';
else
led_R(8) <= led_R_in(8);
led_G(8) <= '0';
led_B(8) <= '1';
end if;
if (led_R_in(9)='0' AND ((led_R_in(1)='0' AND led_R_in(5)='0') OR (led_R_in(10)='0' AND led_R_in(8)='0'))) then
led_B(9) <= '0';
led_R(9) <= '1';
led_G(9) <= '1';
else
led_R(9) <= led_R_in(9);
led_G(9) <= '0';
led_B(9) <= '1';
end if;
if (led_R_in(10)='0' AND ((led_R_in(9)='0' AND led_R_in(8)='0') OR (led_R_in(5)='0' AND led_R_in(0)='0') OR (led_R_in(6)='0' AND led_R_in(2)='0'))) then
led_B(10) <= '0';
led_R(10) <= '1';
led_G(10) <= '1';
else
led_R(10) <= led_R_in(10);
led_G(10) <= '0';
led_B(10) <= '1';
end if;
END PROCESS;
PROCESS -- executes at the beginning (when is equal to "00") and changes its value every 10 ms
BEGIN
counter <= counter + "01"; -- there is an intended combinational loop here, so that it does this forever changing the row.
WAIT for 10 ms;
END PROCESS;
PROCESS (counter) -- executes at the beginning (when is equal to "00") and when counter changes (every 10 ms)
BEGIN
CASE counter IS
WHEN "00" => row <= "1000";
WHEN "01" => row <= "0100";
WHEN "10" => row <= "0010";
WHEN OTHERS => Null; -- for avoiding the automatic generation of latches due to non existing assignments. although it could also be row <= "0001"
END CASE;
END PROCESS;
END arc1;
why is it not working with the behaviour that I want?
I am trying to simulate my small program and I keep getting error messages and I have not been able to figure out why.
The error messages are:
line 131 error near process
line 132 error near behavioral ; expected type void
The lines:
130 end if;
131 end process;
132 end Behavioral;
I have tried to solve these for hours and I still do not have any clue.
Whole code:
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity kuutonen is
Port ( A1 : in STD_LOGIC;
B1 : in STD_LOGIC;
clk : in STD_LOGIC;
A : out STD_LOGIC;
B : out STD_LOGIC;
C : out STD_LOGIC;
D : out STD_LOGIC;
E : out STD_LOGIC;
F : out STD_LOGIC;
G : out STD_LOGIC);
end kuutonen;
architecture Behavioral of kuutonen is
signal tmp : std_logic_vector (2 downto 0);
begin
process (clk)
begin
if(tmp = "110")then
tmp <= "000";
end if;
if (A1 = '0' and B1 = '0') then
if (tmp ="000") then
A <= '1';
B <= '0';
C <= '0';
D <= '0';
E <= '0';
F <= '0';
G <= '0';
tmp <= tmp + 1;
end if;
if (tmp ="001")then
B <= '1';
A <= '0';
C <= '0';
D <= '0';
E <= '0';
F <= '0';
G <= '0';
tmp <= tmp + 1;
end if;
if (tmp ="010")then
C <= '1';
B <= '0';
A <= '0';
D <= '0';
E <= '0';
F <= '0';
G <= '0';
tmp <= tmp + 1;
end if;
if (tmp ="011")then
D <= '1';
B <= '0';
C <= '0';
A <= '0';
E <= '0';
F <= '0';
G <= '0';
E <= '1';
if (tmp ="100")then
E <= '1';
B <= '0';
C <= '0';
D <= '0';
A <= '0';
F <= '0';
G <= '0';
tmp <= tmp+1;
end if;
if (tmp ="101")then
F <= '1';
B <= '0';
C <= '0';
D <= '0';
E <= '0';
A <= '0';
G <= '0';
tmp <= tmp+1;
end if;
if (tmp ="110")then
G <= '1';
B <= '0';
C <= '0';
D <= '0';
E <= '0';
F <= '0';
A <= '0';
end if;
end if;
end process;
end Behavioral;
Just from inspection, I'd say it's probably due to a missing "end if;" between the case for tmp=001 and tmp=100.