水ライトのプロジェクトを説明するためのシンプルなアイテム(1)

EDITORIAL言葉

私たちが書かれた水のランプドライバを達成するために持っていることのこのセクションには、もちろん、照明が終わりではない、最も重要なのは、我々は、この軽水のコードを達成するために、いくつかの重要な仕様を持つことができるということです。

プロジェクトの要件

次のように我々は、軽水モードを主張:リセットボタンが押されると、すべてのライトは、リセットボタンが解除されると、まず、第1のランプが点灯され、第2のランプが点灯している間に、次に第1のランプは、次いで、オフ、オフ第二の光は、第三の照明ランプ、及び第三のライトがオフになっている間、第四のランプが同時に点灯し、オフであり、第1のランプが点灯しながら、最終的に第四の光が、消灯しているので、サイクル、水を達成。

関連技術の説明

プロジェクトの要件は、私たちが見ていると信じて、そして、我々はそれがどのように行うのですか?コードを書きますか?NO  我々はプロジェクトのニーズを詳しく見てとる内部キーを伴う、LEDが点灯し、我々はまた、光の流れを開始または停止するには、ボタンを制御する必要があります。あなたがコードを書く前に、そう、私たちは、最初にクリアキーを押しべきと違い何解放し、LED照明が低いか高い光です。唯一の明確なパフォーマンスの周辺機器、我々は適切にこれらの周辺機器を駆動するためにコードを書くことがあります。コードは、私たちの思考に反映されているので、私たちが書く前にコードが最初に無益でなければならないコードを書くためにそうブラインド、自分のアイデアをまっすぐ必要があります。

ハードウェア設計

次の図は、ボタンのタッチ示す接続関係FPGAの概略図を

キーが解放され、上記回路図から、FPGAポートはプルアップ抵抗、ハイレベルの検出に等しいです押下するとき、接地面にキーを介してFPGA端子がローレベルに検出されます。

次の図に示す LEDとFPGAとの接続関係を模式的に

上から見た回路図で正極のすべてに3.3V電源のLED。次いで、ポートはFPGAの低レベルが与えられた場合にのみ、LEDが点灯します。場合ハイエンドのFPGAは、LED消灯しました。

トップレベルのアーキテクチャ設計

関連する周辺機器のすべてのプロジェクトの要件とプロジェクトの要件は次がそれをコーディングを開始することができません、明確に分析されていますか?答えは -NO!ハハ、本当にケーキの一部であるコードを書くエンジニアのために、実際には、心配しないで、目がああ数行をノックすることができます閉じました。最終的な実装の成功を決める最も重要なプロジェクトは、一般的に特定のコードではなく、予備設計のアーキテクチャは、優れたアーキテクチャは同じように簡単に簡略化することができ、非常に複雑なプロジェクトは徐々に多くの単純なサブに分割されますモジュールは、設計効率と成功率が向上するだけでなく、労働力のチーム、部門として戦うために、より適していないだけ。前設計コードの先頭に最後まで明確な枠組みを持っていないとさえそれは単に原理でできないかもしれない場合は、全体的なアーキテクチャは、良い友達よりも多くの害ように再設計する必要があります。私たちの水のために以下に示すようにただ一つのモジュールにさらに簡単に、非常に単純なものの、基本的なビルディングブロックを、点灯が、その後、私たちは、このような習慣を開発する必要があります。

 

ポート説明

ポート名

機能

CLK

システムクロック入力(50MHzの)

RST_N

リセットボタン(アクティブロー)

pio_led

4ビットLED駆動ポート

 コードの説明

コードを書くことが最後にでき、特定のコードの実装手順は、(後で書くために何を、何を書くために)、あなたがビデオをサポートしている夢の翼兄弟を見ることができます。ここでは、特定のコードは、直接以下で与えます

/ ************************************************* ***          

*エンジニア:    ドリーム・ブラザーウイング

* QQ:761664056

*モジュール機能:水ライト

************************************************** *** /

01   モジュール  led_learn

CLK 02    // システム・クロック入力

RST_N 03  // システムリセット

04 pio_led // LED 駆動出力

05                   )。

06 // システム入力

07   入力  CLKを    // システム・クロック入力

08   INPUT  RST_N ;  // リセット

09 // システム出力

10   出力 REG  [ 3 0 ] pio_led ; // LED 駆動出力

11 // 定義されたバッファレジスタ

12は、   REG  [ 1 0 ]の状態; // ステータス・レジスタ定義

13 // LED 駆動ロジック

14   常に(@ posedgeの  CLK または negedgeの  RST_N

15       始めます

16           もし(! RST_N

17               始めます

Pio_led 18は、<= 4'b1111 ; // LEDが消灯しています

。状態19 <= 0 ; // 初期値を登録します

20               終了 

21           他に 始めます 

22              case(state)

23                  0:begin

24                      pio_led<=4'b0111;//第一个灯点亮

25                      state<=1;//状态跳转

26                  end 

27                  1:begin

28                      pio_led<=4'b1011;//第二个灯点亮

29                      state<=2;//状态跳转                 

30                  end 

31                  2:begin

32                      pio_led<=4'b1101;//第三个灯点亮

33                      state<=3;//状态跳转                 

34                  end 

35                  3:begin

36                      pio_led<=4'b1110;//第四个灯点亮

37                      state<=0;//状态跳转                 

38                  end 

39                  default:state<=0;

40                  endcase 

41          end

42      end 

43  endmodule 

 

这里我们应用的就是状态机的概念,第一步进行某些操作,然后跳到下一步进行其他操作,直到所有操作完成以后再返回初始状态

那么我们现在想当然写出来的逻辑是不是可以正确实现我们的目标呢?这其实还是一个大大的问号,那么接下来,我们需要做的就是进行逻辑仿真,梦翼师兄在教学过程中常说的一句话就是“对不对,只有仿真说了算”。

接下来我们编写仿真代码如下

/****************************************************          

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:流水灯测试模块

*****************************************************/

01  `timescale 1ns/1ps //时间单位和精度定义

02  module tb;

03

04  //系统输入

05  reg clk;   //系统时钟输入

06  reg rst_n; //系统复位

07  //系统输出

08  wire [3:0]pio_led;//LED驱动输出

09  

10  initial

11      begin

12          clk=0;

13          rst_n=0;

14          #1000.1 rst_n=1;

15      end 

16      

17      always #10 clk=~clk;//50MHz时钟

18      

19  led_learn led_learn(

20          .clk(clk),       //系统时钟输入

21          .rst_n(rst_n),   //系统复位

22          .pio_led(pio_led)//LED驱动输出

23        );

24  endmodule

 运行仿真软件Modelsim 查看仿真波形(软件具体操作请观看梦翼师兄配套教学视频)

 

由仿真图,我们可以看到在每个时钟的上升沿pio_led的值发生一次切换,从第一个到第四个灯依次循环点亮,说明逻辑设计正确。

好了,波形仿真正确了,如果下载到开发板,流水灯可以实现了吗?答案还是NO!什么?梦翼师兄疯了吧,一会儿说逻辑对了,一会儿又说流水灯还不能实现,到底能不能愉快的玩耍啦?哈哈,这就是仿真和真实环境条件切换的一个误区。大家试想一下,我们现在每来一个时钟,LED就会切换一次状态,那么由于我们的时钟是50MHz,因此我们的时钟周期仅仅为20Ns,这么快的速度,人的眼睛是无法分辨的,那么在这种条件下,我们当然是看不到流水现象的。

那么如何才能看到流水呢?对,我们必须降低LED的切换速度。那么LED的切换速度和谁有关系呢?第一当然是时钟,假设时钟速度很慢,那么流水的速度自然也会很慢,第二个原因就是状态机,因为不管时钟速度如何,状态机只要控制自己的状态不要那么快切换,那么也可以实现我们的目的。

那么,首先让我们从状态机的角度去控制LED的切换速度,我们给出修改的代码如下

/****************************************************          

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:流水灯

*****************************************************/

01  module led_learn(

02                      clk,   //系统时钟输入

03                      rst_n, //系统复位

04                      pio_led//LED驱动输出

05                  );

06  //系统输入

07  input clk;   //系统时钟输入

08  input rst_n; //系统复位

09  //系统输出

10  output reg [3:0]pio_led;//LED驱动输出

11  //中间寄存器定义

12  reg [1:0]state;//状态寄存器定义

13  reg [40:0]counter;//计数寄存器

14  //LED驱动逻辑

15  always@(posedge clk or negedge rst_n)

16      begin

17          if(!rst_n)

18              begin

19                  pio_led<=4'b1111;//LED全部熄灭

20                  state<=0;//寄存器赋初值

21                  counter<=0;//计数器赋初值

22              end 

23          else begin 

24              case(state)

25                  0:begin

26                      pio_led<=4'b0111;//第一个灯点亮

27                      if(counter<12)//延时时间不够则继续计数

28                          counter<=counter+1;

29                      else 

30                          begin 

31                              state<=1;//状态跳转

32                              counter<=0;//计数器清零

33                          end 

34                  end 

35                  1:begin

36                      pio_led<=4'b1011;//第二个灯点亮

37                      if(counter<12)//延时时间不够则继续计数

38                          counter<=counter+1;

39                      else 

40                          begin 

41                              state<=2;//状态跳转

42                              counter<=0;//计数器清零

43                          end                 

44                  end 

45                  2:begin

46                      pio_led<=4'b1101;//第三个灯点亮

47                      if(counter<12)//延时时间不够则继续计数

48                          counter<=counter+1;

49                      else 

50                          begin 

51                              state<=3;//状态跳转

52                              counter<=0;//计数器清零

53                          end                 

54                  end 

55                  3:begin

56                      pio_led<=4'b1110;//第四个灯点亮

57                      if(counter<12)//延时时间不够则继续计数

58                          counter<=counter+1;

59                      else 

60                          begin 

61                              state<=0;//状态跳转

62                              counter<=0;//计数器清零

63                          end                     

64                  end 

65                  default:state<=0;

66                  endcase 

67          end

68      end 

69  endmodule 

该段代码和上一段代码唯一的区别之处在于我们在状态机状态跳转的部分加入了延时计数器,只有累计时钟上升沿达到一定数量以后,状态才会发生跳转。这样就可以有效延长每个LED灯点亮的时间。当然啦,这里面计数值到12完全是梦翼师兄为了仿真方便而乱写的一个数,如果真的要实现流水灯,计数值应该很大才可以哦。接下来让我们看一下这段代码的仿真波形

对比两个波形图,我们可以看到加延时计数器之后,流水灯的切换速度明显变慢,可以实现我们的设计要求。通过该实验,我们同时也学到了计数器的用法。那么还剩下一种方式,那就是控制我们的频率了,我们设计代码如下

/****************************************************          

*   Engineer        :   梦翼师兄

*   QQ               :   761664056

*   The module function:流水灯

*****************************************************/

01  module led_learn(

02                      clk,   //系统时钟输入

03                      rst_n, //系统复位

04                      pio_led//LED驱动输出

05                  );

06  //系统输入

07  input clk;   //系统时钟输入

08  input rst_n; //系统复位

09  //系统输出

10  output reg [3:0]pio_led;//LED驱动输出

11  //中间寄存器定义

12  reg [1:0]state;//状态寄存器定义

13  reg [40:0]counter;//计数器定义

14  reg clk_slow;//慢时钟定义

15  //时钟分频电路

16  always@(posedge clk or negedge rst_n)

17      begin

18          if(!rst_n)

19              begin

20                  counter<=0;

21                  clk_slow<=0;

22              end 

23          else 

24              begin

25                  if(counter<12)

26                      counter<=counter+1;

27                  else 

28                      begin

29                          counter<=0;

30                          clk_slow<=~clk_slow;

31                      end 

32              end 

33      end 

34      

35  //LED驱动逻辑

36  always@(posedge clk_slow or negedge rst_n)

37      begin

38          if(!rst_n)

39              begin

40                  pio_led<=4'b1111;//LED全部熄灭

41                  state<=0;//寄存器赋初值

42              end 

43          else begin 

44              case(state)

45                  0:begin

46                      pio_led<=4'b0111;//第一个灯点亮

47                      state<=1;//状态跳转

48                  end 

49                  1:begin

50                      pio_led<=4'b1011;//第二个灯点亮

51                      state<=2;//状态跳转                 

52                  end 

53                  2:begin

54                      pio_led<=4'b1101;//第三个灯点亮

55                      state<=3;//状态跳转                 

56                  end 

57                  3:begin

58                      pio_led<=4'b1110;//第四个灯点亮

59                      state<=0;//状态跳转                 

60                  end 

61                  default:state<=0;

62                  endcase 

63          end

64      end 

65  endmodule 

以上代码16-33行为我们添加的计数器分频模块,通过计数器计数,利用快时钟分频得到一路慢时钟。代码36行

36  always@(posedge clk_slow or negedge rst_n)

我们用分频得到的慢时钟作为状态机的切换时钟,这样也可以有效控制状态机切换的速度。查看仿真波形如下

由仿真图可知,第一:快时钟正确生产了慢时钟 第二:LED在慢时钟的控制下进行切换,说明我们的逻辑设计正确。通过该实验,我们也可以学会分频电路的设计方法。这也是梦翼师兄的初衷,尽可能通过一个实验项目多学东西,后面我们就可以利用这些知识点来解决其他问题啦。

 

おすすめ

転載: www.cnblogs.com/mengyi1989/p/11517606.html