利用條件語句實現不同佔空比的分頻時鐘電路

1,要實現的是如下的一個“產生佔空比不同的分頻時鐘”:


(1)、建模:

module fdivision_module(clock,d_clock,reset,j);
  input clock,reset;
  output d_clock,j;
  
  reg d_clock;
  reg [2:0]j;
  
  always @(posedge clock)
  begin
    if(!reset)

//初始化過程
      begin
        d_clock<=0;
        j<=0;
      end
    else
      begin
      if(j==4)
        j<=0;
      else if(j==1)
        begin
          d_clock=1;
          j<=j+1;
        end
      else
        begin
          d_clock=0;
          j<=j+1;
        end
      end
  end
endmodule

(2)testbench:

`include "fdivision_module.v"
module fdivision_stimulus;


  reg clock,reset;
  wire d_clock;
  wire [2:0]j;
  
  fdivision_module  fd(clock,d_clock,reset,j);
  
  initial
  begin
    clock=0;
    forever #5 clock=~clock;
  end
  
  initial
  begin
    reset=0;
    #20 reset=1;
    #100 reset=1;
    #5 reset=1;
  end

(3)、正確仿真波形:


2、出現的問題及解決辦法:

(1)、第一次的仿真結果如下:由圖可見,在reset置0的時候,d_clock並沒有置0,沒有初始化


(2)、爲了調試程序,我將局部變量j也作爲輸出變量,得到下面的仿真結果:局部起到計數的變量一直爲未知量x


(3)、改動程序,將reset也放入always的敏感列表中,寫成always @(posedge clock,negedge reset),得到下面的結果:很顯然,儘管仿真出結果,但是佔空比錯誤,這個錯歸根結底還是在於計數器的設定,開始我寫成(j==5)時,j<=0;(j==2)時,d_clock=1;特別很明顯0~5總共經歷了6個時鐘。所以,建模過程中,要特別注意計數器j的設定。


(4),現在回過頭來想想最開始的建模有什麼錯誤,在2.3中,將reset置於敏感列表中,寫成always @(posedge clock,negedge reset),這相當於異步置0 ,reset的置0信號是不受時鐘控制的,只要reset=0,就能將d_clock和j置0。但是在最開始錯誤的2.1中,敏感列表爲always @(posedge clock),再在後面過程塊中寫,reset=0時,j=0,d_clock=0;那麼這時的reset置0爲同步置0,只有當上升沿出現時,才生效,給j和d_clock賦值。但是,我在testbench模塊中,給reset的賦值如下圖:很顯然,在0~5ns時,reset=0,#5ns之後reset=1,則當#10ns,上升沿到來時,reset已經爲1,不能再給j和d_clock賦值了,所以造成了2.1的錯誤。特別值得注意的是,在異步置0時,reset=0的保持時間可以任意,但同步置0時,reset=0的保持時間需要大於一個時鐘,否則就會出現上面上升沿還沒到來,reset就爲1,不能賦值的錯誤。 



發佈了64 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章