verilog语言的FPGA变速花样流水灯设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于XILINX--XSE500E型FPGA

的变速流水灯以及花样流水灯的verilog语言设计

摘要

临近大四毕业,诸多工科院校电子电科通信等专业会选择用FPGA项目作为课程设计的课题,笔者同样经历了这个过程,收获颇多,在此将设计成果在此分享,以帮助大家更好掌握FPGA设计。

FPGA种类繁多,时效性非常好,设计过程中十分注重实时性,在时间点控制上非常优秀。此次设计采用XILINX的XSE500E型芯片的开发板,芯片采用FG320型接口,速度级别-4。板载时钟50MHz,如需其他时钟周期,可采用IP核中的clocking,其中的 DCM可以实现变频,引入DCM,输入频率50MHz,输出频率填入需要的频率即可,之后进行实例化。此外,可以借助计数器进行延时减速,此次设计采用了计数器延时方法。

本次列举了四种流水灯相关设计:普通流水灯(向左和向右滚动),自动反复式流水灯(到最右端自动向左滚动,到左端自动向右滚动),花样流水灯,变速流水灯。

谢谢大家的支持!

正文

一,普通流水灯

1,建模思想

普通流水灯,可以向右滚动,到最右端返回最左端,也可以向左滚动,到最左端返回最右端。

普通流水灯模块涉及的端口有:clk,它是时钟输入,一般就是板载时钟,这里是50MHz,具体参照开发板说明。还有复位输入rst,高电平有效。此外就是led端口,这个端口有8根管脚,共8位,连接8个led灯。

采用verilog语言,端口定义格式如下:

module led(

input clk,

input rst,

output reg[7:0] led //此行定义说明led端口既是驱动管脚的,又是寄存器

);

采用过程建模,这里不采用行为建模和功能建模,因为这个过程就是一个大循环,规律性极强。由于板载时钟50MHz,如果每个时钟周期都要滚动流水灯,那么速度是惊人的,人眼根本无法分辨。所以采用计数器延时,当计数达到约4千万时候,驱动系统进行动作,可以判断,也可以进行流水灯动作。

普通流水灯,需要判断流水灯是否到了尽头,如果到了尽头,需要回归起点。

每次上电之后,需要按一下复位,才能进行流水灯循环。

Rst的作用就是初始化,首先为led赋予一个初始状态,可以让一个灯循环,也可以让几个灯一起亮,一起循环。几个灯亮,关键在于rst初始化。

2,全部代码如下:这里列举右滚动流水灯

module led( //这行定义了模块名字为led

input clk,

input rst,

output reg[7:0] led

);

reg [25:0] count; //延时计数器,这里是25位计数器,为32M。

always @(posedge clk) //每个时钟上升沿进行下面动作

if(rst)

led <= 8'b10000000; //复位初始化,只有一个灯亮着,这里做一个灯的流水灯,如always @(posedge clk) 果做两个灯,就是11000000

If(reg[25] == 1) //计数满32M之后再进行下面动作,延时。

begin

If (led == 8’b00000001) //当滚动到尽头,回到左侧起始端

led <= 8’b10000000;

else

led <= {led[0],led[7:1]} //右移,用并置符实现

end

endmodule

左滚动可以很容易得出,在此不做详细解释,读者自行分析。

module led( //这行定义了模块名字为led

input clk,

input rst,

output reg[7:0] led

);

reg [25:0] count; //延时计数器,这里是25位计数器,为32M。

always @(posedge clk) //每个时钟上升沿进行下面动作

if(rst)

led <= 8'b00000001; //复位初始化,只有一个灯亮着,这里做一个灯的流水灯,如always @(posedge clk) 果做两个灯,就是00000011

If(reg[25] == 1) //计数满32M之后再进行下面动作,延时。

begin

If (led == 8’b10000000) //当滚动到尽头,回到左侧起始端

led <= 8’b00000001;

else

led <= {led[6:0],led[7]} //左移,用并置符实现

end

endmodule

二,自循环流水灯

此代码引用自课堂实验的代码,非本人原创,在此分析一下。大家可以自行理解。每次上电,按一下rst复位键,流水灯出现一个或者几个灯亮起来,接下来按住run,则流水灯从左向右滚动,滚到最右,自动向左滚,滚到左侧,再向右滚动,周而复始。

1,建模思想

该模块一共有四个端口,led是驱动流水灯的8个管脚的端口,clk是板载50MHz时钟,rst是复位信号输入,run是控制流水灯开始滚动的信号。

该模块采用计数器延时,通过flag寄存器控制流动方向,flag为1时候左滚动,flag为0,向右滚动。滚动到位自行判断。

2,代码分析

module Led(clk,reset,run,led);

input clk,reset,run;

output reg[7:0] led;

reg [22:0] count;

reg [7:0] mled;

reg flag;

always@(posedge clk)

if(count[22] == 1)

count <= 0;

else

count <= count+1;

always@(posedge clk )

begin

if(count [22] == 1)

if(reset)

begin

led <= 8'b0000_0001; //这里我们只让一个灯亮着,如果两个灯就是00000011

flag <= 1; //初始化默认向左滚动

end

else if(run ) //按下run之后才会滚动

if(flag) //左滚动状态

begin

led <= {led[6:0],led[7]}; //左移

if(led == 8'b0111_0000) //移到左端,之后要向右滚动

flag <= 0; //控制向右滚动

else ; //使用空的else语句是为了避免产生锁存器

end

else //flag==0即右滚状态

begin

led <= {led[0],led[7:1]}; //右移

if(led == 8'b0000_1110) //右移到尽头,要控制左移

flag <= 1; //控制左移

else ;

end

else

led <= led; //不按run的时候,led保持原来的状态,不动。

end

endmodule

三,花样流水灯

1,建模思想

笔者逻辑思维有限,并非专职码农,写出的代码,只能保证可以实现效果,至于执行效率,你懂的。

不过,可读性肯定没问题,一看便懂。

Verilog采用了c语言的风格,要说C语言什么最难,数组?指针?结构体?链表?

相关文档
最新文档