Zynq开发实践(FPGA之输入、输出整合)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
fpga开发的时候习惯上先把功能拆分成若干个模块。针对这些模块,一个一、个实现好之后,再用wire连接即可。这一点有点像软件编程的function。如果是规模不大的c项目,例如嵌入式mcu项目。我们也是先把项目拆分成若干个function,一个一个实现好function后,再用全局变量或者临时变量把这些function联系在一起,这样项目就可以拼起来了。fpga也是一样的。
1、自顶向下开发
自顶向下开发,主要是面向客户开发。首先确认开户需要什么功能,然后把这些功能切分成一个一个业务。业务部分分好后,就会进一步切分成不同的状态机和外设。外设部分又会涉及到一些总线、接口和协议。总之,一个fpga产品根据规模大小,需要至上而下一步一步拆分和开发。一方面这样可以降低风险,另外一方面时间和质量可控,也有利于降低风险。
2、修改led.v程序
之前我们写过led.v,当时led闪烁的实现是通过计数器来进行的。因此既然上一次我们实现了按键功能,那么就可以通过按键实现led.v功能了。即,按一下,led取反一次。这样,就会形成按键和led的交互功能。
module led(input clk,input rst,input ce,output led);reg led_o;always@(posedge clk or negedge rst)if(!rst)led_o <= 1'b0;else if(ce)led_o <= ~led_o;assign led = led_o;endmodule
代码部分不难,就是这里出现了一个ce,而这个ce正是按键提供的。
3、led.v和key.v连接信号
事实上,把所有的verilog文件整合成一个.v也是可以的。只不过这样的.v结构过于庞大,很容易出错,所以一般就拆分成若干个模块。彼此之间用wire联系。这里的key.v和led.v就是用一个out信号连接。
key key(.rst(rst),.clk(clk),.in(in),.out(out));led led(.rst(rst),.clk(clk),.ce(out),.led(led_out));
注意,这里的rst和clk都是共享的,也就是说每一个clock的边沿触发,两个模块都是同时工作的。但是led的工作依赖于key的输出,也就是说如果out没有输出,那么led虽然也工作,但是没有状态的改变。只有等到out输出为1的时候,才会发生led的翻转。
4、测试和验证
这里没有把led和key做一个整合,只是在tb.v做了连接。本质上其实是一样的,有需要的同学可以重新写一个verilog,里面调用led.v和key.v,类似于这样,
module key_led_top(input clk,input rst,input in,output led_out);wire out;key key(.rst(rst),.clk(clk),.in(in),.out(out));led led(.rst(rst),.clk(clk),.ce(out),.led(led_out));endmodule
在此基础上修改一下命令行,
C:\iverilog\bin\iverilog.exe -o tb tb.v key_led_top.v key.v led.v && C:\iverilog\bin\vvp.exe -n tb -lxt2 &&C:\iverilog\gtkwave\bin\gtkwave.exe hello.vcd
这昂就可以生成我们需要的波形文件。首先确认下整体功能对不对。如果不对,就继续看下子模块的信号,这就是一般的仿真测试步骤。通过图形可以明显看到,只有in输入达到一定时间的时候,才会发生led信号翻转。