VHDL脉冲发生器似乎卡住了

VHDL脉冲发生器似乎卡住了,vhdl,fpga,xilinx-ise,Vhdl,Fpga,Xilinx Ise,我试图建立一个脉冲发生器,它由两个脉冲发生器组成,由一个mod-m计数器驱动。计数器以设定的时间循环一个周期,每当它达到某个指定的时间,脉冲发生器就会在该时间产生短的方波脉冲 这在模拟中起作用,但当我在FPGA板上实现这一点时,它将成功地运行一个方波脉冲周期,但随后被卡住,就像计数器被永久地卡住在0一样(输出myag\u q和byag\u q被卡住在0和byag\u l,myag\u l被卡住在1)。我自己模拟了计数器,知道它在0和M之间继续循环 顶级模块、mod-m计数器和脉冲发生器的代码如下

我试图建立一个脉冲发生器,它由两个脉冲发生器组成,由一个mod-m计数器驱动。计数器以设定的时间循环一个周期,每当它达到某个指定的时间,脉冲发生器就会在该时间产生短的方波脉冲

这在模拟中起作用,但当我在FPGA板上实现这一点时,它将成功地运行一个方波脉冲周期,但随后被卡住,就像计数器被永久地卡住在0一样(输出
myag\u q
byag\u q
被卡住在0和
byag\u l
myag\u l
被卡住在1)。我自己模拟了计数器,知道它在0和M之间继续循环

顶级模块、mod-m计数器和脉冲发生器的代码如下所示。另一个脉冲发生器与第一个非常相似。无需检查我的用户约束文件,因为我确信我正确获得了pin分配。我需要一个大概的想法,我是否在组合这些模块时犯了任何大错误/最后一个程序(脉冲发生器)是否编写正确。最重要的是,我需要知道我使用计数器触发脉冲的方式是否正确。

顶层模块

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity trigger is
    Port ( clk, rst : in  STD_LOGIC;
              d: in STD_LOGIC_VECTOR(25 downto 0);
           myag_l, myag_q, byag_l, byag_q : out  STD_LOGIC);
end trigger;

architecture struc_arch of trigger is
signal counter: STD_LOGIC_VECTOR (25 downto 0);
begin

mini_yag: entity work.mini_yag(Behavioral)
port map(clk=>clk,rst=>rst,count=>counter,myag_l=>myag_l,myag_q=>myag_q);
big_yag: entity work.big_yag(Behavioral)
port map(clk=>clk,rst=>rst,d=>d,count=>counter,byag_l=>byag_l,byag_q=>byag_q);
baud: entity work.mod_m_counter(arch)
generic map(N=>26,M=>6434344)
port map(clk=>clk,reset=>rst,max_tick=>open,q=>counter);

end struc_arch;
Mod-M计数器

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity mod_m_counter is
     generic (
        N: integer := 4; -- number of bits
        M: integer := 10 -- mod-M
     );
    Port ( clk, reset : in  STD_LOGIC;
           max_tick : out  STD_LOGIC;
           q : out  STD_LOGIC_VECTOR (N-1 downto 0));
end mod_m_counter;

architecture arch of mod_m_counter is
    signal r_reg: unsigned (N-1 downto 0);
    signal r_next: unsigned (N-1 downto 0);
begin
    --register
    process(clk,reset)
    begin
        if (reset='1') then
            r_reg <= (others=>'0');
        elsif (clk'event and clk='1') then
            r_reg <= r_next;
        end if;
    end process;
    --next-state logic
    r_next <= (others=>'0') when r_reg=(M-1) else
                 r_reg + 1;
    --output logic
    q <= std_logic_vector(r_reg);
    max_tick <= '1' when r_reg=(M-1) else '0';
end arch;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.NUMERIC_STD.ALL;
实体mod_m_计数器为
一般的(
N:整数:=4;--位数
M:整数:=10--mod-M
);
端口(时钟,复位:在标准逻辑中;
最大勾选:输出标准逻辑;
q:输出标准逻辑向量(N-1到0);
终端模块计数器;
mod_m_计数器的架构是
信号r_reg:无符号(N-1向下至0);
信号r_next:无符号(N-1向下至0);
开始
--登记册
过程(时钟、复位)
开始
如果(reset='1'),则
r_reg“0”);
elsif(clk'事件和clk='1'),然后

r_reg模拟与现实之间的不匹配通常归结为以下一个或多个问题:

  • 测试台不能提供与实际电路相同的刺激。
    • 示例:测试台将按钮按下模拟为一个简单的
      1
      0
      1
      序列,但实际按钮不会有这种“干净”行为
  • 设计未通过计时约束,或设计未正确约束
  • 由于未锁定/异步路径设计中的问题,设计中存在竞争条件或危险。
    • 示例:当
      reg\u M
      更改时,您的
      max\u tick
      信号可能会出现故障
  • 任何时钟域交叉点的设计都存在问题

我唯一的评论是:(1)我的观点:将功能划分为太多的小流程(_next和_reg)只会增加代码大小、复杂性、理解难度和不可靠性(2)使用幻数(643434)增加意外的范围:在包中定义常量并一致使用它(3)通过更好地选择类型,可以避免一些不必要的转换:例如,计数器端口的无符号转换,甚至是自然转换(4)如果您的脉冲发生器如此相似,为什么不使用一个组件?(5)“无需检查xxx…”著名的最后一句话?谢谢您的建议。关于(1),我可以使用什么替代_next和_reg?我正在阅读的教科书专门用于FSM设计(分为寄存器、下一状态逻辑和输出逻辑)。我想我知道这本教科书。。。在线上应该有很多关于“VHDL单进程状态机”的信息,包括这里的Stack Exchange。这是我最近发布的一个。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity big_yag is
generic(
T1: unsigned :=to_unsigned(0,26); --Lamp On
T2: unsigned :=to_unsigned(138889,26); --Lamp Off
T3: unsigned :=to_unsigned(4305555,26); --Q-switch On
T4: unsigned :=to_unsigned(4343434,26); --Q-switch Off
T5: unsigned :=to_unsigned(6434343,26)  --Reset Sequence
);
Port( 
clk,rst : in STD_LOGIC;
d,count: in STD_LOGIC_VECTOR(25 downto 0);
byag_l,byag_q : out STD_LOGIC
);
end big_yag;

architecture Behavioral of big_yag is
signal delay,counter: unsigned (25 downto 0);
signal byag_l_reg,byag_l_next,byag_q_reg,byag_q_next: std_logic;
begin
delay <= unsigned(d);
counter <= unsigned(count);

--register
process(rst,clk)
begin
if rst='1' then
    byag_l_reg <= '0';
    byag_q_reg <= '0';
elsif (clk='1' and clk'event) then
    byag_l_reg <= byag_l_next;
    byag_q_reg <= byag_q_next;
end if;
end process;

--next state logic
byag_l_next <= '1' when counter = T1+delay else
               '0' when counter = T2+delay else
               byag_l_reg;
byag_q_next <= '0' when counter = T1+delay else
               '1' when counter = T3+delay else
               '0' when counter = T4+delay else
               byag_q_reg;

--output logic
byag_l <= byag_l_reg;
byag_q <= byag_q_reg;

end Behavioral;