2016-07-10 77 views
0

,我需要解決的FPGA原型驗證通過Verilog實例的問題PongFSM實現去除抖動電路的Verilog(誤差在時間刻度)

如果它的作者日期錯誤或我做某事錯 當我在模擬vivado我沒有發現任何變化

q_reg <= q_next; // ? q_next never initialised ??? 
    // next-state logic // How he wants to set time tick ? 
    assign q_next = q_reg + 1; 
    // output tick 

去抖動電路的狀態圖。被定義爲圖片

考慮部
//計數器來產生10毫秒蜱

enter image description here

module db_fsm 
    (
    input wire clk, reset, 
    input wire sw, 
    output reg db 
    ); 

    // symbolic state declaration 
    localparam [2:0] 
       zero = 3'b000, 
       wait1_1 = 3'b001, 
       wait1_2 = 3'b010, 
       wait1_3 = 3'b011, 
       one  = 3'b100, 
       wait0_1 = 3'b101, 
       wait0_2 = 3'b110, 
       wait0_3 = 3'b111; 

    // number of counter bits (2^N * 20ns = 10ms tick) 
    localparam N =19; 

    // signal declaration 
    reg [N-1:0] q_reg; 
    wire [N-1:0] q_next; 
    wire m_tick; 
    reg [2:0] state_reg, state_next; 

    // body 

    //============================================= 
    // counter to generate 10 ms tick 
    //============================================= 
    always @(posedge clk) 
     q_reg <= q_next; 
    // next-state logic 
    assign q_next = q_reg + 1; 
    // output tick 
    assign m_tick = (q_reg==0) ? 1'b1 : 1'b0; 

    //============================================= 
    // debouncing FSM 
    //============================================= 
    // state register 
    always @(posedge clk, posedge reset) 
     if (reset) 
      state_reg <= zero; 
     else 
      state_reg <= state_next; 

    // next-state logic and output logic 
    always @* 
    begin 
     state_next = state_reg; // default state: the same 
     db = 1'b0;    // default output: 0 
     case (state_reg) 
     zero: 
      if (sw) 
       state_next = wait1_1; 
     wait1_1: 
      if (~sw) 
       state_next = zero; 
      else 
       if (m_tick) 
        state_next = wait1_2; 
     wait1_2: 
      if (~sw) 
       state_next = zero; 
      else 
       if (m_tick) 
        state_next = wait1_3; 
     wait1_3: 
      if (~sw) 
       state_next = zero; 
      else 
       if (m_tick) 
        state_next = one; 
     one: 
      begin 
       db = 1'b1; 
       if (~sw) 
       state_next = wait0_1; 
      end 
     wait0_1: 
      begin 
       db = 1'b1; 
       if (sw) 
        state_next = one; 
       else 
       if (m_tick) 
        state_next = wait0_2; 
      end 
     wait0_2: 
      begin 
       db = 1'b1; 
       if (sw) 
        state_next = one; 
       else 
       if (m_tick) 
        state_next = wait0_3; 
      end 
     wait0_3: 
      begin 
       db = 1'b1; 
       if (sw) 
        state_next = one; 
       else 
       if (m_tick) 
        state_next = zero; 
      end 
     default: state_next = zero; 
     endcase 
    end 

endmodule 
+0

您的問題似乎已被切斷:「當我在vivado上模擬時,我沒有發現任何變化」。你如何測試這段代碼?您遇到什麼問題或錯誤? – Teajay

+0

@TJ遵循Greg和RahulMenon的迴應 – tohidprogram

回答

2

q_next不需要被初始化,它是從q_reg衍生的組合邏輯。 q_reg未明確初始化,因此它將採用默認值。

FPGA上觸發器的默認值爲0,但對於仿真器,默認值爲X。這種差異的原因是因爲Verilog也用於模擬集成電路(IC);誰觸發器可以具有由於技術節點,製造工藝和變化,溫度等

由於目標是FGPA,簡單的解決方案是增加行initial q_reg = {N{1'b0}};或更改reg [N-1:0] q_reg;reg [N-1:0] q_reg = {N{1'b0}};要麼似乎隨機的初始值初始化方式q_reg將會讓你進行Verilog仿真和FPGA匹配。 BTW:對於ASIC作爲目標,FPGA解決方案將不起作用(ASIC合成器忽略初始化器)。一個ASIC解決方案可能會爲分配觸發器的always塊添加一個復位條件(同步或異步)。 ASIC解決方案適用於FPGA,但FPGA的異步復位/集合通常具有有限的觸發器數目(如果有)

+0

(@ Greg)儘管重置解決方案是ASIC的首選方式,但計數器(在最初的幾個時鐘週期後,最大值)將穩定到一個隨機值,並在第一次翻轉啓動後生成常規的m_ticks。這應該不是那麼好,因爲主要關注的是去除正常的m_tick?第一個m_tick是可以忽略的。 –

+0

@RahulMenon,在這種設計的情況下,等待正常m_tick浪費高達10ms可能是可以接受的,但這將是ASIC設計的整體最佳實踐中的一個小例外。對於大多數ASIC設計來說,10ms浪費的時間太多了。另外一個典型的ASIC有幾百甚至幾千甚至幾百萬的觸發器,其中大部分用於控制邏輯。一個未知的控制狀態會產生不可預測和有害的行爲。在ASIC中我唯一看到故意沒有異步復位的觸發器是在高速數據管道中保證不影響控制邏輯。 – Greg