FlyingDutch
Advanced Member level 1
- Joined
- Dec 16, 2017
- Messages
- 458
- Helped
- 45
- Reputation
- 92
- Reaction score
- 55
- Trophy points
- 28
- Location
- Bydgoszcz - Poland
- Activity points
- 5,027
Hello Everybody,
I am new to this forum and to "programmable logic" so I would like to say Hello :roll: to forum members and ask for indulgence. I am learning VHDL and FPGA's for about a half of year. I had finished only one my own project - "Controller for roller-blinds with 12V DC motor". Project is written in VHDL for Xilinx Spartan3A
(for synthesis I am using ISE Webpack 14.7) - more precisely for "Elbert V2" board (and MOSFET bridge as a driver for 12V DC motor). Here is link to this board:
https://numato.com/product/elbert-v2-spartan-3a-fpga-development-board
There is three buttons:
- one for starting closing of rollers
- one for starting opening for rollers
- reset (for reseting error state - for example overloading of motor)
There are also few sensors:
- analog comparator for detecting to much current of motor
- two final sensor (position of rollers: end position and start position)
I am using pwm generator (core from opencores.org) for generating of 'soft-start' and 'soft-stop' of DC motor for avoiding overvoltage of motor. The major component is a state-machine steering most of others components. The project is practically deployed in my flat and is working OK (before I had write bench-tests for veryfiing the correctness of project). I also have simple one way comunication from controller (FPGA) over RS-485 protocol and converters UART-RS485. The FPGA controller is sending status vector (4 bit of his internal state) to Arduino UNO with small OLED display.
Here is my major project entity:
Below entity WEKTORY_WYPELNIEN for generating changing PWM signal (soft-start for example):
And last example: state-machine:
For last month I had started to learn myself Xilinx Vivado. I also had purchased a 'larger' FPGA board - "Digilent Cmod-A7' board:
https://reference.digilentinc.com/reference/programmable-logic/cmod-a7/start?redirect=1id=cmod_a7/cm
with Xilinx Artix-7 FPGA
and I would like to experiment with Xilinx soft-CPU Microblaze.
I am also interested with HLS (High Level Synthesis) and "Vivado HLS".
Best Regards
I am new to this forum and to "programmable logic" so I would like to say Hello :roll: to forum members and ask for indulgence. I am learning VHDL and FPGA's for about a half of year. I had finished only one my own project - "Controller for roller-blinds with 12V DC motor". Project is written in VHDL for Xilinx Spartan3A
(for synthesis I am using ISE Webpack 14.7) - more precisely for "Elbert V2" board (and MOSFET bridge as a driver for 12V DC motor). Here is link to this board:
https://numato.com/product/elbert-v2-spartan-3a-fpga-development-board
There is three buttons:
- one for starting closing of rollers
- one for starting opening for rollers
- reset (for reseting error state - for example overloading of motor)
There are also few sensors:
- analog comparator for detecting to much current of motor
- two final sensor (position of rollers: end position and start position)
I am using pwm generator (core from opencores.org) for generating of 'soft-start' and 'soft-stop' of DC motor for avoiding overvoltage of motor. The major component is a state-machine steering most of others components. The project is practically deployed in my flat and is working OK (before I had write bench-tests for veryfiing the correctness of project). I also have simple one way comunication from controller (FPGA) over RS-485 protocol and converters UART-RS485. The FPGA controller is sending status vector (4 bit of his internal state) to Arduino UNO with small OLED display.
Here is my major project entity:
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Project is
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
b1 : in STD_LOGIC;--button zamykaj
b2 : in STD_LOGIC;--button otwieraj
krancEND : in STD_LOGIC;--wyłącznik krancow
krancPOC : in STD_LOGIC;--wyłącznik krancow
OVERLOAD : in STD_LOGIC;--z komparatora (za duży prąd płynie przez silnik)
brakZasilaniaCz : in STD_LOGIC;--Brak zasilania czujnikow (aktywne 0)
zdalneZamykanie : in STD_LOGIC;--Zdalne zamykanie drzwi(aktywne 0)
DIRPIN : inout STD_LOGIC;
SLPPIN : out STD_LOGIC;
AWARIA : out STD_LOGIC;--Aktywne 1
STATUS : out STD_LOGIC_VECTOR (3 downto 0);--Opis stanu ukladu (Praca/Awaria)
LEDOTWARTE : out STD_LOGIC;
LEDZAMKNIETE : out STD_LOGIC;
LEDPRACA : out STD_LOGIC;
LEDAWARIA : out STD_LOGIC;
WyjPWM : out STD_LOGIC_VECTOR (0 downto 0)
);--wyjscie pwm na mostek MOSFET
end Project;
architecture Behavioral of Project is
component divider is
Port ( clk : in STD_LOGIC;
clk_out : inout STD_LOGIC := '0');--clk_out 1MHZ
end component;
component debounce is
port ( clk : IN STD_LOGIC; --input clock
button : IN STD_LOGIC; --input signal to be debounced
result : OUT STD_LOGIC); --debounced signal
end component;
component DMASM is
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
bt1 : in STD_LOGIC;--btn zamykanie
bt2 : in STD_LOGIC;--btn otwieranie
krancEND : in STD_LOGIC;--active 0
krancPOC : in STD_LOGIC;--active 0
OVERLOAD : in STD_LOGIC;--active 0 (przeciazenie silnika)
TIM2LONGZ : in STD_LOGIC;--Timer operacja trwa za dlugo(zamykanie)
TIM2LONGO : in STD_LOGIC;--Timer operacja trwa za dlugo(otwieranie)
NoPowerSensors : in STD_LOGIC;--Brak zasilania czujnikow (aktywne 0)
RemoteZamykanie : in STD_LOGIC;--Zdalne zamykanie drzwi(aktywne 0)
DIRPIN : out STD_LOGIC;--Direction Motor ( 0 - FORWARD)
SLPPIN : out STD_LOGIC;--SLEEP PIN Mostek (0 - mostek zablokowany)
pb1_Zam : out STD_LOGIC;--gdy 0 zamykanie
pb2_Otw : out STD_LOGIC;--gdy 0 otwieranie
blokada_Zam : out STD_LOGIC;--gdy 0 blokada
blokada_Otw : out STD_LOGIC;--gdy 0 blokada
SELO : out STD_LOGIC_VECTOR (1 downto 0);--wybor pwm dla multiplexera
AWARIA : out STD_LOGIC;--gdy 1 awaria ukladu
STATUSO : out STD_LOGIC_VECTOR (3 downto 0);--Opis stanu ukladu (Praca/Awaria)
LEDZAMKNIETE : out STD_LOGIC;--gdy 1 LED zamkniete
LEDOTWARTE : out STD_LOGIC;--gdy 1 LED otwarte
LEDPRACA : out STD_LOGIC;--gdy 1 LED Zamykanie/otwieranie
LEDAWARIA : out STD_LOGIC);--gdy 1 LED awaria;
end component;
component WEKTORY_WYPELNIEN is
port ( clk :in std_logic;
pushB :in std_logic;
blokada :in std_logic;
rst : in STD_LOGIC; --aktywne 0
timerO : out std_logic;
data : out std_logic_vector(7 downto 0) );
end component;
component WEKTORY_REVERSE is
port ( clk :in std_logic;
pushB :in std_logic;
data : out std_logic_vector(7 downto 0) );
end component;
component pwm is
Port ( clk : in STD_LOGIC;
reset_n : in STD_LOGIC;
ena : in STD_LOGIC;
duty : in STD_LOGIC_VECTOR (7 downto 0);
pwm_out : out STD_LOGIC_VECTOR (0 downto 0);
pwm_n_out : out STD_LOGIC_VECTOR (0 downto 0));
end component;
component mux4to1 is
Port ( SEL : in STD_LOGIC_VECTOR (1 downto 0); -- select input
A : in STD_LOGIC_VECTOR (0 downto 0); -- inputs
B : in STD_LOGIC_VECTOR (0 downto 0);
C : in STD_LOGIC_VECTOR (0 downto 0);
D : in STD_LOGIC_VECTOR (0 downto 0);
X : out STD_LOGIC_VECTOR (0 downto 0)); -- output
end component;
signal data1_signal :STD_LOGIC_VECTOR (7 downto 0);
signal data2_signal :STD_LOGIC_VECTOR (7 downto 0);
signal data3_signal :STD_LOGIC_VECTOR (7 downto 0);
signal data4_signal :STD_LOGIC_VECTOR (7 downto 0);
signal b1_DB :STD_LOGIC;
signal b2_DB :STD_LOGIC;
signal clk_1MHz :STD_LOGIC;
signal pwm1_out :STD_LOGIC_VECTOR (0 downto 0);
signal pwm2_out :STD_LOGIC_VECTOR (0 downto 0);
signal pwm3_out :STD_LOGIC_VECTOR (0 downto 0);
signal pwm4_out :STD_LOGIC_VECTOR (0 downto 0);
signal pwm1_n_out :STD_LOGIC_VECTOR (0 downto 0);
signal pwm2_n_out :STD_LOGIC_VECTOR (0 downto 0);
signal pwm3_n_out :STD_LOGIC_VECTOR (0 downto 0);
signal pwm4_n_out :STD_LOGIC_VECTOR (0 downto 0);
--signal WyjPWM :STD_LOGIC_VECTOR (0 downto 0);
signal pb1_Zam :STD_LOGIC;
signal pb2_Otw :STD_LOGIC;
signal blokada_Zam :STD_LOGIC;
signal blokada_Otw :STD_LOGIC;
signal SELO :STD_LOGIC_VECTOR (1 downto 0);
signal TIM2LONGZ :STD_LOGIC;
signal TIM2LONGO :STD_LOGIC;
--signal brakZasilaniaCz :STD_LOGIC;
--signal zdalneZamykanie :STD_LOGIC;
begin
C1: divider port map (CLK, clk_1MHz);
C2: debounce port map (clk_1MHz, b1, b1_DB);
C3: debounce port map (clk_1MHz, b2, b2_DB);
C4: WEKTORY_WYPELNIEN port map (clk_1MHz, pb1_Zam, blokada_Zam, RST, TIM2LONGZ, data1_signal);
C5: WEKTORY_WYPELNIEN port map (clk_1MHz, pb2_Otw, blokada_Otw, RST, TIM2LONGO, data2_signal);
C6: DMASM port map (clk_1MHz,
RST,
b1_DB,
b2_DB,
krancEND,
krancPOC,
OVERLOAD,
TIM2LONGZ,
TIM2LONGO,
brakZasilaniaCz,
zdalneZamykanie,
DIRPIN,
SLPPIN,
pb1_Zam,
pb2_Otw,
blokada_Zam,
blokada_Otw,
SELO,
AWARIA,
STATUS,
LEDZAMKNIETE,
LEDOTWARTE,
LEDPRACA,
LEDAWARIA);
C7: pwm port map (clk_1MHz, RST, '1', data1_signal, pwm1_out, pwm1_n_out);
C8: pwm port map (clk_1MHz, RST, '1', data2_signal, pwm2_out, pwm2_n_out);
C9: WEKTORY_REVERSE port map (clk_1MHz, blokada_Zam, data3_signal);
C10: WEKTORY_REVERSE port map (clk_1MHz, blokada_Otw, data4_signal);
C11: pwm port map (clk_1MHz, RST, '1', data3_signal, pwm3_out, pwm3_n_out);
C12: pwm port map (clk_1MHz, RST, '1', data4_signal, pwm4_out, pwm4_n_out);
C13: mux4to1 port map (SELO, pwm1_out, pwm2_out, pwm3_out, pwm4_out, WyjPWM);
end Behavioral;
Below entity WEKTORY_WYPELNIEN for generating changing PWM signal (soft-start for example):
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity WEKTORY_WYPELNIEN is
generic (
NBit : natural := 30;
Div : natural := 3_000_000 --3s
);
port ( clk :in std_logic;
pushB :in std_logic;
blokada :in std_logic;
rst : in STD_LOGIC; --aktywne 0
timerO : out std_logic;
data : out std_logic_vector(7 downto 0) );
end WEKTORY_WYPELNIEN;
architecture BEHAVE of WEKTORY_WYPELNIEN is
signal ADDRESS :integer range 0 to 32 :=0;
signal TEMP :integer range 0 to 10_000_000 :=0; -- liczba impulsów
-- jaka ma minąć zanim dojdzie do zmiany adresu
signal GENERACJA_SERII_WEKTOROW : std_logic :='0';
-- okreslanie kiedy ma sie zaczac generacja serii wektorow
signal GENERACJA2_SERII_WEKTOROW : std_logic :='0';
signal KONIEC_GENERACJI_WEKTOROW : std_logic :='0';
-- okreslenie kiedy koniec generacji serii wektorow
signal OPOZNIENIE_BUTTONA :integer range 0 to 1_000_000 :=0;
signal cnt: std_logic_vector(Nbit -1 downto 0) := (others=>'0'); --licznik timera czasu otwarcia
type mem is array ( 0 to 2**5 - 1) of std_logic_vector(7 downto 0);
constant my_Rom : mem := (
0 => "00000011",
1 => "00000111",
2 => "00001110",
3 => "00001111",
4 => "00010101",
5 => "00011100",
6 => "00100011",
7 => "00010000",
8 => "00101010",
9 => "00110001",
10 => "00111000",
11 => "00111111",
12 => "01000110",
13 => "01001101",
14 => "01010100",
15 => "01011011",
16 => "01100010",
17 => "01101001",
18 => "01110000",
19 => "01110111",
20 => "01111110",
21 => "10000101",
22 => "10001100",
23 => "10010011",
24 => "10011010",
25 => "10100001",
26 => "10101000",
27 => "10010111",
28 => "10110110",
29 => "11011001",
30 => "11100000",
31 => "11111111"
);
begin
-- ZWIEKSZANIE ADRESU KOLEJNYCH WEKTOROW WYPELNIEN
process (CLK)
begin
if rising_edge(CLK) then
if (rst= '0') then
ADDRESS <= 0;
TEMP <= 0; -- liczba impulsów
GENERACJA_SERII_WEKTOROW <= '0';
GENERACJA2_SERII_WEKTOROW <= '0';
KONIEC_GENERACJI_WEKTOROW <= '0';
OPOZNIENIE_BUTTONA <= 0;
else
-- SPRAWDZENIE CZY PRZYCISK JEST NACISNIETY CZY NIE
if (pushB = '0') then -- lub '0' gdy po nacisnieciu
-- przycisku generowane jest przerwanie
if (OPOZNIENIE_BUTTONA < 10_000) then
-- opoznienie dzialania przycisku, aby za szybko
-- nie szla generacja po nacisnieciu
OPOZNIENIE_BUTTONA <= OPOZNIENIE_BUTTONA + 1;
else
if (KONIEC_GENERACJI_WEKTOROW = '0') then
-- jesli jest koniec to nie wznawiaj generacji
GENERACJA_SERII_WEKTOROW <= '1';
GENERACJA2_SERII_WEKTOROW <= '0';
end if;
end if;
else
KONIEC_GENERACJI_WEKTOROW <= '0';
OPOZNIENIE_BUTTONA <= 0;
-- zeruj koniec, gdy przycisk jest puszczony
-- zeruj opoznienie przycisku
end if;
-- GENERACJA SERII WEKTOROW PO NACISNIECIU PRZYCISKU
-- ORAZ OKRESLENIE JEJ KONCA PO JEJ WYKONANIU
if (GENERACJA_SERII_WEKTOROW = '1') then
if (TEMP < 20_000) then --okolo 0,02 s : 0,64 s calosc
TEMP <= TEMP + 1;
else
TEMP <= 0;
if (ADDRESS < 31) then
ADDRESS <= ADDRESS + 1;
else
KONIEC_GENERACJI_WEKTOROW <= '1';
GENERACJA_SERII_WEKTOROW <= '0';
GENERACJA2_SERII_WEKTOROW <= '1';
ADDRESS <= 0;
end if;
end if;
else
TEMP <= 0;
end if;
end if;
end if;
end process;
-- GENEROWANIE WEKTOROW WYPELNIEN
process (CLK)
begin
if rising_edge(CLK) then
if (rst= '0') then
DATA <= "00000000";
elsif (blokada = '0') then
DATA <= "00000000";
else
if (GENERACJA_SERII_WEKTOROW = '1') and (GENERACJA2_SERII_WEKTOROW = '0') then-- gdy trwa generacja -- wektorow
DATA <= my_rom(ADDRESS);
else if (GENERACJA2_SERII_WEKTOROW = '1') then
DATA <= "11100000";
else -- gdy generacja nie trwa
DATA <= "00000000";
end if;
end if;
end if;
end if;
end process;
-- Timer do odliczania czasu otwierania
process(CLK)
begin
if (CLK'event and CLK='1') then
if ((rst = '0') or (blokada = '0')) then
cnt <= (others => '0');
timerO <= '0';
else
if ((GENERACJA_SERII_WEKTOROW = '1') or (GENERACJA2_SERII_WEKTOROW = '1')) then
if cnt < Div then
--timerO <= '0';--Check this
cnt <= cnt+1;
else
cnt <= (others=>'0');
timerO <= '1';
end if;
end if;
end if;
end if;
end process;
end BEHAVE;
And last example: state-machine:
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity DMASM is
Port ( CLK : in STD_LOGIC;--Zegar
RST : in STD_LOGIC;--Reset
bt1 : in STD_LOGIC;--btn zamykanie
bt2 : in STD_LOGIC;--btn otwieranie
krancEND : in STD_LOGIC;--active 0
krancPOC : in STD_LOGIC;--active 0
OVERLOAD : in STD_LOGIC;--active 0 (przeciazenie silnika)
TIM2LONGZ : in STD_LOGIC;--Timer operacja trwa za dlugo(zamykanie)
TIM2LONGO : in STD_LOGIC;--Timer operacja trwa za dlugo(otwieranie)
NoPowerSensors : in STD_LOGIC;--Brak zasilania czujnikow (aktywne 0)
RemoteZamykanie : in STD_LOGIC;--Zdalne zamykanie drzwi(aktywne 0)
DIRPIN : out STD_LOGIC;--Direction Motor ( 0 - FORWARD)
SLPPIN : out STD_LOGIC;--SLEEP PIN Mostek (0 - mostek zablokowany)
pb1_Zam : out STD_LOGIC;--gdy 0 zamykanie
pb2_Otw : out STD_LOGIC;--gdy 0 otwieranie
blokada_Zam : out STD_LOGIC;--gdy 0 blokada
blokada_Otw : out STD_LOGIC;--gdy 0 blokada
SELO : out STD_LOGIC_VECTOR (1 downto 0);--wybor pwm dla multiplexera
AWARIA : out STD_LOGIC;--gdy 0 awaria ukladu
STATUSO : out STD_LOGIC_VECTOR (3 downto 0);--Opis stanu ukladu (Praca/Awaria)
LEDZAMKNIETE : out STD_LOGIC;--gdy 1 LED zamkniete
LEDOTWARTE : out STD_LOGIC;--gdy 1 LED otwarte
LEDPRACA : out STD_LOGIC;--gdy 1 LED Zamykanie/otwieranie
LEDAWARIA : out STD_LOGIC);--gdy 1 LED awaria;
end DMASM;
architecture BEHAVE of DMASM is
type STATE is (S0Otwarte, S1ZamykanieLocal, S2Zamkniete, S3OtwieranieLocal, S4ZamykanieRemote,
S5Overload, S6TooLongOper, S7NoPowerSensors, S8PositionError,
S9UnknowError, S10Awaria, S11DomkZamykanie, S12DomkOtwieranie,
S13BetweenEdges);
signal CURRENT_STATE, NEXT_STATE: STATE;
constant LICZNIK_LIMIT : integer := 2_000_000; -- 2s deklaracja stalej z max wart licznika
signal licznik : unsigned(24 downto 0); -- definicja syg lokalnego
begin
SEQ: process (RST, CLK, krancPOC, krancEND, OVERLOAD, NoPowerSensors, RemoteZamykanie)
begin
if (RST = '0') then
licznik <= b"0000000000000000000000000";
if ((krancPOC = '0') and (krancEND = '1')) then
CURRENT_STATE <= S0Otwarte;
else if ((krancPOC = '1') and (krancEND = '0')) then
CURRENT_STATE <= S2Zamkniete;
elsif ((krancPOC = '1') and (krancEND = '1')) then
CURRENT_STATE <= S13BetweenEdges;
end if;
end if;
elsif (CLK' event and CLK = '1' ) then
if (CURRENT_STATE = S11DomkZamykanie) and (NEXT_STATE = S11DomkZamykanie) then
licznik <= licznik + 1;
if licznik = LICZNIK_LIMIT then
licznik <= b"0000000000000000000000000";
CURRENT_STATE <= S2Zamkniete;
end if;
elsif (CURRENT_STATE = S12DomkOtwieranie) and (NEXT_STATE = S12DomkOtwieranie) then
licznik <= licznik + 1;
if licznik = LICZNIK_LIMIT then
licznik <= b"0000000000000000000000000";
CURRENT_STATE <= S0Otwarte;
end if;
elsif (OVERLOAD = '0') then--tu obsluga bledow dla all states
CURRENT_STATE <= S5Overload;
elsif (NoPowerSensors = '0') then
CURRENT_STATE <= S7NoPowerSensors;
elsif ((krancEND = '0') and (krancPOC = '0')) then
CURRENT_STATE <= S8PositionError;
else
CURRENT_STATE <= NEXT_STATE;
end if;
end if;
end process;
COMB: process (CURRENT_STATE, RST, bt1, bt2, krancEND, KrancPOC,
TIM2LONGZ, TIM2LONGO)
begin
case CURRENT_STATE is
when S0Otwarte => DIRPin <= '0';
SLPPin <= '0';--mostek zablokowany
pb1_Zam <= '1';
pb2_Otw <= '1';--blokada ALL
blokada_Zam <= '0';
blokada_Otw <= '0';
SELO <= "11";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '1';
LEDPRACA <= '0';
LEDAWARIA <= '0';
STATUSO <= "0000";
if (bt1 = '0') then
NEXT_STATE <= S1ZamykanieLocal;
elsif (RemoteZamykanie = '0') then
NEXT_STATE <= S4ZamykanieRemote;
elsif ((krancPOC = '0') and (krancEND = '1')) then
NEXT_STATE <= S0Otwarte;
elsif ((krancPOC = '1') and (krancEND = '0')) then
NEXT_STATE <= S2Zamkniete;
elsif ((krancPOC = '1') and (krancEND = '1')) then
NEXT_STATE <= S13BetweenEdges;
end if;
when S1ZamykanieLocal => DIRPin <= '0';
SLPPin <= '1';--FORWARD,MOSTEK OTWARTY
pb1_Zam <= '0';
pb2_Otw <= '1';
blokada_Zam <= '1';
blokada_Otw <= '0';
SELO <= "00";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '1';
LEDPRACA <= '1';
LEDAWARIA <= '0';
STATUSO <= "0001";
if (bt2 = '0') then
NEXT_STATE <= S3OtwieranieLocal;
else
if ((krancEND = '0') and (krancPOC = '1')) then
NEXT_STATE <= S11DomkZamykanie;
elsif (TIM2LONGZ = '1') then
NEXT_STATE <= S6TooLongOper;
else
NEXT_STATE <= S1ZamykanieLocal;
end if;
end if;
when S2Zamkniete => DIRPin <= '1';
SLPPin <= '0';
pb1_Zam <= '1';
pb2_Otw <= '1';--blokada ALL
blokada_Zam <= '0';
blokada_Otw <= '0';
SELO <= "10";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '1';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '0';
STATUSO <= "0010";
if (bt2 = '0')then --Button otwieranie
NEXT_STATE <= S3OtwieranieLocal;
else
if ((krancPOC = '0') and (krancEND = '1')) then
NEXT_STATE <= S0Otwarte;
elsif ((krancPOC = '1') and (krancEND = '0')) then
NEXT_STATE <= S2Zamkniete;
elsif ((krancPOC = '1') and (krancEND = '1')) then
NEXT_STATE <= S13BetweenEdges;
end if;
end if;
when S3OtwieranieLocal => DIRPin <= '1';
SLPPin <= '1';
pb1_Zam <= '1';
pb2_Otw <= '0';--BACKWARD,MOSTEK OTWARTY
blokada_Zam <= '0';
blokada_Otw <= '1';
SELO <= "01";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '1';
LEDOTWARTE <= '0';
LEDPRACA <= '1';
LEDAWARIA <= '0';
STATUSO <= "0011";
if (bt1 = '0') then --Button zamykanie
NEXT_STATE <= S1ZamykanieLocal;
elsif ((krancPOC = '0') and (krancEND = '1')) then -- zmiana stanu czuj. krancowych
NEXT_STATE <= S12DomkOtwieranie;
else -- gdy nie ma awarii
if (TIM2LONGO = '1') then -- gdy jest awaria
NEXT_STATE <= S6TooLongOper;
else
NEXT_STATE <= S3OtwieranieLocal;
end if;
end if;
when S4ZamykanieRemote => DIRPin <= '0';
SLPPin <= '1';--FORWARD,MOSTEK OTWARTY
pb1_Zam <= '0';
pb2_Otw <= '1';
blokada_Zam <= '1';
blokada_Otw <= '0';
SELO <= "00";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '1';
LEDPRACA <= '1';
LEDAWARIA <= '0';
STATUSO <= "0100";
if (bt2 = '0') then --klawisz otwieranie
NEXT_STATE <= S3OtwieranieLocal;
elsif ((krancEND = '0') and (krancPOC = '1')) then
NEXT_STATE <= S11DomkZamykanie;
else
if (TIM2LONGZ = '1') then -- gdy jest awaria
NEXT_STATE <= S6TooLongOper;
else
NEXT_STATE <= S4ZamykanieRemote;
end if;
end if;
when S5Overload => DIRPin <= '1';--stan S4Awaria
SLPPin <= '0';--blokada mostka
pb1_Zam <= '1';
pb2_Otw <= '1';--klawisze nieaktywne
blokada_Zam <= '0';
blokada_Otw <= '0';
AWARIA <= '1'; --sygnal aktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '1';
STATUSO <= "1000";
NEXT_STATE <= S10Awaria;
when S6TooLongOper => DIRPin <= '1';--stan S4Awaria
SLPPin <= '0';--blokada mostka
pb1_Zam <= '1';
pb2_Otw <= '1';--klawisze nieaktywne
blokada_Zam <= '0';
blokada_Otw <= '0';
AWARIA <= '1'; --sygnal aktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '1';
STATUSO <= "1010";
NEXT_STATE <= S10Awaria;
when S7NoPowerSensors => DIRPin <= '1';--stan S4Awaria
SLPPin <= '0';--blokada mostka
pb1_Zam <= '1';
pb2_Otw <= '1';--klawisze nieaktywne
blokada_Zam <= '0';
blokada_Otw <= '0';
AWARIA <= '1'; --sygnal aktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '1';
STATUSO <= "1001";
NEXT_STATE <= S10Awaria;
when S8PositionError => DIRPin <= '1';--stan S4Awaria
SLPPin <= '0';--blokada mostka
pb1_Zam <= '1';
pb2_Otw <= '1';--klawisze nieaktywne
blokada_Zam <= '0';
blokada_Otw <= '0';
AWARIA <= '1'; --sygnal aktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '1';
STATUSO <= "1011";
NEXT_STATE <= S10Awaria;
when S9UnknowError => DIRPin <= '1';--stan S4Awaria
SLPPin <= '0';--blokada mostka
pb1_Zam <= '1';
pb2_Otw <= '1';--klawisze nieaktywne
blokada_Zam <= '0';
blokada_Otw <= '0';
AWARIA <= '1'; --sygnal aktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '1';
STATUSO <= "1100";
NEXT_STATE <= S10Awaria;
when S10Awaria => DIRPin <= '1';--stan S10Awaria
SLPPin <= '0';--blokada mostka
pb1_Zam <= '1';
pb2_Otw <= '1';--klawisze nieaktywne
blokada_Zam <= '0';
blokada_Otw <= '0';
AWARIA <= '1'; --sygnal aktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '1';
when S11DomkZamykanie => DIRPin <= '0';
SLPPin <= '1';
pb1_Zam <= '1';
pb2_Otw <= '1';--blokada ALL
blokada_Zam <= '0';
blokada_Otw <= '0';
SELO <= "10";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '1';
LEDPRACA <= '1';
LEDAWARIA <= '0';
STATUSO <= "0101";
if (bt2 = '0') then --klawisz otwieranie
NEXT_STATE <= S3OtwieranieLocal;
else
NEXT_STATE <= S11DomkZamykanie;
end if;
when S12DomkOtwieranie => DIRPin <= '1';
SLPPin <= '1';
pb1_Zam <= '1';
pb2_Otw <= '1';--blokada ALL
blokada_Zam <= '0';
blokada_Otw <= '0';
SELO <= "11";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '1';
LEDOTWARTE <= '0';
LEDPRACA <= '1';
LEDAWARIA <= '0';
STATUSO <= "0110";
if (bt1 = '0') then --Button zamykanie
NEXT_STATE <= S1ZamykanieLocal;
else
NEXT_STATE <= S12DomkOtwieranie;
end if;
when S13BetweenEdges => DIRPin <= '0';
SLPPin <= '0';--mostek zablokowany
pb1_Zam <= '1';
pb2_Otw <= '1';--blokada ALL
blokada_Zam <= '0';
blokada_Otw <= '0';
SELO <= "11";
AWARIA <= '0'; --klawisz nieaktywny
LEDZAMKNIETE <= '0';
LEDOTWARTE <= '0';
LEDPRACA <= '0';
LEDAWARIA <= '0';
STATUSO <= "0111";
if (bt2 = '0') then --Button otwieranie
NEXT_STATE <= S3OtwieranieLocal;
elsif (bt1 = '0') then --Button zamykanie
NEXT_STATE <= S1ZamykanieLocal;
elsif (RemoteZamykanie = '0') then
NEXT_STATE <= S4ZamykanieRemote;
else
if ((krancPOC = '0') and (krancEND = '1')) then
NEXT_STATE <= S0Otwarte;
elsif ((krancPOC = '1') and (krancEND = '0')) then
NEXT_STATE <= S2Zamkniete;
elsif ((krancPOC = '1') and (krancEND = '1')) then
NEXT_STATE <= S13BetweenEdges;
end if;
end if;
when others => STATUSO <= "1010";--sygnalizacja TooLongOper
NEXT_STATE <= S10Awaria;
end case;
end process;
end BEHAVE;
For last month I had started to learn myself Xilinx Vivado. I also had purchased a 'larger' FPGA board - "Digilent Cmod-A7' board:
https://reference.digilentinc.com/reference/programmable-logic/cmod-a7/start?redirect=1id=cmod_a7/cm
with Xilinx Artix-7 FPGA
and I would like to experiment with Xilinx soft-CPU Microblaze.
I am also interested with HLS (High Level Synthesis) and "Vivado HLS".
Best Regards