1

我正在尝试在 verilog 中创建一个有限状态机。该系统有 4 个1-bit 输入 rst,和1个输出clk, 。ABZ

Z 等于 1,如果: A 在最后两个时钟沿具有相同的值。

或 B 自上一条规则成立以来在每个时钟沿都为高 (1)。

否则z=0

我没有工具来模拟我的尝试 atm。所以我想知道这是否是正确的方法,如果我走在正确的轨道上?

module StateMachine( R, A, B, clk, Z);
   input R, A, B, clk;
   output reg Z;

   reg ATemp;
   reg state;

   always @ (posedge clk or A)
      if (A == 1'b1) 
      /////////////////
      begin
         if (ATemp == 1'b1) state <= 1'b1; 
         else ATemp <= A;
       end
       ////////////////
       else
       ////////////
       begin
          if (ATemp == 1'b0) state <= 1'b1;
          else ATemp <= A;
       end


   always @ (state)
      case(state)
         1'b0: Z=0;
         1'b1: Z=1;

         default: Z=0;
      endcase

endmodule
4

3 回答 3

1

您可以使用以下工具:

GHDL是 VHDL 语言的开源模拟器(用户指南

此外,这些是最流行的模拟工具

更多资源:

还有stackexchange电子社区和codereview

此外,注意C 到 HDL编译器工具

(.. 我怀疑很多人可以在 3 分钟内查看您的代码,我也不想要它们)

于 2012-09-24T17:58:11.737 回答
0

你对触发器的定义有点错误。你有always @ (posedge clk or A). 不应将边沿触发和非边沿触发结合使用。它可能在模拟中工作,但你不会在综合中得到你想要的。

如果您只希望值在时钟边沿发生变化,则使用always @( posedge clk)or 用于组合输入,即输出随输入使用always @( A )或更现代的版本而变化always @*。@* 将触发任何更改。敏感度列表中缺少项目是合成代码无法模拟 RTL 的主要原因。

说如果你正在构建一个触发器,你应该包括一个复位。always @ (posedge clk or negedge rst_n)

另请注意,状态永远不会设置为 0,因此第一印象是这将锁定到特定的状态/输出。我很难看到代码是如何实现被问到的问题的。我的解决方案是这样的:

module statemachine(
  input      rst,
  input      A,
  input      B,
  input      clk,
  output reg Z
);

  reg  [1:0] a_last_two;
  wire      rule_one;

  always @ (posedge clk or negedge rst) begin
    if (~rst) begin
      a_last_two <= 2'b0;
    end
    else begin
      a_last_two <= {a_last_two[0] ,A}; 
    end
  end

  assign rule_one = (a_last_two[1] == a_last_two[0]); 
  //rule one could be written as ~^a_last_two (xnor reduction operator)

  reg rule_two;
  always @ (posedge clk or negedge rst) begin
    if (~rst) begin
      rule_two <= 1'b0 ;
    end
    else begin
      //rule 2 resets when rule_one is true
      if (rule_one) begin
        rule_two <= 1'b1 ;
      end
      else begin
        rule_two <= rule_two & B ;
      end
    end
  end

  assign Z = rule_one | rule_two ;

endmodule
于 2012-09-25T06:54:41.007 回答
0

您没有下一个状态逻辑,因此状态永远不会改变,并且没有重置,因此状态将以 1'bz 开始。我建议在编码状态机时从Xilinx 指南开始。

于 2012-09-24T17:58:52.147 回答