博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
交通灯控制器的verilog实现
阅读量:6899 次
发布时间:2019-06-27

本文共 11575 字,大约阅读时间需要 38 分钟。

用状态机实现交通灯控制器,仿真通过,有代码以及testbench。


 

要求:

方向1是主干道,绿灯时间较长,交通灯状态循环为:

绿:40

黄:5

左:15

黄:5

红:55

方向2不是主干道,绿灯时间较少,交通灯状态循环为:

红:65

绿:30

黄:5

左:15

黄:5


 

 注意:

  1. 此处将两个交通灯的状态合在一起,从而便于对两个等进行同步控制。将两个灯的5个状态合为8个状态,即:

绿1:40

黄1:5

左1:15

黄1:5

绿2:30

黄2:5

左2:15

黄2:5

对状态转换以及输出控制采用组合逻辑,在调试的过程中也曾使用时序逻辑来实现,仿真发现各种时序混乱。

在状态转换控制中,在change有效后,马上将其清零,代码如下,这是为了便于控制,调试时,发现这样比较方便,其他方法易出错。

在仿真图上就看不到change有效过,但仿真图上的其他信号是正确的。

1     G2   : if(trigger)  2                            nxt_state = G1;3            else if(change)  5                   begin6                         change = 1'b0;7                         nxt_state = Y2_1;

 


 

代码如下:

1 module traffic_light(rst_n,  2                             clk,  3                             trigger, //触发信号,使得状态机进入循环  4                             light1,  5                             light2  6                                  );  7 input rst_n;  8 input clk;  9 input trigger; 10  11 output [3:0] light1;   //4bit分别对应绿、黄、左、红灯 12 output [3:0] light2; 13  14 //灯亮时间 15 parameter G1_T = 7'd40;  //方向1的亮灯时间 16 parameter Y1_T = 7'd5; 17 parameter L1_T = 7'd15; 18  19 parameter G2_T = 7'd30;    //方向2的亮灯时间 20 parameter Y2_T = 7'd5; 21 parameter L2_T = 7'd15; 22  23 //状态编码 24 parameter IDLE = 4'd0;    //此处为了方便采用简单的binary编码,可用one-hot或gray提高性能 25 parameter G1 = 4'd1; 26 parameter Y1_1 = 4'd2; 27 parameter L1 = 4'd3; 28 parameter Y1_2 = 4'd4; 29  30 parameter G2 = 4'd5; 31 parameter Y2_1 = 4'd6; 32 parameter L2 = 4'd7; 33 parameter Y2_2 = 4'd8; 34  35 reg [3:0] cur_state; 36 reg [3:0] nxt_state; 37  38 reg [3:0] light1; 39 reg [3:0] light2; 40  41 reg [3:0] light1_tmp; 42 reg [3:0] light2_tmp; 43  44 reg [6:0] light_t_tmp; 45 reg [6:0] light_t; 46  47 reg change; 48 reg start; 49  50 //状态寄存,时序逻辑 51 always@(posedge clk) 52     if(!rst_n) 53         cur_state <= IDLE; 54     else 55         cur_state <= nxt_state; 56  57 //状态转换,组合逻辑         58 always@(*) 59     if(!rst_n) 60         begin 61             //start <= 1'b0; 62             nxt_state = IDLE; 63         end 64     else   65         begin 66             case(cur_state) 67                 IDLE : //if(change)  68                         if(trigger)  //状态机通过trigger进入状态循环 69                             begin 70                                 //start <= 1'b1;  //start与计数值light_t_tmp是同步的,因此一同写在输出控制中  71                                 nxt_state = G1;  //状态变换由组合逻辑实现,采用阻塞赋值即=,而非<= 72                             end 73                 G1   : if(trigger)   74                             begin 75                                 //start <= 1'b1; 76                                 nxt_state = G1; 77                             end 78                         else if(change)   79                                 begin 80                                     //start <= 1'b1; 81                                     change = 1'b0; 82                                     nxt_state = Y1_1; 83                                 end 84                 Y1_1 : if(trigger)   85                             begin 86                                 //start <= 1'b1; 87                                 nxt_state = G1; 88                             end 89                         else if(change)   90                             begin 91                                 //start <= 1'b1; 92                                 change = 1'b0; 93                                 nxt_state = L1; 94                             end 95                 L1   : if(trigger)   96                             begin 97                                 //start <= 1'b1; 98                                 nxt_state = G1; 99                             end100                         else if(change)  101                             begin102                                 //start <= 1'b1;103                                 change = 1'b0;104                                 nxt_state = Y1_2;105                             end106                 Y1_2 : if(trigger)  107                             begin108                                 //start <= 1'b1;109                                 nxt_state = G1;110                             end111                         else if(change)  112                             begin113                                 //start <= 1'b1;114                                 change = 1'b0;115                                 nxt_state = G2;116                             end117                 G2   : if(trigger)  118                             begin119                                 //start <= 1'b1;120                                 nxt_state = G1;121                             end122                         else if(change)  123                             begin124                                 //start <= 1'b1;125                                 change = 1'b0;126                                 nxt_state = Y2_1;127                             end128                 Y2_1 : if(trigger)  129                             begin130                                 //start <= 1'b1;131                                 nxt_state = G1;132                             end133                         else if(change)  134                             begin135                                 //start <= 1'b1;136                                 change = 1'b0;137                                 nxt_state= L2;138                             end139                 L2   : if(trigger)  140                             begin141                                 //start <= 1'b1;142                                 nxt_state = G1;143                             end144                         else if(change)  145                             begin146                                 //start <= 1'b1;147                                 change = 1'b0;148                                 nxt_state = Y2_2;149                             end150                 Y2_2 : if(trigger)  151                             begin152                                 //start <= 1'b1;153                                 nxt_state = G1;154                             end155                         else if(change)  156                             begin157                                 //start <= 1'b1;158                                 change = 1'b0;159                                 nxt_state = G1;160                             end161                 default : nxt_state = IDLE;162             endcase163         end        164         165 //输出控制,组合逻辑166 //start与计数值light_t_tmp是同步的,因此一同写在输出控制中 167 //always@(posedge clk)   //输出为组合逻辑,因此不在clk下动作168 always@(*)169     if(!rst_n)170         begin171             start = 1'b0;172             light_t_tmp = 7'd0;173             light1_tmp = 4'b0000;174             light2_tmp = 4'b0000;175         end176     else case(cur_state)177             G1   : begin178                         start = 1'b1;179                         light_t_tmp = G1_T;180                         light1_tmp = 4'b1000;181                         light2_tmp = 4'b0001;                    182                      end183             Y1_1 : begin184                         start = 1'b1;185                         light_t_tmp = Y1_T;186                         light1_tmp = 4'b0100;187                         light2_tmp = 4'b0001;                188                      end189             L1   : begin190                         start = 1'b1;191                         light_t_tmp = L1_T;192                         light1_tmp = 4'b0010;193                         light2_tmp = 4'b0001;                194                      end195             Y1_2 : begin196                         start = 1'b1;197                         light_t_tmp = Y1_T;198                         light1_tmp = 4'b0100;199                         light2_tmp = 4'b0001;                200                      end201             G2   : begin202                         start = 1'b1;203                         light_t_tmp = G2_T;204                         light1_tmp = 4'b0001;205                         light2_tmp = 4'b1000;                206                      end207             Y2_1 : begin208                         start = 1'b1;209                         light_t_tmp = Y2_T;210                         light1_tmp = 4'b0001;211                         light2_tmp = 4'b0100;                212                      end213             L2   : begin214                         start = 1'b1;215                         light_t_tmp = L2_T;216                         light1_tmp = 4'b0001;217                         light2_tmp = 4'b0010;                218                      end219             Y2_2 : begin220                         start = 1'b1;221                         light_t_tmp = Y2_T;222                         light1_tmp = 4'b0001;223                         light2_tmp = 4'b0100;                224                      end225         endcase226 227 //灯亮时间倒计时228 //时序逻辑,要在clk时钟下动作229 always@(posedge clk)230     if(!rst_n)231         begin232             light_t <= 7'd0;233         end234     else if(start)235                 begin236                     start <= 1'b0;237                     light_t <= light_t_tmp;238                 end239          else240             begin241                 light_t <= light_t - 1'b1;242             end243             244 //在light_t减到2时,置为change信号245 //用组合逻辑246 always@(*)247     if(!rst_n)248         change = 1'b0;  249     else if(light_t == 4'd2)250         change = 1'b1;251         252 //输出寄存    253 always@(posedge clk)254     if(!rst_n)255         begin256             light1 <= 4'd0;257             light2 <= 4'd0;258         end259     else260         begin261             light1 <= light1_tmp;262             light2 <= light2_tmp;263         end264         265 //下面是调试过程中对change以及start的控制    266 //因为使用了时序逻辑,导致各种错误267 /*268 always@(posedge clk)269     if(!rst_n)270         begin271             light_t <= 7'd0;272             //change <= 1'b0;  //复位,开始状态转换273         end274     else if(start)275                 begin276                     start <= 1'b0;277                     //change <= 1'b0;278                     //change_r <= 1'b0;279                     light_t <= light_t_tmp;280                 end281             //else if(light_t == 4'd1)282             //        change <= 1'b1;283                  else284                     begin285                         light_t <= light_t - 1'b1;286                         //change <= 1'b0;287                     end288 */289             290 /*            291 always@(*)292     if(!rst_n)293         change = 1'b0;  //复位,开始状态转换294     else if(start)295             change = 1'b0;296         else if(light_t == 4'd1)297         else if(light_t == 4'd2)298             change = 1'b1;        299 */    300 301 endmodule

testbench如下:

1 module traffic_light_tb; 2  3     // Inputs 4     reg rst_n; 5     reg clk; 6     reg trigger; 7  8     // Outputs 9     wire [3:0] light1;10     wire [3:0] light2;11 12     // Instantiate the Unit Under Test (UUT)13     traffic_light uut (14         .rst_n(rst_n), 15         .clk(clk), 16         .trigger(trigger),17         .light1(light1), 18         .light2(light2)19     );20     21     parameter CLK_PERIOD = 10;22 23     initial begin24         rst_n = 0;25         clk = 1;26         trigger = 0;27 28         #100;    29         rst_n = 1;30         trigger = 1;   //初始给出trigger信号,使得状态机进行状态循环31         #CLK_PERIOD trigger = 0;32         33         //#1000 trigger = 1;  //trigger复位状态机34         //#100 trigger = 0;35         36     end37     38     always #(CLK_PERIOD/2) clk = ~clk;39       40 endmodule

ISIM仿真结果:

可以看到,两个交通灯从给定的状态间循环,且时间同步。

转载地址:http://xqsdl.baihongyu.com/

你可能感兴趣的文章
第二篇*2、Python字符串格式化
查看>>
正则表达式以过滤特殊字符
查看>>
关于bootstrap
查看>>
【DM642】H.264源代码在DM642上的移植
查看>>
清晰化算法在DSP上的实现
查看>>
图的存储结构(邻接矩阵)
查看>>
Delphi7_Lite_Fullv7.3优化精简全功能版
查看>>
Android笔记之自定义对话框
查看>>
pip安装使用详解
查看>>
sql新语句
查看>>
【转】超实用的JavaScript技巧及最佳实践
查看>>
HTML整理01
查看>>
[C#][DevPress]自定义数据分页控件
查看>>
bzoj 1001狼抓兔子(对偶图+最短路)最大流
查看>>
依然前往
查看>>
三个问题?
查看>>
多线程死锁
查看>>
Eclipse 不能自动编译
查看>>
Flask入门第一天
查看>>
EIGRP高级特性(汇总,偏移列表,SIA,Stub)
查看>>