差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
10._交通灯 [2017/03/23 03:27]
zhijun
10._交通灯 [2021/10/05 23:40] (当前版本)
gongyu
行 1: 行 1:
-=====简易交通灯=====+## 简易交通灯
  
 本节将向您介绍Verilog语法之中的精髓内容——状态机,并且将利用状态机实现十字路口的交通灯。 本节将向您介绍Verilog语法之中的精髓内容——状态机,并且将利用状态机实现十字路口的交通灯。
  
 \\ \\
-====硬件说明与实现项目框图==== +### 1. 硬件说明与实现项目框图 
-------- + 
-{{ ::​jiaotongdeng.png?​800 |}}+// 
 +{{ ::​jiaotongdeng.png?​300 |}} 
 +//
 上图为十字路口交通示意图分之路与主路,要求如下: 上图为十字路口交通示意图分之路与主路,要求如下:
-* 交通灯主路上绿灯持续15s的时间,黄灯3s的时间,红灯10s的时间; +  ​* 交通灯主路上绿灯持续15s的时间,黄灯3s的时间,红灯10s的时间; 
-* 交通灯支路上绿灯持续7s的时间, 黄灯持续3秒的时间,红灯18秒的时间; +  * 交通灯支路上绿灯持续7s的时间, 黄灯持续3秒的时间,红灯18秒的时间; 
-{{ ::​状态机框架.png?​800 |}}+ 
 +// 
 +{{ ::​状态机框架.png?​300 |}} 
 +//
 根据上述要求,状态机设计框架分析如下: 根据上述要求,状态机设计框架分析如下:
-* S1:​主路绿灯点亮,支路红灯点亮,持续15s的时间; +  ​* S1:​主路绿灯点亮,支路红灯点亮,持续15s的时间; 
-* S2:​主路黄灯点亮,支路红灯点亮,持续3s的时间; +  * S2:​主路黄灯点亮,支路红灯点亮,持续3s的时间; 
-* S3:​主路红灯点亮,支路绿灯点亮,持续10s的时间; +  * S3:​主路红灯点亮,支路绿灯点亮,持续10s的时间; 
-* S4:​主路红灯点亮,支路黄灯点亮,持续3s的时间; +  * S4:​主路红灯点亮,支路黄灯点亮,持续3s的时间; 
-{{ ::​状态示意图.png?​800 |}} +// 
-====Verilog代码==== +{{ ::​状态示意图.png?​500 |}} 
-------+// 
 + 
 +### 2. Verilog代码 
 首先是时钟分频部分: 首先是时钟分频部分:
 <code verilog> <code verilog>
行 55: 行 63:
  //DEFINE PARAMETER  //DEFINE PARAMETER
  //​*******************  //​*******************
- parameter WIDTH = 3;​ + parameter WIDTH = 3; 
- parameter N = 5;+ parameter N = 5;
   
  //​*******************  //​*******************
行 72: 行 80:
  //​********************  //​********************
  //REGS  //REGS
- reg [WIDTH-1:​0] cnt_p,​cnt_n;​ + reg [WIDTH-1:​0] cnt_p,​cnt_n;​ 
- reg clk_p,​clk_n;​+ reg clk_p,​clk_n;​
  
  assign clkout = (N==1)?​clk:​(N[0])?​(clk_p&​clk_n):​clk_p;​  assign clkout = (N==1)?​clk:​(N[0])?​(clk_p&​clk_n):​clk_p;​
行 120: 行 128:
 接下来就是利用三段式状态机实现的交通灯部分: 接下来就是利用三段式状态机实现的交通灯部分:
 <code verilog> <code verilog>
-//​******************************************************** +// ******************************************************************** 
-//   Copyright(c)2016,​ STEP FPGA  +// >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​ 
-//   All rights reserved +// ******************************************************************** 
-//   ​File name       ​  ​traffic.v +// File name    : traffic.v 
-//   ​Module name     ​  ​traffic +// Module name  : traffic 
-//   ​Author ​           ​STEP +// Author ​      ​: STEP 
-//   Email             info@stepfpga.com +// Description  ​:  
-//   Data            ​  2016/​08/​01 +// Web          ​www.stepfpga.com 
-//   ​Version ​        : ​  V1.0 +//  
-//   Description ​    : ​   +// -------------------------------------------------------------------- 
-// +// Code Revision History :  
-//   ​Modification history +// -------------------------------------------------------------------- 
-//   ---------------------------------------------------------------------------- +// Version: |Mod. Date:   ​|Changes Made: 
-// Version ​      ​ +// V1.0     ​|2017/​03/​02 ​  ​|Initial ver 
-// Description +// -------------------------------------------------------------------- 
-// +// Module Function:​简易交通灯
-//********************************************************+
  
  
-//​******************* 
-//DEFINE MODULE PORT 
-//​******************* 
 module traffic module traffic
 ( (
- //INPUT + clk , ​   ​//时钟 
- clk , + rst_n , ​   //复位 
- rst_n , + out      //​三色led代表交通灯
- //OUTPUT +
- out +
 ); );
- //​******************* +
- //DEFINE INPUT +
- //​*******************+
  input clk,​rst_n; ​      input clk,​rst_n; ​    
- 
-    //​******************* 
- //DEFINE OUTPUT 
- //​******************* 
  output reg[5:​0] out;​  output reg[5:​0] out;​
 + 
 + parameter ​     S1 = 4'​b00, ​   //​状态机状态编码
 + S2 = 4'b01,
 + S3 = 4'b10,
 + S4 = 4'b11;
   
- //​******************* + parameter time_s1 = 4'​d15, ​//​计时参数 
- //DEFINE PARAMETER + time_s2 = 4'​d3,​ 
- //​******************* ​   + time_s3 = 4'd7
-  + time_s4 = 4'​d3;​ 
- parameter ​     S1 = 4'​b00, ​    + //​交通灯的控制 
- S2 = 4'​b01,​ + parameter led_s1 = 6'​b101011, ​// LED2 绿色 LED1 红色 
- S3 = 4'​b10,​ + led_s2 = 6'b110011// LED2 蓝色 LED1 红色 
- S4 = 4'​b11;​ + led_s3 = 6'​b011101, ​// LED2 红色 LED1 绿色 
-     + led_s4 = 6'b011110; // LED2 红色 LED1 蓝色 
- parameter time_s1 = 4'​d15,​ + 
- time_s2 = 4'​d3,​ +
- time_s3 = 4'd10+
- time_s4 = 4'​d3;​ +
-  +
- parameter led_s1 = 6'​b101011,​ +
- led_s2 = 6'b001011+
- led_s3 = 6'​b011101,​ +
- led_s4 = 6'b011001; +
-  +
- //********************* +
- //INNER SIGNAL DECLARATION +
- //​********************* +
- //REGS +
  reg [3:0] timecont;  reg [3:0] timecont;
- reg [1:0] cur_state,​next_state; ​+ reg [1:0] cur_state,​next_state; ​ //​现态、次态 
 +  
 + wire clk1h; ​ //1Hz时钟
   
- //WIRES + //产生1秒的时钟周期
- wire clk1h;​ +
  divide #​(.WIDTH(32),​.N(12000000)) CLK1H (  divide #​(.WIDTH(32),​.N(12000000)) CLK1H (
- .clk(clk),​ + .clk(clk),​ 
- .rst_n(rst_n),​ + .rst_n(rst_n),​ 
- .clkout(clk1h));​ + .clkout(clk1h));​ 
- //Sequential logic style + //第一段 同步逻辑 描述次态到现态的转移 
- always @ (posedge clk1h)+ always @ (posedge clk1h or negedge rst_n)
  begin  begin
- if(!rst_n) cur_state <= S1; + if(!rst_n) ​ 
-        else cur_state <= next_state;+ cur_state <= S1; 
 +        else  
 + cur_state <= next_state;
  end  end
 + //​第二段 组合逻辑描述状态转移的判断
  always @ (cur_state or rst_n or timecont)  always @ (cur_state or rst_n or timecont)
  begin  begin
  if(!rst_n) begin  if(!rst_n) begin
- next_state = S1;+         ​next_state = S1;
  end  end
  else begin  else begin
  case(cur_state)  case(cur_state)
  S1:​begin  S1:​begin
- if(timecont==1) next_state = S2; + if(timecont==1) ​ 
- else next_state = S1;+ next_state = S2; 
 + else ​ 
 + next_state = S1;
  end  end
 + 
                 S2:begin                 S2:begin
- if(timecont==1) next_state = S3; + if(timecont==1) ​ 
- else next_state = S2;+ next_state = S3; 
 + else ​ 
 + next_state = S2;
  end  end
 + 
                 S3:begin                 S3:begin
- if(timecont==1) next_state = S4; + if(timecont==1) ​ 
- else next_state = S3;+ next_state = S4; 
 + else ​ 
 + next_state = S3;
  end  end
 + 
                 S4:begin                 S4:begin
- if(timecont==1) next_state = S1; + if(timecont==1) ​ 
- else next_state = S4;+ next_state = S1; 
 + else ​ 
 + next_state = S4;
  end  end
- + 
  default:​ next_state = S1;  default:​ next_state = S1;
  endcase  endcase
  end  end
  end  end
-  + //​第三段 ​ 同步逻辑 描述次态的输出动作 
- always @ (posedge clk1h)+ always @ (posedge clk1h or negedge rst_n)
  begin  begin
- if(!rst_n) begin+ if(!rst_n==1) begin
  out <= led_s1;  out <= led_s1;
  timecont <= time_s1;  timecont <= time_s1;
- end else begin+ end  
 + else begin
  case(next_state)  case(next_state)
  S1:​begin  S1:​begin
  out <= led_s1;  out <= led_s1;
- if(timecont == 1) timecont <= time_s1; + if(timecont == 1)  
- else timecont <= timecont - 1;+ timecont <= time_s1; 
 + else ​ 
 + timecont <= timecont - 1;
  end  end
- + 
  S2:​begin  S2:​begin
  out <= led_s2;  out <= led_s2;
- if(timecont == 1) timecont <= time_s2; + if(timecont == 1)  
- else timecont <= timecont - 1;+ timecont <= time_s2; 
 + else ​ 
 + timecont <= timecont - 1;
  end  end
- + 
  S3:​begin  S3:​begin
  out <= led_s3;  out <= led_s3;
- if(timecont == 1) timecont <= time_s3; + if(timecont == 1)  
- else timecont <= timecont - 1;+ timecont <= time_s3; 
 + else ​ 
 + timecont <= timecont - 1;
  end  end
- + 
  S4:​begin  S4:​begin
  out <= led_s4;  out <= led_s4;
- if(timecont == 1) timecont <= time_s4; + if(timecont == 1)  
- else timecont <= timecont - 1;+ timecont <= time_s4; 
 + else ​ 
 + timecont <= timecont - 1;
  end  end
- + 
  default:​begin  default:​begin
  out <= led_s1;  out <= led_s1;
行 273: 行 280:
 \\  ​ \\  ​
 \\  ​ \\  ​
-====引脚分配==== + 
--------+### 3. 引脚分配 
 小脚丫上正好有4路按键和4路开关,可以用来作为输入信号分别控制数码管的输出。按照下面表格定义输入输出信号 小脚丫上正好有4路按键和4路开关,可以用来作为输入信号分别控制数码管的输出。按照下面表格定义输入输出信号
 \\ \\
行 287: 行 295:
 配置好以后编译下载程序。您也可以试试修改程序,观察修改代码对于FPGA内部电路所造成的影响。\\ 配置好以后编译下载程序。您也可以试试修改程序,观察修改代码对于FPGA内部电路所造成的影响。\\
  
-====小结==== +### 4. 小结 
-------+
 状态机是一类很重要的时序逻辑电路,是许多数字系统的核心部件,掌握状态机的使用是利用FPGA与CPLD进行开发的一项必会技能,本小节的交通灯程序即是利用三段式状态机描述方法实现的,希望读者能够快速掌握这项技能。 状态机是一类很重要的时序逻辑电路,是许多数字系统的核心部件,掌握状态机的使用是利用FPGA与CPLD进行开发的一项必会技能,本小节的交通灯程序即是利用三段式状态机描述方法实现的,希望读者能够快速掌握这项技能。