我是靠谱客的博主 忐忑酒窝,最近开发中收集的这篇文章主要介绍VHDL---基于状态机的十进制加法计数器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。状态机简写为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---基于状态机的十进制加法计数器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部