verilog语言的FPGA变速花样流水灯设计.docx
- 文档编号:6610311
- 上传时间:2023-01-08
- 格式:DOCX
- 页数:12
- 大小:18.62KB
verilog语言的FPGA变速花样流水灯设计.docx
《verilog语言的FPGA变速花样流水灯设计.docx》由会员分享,可在线阅读,更多相关《verilog语言的FPGA变速花样流水灯设计.docx(12页珍藏版)》请在冰豆网上搜索。
verilog语言的FPGA变速花样流水灯设计
基于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语言,端口定义格式如下:
moduleled(
inputclk,
inputrst,
outputreg[7:
0]led//此行定义说明led端口既是驱动管脚的,又是寄存器
采用过程建模,这里不采用行为建模和功能建模,因为这个过程就是一个大循环,规律性极强。
由于板载时钟50MHz,如果每个时钟周期都要滚动流水灯,那么速度是惊人的,人眼根本无法分辨。
所以采用计数器延时,当计数达到约4千万时候,驱动系统进行动作,可以判断,也可以进行流水灯动作。
普通流水灯,需要判断流水灯是否到了尽头,如果到了尽头,需要回归起点。
每次上电之后,需要按一下复位,才能进行流水灯循环。
Rst的作用就是初始化,首先为led赋予一个初始状态,可以让一个灯循环,也可以让几个灯一起亮,一起循环。
几个灯亮,关键在于rst初始化。
2,全部代码如下:
这里列举右滚动流水灯
moduleled(//这行定义了模块名字为led
inputclk,
inputrst,
outputreg[7:
0]led
reg[25:
0]count;//延时计数器,这里是25位计数器,为32M。
always@(posedgeclk)//每个时钟上升沿进行下面动作
if(rst)
led<=8'b10000000;//复位初始化,只有一个灯亮着,这里做一个灯的流水灯,如
always@(posedgeclk)果做两个灯,就是11000000
If(reg[25]==1)//计数满32M之后再进行下面动作,延时。
begin
If(led==8’b00000001)//当滚动到尽头,回到左侧起始端
led<=8’b10000000;
else
led<={led[0],led[7:
1]}//右移,用并置符实现
end
endmodule
左滚动可以很容易得出,在此不做详细解释,读者自行分析。
moduleled(//这行定义了模块名字为led
inputclk,
inputrst,
outputreg[7:
0]led
reg[25:
0]count;//延时计数器,这里是25位计数器,为32M。
always@(posedgeclk)//每个时钟上升沿进行下面动作
if(rst)
led<=8'b00000001;//复位初始化,只有一个灯亮着,这里做一个灯的流水灯,如
always@(posedgeclk)果做两个灯,就是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,代码分析
moduleLed(clk,reset,run,led);
inputclk,reset,run;
outputreg[7:
0]led;
reg[22:
0]count;
reg[7:
0]mled;
regflag;
always@(posedgeclk)
if(count[22]==1)
count<=0;
else
count<=count+1;
always@(posedgeclk)
begin
if(count[22]==1)
if(reset)
begin
led<=8'b0000_0001;//这里我们只让一个灯亮着,如果两个灯就是00000011
flag<=1;//初始化默认向左滚动
end
elseif(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语言什么最难,数组?
指针?
结构体?
链表?
NO!
是if.....elseif.....else......分支判断,尤其是嵌套,if嵌套可以把码农瞬间搞疯。
C语言的if下面要跟着{},括号里面的是一个整体,这还容易判断,可是verilog呢?
连个括号都没有,根本无法判断谁跟谁是站在一起的。
所以,根据程序是个大循环的思想,我采用过程建模,同时依靠行为建模,判断每个时间点该做点什么,确定每个点的行为,组成时间循环。
没错,case语句此时此刻就显得和蔼可亲了。
所以呢,我们采用case语句判断,依次判断。
下面分析一下代码:
注意case下面那些赋值语句中,0和1的位置,哪里是1,哪个灯就是亮的。
moduleled(
inputclk,
outputreg[5:
0]led
reg[24:
0]count;
reg[5:
0]mod;
always@(posedgeclk)
if(count[24]==0)
count<=0;
else
count<=count+1;
always@(posedgeclk)
if(count[24]==0)
if(mod[5]==1)//每次计数满了再行动,用来延时,另外,这里有个5位计数
mod<=0;器,说明这个循环一共有32个状态,每个状态由你做主
else
mod<=mod+1;
always@(posedgeclk)
begin
case(mod)
5'h00:
led<=8'b11000000;
5'h01:
led<=8'b01100000;
5'h02:
led<=8'b00110000;
5'h03:
led<=8'b00011000;
5'h04:
led<=8'b00001100;
5'h05:
led<=8'b00000110;
5'h06:
led<=8'b00000011;
5'h07:
led<=8'b00001100;
5'h08:
led<=8'b00110000;
5'h09:
led<=8'b01100000;
5'h0a:
led<=8'b11000000;
5'h0b:
led<=8'b00110000;
5'h0c:
led<=8'b00001100;
5'h0d:
led<=8'b00011000;
5'h0e:
led<=8'b00011000;
5'h0f:
led<=8'b00001100;
5'h10:
led<=8'b00001100;
5'h11:
led<=8'b00000110;
5'h12:
led<=8'b00000110;
5'h13:
led<=8'b00000011;
5'h14:
led<=8'b00000110;
5'h15:
led<=8'b00001100;
5'h16:
led<=8'b00011000;
5'h17:
led<=8'b00110000;
5'h18:
led<=8'b01100000;
5'h19:
led<=8'b11000000;
5'h1a:
led<=8'b01010000;
5'h1b:
led<=8'b01001000;
5'h1c:
led<=8'b01000100;
5'h1d:
led<=8'b01000010;
5'h1e:
led<=8'b10000001;
5'h1f:
led<=8'b01000010;
default:
led<=5'h11;
endcase
end
endmodule
再唠叨两句,这个段子虽然长,但是原理是万能的,32个状态位,因为mod寄存器有6位,如果mod寄存器只有4位,那么就只有8种状态。
可以修改mod位数,来决定多少个装态,每个状态赋值不同,产生的花样也不同。
花样如何,你做主!
四,变速流水灯
1,建模思想
变速流水灯,技术含量那个高啊,折磨我足足好几天,最后无奈了,采取了列举法。
我最怕什么ifelse了,没办法,笨是无法挽救的。
其实变速,你懂得,为什么快,因为每秒滚动一位,为什么慢,经过十几秒才滚动一次。
每秒滚动一次,那么每个状态只停留一秒,十几秒滚动一位,那么一个状态要停留十几秒,所以,根据每个状态停留的时间不同,发生变速。
我们这里列举了越来越慢的方法,注意case语句后面的各赋值句。
每个状态停留时间越长,那么速度就越慢。
2,源代码
oduleled(
inputclk,
outputreg[7:
0]led
reg[24:
0]count;
reg[7:
0]mod;
always@(posedgeclk)
if(count[24]==1)
count<=0;
else
count<=count+1;
always@(posedgeclk)
if(count[24]==1)
if(mod[7]==1)
mod<=0;
else
mod<=mod+1;
always@(posedgeclk)
begin
case(mod)
8'h00:
led<=8'b11000000;我们这里有128个状态,且只从左向右滚动。
可
8'h01:
led<=8'b01100000;以自己修改后面的1和0的位置得到很多花样
8'h02:
led<=8'b00110000;
8'h03:
led<=8'b00011000;
8'h04:
led<=8'b00001100;
8'h05:
led<=8'b00000110;
8'h06:
led<=8'b00000011;
8'h07:
led<=8'b11000000;
8'h08:
led<=8'b11000000;
8'h09:
led<=8'b01100000;
8'h0a:
led<=8'b01100000;
8'h0b:
led<=8'b00110000;
8'h0c:
led<=8'b00110000;
8'h0d:
led<=8'b00011000;
8'h0e:
led<=8'b00011000;
8'h0f:
led<=8'b00001100;
8'h10:
led<=8'b00001100;
8'h11:
led<=8'b00000110;
8'h12:
led<=8'b00000110;
8'h13:
led<=8'b00000011;
8'h14:
led<=8'b00000011;
8'h15:
led<=8'b11000000;
8'h16:
led<=8'b11000000;
8'h17:
led<=8'b11000000;
8'h18:
led<=8'b11000000;
8'h19:
led<=8'b01100000;
8'h1a:
led<=8'b01100000;
8'h1b:
led<=8'b01100000;
8'h1c:
led<=8'b01100000;
8'h1d:
led<=8'b00110000;
8'h1e:
led<=8'b00110000;
8'h1f:
led<=8'b00110000;
8'h20:
led<=8'b00110000;
8'h21:
led<=8'b00011000;
8'h22:
led<=8'b00011000;
8'h23:
led<=8'b00011000;
8'h24:
led<=8'b00011000;
8'h25:
led<=8'b00001100;
8'h26:
led<=8'b00001100;
8'h27:
led<=8'b00001100;
8'h28:
led<=8'b00001100;
8'h29:
led<=8'b00000110;
8'h2a:
led<=8'b00000110;
8'h2b:
led<=8'b00000110;
8'h2c:
led<=8'b00000110;
8'h2d:
led<=8'b00000011;
8'h2e:
led<=8'b00000011;
8'h2f:
led<=8'b00000011;
8'h30:
led<=8'b00000011;
8'h31:
led<=8'b11000000;
8'h32:
led<=8'b11000000;
8'h33:
led<=8'b11000000;
8'h34:
led<=8'b11000000;
8'h35:
led<=8'b11000000;
8'h36:
led<=8'b11000000;
8'h37:
led<=8'b01100000;
8'h38:
led<=8'b01100000;
8'h39:
led<=8'b01100000;
8'h3a:
led<=8'b01100000;
8'h3b:
led<=8'b01100000;
8'h3c:
led<=8'b01100000;
8'h3d:
led<=8'b00110000;
8'h3e:
led<=8'b00110000;
8'h3f:
led<=8'b00110000;
8'h40:
led<=8'b00110000;
8'h41:
led<=8'b00110000;
8'h42:
led<=8'b00110000;
8'h43:
led<=8'b00011000;
8'h44:
led<=8'b00011000;
8'h45:
led<=8'b00011000;
8'h46:
led<=8'b00011000;
8'h47:
led<=8'b00011000;
8'h48:
led<=8'b00011000;
8'h49:
led<=8'b00001100;
8'h4a:
led<=8'b00001100;
8'h4b:
led<=8'b00001100;
8'h4c:
led<=8'b00001100;
8'h4d:
led<=8'b00001100;
8'h4e:
led<=8'b00001100;
8'h4f:
led<=8'b00000110;
8'h50:
led<=8'b00000110;
8'h51:
led<=8'b00000110;
8'h52:
led<=8'b00000110;
8'h53:
led<=8'b00000110;
8'h54:
led<=8'b00000110;
8'h55:
led<=8'b00000011;
8'h56:
led<=8'b00000011;
8'h57:
led<=8'b00000011;
8'h58:
led<=8'b00000011;
8'h59:
led<=8'b00000011;
8'h5a:
led<=8'b00000011;
8'h5b:
led<=8'b11000000;
8'h5c:
led<=8'b11000000;
8'h5d:
led<=8'b11000000;
8'h5e:
led<=8'b11000000;
8'h5f:
led<=8'b11000000;
8'h60:
led<=8'b11000000;
8'h61:
led<=8'b11000000;
8'h62:
led<=8'b11000000;
8'h63:
led<=8'b01100000;
8'h64:
led<=8'b01100000;
8'h65:
led<=8'b01100000;
8'h66:
led<=8'b01100000;
8'h67:
led<=8'b01100000;
8'h68:
led<=8'b01100000;
8'h69:
led<=8'b01100000;
8'h6a:
led<=8'b01100000;
8'h6b:
led<=8'b00110000;
8'h6c:
led<=8'b00110000;
8'h6d:
led<=8'b00110000;
8'h6e:
led<=8'b00110000;
8'h6f:
led<=8'b00110000;
8'h70:
led<=8'b00110000;
8'h71:
led<=8'b00110000;
8'h72:
led<=8'b00110000;
8'h73:
led<=8'b00011000;
8'h74:
led<=8'b00011000;
8'h75:
led<=8'b00011000;
8'h76:
led<=8'b00011000;
8'h77:
led<=8'b00011000;
8'h78:
led<=8'b00011000;
8'h79:
led<=8'b00011000;
8'h7a:
led<=8'b00011000;
8'h7b:
led<=8'b00001100;
8'h7c:
led<=8'b00001100;
8'h7d:
led<=8'b00001100;
8'h7e:
led<=8'b00001100;
8'h7f:
led<=8'b00001100;
8'h80:
led<=8'b00001100;
default:
led<=8'h00;
endcase
end
endmodule
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- verilog 语言 FPGA 变速 花样 流水 设计