【黑金原創教程】【FPGA那些事兒-驅動篇I 】【實驗一】流水燈模塊

實驗一:流水燈模塊

對於發展商而言,動土儀式無疑是最重要的任務。爲此,流水燈實驗做爲低級建模II的動土儀式再適合不過了。廢話少說,咱們仍是開始實驗吧。css

clip_image002

圖1.1 實驗一建模圖。html

如圖1.1 所示,實驗一有名爲 led_funcmod的功能模塊。若是無視環境信號(時鐘信號還有復位信號),該功能模塊只有一組輸出端,亦即4位LED信號。接下來讓咱們來看具體內容:學習

led_funcmod.v
1.    module led_funcmod
2.    (
3.         input CLOCK, RESET,
4.         output [3:0]LED
5.    );

以上內容爲出入端聲明。spa

6.         parameter T1S = 26'd50_000_000; //1Hz
7.         parameter T100MS = 26'd5_000_000; //10Hz
8.         parameter T10MS = 26'd500_000; //100Hz
9.         parameter T1MS = 26'd50_000; //1000Hz
10.         

以上內容爲常量聲明。分別是1秒至1毫秒。code

11.         reg [3:0]i;
12.         reg [25:0]C1;
13.         reg [3:0]D;
14.         reg [25:0]T;
15.         reg [3:0]isTag;
16.         
17.         always @ ( posedge CLOCK or negedge RESET )
18.             if( !RESET )
19.                  begin
20.                         i <= 4'd0;
21.                         C1 <= 26'd0;
22.                         D <= 4'b0001;
23.                         T <= T1S;
24.                         isTag <= 4'b0001;
25.                    end
26.              else

以上內容是相關的寄存器聲明以及復位操做。寄存器i用來指向步驟,寄存器C1用來計數,寄存器D用來暫存結果和驅動輸出,寄存器T用來暫存計數量,isTag則用來暫存延遲標籤。htm

27.                case( i )
28.                
29.                      0:
30.                      if( C1 == T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
31.                      else begin C1 <= C1 + 1'b1; D <= 4'b0001; end
32.                      
33.                      1:
34.                      if( C1 == T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
35.                      else begin C1 <= C1 + 1'b1; D <= 4'b0010; end
36.                      
37.                      2:
38.                      if( C1 == T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
39.                      else begin C1 <= C1 + 1'b1; D <= 4'b0100; end
40.                      
41.                      3:
42.                      if( C1 == T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
43.                      else begin C1 <= C1 + 1'b1; D <= 4'b1000; end
44.                      
45.                      4:
46.                      begin isTag <= { isTag[2:0], isTag[3] }; i <= i + 1'b1; end
47.                      
48.                      5:
49.                      if( isTag[0] ) begin T <= T1S; i <= 4'd0; end
50.                      else if( isTag[1] ) begin T <= T100MS; i <= 4'd0; end
51.                      else if( isTag[2] ) begin T <= T10MS; i <= 4'd0; end
52.                      else if( isTag[3] ) begin T <= T1MS; i <= 4'd0; end 
53.                      
54.              endcase        
55.        
 
56.        assign LED = D;
57.            
58.    endmodule

以上內容爲是核心操做以及輸出驅動聲明。步驟0~3用來實現流水燈效果。最初,每一個步驟的停留時間是 1秒,而後步驟0~3按順序執行便會產生流水效果。步驟4是用來切換模式,步驟5則是根據isTag的內容再爲 T寄存器載入不一樣的延遲內容,如 [0] 延遲1秒,[1] 延遲100毫妙,[2] 延遲10毫妙,[3] 延遲1毫妙。默認下爲模式0(第24行),既延遲1秒(第23行)。blog

這個實驗所在意的內容根本不是實驗結果而是低級建模II自己。倘若比較《建模篇》的流水實驗,低級建模I與低級建模II之間是有明顯的差距。首先,低級建模II不再見計數器或者定時器等周邊操做。再者,低級建模II的整合度很高,例如步驟0~3:ip

1.           0:
2.          if( C1 == T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
3.          else begin C1 <= C1 + 1'b1; D <= 4'b0001; end 
4.          1:
5.          if( C1 == T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
6.          else begin C1 <= C1 + 1'b1; D<= 4'b0010; end          
7.          2:
8.          if( C1 ==T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
9.          else begin C1 <= C1 + 1'b1; D <= 4'b0100; end          
10.          3:
11.          if( C1 == T -1) begin C1 <= 26'd0; i <= i + 1'b1; end
12.          else begin C1 <= C1 + 1'b1; D <= 4'b1000; end

代碼1.1rem

內容如代碼1.1所示,步驟0~3每一個步驟示意一段完整的小操做,例如步驟0爲4’b0001保持一段時間,步驟1爲4’b0010保持一段時間,步驟2~3也是如此。其中 -1也考慮了步驟切換的時間。假設流水間隔要求1毫妙,那麼每一個步驟都會準確無誤停留50000個時鐘。事實上,步驟0也能夠換成比較方便的寫法,如代碼1.2所示:rpc

1.        reg [3:0] D = 4’b0001;  
2.        ......
3.        0,1,2,3:
4.        if( C1 == T -1) begin D <= { D[2:0], D[3] }; C1 <= 26'd0; i <= i + 1'b1; end
5.        else begin C1 <= C1 + 1'b1; end

代碼1.2

代碼1.2表示,只要寄存器D準備好初值,例如 4’b0001,那麼步驟0~3均可以共享一樣的操做,如此一來會大大減小行數,節省空間。好奇的同窗必定以爲疑惑,既然代碼1.2的寫法那麼方便,反之筆者爲什麼要選擇代碼1.1的寫法呢?緣由很單純,那是爲了清晰模塊內容,以至咱們容易腦補時序。感受上,二者雖然都差很少,可是咱們只要仔看,咱們便會發現 ... 代碼1.2它雖然書寫方便,但是細節模糊並且內容也不直觀。

在此,筆者須要強調!低級建模II雖然有整合技巧讓操做變得更加便捷,不過比起整合它更加註重表達能力以及清晰度。這樣作的關鍵是爲了發揮主動思想,以便擺脫無謂的仿真。因此說,若是讀者想和低級建模II做朋友,建模以前應該優先考慮內容的清晰度,而不是內容的精簡性。若是內容即精簡又直觀,這種狀況固然是最好的結果。

至於實驗一是沒有仿真的必要,由於內容足夠直白,這種程度足以腦補時序。最後筆者還要說道,實驗一雖然沒有什麼學習的價值,可是實驗一要表達的信息也很是清楚,即低級建模II是注重清晰,直觀的建模技巧。此外,實驗一也能夠做爲學習的熱身。

相關文章
相關標籤/搜索