学fpga(流水灯)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】从学习方法上说,fpga的学习方面和linux下面c开发有点相似。fpgalinux语言verilog。vhdlc,c++开发工具vivado,quartusgcc调试工具chip scope,signal tapgdb仿真modelsimx86 linux虚拟机运行...
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
从学习方法上说,fpga的学习方面和linux c开发有点相似。
fpga | linux | |
语言 | verilog,vhdl | c,c++ |
开发工具 | vivado,quartus | gcc,g++ |
调试工具 | chip scope,signal tap | gdb |
仿真 | modelsim | x86 linux虚拟机 |
运行 | fpga开发板 | arm linux开发板 |
通过上面的表格,可以看出来,不管是哪一种开发方法,都需要对应的语言、开发工具、调试工具、仿真平台和实际验证环境,这些都是少不了的。只不过,fpga侧重的是并发流水线,软件倡导的是顺序执行而已。
前面,我们讨论过计数器,也就是说从复位开始,计数器就会不停地计数下去。这么一直计数下去其实也是可以的,只要有这么一个需求就可以,或者只是想看一下计数器是不是真的会这么走下去。真实场景下面,更多的是用计数器来做一个定时器。比如,复位之后,计数器从0开始,等到计数到99的时候,就会恢复到0。这样一来,就好像有这么一个100的计数器,它会周期性的重新计数。设想一下,如果这个周期拓展到1s,那么其实就是一个1s的定时器了。不过,一般对fpga来说,1s的时间太长了,我们可以用wavedrom设计一个1周期为100的定时器。
{ "signal" : [
{ "name": "clk", "wave": "p......|.." },
{ "name": "rst", "wave": "010....|.." },
{ "name": "cnt", "wave": "x22345x|67", data:["0","0","1","2","3","99","0"] }
]
}
转变成时序图就是这样的,
所以,这个时候需要做的就是在之前的verilog代码上面添加一个判断语句,即
always@(posedge clk or posedge rst)
if(rst)
cnt <= 4'd0;
else if(cnt == 4'd99)
cnt <= 4'd0;
else
cnt <= cnt + 1;
有同学也许会说,这和流水灯有什么关系。大家不要着急,关键是这里的cnt 99,完全可以用这一条件实现led的开和灭的功能。
{ "signal" : [
{ "name": "clk", "wave": "p......|.." },
{ "name": "rst", "wave": "010....|.." },
{ "name": "cnt", "wave": "x22345x|67", data:["0","0","1","2","3","99","0"] },
{ "name": "led", "wave": "x0.....|.1", },
]
}
上面的json转换成图形,就是这样的,
注意这里的cnt为99的时候,led就会跳转为1高电平。等到下一个99的时候再跳转为0,这样就实现了周期性熄灭的效果。写成verilog代码应该是这样的,
always @(posedge clk or posedge rst)
if (rst)
led <= 1'b0;
else if(cnt == 8'd99)
led <= ~led;
做到这一点似乎离我们的目标越来越近。大家可以想象一下如果有4个led灯,那么应该怎么处理。是不是可以把cnt分成4部分。99的时候,只有led1灯亮;199的时候,只有led2灯亮;299的时候,只有led3亮;399的时候只有led4灯亮。
{ "signal" : [
{ "name": "clk", "wave": "p.....|......|.." },
{ "name": "rst", "wave": "010...|......|.." },
{ "name": "cnt", "wave": "x2245x|6789x.|45", data:["0","0","1","2","99","100","101","102","199","200"] },
{ "name": "led0", "wave": "x1....|.0....|..", },
{ "name": "led2", "wave": "x0....|.1....|.0", },
{ "name": "led3", "wave": "x0....|......|.1", },
{ "name": "led4", "wave": "x0....|......|..", },
]
}
转换成图形就是这样的,
当然上面只是一种设计方法,大家可以集思广益,用自己的方法来设计出不一样的流水灯效果。流水灯固然简单,关键还是考察背后的思考过程。
更多推荐
所有评论(0)