概述
状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。状态机简写为FSM(Finite State Machine),主要分为2大类:
第一类,若输出只和状态有关而与输入无关,则称为Moore状态机;
第二类,输出不仅和状态有关而且和输入有关系,则称为Mealy状态机。
程序的状态转换图如下:
代码工程由四部分构成:顶层文件、数码管显示元件、分频元件、基于状态机的加法计数器。
顶层文件:
--数码管显示
--通过拨码开关控制CLK,EN,LOAD;
--通过独立按键控制RST.
--v1.0 使用拨码开关产生时钟信号,不稳定。
--v1.1 时钟信号
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity led_sm is
port
(
inCLK,RST_in: IN STD_LOGIC;
data_hex7:out std_logic_vector(7 downto 0);--数码管段码输出
com:out std_logic_vector(3 downto 0)--位码输出
);
end led_sm;
architecture Lin of led_sm is
component led_change is
port
(
data_in : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
LED7S : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
com : out std_logic_vector(3 downto 0) -- 选通引脚
);
end component led_change;
component CNT10 is
PORT
(
CLK,RST:IN STD_LOGIC; --
DOUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
end component CNT10;
--design the signal of the data
signal dd :STD_LOGIC_VECTOR(3 DOWNTO 0);
signal num:STD_LOGIC_VECTOR(3 DOWNTO 0);
signal jinwei:STD_LOGIC;
signal data_num:std_logic_vector(3 downto 0);
--Converted data
signal data_sm:std_logic_vector(7 downto 0);
begin
part1: --CNT10 process
CNT10 port map
(
CLK =>inCLK,RST =>RST_in, --
DOUT => num
);
data_num <= num;
part2: --the led-change process
led_change port map
(
data_in => data_num,
LED7S =>data_sm,
com =>com
);
data_hex7<=data_sm;
END Lin;
数码管显示元件:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY led_change IS
PORT (
data_in : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
LED7S : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
com : out std_logic_vector(3 downto 0) -- 选通引脚
);
END ;
ARCHITECTURE one OF led_change IS
TYPE states IS(SR0,SR1,SR2,SR3,SR4,SR5,SR6,SR7,SR8,SR9);
SIGNAL LIN :states;
BEGIN
com <= "1101"; --choose the shumaguan
--引脚设置
--com[3] PIN_141
--com[2] PIN_142
--com[1] PIN_144
--com[0] PIN_6
PROCESS (data_in) BEGIN
CASE data_in IS
WHEN "0000" => LED7S <= X"03";
WHEN "0001" => LED7S <= X"9F";
WHEN "0010" => LED7S <= X"25";
WHEN "0011" => LED7S <= X"0d";
WHEN "0100" => LED7S <= X"99";
WHEN "0101" => LED7S <= X"49";
WHEN "0110" => LED7S <= X"41";
WHEN "0111" => LED7S <= X"1F";
WHEN "1000" => LED7S <= X"01";
WHEN "1001" => LED7S <= X"09";
when others=>LED7S<=X"FF";--支持0-9字符
END CASE ;
END PROCESS;
END one;
分频元件:
--通用偶数分频器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity gen_div is
generic(div_param:integer:=1);
--分频因子,分频为2*div_param,默认2分频
port
(
clk_in:in std_logic;--输入时钟
bclk:out std_logic;--分频输出
resetb:in std_logic--复位信号
);
end gen_div;
architecture behave of gen_div is
signal tmp:std_logic;--输出暂存寄存器
signal cnt:integer range 0 to div_param:=0;--计数寄存器
begin
------------------------------
process(clk_in,resetb)
begin
if resetb='1' then --reset有效时,bclk始终是0
cnt<=0;
tmp<='0';
elsif rising_edge(clk_in) then
cnt<=cnt+1;
if cnt=div_param-1 then
tmp<=not tmp;--取反信号
cnt<=0;
end if;
end if;
end process;
bclk<=tmp;--输出
--------------------------------
end behave;
加法计数器:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--v1.0 使用拨码开关产生时钟信号,不稳定。
--v1.1 增加分频器,以此产生时钟信号
ENTITY CNT10 IS
PORT (CLK,RST:IN STD_LOGIC; --
DOUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END CNT10;
ARCHITECTURE behav OF CNT10 IS
------------------------------
TYPE states IS(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9);
SIGNAL ST,NST :states :=s0;
signal clk_tmp:std_logic;--半秒脉冲
component gen_div is--分频元件调用声明
generic(div_param:integer:=40000000);--20000000分频的,产生半秒脉冲
port
(
clk_in:in std_logic;
bclk:out std_logic;
resetb:in std_logic
);
end component gen_div;
BEGIN
gen_1s: --分频产生0.5s脉冲
gen_div port map--分频元件例化
(
clk_in=>CLK,
resetb=>not RST,
bclk=>clk_tmp
);
REG: PROCESS (clk_tmp,RST)
BEGIN
IF RST='0' THEN ST <=s0;
ELSIF clk_tmp'EVENT AND clk_tmp ='1' THEN
ST <= NST;
END IF;
END PROCESS REG;
COM: PROCESS(ST)
VARIABLE Q:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
CASE ST IS
WHEN s0 => Q :="0000"; DOUT <=Q; NST <=s1;
WHEN s1 => Q :="0001"; DOUT <=Q; NST <=s2;
WHEN s2 => Q :="0010"; DOUT <=Q; NST <=s3;
WHEN s3 => Q :="0011"; DOUT <=Q; NST <=s4;
WHEN s4 => Q :="0100"; DOUT <=Q; NST <=s5;
WHEN s5 => Q :="0101"; DOUT <=Q; NST <=s6;
WHEN s6 => Q :="0110"; DOUT <=Q; NST <=s7;
WHEN s7 => Q :="0111"; DOUT <=Q; NST <=s8;
WHEN s8 => Q :="1000"; DOUT <=Q; NST <=s9;
WHEN s9 => Q :="1001"; DOUT <=Q; NST <=s0;
END CASE;
END PROCESS COM;
END behav;
--PROCESS(clk_tmp,RST)
-- VARIABLE Q:STD_LOGIC_VECTOR(3 DOWNTO 0);
--BEGIN
-- IF RST='0' THEN Q:=(OTHERS=>'0');
-- ELSIF clk_tmp'EVENT AND clk_tmp ='1' THEN
-- IF Q<9 THEN Q:=Q+1;
-- ELSE Q := (OTHERS =>'0');
-- END IF;
-- END IF;
-- DOUT <=Q;
-- END PROCESS;
--
-- END behav;
最后
以上就是忐忑酒窝为你收集整理的VHDL---基于状态机的十进制加法计数器的全部内容,希望文章能够帮你解决VHDL---基于状态机的十进制加法计数器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复