Verilog case变量应该是原子递增的吗?

Verilog case变量应该是原子递增的吗?,verilog,fpga,Verilog,Fpga,我正在编写Verilog代码,它通过迭代FSM的状态来逐步执行计算。该应用程序已按预期完成并运行,但对于效率要求,我想知道以下几点 我正在原子化地更新case变量“I”,如下面的摘录1所示,是否有必要确保它不会跳过FSM中的一个步骤 或者,摘录2中的方法是否同样安全,可以在不遗漏任何步骤的情况下运行 摘录二的速度是摘录一的两倍 在被问到之前。一切运行,一切都在使用前初始化,完成并封装在模块中时计数器重置为0 “i”的原子更新代码 “i”的非原子更新代码 在这两种情况下,每个clk上升沿仅执行

我正在编写Verilog代码,它通过迭代FSM的状态来逐步执行计算。该应用程序已按预期完成并运行,但对于效率要求,我想知道以下几点

我正在原子化地更新case变量“I”,如下面的摘录1所示,是否有必要确保它不会跳过FSM中的一个步骤

或者,摘录2中的方法是否同样安全,可以在不遗漏任何步骤的情况下运行

摘录二的速度是摘录一的两倍

在被问到之前。一切运行,一切都在使用前初始化,完成并封装在模块中时计数器重置为0


“i”的原子更新代码


“i”的非原子更新代码


在这两种情况下,每个clk上升沿仅执行一次always块。它们不会在相同的增量周期内重新评估(除非clk本身存在故障)

任何always块中的代码都像在其他编程语言中一样按顺序执行

因此,根据您的示例,第一个将每隔时钟边缘递增'i',而第二个将每隔时钟边缘递增'i'

我正在原子化地更新case变量“I”,如下面的摘录1所示,是否有必要确保它不会跳过FSM中的一个步骤

我不确定您在这里的意思,但是
I
将一个接一个地递增,而不会跳过,并且您的fsm中的case语句将有机会对两种情况下的每个“I”值作出反应。由于在第一个示例中使用了
ITERATE
,因此在计时方面会有所不同。此外,在第一个示例中,
i
将在case语句之前递增,在第二个示例中,在case语句之后递增。这是另一个区别

顺便说一句,单词
atomic
不适用于任何情况。你这是什么意思


还要注意的是,您并没有按照一般建议编写状态机、拆分状态和转换逻辑,而且您很可能在示例中误用了阻塞分配。这些可能是测试台可以接受的代码示例,但它们可能不适合RTL

verilog不是一种常规的编程语言。上面的例子并不是真正的verilog。您需要使用verilog进程、时钟和其他功能。在没有其他东西的情况下,很难分析您的意图,即总是阻塞。我建议您通过添加真实的verilog来编辑您的示例。我不会发布500行无关的代码,当这是有问题的代码时。我编写/设计的完整程序是一个可运行且可合成的verilog程序。MCVE的理念是,你,提问者,将500行代码减少到相关的位,但仍保持其可编译和可验证性。原子操作是并行/多线程/并发编程中使用的标准术语,意思是:“并发编程中的原子操作是完全独立于任何其他进程运行的程序操作。”——Java将其定义为:“原子操作”。原子操作是作为单个工作单元执行的操作,不可能受到其他操作的干扰。“谢谢你的回答。它澄清了我的信念,因此我可以不厌其烦地实现它。verilog是一种并发语言,但不是多线程。这意味着所有的语句都是你提到的原子式的。此外,所有始终块内容在某种程度上都是原子的(除非您有意插入模拟控制语句)。一般来说,“原子”不适用于verilog编程。
always @(posedge clk) begin
  if( ITERATE ) i = i + 1; //Atomic increment of variable
  else begin
    case( i )
      0: ....
      .: .... 
      n: The case internals are not pertinent
    endcase
  end
  ITERATE = !ITERATE; //Trigger for atomic update of i
end
always @(posedge clk) begin
  case( i )
    0: ....
    .: .... 
    n: The case internals are not pertinent
  endcase
  i = i + 1; //Non-atomic increment of variable
end