【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 聯系信箱: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信號翻轉。