当前位置:   article > 正文

基于BASYS 3的双路红绿灯控制器(Verilog)_basys3中eeprom

basys3中eeprom

实现功能:十字路口A和B两个方向用红灯20秒、黄灯5秒、绿灯9秒的方式变化,数码管同时倒计时显示通行或禁止通行时间。

         

      

所需模块:

1.数码管动态扫描子模块

2.数码管显示子模块

3.1秒时钟产生子模块

4.9s-5s-20s-20s顺序计时子模块

5.20s-20s-9s-5s顺序计时子模块

6.mealy四状态机子模块

7.顶层运用模块

应用原理及方法:

状态机:MOORE状态机、MEALY状态机

仿真:

1.将各个功能模块化,分别测试各个模块的功能是否正确。

2.仿真初值设置,采用rst按键复位产生初值。

代码:

顶层模块:

  1. module main(clk,dig,rst,seg,ledA,ledB);
  2. input clk;
  3. output ledA,ledB;
  4. input rst;
  5. output dig;
  6. output seg;
  7. wire [3:0]dig;
  8. wire [7:0]seg;
  9. wire [2:0]ledA,ledB;
  10. wire clk_1Hz;//1Hz
  11. wire clkA,clkB;//15s
  12. wire clk_scan;//动态扫描频率
  13. wire [3:0]cntA_1,cntA_2;
  14. wire [3:0]cntB_1,cntB_2;
  15. CLK_1S CLK1S(.clk_100MHz(clk),.clk_1Hz(clk_1Hz));//产生1Hz时钟
  16. CLK_A A1(.clk_1Hz(clk_1Hz),.clk_out(clkA),.cnt_1(cntA_1),.cnt_2(cntA_2));//产生周期为15秒时钟
  17. CLK_B B1(.clk_1Hz(clk_1Hz),.clk_out(clkB),.cnt_1(cntB_1),.cnt_2(cntB_2));
  18. CLK_SCAN S1(.clk_100MHz(clk),.clk_scan(clk_scan));//产生3KHz扫描时钟
  19. DIG_SEG D1(.clk_sel(clk_scan),.dig(dig),.seg(seg),.seg1(cntB_2),.seg2(cntB_1),.seg3(cntA_2),.seg4(cntA_1));//数码管显示
  20. STATEA L1(.clk_in(clkA),.rst(rst),.currentstate(ledA));
  21. STATEB L2(.clk_in(clkB),.rst(rst),.currentstate(ledB));
  22. endmodule

1秒时钟产生子模块:

BASYS 3的时钟为100MHz,100M个周期,即是一秒。T=1S时,0.5S反转一次。所以这里用到一个cnt,计数50M满,1s输出信号跳变,cnt==28'b10111110101111000010000000,50 000 000。

  1. //时钟分频模块:将Basys3上的100MHz时钟clk分频到1Hz输出,作为15秒倒计时计数时钟clk_1hz ;
  2. module CLK_1S(clk_100MHz,clk_1Hz);
  3. input clk_100MHz;//100M时钟输入
  4. output reg clk_1Hz;//输出1s
  5. reg [27:0] cnt;
  6. always @(posedge clk_100MHz)
  7. begin
  8. if(cnt==28'b0010_1111_1010_1111_0000_1000_0000)//100MHz/1Hz
  9. begin
  10. cnt <=0;//清零
  11. clk_1Hz <= ~clk_1Hz;
  12. end
  13. else
  14. cnt <= cnt + 1;
  15. end
  16. endmodule

9s-5s-20s-20s顺序计时子模块:

  1. module CLK_A(clk_1Hz,clk_out,cnt_1,cnt_2);
  2. input clk_1Hz;//1s
  3. output reg clk_out;//15s
  4. output cnt_1,cnt_2;//两位记数 0-9
  5. reg [4:0]cnt;//0-15
  6. wire [3:0]cnt_1;//十位
  7. wire [3:0]cnt_2;//个位
  8. reg [1:0]sig;
  9. assign cnt_1 =cnt/'b1010; //十位除10
  10. assign cnt_2 =cnt%'b1010;//各位余10
  11. always @(posedge clk_1Hz)//产生两位数
  12. begin
  13. if(cnt==5'b00000||cnt==5'b11111)begin // cnt0-14 不需要到达1
  14. case(sig)
  15. 2'b00:begin
  16. cnt<=5'b01001; //9
  17. sig<=sig+'b1;
  18. clk_out<=1;
  19. end
  20. 2'b01:begin
  21. cnt<=5'b00101; //5
  22. sig<=sig+'b1;
  23. clk_out<=1;
  24. end
  25. 2'b10:begin
  26. cnt<=5'b10100; //20
  27. sig<=sig+'b1;
  28. clk_out<=1;
  29. end
  30. 2'b11:begin
  31. cnt<=5'b10100; //20
  32. sig<=sig+'b1;
  33. clk_out<=1;
  34. end
  35. endcase
  36. end
  37. else begin
  38. cnt <= cnt -'b1;
  39. clk_out<=0;
  40. end
  41. end
  42. endmodule

20s-20s-9s-5s顺序计时子模块:

  1. module CLK_B(clk_1Hz,clk_out,cnt_1,cnt_2);
  2. input clk_1Hz;//1s
  3. output reg clk_out;//15s
  4. output cnt_1,cnt_2;//两位记数 0-9
  5. reg [4:0]cnt;//0-15
  6. wire [3:0]cnt_1;//十位
  7. wire [3:0]cnt_2;//个位
  8. reg [1:0]sig;
  9. assign cnt_1 =cnt/'b1010; //十位除10
  10. assign cnt_2 =cnt%'b1010;//各位余10
  11. always @(posedge clk_1Hz)//产生两位数
  12. begin
  13. if(cnt==5'b00000||cnt==5'b11111)begin // cnt0-14 不需要到达1
  14. case(sig)
  15. 2'b00:begin
  16. cnt<=5'b10100; //20
  17. sig<=sig+'b1;
  18. clk_out<=1;
  19. end
  20. 2'b01:begin
  21. cnt<=5'b10100; //20
  22. sig<=sig+'b1;
  23. clk_out<=1;
  24. end
  25. 2'b10:begin
  26. cnt<=5'b01001; //9
  27. sig<=sig+'b1;
  28. clk_out<=1;
  29. end
  30. 2'b11:begin
  31. cnt<=5'b00101; //5
  32. sig<=sig+'b1;
  33. clk_out<=1;
  34. end
  35. endcase
  36. end
  37. else begin
  38. cnt <= cnt -'b1;
  39. clk_out<=0;
  40. end
  41. end
  42. endmodule

数码管动态扫描子模块:

  1. //100MHz分频到2.5KHz~4KHz输出,作为数码管动态显示的扫描频率clk-scan,3Khz动态扫描
  2. module CLK_SCAN(clk_100MHz,clk_scan);
  3. input clk_100MHz;
  4. output reg clk_scan;
  5. reg [15:0] cnt;
  6. always @(posedge clk_100MHz)
  7. begin
  8. cnt <= cnt + 1;
  9. if(cnt==16'b1000_0010_0011_0101)//100MHz/33333Hz
  10. begin
  11. cnt <=0;//清零
  12. clk_scan <= ~clk_scan;
  13. end
  14. end
  15. endmodule

数码管显示子模块:

  1. odule DIG_SEG(clk_sel,seg1,seg2,seg3,seg4,dig,seg);
  2. input clk_sel;
  3. input [3:0]seg1,seg2,seg3,seg4;
  4. output dig,seg;
  5. reg [3:0]dig;
  6. reg [7:0]seg;
  7. reg [1:0]selcnt;
  8. //parameter seg_0=8'b11000000;
  9. //parameter seg_1=8'b11111001;
  10. //parameter seg_2=8'b10100100;
  11. //parameter seg_3=8'b10110000;
  12. //parameter seg_4=8'b10011001;
  13. //parameter seg_5=8'b10010010;
  14. //parameter seg_6=8'b10000010;
  15. //parameter seg_7=8'b11111000;
  16. //parameter seg_8=8'b10000000;
  17. //parameter seg_9=8'b10010000;
  18. always @(posedge clk_sel)//位选标志位
  19. begin
  20. selcnt <= selcnt + 1;//标志位+111记满后加一回到00
  21. end
  22. always @(selcnt) //位选信号控制
  23. begin
  24. case (selcnt)
  25. 2'b00: begin dig <= 4'b0111;end //1号数码管显示ain对应的段码
  26. 2'b01: begin dig <= 4'b1011;end
  27. 2'b10: begin dig <= 4'b1101;end
  28. 2'b11: begin dig <= 4'b1110;end
  29. endcase
  30. end
  31. always @(selcnt or seg1 or seg2 or seg3 or seg4) //位选信号控制
  32. begin
  33. if (selcnt==2'b00)
  34. begin
  35. case(seg1)
  36. 4'b0000:seg <= 8'b11000000;
  37. 4'b0001:seg <= 8'b11111001;
  38. 4'b0010:seg <= 8'b10100100;
  39. 4'b0011:seg <= 8'b10110000;
  40. 4'b0100:seg <= 8'b10011001;
  41. 4'b0101:seg <= 8'b10010010;
  42. 4'b0110:seg <= 8'b10000010;
  43. 4'b0111:seg <= 8'b11111000;
  44. 4'b1000:seg <= 8'b10000000;
  45. 4'b1001:seg <= 8'b10010000;
  46. default: seg<=8'b11000000;
  47. endcase
  48. end
  49. if (selcnt==2'b01)
  50. begin
  51. case(seg2)
  52. 4'b0000:seg <= 8'b11000000;
  53. 4'b0001:seg <= 8'b11111001;
  54. 4'b0010:seg <= 8'b10100100;
  55. 4'b0011:seg <= 8'b10110000;
  56. 4'b0100:seg <= 8'b10011001;
  57. 4'b0101:seg <= 8'b10010010;
  58. 4'b0110:seg <= 8'b10000010;
  59. 4'b0111:seg <= 8'b11111000;
  60. 4'b1000:seg <= 8'b10000000;
  61. 4'b1001:seg <= 8'b10010000;
  62. default: seg<=8'b11000000;
  63. endcase
  64. end
  65. if (selcnt==2'b10)
  66. begin
  67. case(seg3)
  68. 4'b0000:seg <= 8'b11000000;
  69. 4'b0001:seg <= 8'b11111001;
  70. 4'b0010:seg <= 8'b10100100;
  71. 4'b0011:seg <= 8'b10110000;
  72. 4'b0100:seg <= 8'b10011001;
  73. 4'b0101:seg <= 8'b10010010;
  74. 4'b0110:seg <= 8'b10000010;
  75. 4'b0111:seg <= 8'b11111000;
  76. 4'b1000:seg <= 8'b10000000;
  77. 4'b1001:seg <= 8'b10010000;
  78. default: seg<=8'b11000000;
  79. endcase
  80. end
  81. if (selcnt==2'b11)
  82. begin
  83. case(seg4)
  84. 4'b0000:seg <= 8'b11000000;
  85. 4'b0001:seg <= 8'b11111001;
  86. 4'b0010:seg <= 8'b10100100;
  87. 4'b0011:seg <= 8'b10110000;
  88. 4'b0100:seg <= 8'b10011001;
  89. 4'b0101:seg <= 8'b10010010;
  90. 4'b0110:seg <= 8'b10000010;
  91. 4'b0111:seg <= 8'b11111000;
  92. 4'b1000:seg <= 8'b10000000;
  93. 4'b1001:seg <= 8'b10010000;
  94. default: seg<=8'b11000000;
  95. endcase
  96. end
  97. end
  98. endmodule

A路状态机:利用sig标志位控制红灯亮两次,sig=0,为红灯时,状态不跳转,红灯显示一次,sig加1。sig=1,为红灯时,状态下一次翻转。

  1. module STATEA(clk_in,rst,currentstate);
  2. input clk_in;
  3. input rst;
  4. output reg [2:0]currentstate;
  5. reg [2:0]nextstate;
  6. reg sig;
  7. parameter S0=3'b001;
  8. parameter S1=3'b010;
  9. parameter S2=3'b100;
  10. always @(posedge clk_in or posedge rst)
  11. begin
  12. if(rst)
  13. currentstate<=S0;
  14. else begin
  15. currentstate<=nextstate;
  16. if(currentstate==S2)
  17. sig<=sig+1;
  18. end
  19. end
  20. always @(currentstate or sig)
  21. begin
  22. case(currentstate)
  23. S0:nextstate=S1;
  24. S1:nextstate=S2;
  25. S2:begin
  26. if(sig)
  27. nextstate=S0;
  28. else
  29. nextstate=S2;
  30. end
  31. default: nextstate=S1;
  32. endcase
  33. end
  34. endmodule

B路状态机:

  1. module STATEB(clk_in,rst,currentstate);
  2. input clk_in;
  3. input rst;
  4. output reg [2:0]currentstate;
  5. reg [2:0]nextstate;
  6. reg sig;
  7. parameter S0=3'b001;
  8. parameter S1=3'b010;
  9. parameter S2=3'b100;
  10. always @(posedge clk_in or posedge rst)
  11. begin
  12. if(rst)
  13. currentstate<=S2;
  14. else begin
  15. currentstate<=nextstate;
  16. if(currentstate==S2)
  17. sig<=sig+1;
  18. end
  19. end
  20. always @(currentstate or sig)
  21. begin
  22. case(currentstate)
  23. S0:nextstate=S1;
  24. S1:nextstate=S2;
  25. S2:begin
  26. if(sig)
  27. nextstate=S0;
  28. else
  29. nextstate=S2;
  30. end
  31. default: nextstate=S1;
  32. endcase
  33. end
  34. endmodule

工程文件实例:

代码改进,若需要不同时间的红绿灯,只需要重新设置在顺序计时模块中的时间条件即可。

         红绿灯系统的目标是优化交通流量,提高交通效率和安全性。单个的红绿灯设计可以帮助我们对状态机的理解。

        但是在实际生活中,红绿灯是一个庞大的系统,一条主干道上有很多的红绿灯,需要对实际路况和车流量和道路宽窄设计转换时间,并且需要和多个红绿灯协同运作。这样的设计才能解决实际性问题。

        当然,现代的红绿灯系统已经很完善了,缺少的是对路况和人车流量的智能检测和分析。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/791223
推荐阅读
相关标签
  

闽ICP备14008679号