• 【连载】 FPGA Verilog HDL 系列实例交通灯的控制


    【连载】 FPGA Verilog HDL 系列实例

    Verilog HDL 之 交通灯的控制

    原理与要求: 

       在十字路口,每条道路各有一组红、黄、绿灯和倒计时显示器,用以指挥车辆和行人有序的通行。其中。红灯亮表示该道路禁止通行;黄灯亮表示停车;绿灯亮表示可以通行;倒计时显示器是用来显示允许通行或禁止通行的时间。交通灯控制器就是用于自动控制十字路口的交通灯和计时器,指挥各种车辆和行人安全通过。
    下面我们就设计一个这样的:
    1)、在十字路口设置一组红、黄、绿等,显示顺序为:红,绿,黄,红……
    2)、设置一组数码管,以倒计时的方式显示允许通过或禁止通过的时间,其中绿灯、黄灯、红灯的持续时间为20s,5s,25s。

    Verilog HDL实现

      实现步骤请参照 【连载】 FPGA Verilog HDL 系列实例--------8-3编码器。这里就不再赘述。

    设计文件输入Verilog HDL代码。

      系统分为两个模块,一个是顶层traffic,一个是分频模块clkgen。

      分频模块clkgen的实现如下:

    clkgen.v
     1 //-------------------------------------------------------------------------------------------------
    2 //
    3 // File : clkgen.v
    4 // Generated : 2011-07-24
    5 // Author : wangliang
    6 //
    7 //-------------------------------------------------------------------------------------------------
    8 `timescale 1 ns / 1 ps
    9
    10 module clkgen ( rst ,clkout ,clk );
    11
    12 input rst ;
    13 wire rst ;
    14 input clk ;
    15 wire clk ;
    16
    17 output clkout ;
    18 reg clkout ;
    19
    20 reg [31:0] count1;
    21
    22 always @ ( posedge clk or negedge rst)
    23
    24 begin
    25 if ( rst== 1'b0 ) begin
    26 clkout <= 1'b0;
    27 count1 <= 17'b0;
    28 end
    29 else begin
    30 if ( count1 >= 32'd25000000) begin
    31 clkout <= ~clkout ;
    32 count1 <=#1 17'b0;
    33 end
    34 else begin
    35 count1 <= count1 + 1;
    36
    37 end
    38 end
    39 end
    40 endmodule

       顶层traffic的实现如下:

    traffic.v
      1 //-------------------------------------------------------------------------------------------------
    2 //
    3 // File : traffic.v
    4 // Generated : 2011-07-24
    5 // Author : wangliang
    6 //
    7 //-------------------------------------------------------------------------------------------------
    8 `timescale 1 ns / 1 ps
    9
    10 module traffic ( clk ,en ,seven_seg ,lamp ,rst);
    11
    12 input clk ;
    13 wire clk ;
    14 input en ;
    15 wire en ;
    16 input rst ;
    17 wire rst ;
    18 output [15:0] seven_seg ;
    19 wire [15:0] seven_seg ;
    20 output [2:0] lamp; //0: green 1: yellow 2:red
    21 reg [2:0] lamp;
    22
    23 reg [7:0] num ;
    24 reg temp ;
    25 reg [7:0] red_t ;
    26 reg [7:0] yellow_t;
    27 reg [7:0] green_t ;
    28 wire clkout ;
    29 reg [1:0] state;
    30
    31 parameter [1:0] red = 2'd0,
    32
    33 green = 2'd2 ,
    34 yellow2 = 2'd3 ;
    35
    36 clkgen clkgen (
    37 .rst ( rst ) ,
    38 . clk ( clk ) ,
    39 .clkout( clkout) );
    40
    41
    42 always @ ( posedge clkout or negedge rst)
    43 begin
    44 if( rst == 0 )
    45 begin
    46 state <= 2'b0 ;
    47 temp <= 1'b0 ;
    48 red_t <= 8'b0010_0101; //设置灯计时器的预置数,采用BCD码
    49 yellow_t <= 8'b0000_0101;
    50 green_t <= 8'b0010_0000;
    51 end
    52 else begin
    53 if ( en )
    54 begin
    55 if ( !temp ) begin
    56 temp <= 1'b1;
    57 case ( state ) //交通灯状态变换
    58 red : begin
    59 num <= red_t ;
    60 lamp <= 3'b100;
    61 state <= green;
    62 end
    63
    64 green : begin
    65 num <= green_t ;
    66 lamp <= 3'b001;
    67 state <= yellow2 ;
    68 end
    69 yellow2 : begin
    70 num <= yellow_t ;
    71 lamp <= 3'b010;
    72 state <= red ;
    73 end
    74 default : lamp <= 3'b100 ;
    75 endcase
    76 end
    77 else begin //倒计数
    78 if ( num >1'b1 )
    79 if ( num [3:0] == 0 ) begin
    80 num [ 3:0 ] <= 4'b1001;
    81 num [7:4] <= num [7:4] -1 ;
    82 end
    83 else num [3:0] <= num [3:0] -1 ;
    84 if ( num == 2 )
    85 temp <= 0 ;
    86 end
    87 end
    88 else begin
    89 lamp <= 3'b100 ;
    90 state <= red ;
    91 temp <= 0 ;
    92 end
    93 end
    94 end
    95
    96
    97 /************************ 数码管译码**************************************/
    98 reg [7:0] Y_r_1;
    99 reg [7:0] Y_r_2;
    100
    101 assign seven_seg[7:0] ={1'b1,(~Y_r_1[6:0])};
    102 assign seven_seg[15:8] = {1'b1,(~Y_r_2[6:0])};
    103
    104 always @(num[3:0] )
    105 begin
    106 Y_r_1 = 7'b1111111;
    107 case (num[3:0] )
    108 4'b0000: Y_r_1 = 7'b0111111; // 0
    109 4'b0001: Y_r_1 = 7'b0000110; // 1
    110 4'b0010: Y_r_1 = 7'b1011011; // 2
    111 4'b0011: Y_r_1 = 7'b1001111; // 3
    112 4'b0100: Y_r_1 = 7'b1100110; // 4
    113 4'b0101: Y_r_1 = 7'b1101101; // 5
    114 4'b0110: Y_r_1 = 7'b1111101; // 6
    115 4'b0111: Y_r_1 = 7'b0000111; // 7
    116 4'b1000: Y_r_1 = 7'b1111111; // 8
    117 4'b1001: Y_r_1 = 7'b1101111; // 9
    118 4'b1010: Y_r_1 = 7'b1110111; // A
    119 4'b1011: Y_r_1 = 7'b1111100; // b
    120 4'b1100: Y_r_1 = 7'b0111001; // c
    121 4'b1101: Y_r_1 = 7'b1011110; // d
    122 4'b1110: Y_r_1 = 7'b1111001; // E
    123 4'b1111: Y_r_1 = 7'b1110001; // F
    124 default: Y_r_1 = 7'b0000000;
    125 endcase
    126 end
    127
    128 always @( num[7:4] )
    129 begin
    130 Y_r_2 = 7'b1111111;
    131 case ( num[7:4] )
    132 4'b0000: Y_r_2 = 7'b0111111; // 0
    133 4'b0001: Y_r_2 = 7'b0000110; // 1
    134 4'b0010: Y_r_2 = 7'b1011011; // 2
    135 4'b0011: Y_r_2 = 7'b1001111; // 3
    136 4'b0100: Y_r_2 = 7'b1100110; // 4
    137 4'b0101: Y_r_2 = 7'b1101101; // 5
    138 4'b0110: Y_r_2 = 7'b1111101; // 6
    139 4'b0111: Y_r_2 = 7'b0000111; // 7
    140 4'b1000: Y_r_2 = 7'b1111111; // 8
    141 4'b1001: Y_r_2 = 7'b1101111; // 9
    142 4'b1010: Y_r_2 = 7'b1110111; // A
    143 4'b1011: Y_r_2 = 7'b1111100; // b
    144 4'b1100: Y_r_2 = 7'b0111001; // c
    145 4'b1101: Y_r_2 = 7'b1011110; // d
    146 4'b1110: Y_r_2 = 7'b1111001; // E
    147 4'b1111: Y_r_2 = 7'b1110001; // F
    148 default: Y_r_2 = 7'b0000000;
    149 endcase
    150 end
    151 endmodule

    注:第36行~第39行:实例化分频模块;第42行~第94行:红绿灯的控制以及时间的递减;第97行~第150行:数码管对时间的显示。

    引脚分配:

    图1.1 分频模块

            图1.2 顶层模块

      图1.2实例化图1.1,所以只需要对图1.2上的引脚进行分配。其中,clk接50MHZ系统时钟,rst接复位信号,en接按键,控制开始与结束,lamp[2..0]接红黄绿灯,seven_seg[15..0]接2个数码管。

    实验结果:

      红灯倒计时25S,转绿灯20S,转黄灯5S,转红灯25S。。。

    PS:有想法的可以再尝试着做个十字路的那种红绿灯哦。
     

  • 相关阅读:
    Code First数据库迁移
    创建静态报表
    JavaScript prototype
    把事务封装成类似Serializable用法的特性
    我的开发框架(WinForm)2
    使用 NPC,NPCManager 在 XNA 中创建 NPC
    ExtJs控件属性配置详细
    Python+Django+Eclipse 在Windows下快速开发自己的网站
    C++ const && 二叉树合集
    验证视图状态 MAC 失败,解决方法
  • 原文地址:https://www.cnblogs.com/kongtiao/p/2114666.html
Copyright © 2020-2023  润新知