verilog语言设计一个交通灯信号控制电路要点Word文档下载推荐.doc
《verilog语言设计一个交通灯信号控制电路要点Word文档下载推荐.doc》由会员分享,可在线阅读,更多相关《verilog语言设计一个交通灯信号控制电路要点Word文档下载推荐.doc(39页珍藏版)》请在冰点文库上搜索。
作用如下:
顶层及控制模块:
此模块做例化,和控制,是本程序的主体,对底层的分频模块和译码显示模块进行例化,并且做控制设计。
控制设计如下:
采用同步时序逻辑。
包括一个循环计数器,三个比较器,always
控制。
通过分频后的CLK1新号(1Hz),进行对一个循环变量“k”的周期为130的循环,进时,重新复值K=0;
当1值减k每进行一次跳变,clk1而控制三个灯的控制;
具体循环为:
为129。
通过比较器,每个灯的条件不同,当129>
=k>
=70时绿灯亮,69>
=60黄灯闪烁,59>
=0红灯亮。
对于数码管输出,当129>
=70时,数码管个位输出=(k-70)_x0010_,十位输出为(k-70-个位)/10;
当69>
=60数码管个位输出=(k-60)_x0010_,十位输出为(k-60-个位)/10,当59>
=0时,数码管个位输出=k_x0010_十位输出为(k-个位)/10。
分频模块:
分频模块用以把输入的50MHz的信号转换为1Hz信号,便于其后的交通灯控制及数码管输出。
译码模块:
考虑到数字显示需要两个七段译码器,且在数字系统中,数字的表示都是采用二进制,因为两个管子分别输入,所以需要把循环变量k转换为有用的十位和各位输出。
为了方便,把循环变量k减去各状态的基数值后,用数学方法取十位和各位分别做输入。
如绿灯时,129>
=70时,数码管个位输出=(k-70)_x0010_,十位输出为(k-70-个位)/10。
七段译码器的设计原理如图:
2.总体设计框图及说明:
blu
rst
Clk
50Hz
循环变量k
控制yel
Clk1
1Hz
129~0
red
图一
输入:
clk全局时钟信号,50MHz
rst全局复位端,高电平有效
输出:
ctrl_1s倒计时个位上数字
ctrl_10s倒计时十位上数字
blu,yel,red各个灯状态
框图说明:
状态机的输入,只有时钟信号clk和复位信号reset.输出为数码管十位和个位的二进制显示状态以及三个灯的颜色显示(blu,yel,red,分别是绿黄红灯,“1”表示灯亮,“0”表示灭)。
输入clk的频率很大,需要通过计数器对其进行分频。
首先计数产生一个1Hz的输出,通过该输出再次循环计数,产生周期为130的计数变量,从而控制各个灯的亮灭。
而控制黄灯闪烁的分频,为方便起见,仍以1s为单位,每秒钟改变一次。
嵌套语句来控制三灯亮与灭,同时间接地进行倒计时的过程,输出个位和十位上的数,if用.
直接用两个七段译码显示倒计时数。
。
0”1”时,三个信号灯及循环变量k复位置“Rst信号是清零用的,为“流程图
开始
50MHz
输入
clk1:
1Hz
循环变量k计数
70≤k≤
blu=1
k60≤≤69
yel=~yel
0≤k≤red=1
图四
显示输出
时序说明:
3.
整段程序共有四个状态:
初始状态、绿灯状态、黄灯状态、红灯状态。
如果有rst的“1”状态,则要进行清零,恢复到初始状态;
这是在控制模块的计数器会清零,倒计时不再进行,三个灯都是灭的状态,
Rst为“1”状态跳转为初始状态的,等待着清零结束,开始工作;
此时七段译码也不会显示。
清零结束后,系统开始正常工作。
首先是分频时钟开始工作,此时循环变量开始循环,绿灯亮60s,译码器开始显示倒计时的输出,直到k=70。
当循环变量k<
=69时,黄灯闪烁10s,同时译码倒计时,直到k=60;
=59时,红灯亮,同时译码倒计时直到k=0。
至此一个周期已经完成,沿此过程循环进行,直到reset信号的出现。
初始
K=K-1
绿灯状态
K≤69
使0K<K=129K=K-1
黄灯状态红灯状态
K=K-1K≤59
图二
4.模块设计框图、相关时序
本程序分为三个模块,顶层模块、控制模块、译码模块,各模块的设计框图以及相关时序说明如下:
顶层及控制模块框图
顶层控制
译码显分频
示块
图三
clk全局时钟信号,50MHz
rst全局复位端,高电平有效
led1个位七段译码
led10十位七段译码
时序说明:
加上时钟信号之后,首先用reset清零,然后分频模块会分频产生分频时钟clk1,根据分频时钟的高与低,进而进行变量循环,然后会控制3个状态之间的跳转,译码显示模块会同步通过数码管来显示倒计时数;
灯控信号blu,yel,red同时输出对交通灯的控制。
输入50MHz的信号,rst为“1”时,计数器j置“0”,并在以后每经历一个系统时钟周期时加1,知道k=49999999时,clk1=~clk1,同时k=0.到此分频完成。
(在实际代码编写中,为了代码的精简,此模块已经集成入顶层及控制模块)
计数器显示计数J=4999clk50MHz9999
clk=~clk
rst
图四
译码显示模块:
输入端口:
din_1s显示器个位数据,由控制模块输入
din_10s显示器十位数据,由控制模块输入
输出端口:
led_data_1s显示器个位数据的译码
led_data_10s显示器十位数据的译码
时序说明:
和clk(50MHz)(系统时钟)并间接受此模块接受主模块输出的个位和十位的数值控制,
(全局复位)rst,及分频时钟clk1的控制,均为上升沿触发,当rst为高电平时,电路复位,重新开始工作。
当rst为低电平时,电路正常。
5.仿真及综合结果
表1仿真结果信号解释说明
信号解释备注
clk为了方便,这里取2ns系统时钟,50MHz
blu,yel,red
分别绿红灯,最终三灯状态
“1”为亮“0”为灭
k循环计数变量用以状态判断控制
led10数码管十位显示倒计时十位七段译码
led1数码管个位显示倒计时个位七段译码
out1控制模块的输出倒计时个位上的数字
out10控制模块的输出倒计时十位上的数字
rst高电平有效系统控制变量
上图中blu,yel,red,三个信号反映的绿黄红交通灯的状态,其中包括绿灯亮60秒,黄灯以2HZ为周期闪烁,红灯亮60s,总周期为130s。
上图为循环控制变量的值随分频后信号从129到0的循环计数。
综合结果:
顶层及控制,分频模块的综合RTL级电路如图:
译码显示模块的综合如下:
RTL级门级
6.代码及注释
此为顶层及控制模块代码:
`include./decode.v
modulebulb(clk,rst,red,blu,yel,led1,led10);
inputclk,rst;
outputblu,yel,red,led1,led10;
regred,yel,blu;
wire[6:
0]led1;
wire[6:
0]led10;
reg[3:
0]out10,out1;
reg[5:
0]j;
reg[7:
0]k;
//j,k
regclk1;
//
initial
begin
k='
d129;
blu<
=0;
yel<
red<
//j=0;
//clk1<
end
//******************************************
//这是分频部分功能实现
//**************?
?
**************************
always@(posedgeclkorposedgerst)
if(rst)
begin
clk1<
j<
end
else
if(j==4)//
begin
=~clk1;
end
else
begin
j<
=j+1;
end
always@(posedgeclk1)
begin
if(k=='
d0)k='
elsek=k-1;
end
//****************************************************
//此为控制部分
if(!
rst)//?
res?
1?
if(k>
='
d70&
&
k<
d129)
begin
red<
blu<
=1;
out1=(k-70)_x0010_;
out10=(k-70-out1)/10;
end
elseif(k>
d60&
d69)
begin
=~yel;
//黄灯闪烁
out1=(k-60)_x0010_;
out10=(k-60-out1)/10;
else
//yel<
out1=k_x0010_;
out10=(k-out1)/10;
else
begin
blu<
yel<
red<
decoded(.din_1s(out1),
.din_10s(out10),
.led_data_1s(led1),
.led_data_10s(led10));
Endmodule
以下是译码及显示模块代码:
moduledecode(
din_1s,//个位输入
din_10s,//十位输入
led_data_1s,//数码管个位输出
led_data_10s//数码管十位输出
);
inputdin_1s;
inputdin_10s;
output[6:
0]led_data_1s;
0]led_data_10s;
reg[6:
always@(din_1s)
case(din_1s)
0:
led_data_1s=7'
b0001000;
1:
b1101101;
2:
b0100010;
3:
b0100100;
4:
b1000101;
5:
b0010100;
6:
b0010000;
7:
b0101101;
8:
b0000000;
9:
b0000100;
default:
b1111111;
endcase
end
always@(din_10s)
case(din_10s)
0:
led_data_10s=7'
endcase
endmodule
测试模块代码:
`timescale1ns/1ns
`includeulb.v
moduletop;
regclk,rst;
wirered,blu,yel,led1,led10;
//regclk1,red,blu,yel;
initial
begin
rst=1;
clk=1;
#500rst=0;
#500rst=1;
always#20clk=~clk;
bulbbulb(clk,rst,red,blu,yel,led1,led10);
五、分析与讨论
电路关键是在进行时序状态转换,倒计时计数,控制黄灯闪烁过程,经过分析,需要一个来判断三个灯状态的判断条件。
本电路主要运用一个循环变量k,作为程序控制的灵魂,进行各个状态循环,黄灯闪烁的判断和数码管的输入。
.
程序亮点:
为了数码管的个位十位输入,把循环变量k进行倒数计时,这样与数码管的倒计时数值一致,经过简单数学计算,就可以把每个状态的k的值换算为数码管的个位十位。
这样一来,省去了为数码管单独设置的变量,化简了代码。
优点:
代码简单易懂。
中心代码仅150多行。
缺陷:
由于未设定具体的状态机循环,只是运用变量k的循环控制,造成了综合时的线路繁杂以及冗余,不能完美符合Verilog语言的关注硬件的特点。
但是没有任何代码是完美的,这也正是我通过此次编程学到的最大的经验。
待优化:
中间黄灯的闪烁频率有点过慢,时间匆忙,未能优化,若把分频频率clk1改为0.5Hz,然后循环变量k按照clk1每2个周期改变一次,即可实现黄灯每0.5s闪一次。
六、教师评语
签名:
日期:
成绩