По поводу стэйт-машин.
Объявляете новый тип данных который включает в себя множество состояний вашего sdram-контроллера.
У меня это было сделано так:
Код
TYPE state is (NOP, READ_SB, READ_PAGE, WRITE_SB, WRITE_PAGE, LOAD_MODE, HOLD);
TYPE lm_state is (NOP, PRECHARGE, REFRESH_1, REFRESH_2, LOAD_MODE);
TYPE rw_sb_state is (NOP, ACTIVE, sREAD, sWRITE, PRECHARGE);
TYPE rw_page_state is (NOP, ACTIVE, sREAD, sWRITE, PRECHARGE);
state - набор состояний
lm_state, rw_sb_state, rw_page_state - набор состояний при загрузке режима, чтении-записи единичного байта и постраничной чтении-записи
А в процессах вашей программы по различным условиям можете осуществлять преходы из одного состояния в другое выполняя необходимые действия.
В примере ниже я когдато писал тестовую программу для sdram-контроллера.
Назначение этого блока по состоянию комбинации входов READ, WRITE, SB_PAGE сгенерировать на выходе набор комманд для исполнительного блока, который непосредственно управляет выводами RAS, CAS и т.д.
Генерацию набора комманд я делал с помощью автомата состояний в котором переход из одного состояния в другое осуществлялся по подтверждению выполнения каждой их комманд.
Пример рабочий так что можете посмотреть и поймёте что имелось ввиду под "стэйт машин"

CODE
--#############################################################################
--
-- Название модуля: sdram_command()
--
-- Назначение: Модуль обработки и исполнения комманд SDRAM-контроллера
--
--#############################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity cmd_gen is
generic
(
ADDRSIZE : integer := 22; -- Размер входного адреса
ROWSIZE : integer := 12; -- Размер адресной шины по строкам
COLSIZE : integer := 8; -- Размер адресной шины по колонкам
BANKSIZE : integer := 2; -- Размер адресной шины по банкам
ROWSTART : integer := 21; --
ROWEND : integer := 10; --
BANKSTART : integer := 9; --
BANKEND : integer := 8; --
COLSTART : integer := 7; --
COLEND : integer := 0 --
);
port (
CLK : in std_logic; -- System Clock
nRESET : in std_logic; -- System Reset
CON_CLK : out std_logic; -- System Clock
CON_nRESET : out std_logic; -- System Reset
SB_PAGE : out std_logic; -- Singl Bit or Burst acess
CMD : out std_logic_vector (2 downto 0); -- Command
PRECH_ALL_AUTO : out std_logic;
CMD_ACK : in std_logic; -- Подтверждение выполнения команды
DATA_ACK : in std_logic; -- Подтверждение считывания данных
ADDRESS : out std_logic_vector(ADDRSIZE-1 downto 0); -- Input address
SB_PAGE_IN : in std_logic; -- Singl Bit or Burst acess
READ : in std_logic; -- Data direction for DATA_MODUL
WRITE : in std_logic; -- Data direction for DATA_MODUL
ODD_EVEN : in std_logic; -- Data direction for DATA_MODUL
VSYNC : in std_logic; -- Data direction for DATA_MODUL
HSYNC : in std_logic; -- Data direction for DATA_MODUL
BLANK : in std_logic; -- Data direction for DATA_MODUL
MODE_HOLD : out std_logic -- Input address
);
end cmd_gen ;
architecture RTL of cmd_gen is
TYPE state is (NOP, READ_SB, READ_PAGE, WRITE_SB, WRITE_PAGE, LOAD_MODE, HOLD);
TYPE lm_state is (NOP, PRECHARGE, REFRESH_1, REFRESH_2, LOAD_MODE);
TYPE rw_sb_state is (NOP, ACTIVE, sREAD, sWRITE, PRECHARGE);
TYPE rw_page_state is (NOP, ACTIVE, sREAD, sWRITE, PRECHARGE);
--is
signal mode_decoder : state;
signal load_mode_exe : lm_state;
signal read_sb_exe : rw_sb_state;
signal write_sb_exe : rw_sb_state;
signal read_page_exe : rw_page_state;
signal write_page_exe : rw_page_state;
signal busy_flag : std_logic;
signal mode_selector : std_logic_vector (2 downto 0);
signal fulladdr : std_logic_vector (ADDRSIZE-1 downto 0);
signal rowaddr : std_logic_vector (ROWSIZE-1 downto 0);
signal coladdr : std_logic_vector (COLSIZE-1 downto 0);
signal bankaddr : std_logic_vector (BANKSIZE-1 downto 0);
signal bank_col_addr : std_logic_vector (COLSIZE+BANKSIZE-1 downto 0);
signal cmd_out : std_logic_vector (2 downto 0);
signal cNOP : std_logic_vector (2 downto 0);
signal cACTIVE : std_logic_vector (2 downto 0);
signal cREAD : std_logic_vector (2 downto 0);
signal cWRITE : std_logic_vector (2 downto 0);
signal cREFRESH : std_logic_vector (2 downto 0);
signal cPRECHARGE : std_logic_vector (2 downto 0);
signal cLOAD_MODE : std_logic_vector (2 downto 0);
signal do_read_sb : std_logic;
signal do_read_page : std_logic;
signal do_write_sb : std_logic;
signal do_write_page : std_logic;
signal do_load_mode : std_logic;
signal prech_type : std_logic;
begin
--Кодированные команды для SDRAM-контроллера
cNOP <= "000";
cACTIVE <= "001";
cREAD <= "010";
cWRITE <= "011";
cREFRESH <= "100";
cPRECHARGE <= "101";
cLOAD_MODE <= "110";
process (nRESET, CLK, SB_PAGE_IN, READ, WRITE)
begin
if(nRESET = '0') then
mode_selector <= (others => '0');
elsif rising_edge(CLK) then
mode_selector(2) <= SB_PAGE_IN;
mode_selector(1) <= READ;
mode_selector(0) <= WRITE;
end if;
end process;
-- реализация диграммы переходов автомата декодирования рабочего режима
process (nRESET, CLK)
begin
if (nRESET = '0') then
mode_decoder <= NOP;
elsif rising_edge(CLK) then
case(mode_decoder)is
when(NOP) => if(busy_flag = '0')then
if (mode_selector = "010") then mode_decoder <= READ_SB;
elsif (mode_selector = "110") then mode_decoder <= READ_PAGE;
elsif (mode_selector = "001") then mode_decoder <= WRITE_SB;
elsif (mode_selector = "101") then mode_decoder <= WRITE_PAGE;
elsif (mode_selector = "011") then mode_decoder <= LOAD_MODE;
elsif (mode_selector = "111") then mode_decoder <= LOAD_MODE;
elsif (mode_selector = "000") then mode_decoder <= NOP;
elsif (mode_selector = "100") then mode_decoder <= NOP;
else null;
end if;
end if;
when(READ_SB) => mode_decoder <= HOLD;
when(READ_PAGE) => mode_decoder <= HOLD;
when(WRITE_SB) => mode_decoder <= HOLD;
when(WRITE_PAGE)=> mode_decoder <= HOLD;
when(LOAD_MODE) => mode_decoder <= HOLD;
when(HOLD) => mode_decoder <= NOP;
end case;
end if;
end process;
-- реализация диграммы переходов автоматов в различных режимах работы
process (nRESET, CLK)
begin
if (nRESET = '0') then
busy_flag <= '0';
load_mode_exe <= NOP;
read_sb_exe <= NOP;
write_sb_exe <= NOP;
read_page_exe <= NOP;
write_page_exe <= NOP;
elsif falling_edge(CLK) then
-- последовательность комманд при загрузке рабочего режима
case(load_mode_exe)is
when(NOP) => if (mode_decoder = LOAD_MODE) then load_mode_exe <= PRECHARGE;
busy_flag <= '1';
do_load_mode <= '1';
else load_mode_exe <= NOP;
do_load_mode <= '0';
end if;
when(PRECHARGE) => if (CMD_ACK = '1') then load_mode_exe <= REFRESH_1;
else load_mode_exe <= PRECHARGE;
end if;
when(REFRESH_1) => if (CMD_ACK = '1') then load_mode_exe <= REFRESH_2;
else load_mode_exe <= REFRESH_1;
end if;
when(REFRESH_2) => if (CMD_ACK = '1') then load_mode_exe <= LOAD_MODE;
else load_mode_exe <= REFRESH_2;
end if;
when(LOAD_MODE) => if (CMD_ACK = '1') then load_mode_exe <= NOP;
busy_flag <= '0';
else load_mode_exe <= LOAD_MODE;
end if;
end case;
-- последовательность комманд при чтении еденичного бита
case(read_sb_exe)is
when(NOP) => if (mode_decoder = READ_SB) then read_sb_exe <= ACTIVE;
busy_flag <= '1';
do_read_sb <= '1';
else read_sb_exe <= NOP;
do_read_sb <= '0';
end if;
when(ACTIVE) => if (CMD_ACK = '1') then read_sb_exe <= sREAD;
else read_sb_exe <= ACTIVE;
end if;
when(sREAD) => if (DATA_ACK = '1') then read_sb_exe <= NOP;
busy_flag <= '0';
else read_sb_exe <= sREAD;
end if;
when others => read_sb_exe <= NOP;--null;
end case;
-- последовательность комманд при записи еденичного бита
case(write_sb_exe)is
when(NOP) => if (mode_decoder = WRITE_SB) then write_sb_exe <= ACTIVE;
busy_flag <= '1';
do_write_sb <= '1';
else write_sb_exe <= NOP;
do_write_sb <= '0';
end if;
when(ACTIVE) => if (CMD_ACK = '1') then write_sb_exe <= sWRITE;
else write_sb_exe <= ACTIVE;
end if;
when(sWRITE) => if (DATA_ACK = '1') then write_sb_exe <= NOP;
busy_flag <= '0';
else write_sb_exe <= sWRITE;
end if;
when others => write_sb_exe <= NOP;--null;
end case;
-- последовательность комманд при чтении страницы
case(read_page_exe)is
when(NOP) => if (mode_decoder = READ_PAGE) then read_page_exe <= ACTIVE;
busy_flag <= '1';
do_read_page <= '1';
else read_page_exe <= NOP;
do_read_page <= '0';
end if;
when(ACTIVE) => if (CMD_ACK = '1') then read_page_exe <= sREAD;
else read_page_exe <= ACTIVE;
end if;
when(sREAD) => if (DATA_ACK = '1') then read_page_exe <= PRECHARGE;
else read_page_exe <= sREAD;
end if;
when(PRECHARGE) => if (CMD_ACK = '1') then read_page_exe <= NOP;
busy_flag <= '0';
else read_page_exe <= PRECHARGE;
end if;
when others => read_page_exe <= NOP;--null;
end case;
-- последовательность комманд при записи страницы
case(write_page_exe)is
when(NOP) => if (mode_decoder = WRITE_PAGE) then write_page_exe <= ACTIVE;
busy_flag <= '1';
do_write_page <= '1';
else write_page_exe <= NOP;
do_write_page <= '0';
end if;
when(ACTIVE) => if (CMD_ACK = '1') then write_page_exe <= sWRITE;
else write_page_exe <= ACTIVE;
end if;
when(sWRITE) => if (DATA_ACK = '1') then write_page_exe <= PRECHARGE;
else write_page_exe <= sWRITE;
end if;
when(PRECHARGE) => if (CMD_ACK = '1') then write_page_exe <= NOP;
busy_flag <= '0';
else write_page_exe <= PRECHARGE;
end if;
when others => write_page_exe <= NOP;--null;
end case;
end if;
end process;
process(nRESET, clk)
begin
if (nRESET = '0') then
cmd_out <= cNOP;
elsif rising_edge(CLK) then
if(do_load_mode = '1') then
--Состояние выводов при загрузке режима
case(load_mode_exe)is
when PRECHARGE => CMD_OUT <= cPRECHARGE; prech_type <= '1';
when REFRESH_1 => CMD_OUT <= cREFRESH; prech_type <= '0';
when REFRESH_2 => CMD_OUT <= cREFRESH;
when LOAD_MODE => CMD_OUT <= cLOAD_MODE;
when NOP => CMD_OUT <= cNOP;
end case;
end if;
--Состояние выводов при чтении одного бита
if(do_read_sb = '1') then
case(read_sb_exe)is
when ACTIVE => CMD_OUT <= cACTIVE;
when sREAD => CMD_OUT <= cREAD; prech_type <= '1';
when NOP => CMD_OUT <= cNOP;
when others => null;
end case;
end if;
--Состояние выводов при записи одного бита
if(do_write_sb = '1') then
case(write_sb_exe)is
when ACTIVE => CMD_OUT <= cACTIVE;
when sWRITE => CMD_OUT <= cWRITE; prech_type <= '1';
when NOP => CMD_OUT <= cNOP;
when others => null;
end case;
end if;
--Состояние выводов при чтении страницы
if(do_read_page = '1') then
case(read_page_exe)is
when ACTIVE => CMD_OUT <= cACTIVE;
when sREAD => CMD_OUT <= cREAD;
when PRECHARGE => CMD_OUT <= cPRECHARGE;
when NOP => CMD_OUT <= cNOP;
when others => null;
end case;
end if;
--Состояние выводов при записи страницы
if(do_write_page = '1') then
case(write_page_exe)is
when ACTIVE => CMD_OUT <= cACTIVE;
when sWRITE => CMD_OUT <= cWRITE;
when PRECHARGE => CMD_OUT <= cPRECHARGE;
when NOP => CMD_OUT <= cNOP;
when others => null;
end case;
end if;
end if;
end process;
--Процесс подтверждения захвата режима
process(nRESET, clk)
begin
if(nRESET = '0')then
MODE_HOLD <= '0';
elsif rising_edge(clk)then
if(mode_decoder = HOLD) then
MODE_HOLD <= '1';
else
MODE_HOLD <= '0';
end if;
end if;
end process;
-- Управление счётчиком строк
process(nRESET, VSYNC, HSYNC, DATA_ACK)
begin
if ((nRESET = '0') or (VSYNC = '1') ) then
rowaddr <= (others => '0');
elsif rising_edge(HSYNC) then
rowaddr <= rowaddr + 1;
end if;
end process;
-- Управление счётчиком банков
process(nRESET, HSYNC, DATA_ACK)
begin
if ((nRESET = '0') or (HSYNC = '1')) then
bankaddr <= (others => '0');
elsif falling_edge(DATA_ACK) then
bankaddr <= bankaddr + 1;
end if;
end process;
-- Управление счётчиком колонок
process(nRESET, VSYNC, HSYNC, DATA_ACK)
begin
if ((nRESET = '0') or (VSYNC = '1')) then
coladdr <= (others => '0');
elsif falling_edge(DATA_ACK) then
coladdr <= coladdr + 1;--coladdr + 1;
end if;
end process;
ADDRESS ( ROWSTART downto ROWEND) <= rowaddr;
ADDRESS ( BANKSTART downto BANKEND) <= bankaddr;
--BANK <= bankaddr;--bank_col_addr (COLSIZE+BANKSIZE-1 downto COLSIZE+BANKSIZE-2);
ADDRESS (COLSTART downto COLEND) <= coladdr;
CON_CLK <= CLK;
CON_nRESET <= nRESET;
SB_PAGE <= SB_PAGE_IN;
CMD <= cmd_out;
PRECH_ALL_AUTO <= prech_type;
end RTL;