差别

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

到此差别页面的链接

后一修订版
前一修订版
上一修订版 两侧同时换到之后的修订记录
10._交通灯 [2017/03/23 03:13]
zhijun 创建
10._交通灯 [2021/10/05 23:38]
gongyu
行 1: 行 1:
-=====简易交通灯=====+## 简易交通灯
  
 本节将向您介绍Verilog语法之中的精髓内容——状态机,并且将利用状态机实现十字路口的交通灯。 本节将向您介绍Verilog语法之中的精髓内容——状态机,并且将利用状态机实现十字路口的交通灯。
  
 \\ \\
-====硬件说明与实现项目框图==== +### 1. 硬件说明与实现项目框图 
--------+ 
 +// 
 +{{ ::​jiaotongdeng.png?​300 |}} 
 +//
 上图为十字路口交通示意图分之路与主路,要求如下: 上图为十字路口交通示意图分之路与主路,要求如下:
-* 交通灯主路上绿灯持续15s的时间,黄灯3s的时间,红灯10s的时间; +  ​* 交通灯主路上绿灯持续15s的时间,黄灯3s的时间,红灯10s的时间; 
-* 交通灯支路上绿灯持续7s的时间, 黄灯持续3秒的时间,红灯18秒的时间;+  * 交通灯支路上绿灯持续7s的时间, 黄灯持续3秒的时间,红灯18秒的时间; 
 + 
 +// 
 +{{ ::​状态机框架.png?​300 |}} 
 +//
 根据上述要求,状态机设计框架分析如下: 根据上述要求,状态机设计框架分析如下:
-* S1:​主路绿灯点亮,支路红灯点亮,持续15s的时间; +  ​* S1:​主路绿灯点亮,支路红灯点亮,持续15s的时间; 
-* S2:​主路黄灯点亮,支路红灯点亮,持续3s的时间; +  * S2:​主路黄灯点亮,支路红灯点亮,持续3s的时间; 
-* S3:​主路红灯点亮,支路绿灯点亮,持续10s的时间; +  * S3:​主路红灯点亮,支路绿灯点亮,持续10s的时间; 
-* S4:​主路红灯点亮,支路黄灯点亮,持续3s的时间;+  * S4:​主路红灯点亮,支路黄灯点亮,持续3s的时间; 
 +// 
 +{{ ::​状态示意图.png?​500 |}} 
 +// 
 + 
 +### 2. Verilog代码
  
-====Verilog代码==== +首先是时钟分频部分
------- +
-首先是时钟分频部分+
 <code verilog> <code verilog>
  
行 53: 行 63:
  //DEFINE PARAMETER  //DEFINE PARAMETER
  //​*******************  //​*******************
- parameter WIDTH = 3;​ + parameter WIDTH = 3; 
- parameter N = 5;+ parameter N = 5;
   
  //​*******************  //​*******************
行 115: 行 125:
 endmodule ​     endmodule ​    
 </​code>​ </​code>​
 +\\
 +接下来就是利用三段式状态机实现的交通灯部分:
 +<code verilog>
 +// ********************************************************************
 +// >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​
 +// ********************************************************************
 +// File name    : traffic.v
 +// Module name  : traffic
 +// Author ​      : STEP
 +// Description ​ : 
 +// Web          : www.stepfpga.com
 +// 
 +// --------------------------------------------------------------------
 +// Code Revision History : 
 +// --------------------------------------------------------------------
 +// Version: |Mod. Date:   ​|Changes Made:
 +// V1.0     ​|2017/​03/​02 ​  ​|Initial ver
 +// --------------------------------------------------------------------
 +// Module Function:​简易交通灯
  
 +
 +module traffic
 +(
 + clk , ​   //时钟
 + rst_n , ​   //复位
 + out  ​    //​三色led代表交通灯
 +);
 +
 + input clk,​rst_n; ​    
 + output reg[5:​0] out;​
 + 
 + parameter ​     S1 = 4'​b00, ​   //​状态机状态编码
 + S2 = 4'b01,
 + S3 = 4'b10,
 + S4 = 4'b11;
 +
 + parameter time_s1 = 4'd15, //​计时参数
 + time_s2 = 4'd3,
 + time_s3 = 4'd7,
 + time_s4 = 4'd3;
 + //​交通灯的控制
 + parameter led_s1 = 6'​b101011,​ // LED2 绿色 LED1 红色
 + led_s2 = 6'​b110011,​ // LED2 蓝色 LED1 红色
 + led_s3 = 6'​b011101,​ // LED2 红色 LED1 绿色
 + led_s4 = 6'​b011110;​ // LED2 红色 LED1 蓝色
 + 
 + reg [3:0] timecont;
 + reg [1:0] cur_state,​next_state; ​ //​现态、次态
 + 
 + wire clk1h; ​ //1Hz时钟
 +
 + //​产生1秒的时钟周期
 + divide #​(.WIDTH(32),​.N(12000000)) CLK1H (
 + .clk(clk),​
 + .rst_n(rst_n),​
 + .clkout(clk1h));​
 + //​第一段 同步逻辑 描述次态到现态的转移
 + always @ (posedge clk1h or negedge rst_n)
 + begin
 + if(!rst_n) ​
 + cur_state <= S1;
 +        else 
 + cur_state <= next_state;
 + end
 + //​第二段 组合逻辑描述状态转移的判断
 + always @ (cur_state or rst_n or timecont)
 + begin
 + if(!rst_n) begin
 +         next_state = S1;
 + end
 + else begin
 + case(cur_state)
 + S1:​begin
 + if(timecont==1) ​
 + next_state = S2;
 + else ​
 + next_state = S1;
 + end
 + 
 +                S2:begin
 + if(timecont==1) ​
 + next_state = S3;
 + else ​
 + next_state = S2;
 + end
 + 
 +                S3:begin
 + if(timecont==1) ​
 + next_state = S4;
 + else ​
 + next_state = S3;
 + end
 + 
 +                S4:begin
 + if(timecont==1) ​
 + next_state = S1;
 + else ​
 + next_state = S4;
 + end
 + 
 + default:​ next_state = S1;
 + endcase
 + end
 + end
 + //​第三段 ​ 同步逻辑 描述次态的输出动作
 + always @ (posedge clk1h or negedge rst_n)
 + begin
 + if(!rst_n==1) begin
 + out <= led_s1;
 + timecont <= time_s1;
 + end ​
 + else begin
 + case(next_state)
 + S1:​begin
 + out <= led_s1;
 + if(timecont == 1) 
 + timecont <= time_s1;
 + else ​
 + timecont <= timecont - 1;
 + end
 + 
 + S2:​begin
 + out <= led_s2;
 + if(timecont == 1) 
 + timecont <= time_s2;
 + else ​
 + timecont <= timecont - 1;
 + end
 + 
 + S3:​begin
 + out <= led_s3;
 + if(timecont == 1) 
 + timecont <= time_s3;
 + else ​
 + timecont <= timecont - 1;
 + end
 + 
 + S4:​begin
 + out <= led_s4;
 + if(timecont == 1) 
 + timecont <= time_s4;
 + else ​
 + timecont <= timecont - 1;
 + end
 + 
 + default:​begin
 + out <= led_s1;
 + end
 + endcase
 + end
 + end
 +endmodule
 +</​code>​
 \\  ​ \\  ​
 \\  ​ \\  ​
-====引脚分配==== + 
--------+### 3. 引脚分配 
 小脚丫上正好有4路按键和4路开关,可以用来作为输入信号分别控制数码管的输出。按照下面表格定义输入输出信号 小脚丫上正好有4路按键和4路开关,可以用来作为输入信号分别控制数码管的输出。按照下面表格定义输入输出信号
 \\ \\
-^信号 ​           ^引脚 ​           ^信号 ​             ^引脚 ​   ^    +^信号 ​    ​^引脚 ​           ^信号 ​     ^引脚 ​   ^    
-|seg_data_1(0) ​  |M7              |seg_data_2(0) ​   ​|L14     ^ +|clk      ​|C1              |rst      ​|L14     ^ 
-|seg_data_1(1) ​  |M8              |seg_data_2(1)    ​|M13     +|out[0] ​  |P2              |out[1]   |N2      ​
-|seg_data_1(2  |M9              |seg_data_2(2) ​   ​|M14     +|out[2  |M2              |out[3] ​  |P4      ​
-|seg_data_1(3) ​  |M10             |seg_data_2(3) ​   ​|N14     ^+|out[4] ​  |N3              ​|out[5] ​  |M3      ​^
 \\ \\
 \\ \\
-^信号 ​           ^引脚 ​           ^信号 ​             ^引脚 ​   ^    
-|seg_led_1(0) ​  ​|A10 ​             |seg_led_2(0) ​   |C12     ^ 
-|seg_led_1(1) ​  ​|C11 ​             |seg_led_2(1) ​   |B14     ^ 
-|seg_led_1(2) ​  ​|F2 ​             |seg_led_2(2) ​   |J1     ^ 
-|seg_led_1(3) ​  ​|E1 ​            ​|seg_led_2(3) ​   |H1     ^ 
-|seg_led_1(4) ​  ​|E2 ​             |seg_led_2(4) ​   |H2     ^ 
-|seg_led_1(5) ​  ​|A9 ​             |seg_led_2(5) ​   |B12     ^ 
-|seg_led_1(6) ​  ​|B9 ​             |seg_led_2(6) ​   |A11     ^ 
-|seg_led_1(7) ​  ​|F1 ​            ​|seg_led_2(7) ​   |K1     ^ 
-|seg_led_1(8) ​  ​|C9 ​            ​|seg_led_2(8) ​   |A12     ^ 
-\\ 
-配置好以后编译下载程序。这样可以通过按键或者开关来控制相应的数码管显示数字。如果你想显示16进制的AbCDeF在数码管,可以试试修改程序。这时候一定要定义一个16*9的存储器来初始化。 
-\\ 
  
-====小结==== +配置好以后编译下载程序。您也可以试试修改程序,观察修改代码对于FPGA内部电路所造成的影响。\\ 
------- + 
-了解了小脚丫码管工作原理在下个实验我们将进行到有趣逻辑。首先如何控制[[5. 时钟分频|时钟分频]]+### 4. 小结 
 + 
 +状态机是一类很重要的时序逻辑电路,是许多字系统核心部件掌握状态机的使用是利用FPGA与CPLD进行开发一项必会技能,本小节的交通灯程利用三段式状态机描述方法实现的,希望读者能够快速掌握这项技能