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