Verilog总是阻止按钮激活,FSM

时间:2014-11-13 01:18:09

标签: verilog fpga fsm quartus

我正在编写一些Verilog代码,以便在 Altera Cyclone II FPGA 板上编程,我有一个always块,应该在按下钥匙开关:

reg START;

...
...

always @ (negedge key[3]) begin
    if (START != 1) START = 1;
end

我正在为有限状态机编写一个程序,这个按键应该表示用户想要开始使用该程序,它应该从其初始状态转移到下一个状态。由于寄存器的初始化不可合成,我不能假设START从0开始。

问题在于,一旦我对电路板进行编程并将其打开,在我按下分配给always的密钥之前,此key[3]块已经运行过一次。我已经在程序执行时检查了START的值,它已经在1。我无法弄清楚为什么会发生这种情况,因为关键是只有在按键时它处于负面边缘。在以前的情况下,我总是使用具有相同条件的块,并且它工作正常,所以我认为这与START的初始化有关吗?

2 个答案:

答案 0 :(得分:1)

你应该使用"首字母"阻止设置信号的启动值。必须设置START和键[3]的值。

initial begin
  START = 1'b0;
  key[3] = 1'b1;
end

你说

  

由于寄存器的初始化不可合成,我不能   假设START从0开始。

但事实并非如此!您可以使用上述方法为设计中的任何信号设置默认值。该值包含在固件的比特流中,并且信号启动时具有此值。

欢呼声

答案 1 :(得分:1)

应该注意initial的可合成性取决于您编码的目标。
例如,如果您为模拟器编码,initial效果很好。如果您的目标是FPGA,那么该工具(在您的情况下为quartus)可以完全控制原理图和内部每个触发器的初始状态:实际上,将固件上传到FPGA会将每个触发器设置为已知状态,并且quartus能够解析initial以得出每个触发器的状态。 相反,如果你的目标是裸硅,每个触发器只是一堆晶体管,它的状态在上电时是完全无限的,所以控制它的通电状态的唯一方法是应用某种类型重置,像这样:

always @(posedge clk, negedge rst_n)
if( !rst_n )
    START <= 1'b0; // no start condition upon reset
else if( some_condition )
    START <= 1'b1;

您的代码的另一点是,在解析来自交换机的输入时,您应该首先重新同步到您的设计时钟,如下所示:

reg start_r, start_rr;
always @(posedge clk)
begin
    start_r  <= START;
    start_rr <= start_r;
end
// now use start_rr instead of START

重新同步是避免同步设计中亚稳状态的关键因素。

第二点是你应该考虑对机械开关的任何输入进行去抖动,除非你的设计能够容忍多次开关跳闸。

回到原来的问题瑞恩麦克卢尔要求。可以看出,在原始代码中没有initial START在启动时未定义,并且只能跳转到&#39; 1&#39;州。因此,合成器只是假设START是恒定的,总是有它&#39; 1&#39;。