四位共阳极数码管显示函数_Verilog笔记
github傳送門(練習寫的代碼,約束文件,仿真文件)
文章目錄
Vivado
基本流程
關于封裝IP核和使用Block Design
Verilog
module / 模塊
always塊
組合邏輯
時序
Generate塊(書上p83)
task / function
其他
仿真
ip核的創建和使用方法:
燒錄
BASYS3
按鍵
防抖方法
數碼管
函數
實現固定頻率的方法:
數碼管數字顯示
約束文件
知識點
進位和溢出
Vivado
基本流程
寫代碼。在sources里添加文件,把寫好的模塊粘貼進去并保存。
[可選] 寫仿真文件 (Simulation)(模板代碼)。用來在電腦上測試代碼的運行結果是否達到預期,如果沒問題就可以下到板子上 (寫好仿真文件后在最左邊Simulation - Run Simulation)(莽的話可以不用仿真直接上板子)。
綜合 (Synthesis)。先檢查代碼有沒有毛病,然后根據代碼機器自動生成最優電路圖(可以在最左邊Synthesis - Open Synthesized Design - Schematics里看到電路圖)。
實現 (Implementation)。把綜合的結果與現實中的板子具體聯系起來(通過約束文件),相當于從軟件走到了硬件。
生成比特流文件 (Bitstream)。生成的比特流文件就可以上傳到板子上了。
上傳到板子上,通過Hardware Manager操作。
關于封裝IP核和使用Block Design
千萬千萬千萬不要把IP核導入到源代碼所在的工程文件里,測試的時候debug有你哭的。
Verilog
module / 模塊
module里的內容都是并發執行的。
不在always和initial塊里的代碼就是單純調用這個module的時候才會執行。(如果輸入改變了會調用這個module)
always塊
多個always塊并發執行,也就是說不同的主循環函數并發執行。
always里不能實例化模塊
一般組合邏輯電路用阻塞賦值(=),時序邏輯電路用非阻塞賦值(<=)。
組合邏輯
always @(觸發器變量)是組合邏輯電路,always @(posedge clk)是時序邏輯電路。
時序
posedge(positive edge) 是上升沿關鍵字,上升沿指的是變量從0變成1的那個瞬間。對應下降沿(negedge - negative edge)就是變量從1變成0的那一瞬間。因此@(posedge var)指的是對var的上升沿敏感,意思就是var達到上升沿的時候就會觸發。
always @()
可以理解成onValueChangeListener,當敏感信號表達式的值發生變化時,就會執行always塊。
因此always @(posedge clk)代表在每次時鐘clk到達上升沿的時候會執行一次(因為并發執行,所以時序邏輯電路用非阻塞賦值就可以實現與時鐘上升沿同步修改變量),因此這個always塊里的代碼可以理解成主循環。
不論上升沿clk還是下降沿rst,在觸發時讀取到clk和rst的值都是這兩個信號接下來要變成的值。(即clk讀取到的值為1,rst讀取到的值為0)
Generate塊(書上p83)
用來在模塊中循環實例化其他模塊。關鍵字為generate,對應聲明循環控制變量的關鍵字為genvar
示例:
genvar i;
generate
for(i=0; i
begin: tag_name
module_name_1 instance_name_1 (input_1,output_1);
//可以繼續實例化別的模塊,如:
//module_name_2 instance_name_2 (input_2,output_2);
end
endgenerate
//執行完generate塊后的實例名字分別為:tag_name[0].module_name_1, tag_name[1].module_name_1 ...
task / function
直接reg、integer、wire不屬于端口,調用task/function的時候沒有對應的傳入。
帶返回值的函數是function,只能定義輸入,function的名字是輸出;不帶返回值的函數是task,可以定義輸入和輸出。
task的output如果有賦值的話至少在module和task中一處定義為reg
task和function內部只能是阻塞賦值
function的返回值可以當作常量
task和function可以帶parameter,但 暫時沒找到調用時改變參數的方法
task可以啟動task和function,function只能啟動function
其他
帶符號關鍵字為signed,默認不帶符號
assign(連續賦值)只能對wire類型,變量賦值只能對reg類型
注意時序電路在仿真時模塊里counter的滿足條件要小得多
initial塊是初次運行時會執行一次。多個initial塊也可以并發執行。
x是未知態,z是高阻態(可以理解成另一種未知態)
casez忽略z,casex既忽略z也忽略x
parameter要理解成常量。變量用reg。
常數定義前的數字表示二進制的位數,與基數無關。比如4’ha等價于4’b1010。
實例化一個模塊的時候它的參數是可以改變的,方法有兩種:module_name #(param1[, param2...]) instance_name (inputs,outputs); 或module_name instance_name(inputs, outputs);
defparam instance_name.param_1 = param1[, instance_name.param_2 = param2...];
if-else和for等語句不能直接寫在模塊里,需要寫在always中。
判斷語句要想寫在assign中,可以assign res = (op == 2'b00) ? res1 :
(op == 2'b01) ? res2 :
defaultres;
input和output等信號默認都是wire類型。一般只有在模塊中有賦值語句時才需要將output信號定義為reg型。
如果輸入的位數與模塊定義的輸入位數不匹配,模塊讀進來時高位會自動補x。
仿真
常用的函數:
函數名
描述
$readmemb(filename, mem)
從文件讀取二進制數據到 mem 數組
$readmemh(filename, mem)
從文件讀取十六進制數據到 mem 數組
$display(“output” [, var] );
在console中輸出,語法類似c的printf,%b 二進制, %d, %h, %t表示時間,對應var = $time
$write(“output”[, var] );
同display,但display自帶換行,write不帶
ip核的創建和使用方法:
http://www.digilent.com.cn/community/332.html%EF%BC%89
燒錄
1.基本知識:
RAM(random access memory)即隨機存儲內存,這種存儲器在斷電時將丟 失其存儲內容,故主要用于存儲短時間使用的程序。
ROM(Read-Only Memory)即只讀內存,是一種只能讀出事先所存數據的固 態半導體存儲器。
RAM和ROM分別對應電腦的內存和硬盤。
2.燒錄含義:
直接把代碼上傳到板子相當于上傳到RAM(內存)里,燒錄是把代碼上傳到ROM(硬盤)里。
板子每次開機或重啟的時候會直接從ROM里調用程序。
3.實現:
參考《你的Basys 3第一個入門實驗官方指導手冊.pdf》第35頁
燒錄時選擇Memory Device型號:s25fl032p-spi-x1_x2_x4
BASYS3
新建工程時選擇板子型號:xc7a35tcpg236-1
BASYS3板子自帶的時鐘CLK頻率是100MHz,對應引腳名為W5,固定常數:
parameter T1S = 100000000 // 即100M
parameter T1MS = 100000;
//或
parameter T1S = 10**8;
parameter T1MS = 10**5;
按鍵
按鍵按下為1,彈起為0
防抖方法
間隔一定時間讀取兩次按鍵值,如果兩次讀取結果一樣則認為不抖了。
數碼管
數碼管是一個四位帶小數點的七段共陽極數碼管(低電平有效,即0是點亮,1是熄滅),共12位。
從高位(第11位)到低位(第0位)分別為:
11 ~ 8位: 控制第幾個數碼管的顯示情況。比如若第10位是0,后面7~0位的值就作用于第二個數碼管的顯示情況
7 ~ 1位: 從最上面一橫開始,順時針一位對應一個數碼管的一小段(一個小直線),中間橫線為第1位
0位: 小數點是否顯示
e.g.1011_00000000_1表示第二個數碼管顯示"8",小數點不亮,其他三個數碼管均熄滅
要想四個數碼管顯示不同的數字,控制數碼管以很快的頻率一次顯示一位即可。
(示例代碼)
針腳名
位數
含義
W4
11
控制第1個數碼管的顯示情況
V4
10
控制第2個數碼管的顯示情況
U4
9
控制第3個數碼管的顯示情況
U2
8
控制第4個數碼管的顯示情況
W7
7
a
W6
6
b
U8
5
c
V8
4
d
U5
3
e
V5
2
f
U7
1
g
V7
0
dp(小數點)
函數
實現固定頻率的方法:
?這種方法不能在硬件上實現,會報錯,只能在仿真的時候實現。
input CLK;
parameter T1MS = 10**5;
always @(posedge CLK) begin
repeat(T1MS*200) @(posedge CLK) // wait 200ms
//do something like changing input values here...
end
或
input CLK;
parameter T1MS = 10**5;
integer count = 0;
always @(posedge CLK) begin
count <= count + 1;
if (count == T1MS*200) begin
count <= 0;
//do every 200ms
//do something like changing input values here...
end
end
或
input CLK;
parameter T1MS = 10**5;
integer count = 0;
reg CLK_10HZ = 0;
always @(posedge CLK) begin
count <= count + 1;
if (count == T1MS*100) begin
count <= 0;
CLK_10HZ = ~CLK_10HZ;
end
end
always @(posedge CLK_10HZ) begin
//do every 100ms / 10HZ
//do something like changing input values here...
end
數碼管數字顯示
代碼在這
約束文件
約束文件是用來把代碼里的input、output的變量名和板子上的管腳一一對應起來用的,格式:
配置引腳:
set_property PACKAGE_PIN 引腳名 [get_ports 對應代碼里的端口變量名]
配置標準電壓:
set_property IOSTANDARD LVCMOS33 [get_ports 對應代碼里的端口變量名]
BASYS3板子上所有引腳對應的約束文件(記得端口名改成自己的):
–
知識點
進位和溢出
進位只在涉及無符號數時有意義
溢出只在使用有符號數時才有意義
只有兩操作數符號位相同,且與結果符號位不同時才溢出
即overflow = x*y*~s + ~x*~y*s
總結
以上是生活随笔為你收集整理的四位共阳极数码管显示函数_Verilog笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ffmpeg 怎么处理udp音频_视音频
- 下一篇: ios开发text kit_iOS富文本