4. 用状态机设计交通灯控制器,设计要求:A路和B路,每路都有红、黄、绿三种灯,持续时间为:红灯45s,黄灯5s,绿灯40秒。

A路和B路灯的状态转换是:

(1) A红,B绿(持续时间40s);

(2) A红,B黄(持续时间5s);

(1) A绿,B红(持续时间40s);

(1) A绿,B黄(持续时间5s);

4.1 设计思路:

由题知共4个状态,每个状态及其输出持续的时间分别为40s或5秒。故设计一个模为90的计数器,分4段,对应每个状态持续的

时间,然后顺序循环。

4.2 两路交通灯控制电路源码如下:

 1 //triffic lights
2 //ex8_4
3 //2020-10-14
4 //by YongFengXie
5 module ex8_4(clk,rst_n,lights);
6 input clk;
7 input rst_n;
8 output reg [5:0] lights; //A and B light
9
10 reg [6:0] cnt; // counter 90
11 reg [3:0] state;
12
13 parameter s0=4'b0001,s1=4'b0010,s2=4'b0100,
14 s3=4'b1000;
15
16 always @(posedge clk or negedge rst_n)
17 begin
18 if(!rst_n)
19 cnt<=7'd0;
20 else if(cnt<7'd90)
21 cnt<=cnt+1'b1;
22 else
23 cnt<=7'd0;
24 end
25
26 always @(posedge clk or negedge rst_n)
27 begin
28 if(!rst_n)
29 begin
30 state<=s0;
31 lights<=6'b100_001;
32 end
33 else if(cnt<7'd40)
34 begin
35 state<=s0;
36 lights<=6'b100_001; //RYG(A)_RYG(B)
37 end
38 else if(cnt>7'd39 &&cnt<7'd45)
39 begin
40 state<=s1;
41 lights<=6'b100_010; //RYG(A)_RYG(B)
42 end
43 else if(cnt>7'd44 && cnt<7'd85)
44 begin
45 state<=s2;
46 lights<=6'b001_100; //RYG(A)_RYG(B)
47 end
48 else
49 begin
50 state<=s3;
51 lights<=6'b001_010; //RYG(A)_RYG(B)
52 end
53 end
54
55 endmodule

4.3 交通灯控制器的测试代码:

 1 //ex8_4 testbench
2 //2020-10-14
3 //by YongFengXie
4 `timescale 1ns/1ns
5 module ex8_4tb;
6 reg clk;
7 reg rst_n;
8 wire [5:0] lights;
9
10 ex8_4 ub(clk,rst_n,lights);
11
12 initial begin
13 clk=1'b0;
14 rst_n=1'b0;
15 #20 rst_n=1'b1;
16 #1000 $stop;
17 end
18
19 always #5 clk=~clk;
20
21 endmodule

4.4 交通灯控制器的仿真结果如图ex8_4_1所示:

图ex8_4_1 交通灯控制器仿真结果

4.5  总结:交通灯控制器这个电路的状态转换挺简单,题目里已经详细列出。难在每种状态持续时间不一样,这是跟前面的序列检测不同的地               方。按照上述设计,在Quartus里未生成状态转换图,仿真和DE2-115上皆可验证正确。期待更好的解法。

4.6  参照https://blog.csdn.net/qq_38318540/article/details/107401152,找到方法,计时模块,状态转换,状态输出,条理清晰的分开写,难点在        于计数器还是只需要一个,控制模不同即可,产生计时的效果,也就是需要40s,5s的计时,设计里在状态发生转换时产生一个标志st,同时          这个st,在计时模块里又扮演计数器清零的一个功能,达到计时到不同值,计数器清零重新开始计数的目的,看似无用的st,关联器状态变化

的节奏。

另一种交通灯控制器的Verilog代码如下:

  1 //triffic lights
2 //ex8_4
3 //2020-10-14
4 //by YongFengXie
5 module ex8_4(clk,rst_n,lights);
6 input clk;
7 input rst_n;
8 output reg [5:0] lights; //A and B light
9
10 reg [6:0] cnt; // counter 90
11 reg [3:0] state,nextstate;
12 wire t1,t2; // t1-40s,t2-5s
13 reg st; // state transition signal
14
15 parameter s0=4'b0001,s1=4'b0010,s2=4'b0100,
16 s3=4'b1000;
17
18 //timing module
19 always @(posedge clk or negedge rst_n)
20 begin
21 if(!rst_n)
22 cnt<=7'd0;
23 else if(st)
24 cnt<=7'd0;
25 else if(cnt<7'd40)
26 cnt<=cnt+1'b1;
27 else
28 cnt<=7'd0;
29 end
30
31 assign t1=(cnt==7'd39)?1'b1:1'b0;
32 assign t2=(cnt==7'd4)?1'b1:1'b0;
33
34 /*
35 always @(posedge clk or negedge rst_n)
36 begin
37 if(!rst_n)
38 begin
39 state<=s0;
40 lights<=6'b100_001;
41 end
42 else if(cnt<7'd40)
43 begin
44 state<=s0;
45 lights<=6'b100_001; //RYG(A)_RYG(B)
46 end
47 else if(cnt>7'd39 &&cnt<7'd45)
48 begin
49 state<=s1;
50 lights<=6'b100_010; //RYG(A)_RYG(B)
51 end
52 else if(cnt>7'd44 && cnt<7'd85)
53 begin
54 state<=s2;
55 lights<=6'b001_100; //RYG(A)_RYG(B)
56 end
57 else
58 begin
59 state<=s3;
60 lights<=6'b001_010; //RYG(A)_RYG(B)
61 end
62 end
63 */
64
65 //state transition module
66 always @(posedge clk or negedge rst_n)
67 begin
68 if(!rst_n)
69 state<=s0;
70 else
71 state<=nextstate;
72 end
73
74 always @(state,t1,t2)
75 begin
76 case(state)
77 s0: begin
78 nextstate<=t1?s1:s0;
79 st<=t1?1'b1:1'b0;
80 end
81 s1: begin
82 nextstate<=t2?s2:s1;
83 st<=t2?1'b1:1'b0;
84 end
85 s2: begin
86 nextstate<=t1?s3:s2;
87 st<=t1?1'b1:1'b0;
88 end
89 s3: begin
90 nextstate<=t2?s0:s3;
91 st<=t2?1'b1:1'b0;
92 end
93 default: begin
94 nextstate<=s0;
95 st<=1'b0;
96 end
97 endcase
98 end
99
100 //state corresponding output
101 always @(state)
102 begin
103 case(state)
104 s0:lights=6'b100_001; //A-R,B-G
105 s1:lights=6'b100_010; //A-R,B-Y
106 s2:lights=6'b001_100; //A-G,B-R
107 s3:lights=6'b010_100; //A-Y,B-R
108 default:lights=6'b100_001; //A-R,B-G
109 endcase
110 end
111
112 endmodule

上面的代码不够简洁,还是有个固定思维的问题,其中从18行开始的计时模块做成模可变的计数器更优,所以,这段,修改如下:

 1 //timing module
2 always @(posedge clk or negedge rst_n)
3 begin
4 if(!rst_n)
5 cnt<=7'd0;
6 else if(st)
7 cnt<=7'd0;
8 else
9 cnt<=cnt+1'b1;
10 /*else if(cnt<7'd40)
11 cnt<=cnt+1'b1;
12 else
13 cnt<=7'd0;*/
14 end

习题8 #第8章 Verilog有限状态机设计-4 #Verilog #Quartus #modelsim的更多相关文章

  1. [Python学习笔记][第五章Python函数设计与使用]

    2016/1/29学习内容 第四章 Python函数设计与使用 之前的几页忘记保存了 很伤心 变量作用域 -一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将这个赋值结果反映到函数之外,可 ...

  2. 《.NET 设计规范》第 5 章:成员设计

    <.NET 设计规范>第 5 章:成员设计 5.1 成员设计的通用规范 要尽量用描述性的参数名来说明在较短的重载中使用的默认值. 避免在重载中随意地改变参数的名字.如果两个重载中的某个参数 ...

  3. MySQL性能调优与架构设计——第 18 章 高可用设计之 MySQL 监控

    第 18 章 高可用设计之 MySQL 监控 前言: 一个经过高可用可扩展设计的 MySQL 数据库集群,如果没有一个足够精细足够强大的监控系统,同样可能会让之前在高可用设计方面所做的努力功亏一篑.一 ...

  4. MySQL性能调优与架构设计——第 17 章 高可用设计之思路及方案

    第 17 章 高可用设计之思路及方案 前言: 数据库系统是一个应用系统的核心部分,要想系统整体可用性得到保证,数据库系统就不能出现任何问题.对于一个企业级的系统来说,数据库系统的可用性尤为重要.数据库 ...

  5. MySQL性能调优与架构设计——第12章 可扩展设计的基本原则

    第12章 可扩展设计的基本原则 前言: 随着信息量的飞速增加,硬件设备的发展已经慢慢的无法跟上应用系统对处理能力的要求了.此时,我们如何来解决系统对性能的要求?只有一个办法,那就是通过改造系统的架构体 ...

  6. 《C++Primer》第五版习题答案--第三章【学习笔记】

    [C++Primer]第五版[学习笔记]习题解答第三章 ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/10 第三章:字符串,向量和数组 ...

  7. 《C++Primer》第五版习题解答--第四章【学习笔记】

    [C++Primer]第五版习题解答--第四章[学习笔记] ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/11 第四章:表达式 练习4. ...

  8. 《C++Primer》第五版习题答案--第五章【学习笔记】

    <C++Primer>第五版习题答案--第五章[学习笔记] ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/15 第五章:语句 ...

  9. 《C++Primer》第五版习题答案--第六章【学习笔记】

    <C++Primer>第五版习题答案--第六章[学习笔记] ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/16 第六章:函数 ...

  10. FPGA Prototyping By Verilog Examples第五章 状态机FSM设计

    上升沿检测电路之Moore型FSM // Listing 5.3module edge_detect_moore ( input wire clk, reset, input wire level, ...

随机推荐

  1. Redis 中 scan 命令太坑了,千万别乱用!!

    作者:铂赛东\链接:www.jianshu.com/p/8cf8aac3dc25 1 原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作.但是最近在使用redis的scan ...

  2. KingbaseES中truncate和oracle中truncate区别

    truncate命令在KingbaseES中本质上区别于oracle.因为oracle中,数据文件datafile可以被表所共享,每张表被分配各自的连续的extents.而在KingbaseES中,数 ...

  3. Java封装xml格式参数请求第三方接口

    Java封装xml格式参数请求第三方接口 1.引用包 import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers ...

  4. IntelliJ IDEA集成本地Maven步骤

    IntelliJ IDEA集成本地Maven步骤 一.前期准备 Maven已经在本地环境配置完成,步骤可以参考我的这篇文章: https://www.cnblogs.com/rainbow-1/p/1 ...

  5. cmd中怎么清屏--cls

    平时我们在 Linux 系统中清除屏幕 用的命令是:  clear 现在在Windows上用的清屏命令是 : cls

  6. Redis之父萨尔瓦多·桑菲利波又名安蒂雷斯

    萨尔瓦多·桑菲利波又名安蒂雷斯 个人博客连接 嗨,我是萨尔瓦多·桑菲利波,也被称为安提雷斯, 一位居住在卡塔尼亚的意大利计算机程序员. 我于7年1977月2020日出生在坎波贝洛迪利卡塔. 2022 ...

  7. Linux之bond和team

    一.bond 和 team 区别 bond只能是双网卡绑定,team不需要手动加载相应内核模块和有更强的拓展性,最高可以绑定8块网卡. 二.模式 bond模式 (1)mode=0(balance-rr ...

  8. 简单写一个eventbus

    前言 闲暇之余,简单写一个eventbus. 正文 什么是eventbus? eventbus 是一个开源的发布订阅模式的框架,用于简化程序间不同组件的通信. 它允许不同组件间松耦合通信,组件之间不通 ...

  9. 重新点亮linux 命令树————二进制安装[十一八]

    前言 简单介绍一下二进制安装 正文 wget https://openresty.org/download/openresty-1.15.8.1.tar.gz tar -zxf openresty-V ...

  10. mysql 重新整理——索引优化explain字段介绍一 [九]

    前言 在七种介绍了explain这东西,那么具体来看下它是如何来运行的吧. 正文 id 来看一条语句:EXPLAIN select * from departments,dept_emp,employ ...