差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
10._交通灯 [2017/03/23 03:27] zhijun |
10._交通灯 [2019/09/06 11:58] (当前版本) gongyu |
||
---|---|---|---|
行 1: | 行 1: | ||
- | =====简易交通灯===== | + | ####简易交通灯 |
+ | |||
+ | --- | ||
本节将向您介绍Verilog语法之中的精髓内容——状态机,并且将利用状态机实现十字路口的交通灯。 | 本节将向您介绍Verilog语法之中的精髓内容——状态机,并且将利用状态机实现十字路口的交通灯。 | ||
\\ | \\ | ||
- | ====硬件说明与实现项目框图==== | + | |
- | ------- | + | #### 硬件说明与实现项目框图 |
- | {{ ::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的时间; | ||
行 16: | 行 21: | ||
* S3:主路红灯点亮,支路绿灯点亮,持续10s的时间; | * S3:主路红灯点亮,支路绿灯点亮,持续10s的时间; | ||
* S4:主路红灯点亮,支路黄灯点亮,持续3s的时间; | * S4:主路红灯点亮,支路黄灯点亮,持续3s的时间; | ||
- | {{ ::状态示意图.png?800 |}} | + | {{ ::状态示意图.png?300 |}} |
- | ====Verilog代码==== | + | |
- | ------ | + | |
+ | \\ | ||
+ | |||
+ | ####Verilog代码 | ||
+ | |||
+ | --- | ||
首先是时钟分频部分: | 首先是时钟分频部分: | ||
<code verilog> | <code verilog> | ||
行 117: | 行 128: | ||
endmodule | endmodule | ||
</code> | </code> | ||
+ | |||
\\ | \\ | ||
+ | |||
接下来就是利用三段式状态机实现的交通灯部分: | 接下来就是利用三段式状态机实现的交通灯部分: | ||
<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'd10, |
- | + | 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; | ||
行 272: | 行 284: | ||
</code> | </code> | ||
\\ | \\ | ||
+ | |||
\\ | \\ | ||
- | ====引脚分配==== | + | |
- | ------- | + | ####引脚分配 |
+ | |||
+ | --- | ||
小脚丫上正好有4路按键和4路开关,可以用来作为输入信号分别控制数码管的输出。按照下面表格定义输入输出信号 | 小脚丫上正好有4路按键和4路开关,可以用来作为输入信号分别控制数码管的输出。按照下面表格定义输入输出信号 | ||
\\ | \\ | ||
行 287: | 行 303: | ||
配置好以后编译下载程序。您也可以试试修改程序,观察修改代码对于FPGA内部电路所造成的影响。\\ | 配置好以后编译下载程序。您也可以试试修改程序,观察修改代码对于FPGA内部电路所造成的影响。\\ | ||
- | ====小结==== | + | \\ |
- | ------ | + | |
- | 状态机是一类很重要的时序逻辑电路,是许多数字系统的核心部件,掌握状态机的使用是利用FPGA与CPLD进行开发的一项必会技能,本小节的交通灯程序即是利用三段式状态机描述方法实现的,希望读者能够快速掌握这项技能。 | + | |
+ | ####小结 | ||
+ | --- | ||
+ | 状态机是一类很重要的时序逻辑电路,是许多数字系统的核心部件,掌握状态机的使用是利用FPGA与CPLD进行开发的一项必会技能,本小节的交通灯程序即是利用三段式状态机描述方法实现的,希望读者能够快速掌握这项技能。 |