Process VHDL中FSM内部的计数器

Process VHDL中FSM内部的计数器,process,synchronization,vhdl,counter,fsm,Process,Synchronization,Vhdl,Counter,Fsm,我的有限状态机出了一个小问题 最近用VHDL写的。我试图创建“智能”计数器 由频率为2 Hz的时钟触发。 此计数器在FSM的一种状态下构建,并通过按下 DE2板上的按钮 首先,整个系统处于空闲状态,如果我按下此按钮,状态为 改为计数,计数器开始递增,其当前 数值显示在LED显示屏上。当它达到模的值后,状态 计数返回空闲状态,计数器设置为零 我的问题是计数器不能正常工作——计数 价值太大了。所以我试着用这个结构来解决它:如果 (时钟滴答声事件和时钟滴答声=1)然后,有一些错误 合成: 错误(108

我的有限状态机出了一个小问题 最近用VHDL写的。我试图创建“智能”计数器 由频率为2 Hz的时钟触发。 此计数器在FSM的一种状态下构建,并通过按下 DE2板上的按钮

首先,整个系统处于空闲状态,如果我按下此按钮,状态为 改为计数,计数器开始递增,其当前 数值显示在LED显示屏上。当它达到模的值后,状态 计数返回空闲状态,计数器设置为零

我的问题是计数器不能正常工作——计数 价值太大了。所以我试着用这个结构来解决它:如果 (时钟滴答声事件和时钟滴答声=1)然后,有一些错误 合成: 错误(10822):Citac_FSM的HDL错误。vhd(57):无法实现 在此时钟边缘上注册分配

错误(10821):Citac_FSM处的HDL错误。vhd(62):无法推断 “AUTOMAT:flg”,因为其行为与任何支持的寄存器都不匹配 模型

请问,有人有办法解决这个问题吗?正确的方法是什么 要使用两个(或更多)时钟源写入时钟触发的FSM?

ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
使用ieee.std_logic_unsigned.all;
实体计数器\u FSM为
一般的(
REGSIZE:integer:=8;--计数器的范围
模:自然:=50——模值
);  
港口(
时钟:在标准逻辑中;--脉冲50兆赫
时钟滴答声:在标准逻辑中;--脉冲2赫兹
重置:在标准_逻辑中;--重置
就绪:OUT STD_LOGIC;--计数器已准备好启动
START_C:在标准逻辑中;--开始计数
DOUT:OUT标准逻辑向量(REGSIZE-1到0)——OUT
);
终端计数器(FSM),;
计数器FSM的架构行为是
类型计数器状态为(空闲,计数);——密克罗尼西亚联邦的国家
信号电流计数器状态:计数器状态;--现状
信号下一计数器状态:计数器状态;——下一个州
信号cnt:std_逻辑_向量(REGSIZE-1向下至0);--柜台
开始
更新:过程(重置,时钟)
开始
如果(重置='0'),则
咖喱酸盐
cnt“0”);--计数器值=零

就绪首先,您不应将时钟信号用作第二个时钟信号。 您应该做的是保存clk_tick的上一个值,然后将clk_tick的当前值与上一个值进行比较,以检测清洗边缘。根据clk_tick的生成方式,您可能需要将clk_tick同步到clk的时钟域

你可以这样写:

when COUNTING => 
    nextCounterState <= COUNTING; 
    READY <= '0';
    if (prev_clk_tick = '0' and clk_tick = '1') then 
        next_cnt <= cnt + 1;         -- yes -> incrementing
        if (cnt = MODULO) then
            next_cnt <= (others => '0');
            nextCounterState <= IDLE;   
        end if;
    end if;
计数时=>

下一个计数器状态我已经解决了我的问题:-)。我已经将计数器移动到单独的进程中,然后将开关信号连接到FSM。所以,它工作得很好

通过读取按钮,我正在使用两个D触发器来同步它

我必须观察一下VHDL编程的风格——它和C语言这样的“普通”编程太不一样了:-D


天气真好

第二个过程是时钟逻辑和非时钟逻辑的混合,这可能会混淆合成工具。把它们分开。并确保计数器已计时:当前未锁定。或者更好的方法是,将整个过程编写为一个更简单、更小的单进程状态机。
clk_tick
是如何生成的?是对称时钟还是每500ms出现一次1/50MHz的脉冲?
when COUNTING => 
    nextCounterState <= COUNTING; 
    READY <= '0';
    if (prev_clk_tick = '0' and clk_tick = '1') then 
        next_cnt <= cnt + 1;         -- yes -> incrementing
        if (cnt = MODULO) then
            next_cnt <= (others => '0');
            nextCounterState <= IDLE;   
        end if;
    end if;