📄 state_machine.vhd
字号:
--###############################################################################---- LOGIC CORE: SDR SDRAM Controller state machine -- MODULE NAME: state_machine() -- date: 2006.8.07-- REVISION HISTORY: -- FUNCTIONAL DESCRIPTION:---- This module is the state_machine for the SDR SDRAM controller.-- Copyright (C) 1991-2000 --##############################################################################library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity state_machine is port ( sdramclk : in std_logic; --系统时钟由 pll产生,100mhz operationreq : in std_logic_vector(2 downto 0); --操作请求码,对应各种操作 CMDACK : in std_logic; --Controller command acknowledgement cmdstate : out std_logic_vector(3 downto 0); --输出当前的状态 -- 命令长度计数器的返回值 tcmdlengthcount : out std_logic_vector(9 downto 0); cmd : inout std_logic_vector(2 downto 0); --输出给sdramcontroller的命令端口 reset : in std_logic; --模块的复位信号 reqack : out std_logic; --操作完成应答信号,10ns的脉冲 fifo1rden : out std_logic; --fifo的使能信号高电平有效 fifo2wren : out std_logic; hostdataen : out std_logic; --ackcounti :out std_logic_vector(2 downto 0); counto5 : out std_logic_vector(2 downto 0); counto3 : out std_logic_vector(2 downto 0));end state_machine;architecture operation of state_machine is--signal cmdlengthcounti : std_logic_vector(9 downto 0):="0000000000"; --计数器signal cmdlengthcountii : std_logic_vector(9 downto 0):="0000000000"; --计数器signal cmdstatei : std_logic_vector(3 downto 0):="0000";signal count1 : std_logic_vector(2 downto 0):="000";signal count2 : std_logic_vector(2 downto 0):="000";signal count3 : std_logic_vector(2 downto 0):="000";signal count4 : std_logic_vector(2 downto 0):="000";signal count5 : std_logic_vector(2 downto 0):="000";signal ackcount : std_logic_vector(2 downto 0):="000";signal stopcount : std_logic;signal operationreqi : std_logic_vector(2 downto 0):="000";signal opq : std_logic_vector(5 downto 0):="000000";begintcmdlengthcount<=cmdlengthcountii;--cmdlengthcount <= cmdlengthcounti;cmdstate <= cmdstatei;--counto1 <= count1;counto5 <= count5;counto3 <= count3;--ackcounti <=ackcount; process(reset,CMDACK,ackcount,sdramclk,cmdstatei)begin if(reset = '0' or cmdstatei="0000") then stopcount <= '0'; else if rising_edge(sdramclk) then if(ackcount<="001") then if(CMDACK='1') then stopcount <= '0'; else stopcount <= '1'; end if; else stopcount <= '1'; end if; end if; end if; end process;process(reset,sdramclk,cmdstatei) --第一次ack后的计数器 begin if (reset = '0' or cmdstatei="0000" ) then --cmdlengthcounti<="0000000000"; cmdlengthcountii <= "0000000000"; else if rising_edge(sdramclk) then if(ackcount="001") then cmdlengthcountii <= cmdlengthcountii+1; else cmdlengthcountii <= "0000000000"; end if; end if; end if;end process;process(reset,CMDACK,cmdstatei,sdramclk) --记录每一种操作的cmdack的个数 begin if(reset = '0' or cmdstatei="0000") then ackcount <= "000"; else if rising_edge(sdramclk) then if(CMDACK = '1') then ackcount <= ackcount+1; end if; end if; end if; end process;process(reset,ackcount,sdramclk,cmdstatei) --第3次ack后的计数器(无用) begin if(reset = '0' or cmdstatei="0000") then count1 <= "000"; else if rising_edge(sdramclk) then --if (ackcount="001") then if (ackcount="011") then count1 <= count1+1; else count1 <= "000"; end if; end if; end if; end process;process(reset,ackcount,sdramclk,cmdstatei) --第4次ack后的计数器(无用) begin if(reset = '0' or cmdstatei="0000") then count2 <= "000"; else if rising_edge(sdramclk) then --if (ackcount="010") then if (ackcount="100") then count2 <= count2+1; end if; end if; end if; end process;process(reset,ackcount,sdramclk,cmdstatei) --第1次ack后的计数器 用来锁存数据使用 begin if(reset = '0' or cmdstatei="0000") then count3 <= "000"; else if rising_edge(sdramclk) then if (ackcount="001" ) then count3 <= count3+1; end if; end if; end if; end process;process(reset,ackcount,sdramclk,cmdstatei) --第1次ack后的计数器 begin if(reset = '0' or cmdstatei="0000") then count4 <= "000"; else if rising_edge(sdramclk) then if (ackcount="010") then count4 <= count4+1; end if; end if; end if; end process;process(reset,ackcount,sdramclk,cmdstatei) --第1次ack后的计数器 begin if(reset = '0' or cmdstatei="0000") then count5 <= "000"; else if rising_edge(sdramclk) then if (ackcount <="000") then count5 <= count5+1; else count5 <= "000"; end if; end if; end if; end process;process(operationreq,sdramclk)begin if rising_edge(sdramclk) then operationreqi <= operationreq; end if;end process;opq <= operationreq & operationreqi;process(reset,opq,sdramclk,CMDACK,ackcount,cmdstatei,cmdlengthcountii) variable ackcount1 :std_logic_vector(9 downto 0); begin if(reset = '0') then cmdstatei <= "0000"; cmd <="000"; reqack <= '0'; fifo1rden <='0'; fifo2wren <='0'; hostdataen <='0'; else if rising_edge(sdramclk) then case cmdstatei is when "0000" => case opq is when "000000" => --idle cmdstatei <= "0000"; when "001000" => --页写 cmdstatei <= "0001"; when "010000" => --页读 cmdstatei <= "0010"; when "011000" => --随机写 cmdstatei <= "0011"; when "100000" => --机读 cmdstatei <= "0100"; when "101000" => --页配置 cmdstatei <= "0101"; when "110000" => --随机配置 cmdstatei <= "0110"; when "111000" => --refresh cmdstatei <= "0111"; when others =>NULL; end case; cmd <="000"; reqack <= '0'; fifo1rden <='0'; fifo2wren <='0'; hostdataen <='0';----------页写请求操作(完成!)------------------------------------------ when "0001" => --page write if(count5="001") then cmd <= "010"; elsif(CMDACK='1'and cmd = "010") then cmd <= "000"; elsif(count4 = "011") then cmd <="100"; elsif(cmdlengthcountii=508) then cmd <= "100"; end if; if(cmdlengthcountii <= "0111111111" and cmdlengthcountii>="0000000000" and ackcount="001") then fifo1rden<= '1' ; else fifo1rden<= '0' ; end if; if(ackcount>="011") then cmdstatei <= "0000"; reqack <= '1'; end if; ---------页读请求操作(完成!)-------------------------------------------- when "0010" => --page READ if(count5="001") then cmd <= "001"; elsif(CMDACK='1'and cmd = "001") then cmd <= "000"; elsif(count4 = "011") then cmd <="100"; elsif(cmdlengthcountii=508) then cmd <= "100"; end if; if(cmdlengthcountii <= 519 and cmdlengthcountii>=4 and ackcount="001") then fifo2wren<= '1' ; else fifo2wren<= '0' ; end if; if(ackcount>="011") then --第三个ack后结束本次页写操作 cmdstatei <= "0000"; reqack <= '1'; end if; ----------随机写请求操作(完成!)------------------------------------------ when "0011" => --write burst length=1 if(count5="001") then cmd <= "010"; elsif(CMDACK='1'and cmd = "010") then cmd <= "000"; end if; if(cmdlengthcountii < 1 and cmdlengthcountii>=0 and ackcount="001") then hostdataen<= '1' ; else hostdataen<= '0' ; end if; if(cmdlengthcountii >10) then reqack <= '1'; cmdstatei <= "0000"; end if;------------------------------------------------------- --------------------随机读请求操作(完成!)---------------------------------- when "0100" => --read burst length=1 if(count5="001") then cmd <= "001"; elsif(CMDACK='1'and cmd = "001") then cmd <= "000"; end if; if(cmdlengthcountii < 8 and cmdlengthcountii>=7 and ackcount="001") then hostdataen<= '1' ; else hostdataen<= '0' ; end if; if(cmdlengthcountii >10) then reqack <= '1'; cmdstatei <= "0000"; end if;-------------------------------------- ----------------页配置操作模式(完成!)------------------------------------- when "0101" => if(count5="001") then cmd <= "100"; --precharge elsif(cmdack='1' and cmd="100") then cmd <= "011"; --precharge elsif(ackcount="010" and cmd="011") then cmd <= "011"; --precharge elsif(cmd = "011" and ackcount="011" ) then --load_mode_reg cmd <="101"; elsif(ackcount="100") then cmd <= "000"; cmdstatei <= "0000"; reqack <= '1'; end if; -------------------------------------------------------------------------------------------随机配置操作模式(完成!)------------------------------------- when "0110" => if(count5="001") then cmd <= "100"; --precharge elsif(cmdack='1' and cmd="100") then cmd <= "011"; --precharge elsif(ackcount="010" and cmd="011") then cmd <= "011"; --precharge elsif(cmd = "011" and ackcount="011" ) then --load_mode_reg cmd <="101"; elsif(ackcount="100") then cmd <= "000"; reqack <= '1'; cmdstatei <= "0000"; end if; ----------------------------------------------------------- when "0111" => if(count5="001") then cmd <= "011"; elsif(CMDACK='1') then cmd <= "000"; cmdstatei <= "0000"; reqack <= '1'; end if; when others =>NULL; --when others => -- reqack <= '0'; end case; end if;end if;end process;end operation;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -