【问题标题】:Verilog behavioral code getting simulated properly but not working as expected on FPGAVerilog 行为代码得到正确模拟,但在 FPGA 上无法按预期工作
【发布时间】:2016-09-15 16:42:29
【问题描述】:

`时间刻度 1ns / 1ps

module StateMachine(
   input [1:0] OP,
   input [1:0] RESULT_COM,
   input clk,
   input rst,
   output reg [1:0] CONTROL_AS=0,
   output reg RESET_C,
   output reg  CONTROL_C,
   output reg [1:0] state=0
    );

  parameter toLOWER=2'b01,toUPPER=2'b10,IDLE=0;
    reg [1:0] n_state = IDLE;
    //reg [1:0] state = IDLE;
    reg [1:0] p_state = IDLE;
    reg [1:0] prevOP = 2'b00;
    reg [1:0] p_state_copy = 2'b00;
    reg [15:0] count = 0;

   always @ (posedge clk)
    begin   
     if(rst == 1)
      RESET_C = 1;
     else
      RESET_C = 0;  

      if(OP == 2'b01)
        n_state = toLOWER;
      else 
        if(OP == 2'b10)
        n_state = toUPPER;
      else
        n_state = IDLE;

      if(prevOP == OP)
         p_state = state;

      if((OP != prevOP && OP[0] != OP[1]) || (rst == 1 && (OP != 2'b00 && OP != 2'b11)))
        CONTROL_C = 1;
      else
        CONTROL_C = 0;

      if(state != n_state)      
         prevOP = OP;

      state = n_state;
   end

   always @ (n_state)
    begin
      p_state_copy = p_state;    
    end

   always @ (p_state)
    begin
      case(p_state)
       toLOWER:
         begin
           if(RESULT_COM == 2'b10)
             CONTROL_AS <= 2'b10;
           else
             CONTROL_AS <= 2'b00; 
         end

       toUPPER:
         begin
           if(RESULT_COM == 2'b01)
             CONTROL_AS <= 2'b01;
           else
             CONTROL_AS <= 2'b00; 
         end

       IDLE:
         begin
           if(p_state_copy == toUPPER && RESULT_COM == 2'b01)
              CONTROL_AS <= 2'b01;  
          else if(p_state_copy == toLOWER && RESULT_COM == 2'b10)
               CONTROL_AS <= 2'b10;
          else if(p_state_copy == toUPPER && RESULT_COM == 2'b10)
              CONTROL_AS <= 2'b0; 
          else if(p_state_copy == toLOWER && RESULT_COM == 2'b01)
              CONTROL_AS <= 2'b0;  
          else if(p_state_copy == toUPPER && RESULT_COM == 2'b0)
              CONTROL_AS <= 2'b0; 
           //(p_state_copy == toLOWER && RESULT_COM == 2'b0)
          else CONTROL_AS <= 2'b0; 
         end

      endcase
    end
endmodule    

它是一个字母转换器。 OP 是 2 位输入。 11 和 00 表示什么都不做。 01 从 ROM 加载下一个字母(使用计数器更新地址)并转换为小写。 10 加载下一个字母并转换为小写。如果字母不是大写或小写,或者是小写但 OP 想要将其转换为小写等,则不会转换字母。如果没有输入(00 或 11)或始终断言有效输入(01 或 10) ,然后输出仍然存在。

我使用 p_state_copy 来保存先前的状态,当下一个 clk 上升沿到来时,它与状态有部分重叠。因此它可以检查之前的状态是否为 IDDLE(输入 00 或 11)。 RESULT_COM 是比较器的结果,用于检查字母状态。图中,RESULT 中的隐藏部分为 0,因为 reset 被断言。enter image description here

我可以模拟、综合和实现它。但我不能在板上运行它。我可以知道问题是什么吗?谢谢。

【问题讨论】:

    标签: verilog


    【解决方案1】:
    always @ (n_state)
     begin
       p_state_copy = p_state;    
     end
    

    这个逻辑无法合成。 FPGA 没有实用的方法在逻辑信号(如n_state)的变化上锁存一个值(如p_state_copy)。

    一般来说,用于在 FPGA 上综合的代码中的 always 块应该对同步块的 posedge clk(或其他一些时钟信号)敏感,或者对于随机逻辑的 * 敏感。指定单个信号只会给您带来麻烦。

    【讨论】:

      【解决方案2】:

      这段代码有几个问题会阻止它正确合成。

       always @ (posedge clk)
       begin   
         if(rst == 1)
           RESET_C = 1;
      

      应该更像

       always @ (posedge clk or posedge rst)
       if(rst == 1)
         RESET_C = 1;
      else
      begin
      

      有几个总是@(...) 不完整的敏感度列表。例如

      always @ (p_state)
      begin
        case(p_state)
         toLOWER:
      

      缺少到目前为止我发现的 p_state_copy 和 RESULT_COM。 我建议使用 always @(*) 或更好的可维护性,如果您的工具允许 always_comb

      但是如果敏感度列表不正确,它几乎肯定会模拟不正确。 (模拟工具只会在指定的输入发生变化时评估代码块,而不是真正的组合逻辑,它不会做出这种限制)。出于这个原因,许多合成引擎会忽略敏感度列表。

      您还在梳状逻辑块中使用非阻塞赋值,并在梳状逻辑块中使用阻塞赋值。

      您正在对变量定义使用初始语句。这些将被合成引擎忽略。

      此外, (rst == 1 && (OP != 2'b00 && OP != 2'b11)) 将无法正确合成。如果您希望它正确运行,您需要坚持使用标准触发器 verilog 模板。

      这些都会导致非常不稳定的模拟结果。我认为您需要先解决这些问题,然后检查您的模拟是否仍按预期运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-24
        • 1970-01-01
        • 1970-01-01
        • 2014-12-06
        • 1970-01-01
        • 2014-12-25
        • 1970-01-01
        相关资源
        最近更新 更多