1.原理
半加器
全加器
當多位數相加時,半加器可用于最低位求和,并給出進位數。第二位的相加有兩個待加數和,還有一個來自前面低位送來的進位數。這三個數相加,得出本位和數(全加和數)和進位數。這種就是“全加"真值表:
2.編程思路
(1)根據真值表編寫
按照半加器和全加器的真值表寫出輸出端的邏輯表達式,對半加器,輸出的進位端是量輸入的“與”,輸出的計算結果是量輸入的異或;對全加器,也按照邏輯表達式做。
//半加器模塊
module adder_half(
inputa,
inputb,
output regsum,
output regcout
);
//這里的always @(*)搭配里面的“=”阻塞賦值符號
//實現的效果和 assign sum = a ^ b; assign cout = a & b;是一樣的
always @(*)
begin
sum = a ^ b;
cout = a & b;
end
endmodule
全加器:
module all_adder(cout,sum,a,b,cin);
input a,b,cin;
output sum,cout;
wire sum,cout;
assign sum=a^b^cin;
assign cout=(a&b)|(a&cin)|(b&cin);
endmodule
3.問題匯總
(1)`timescale 1 ns/1 ps
timescale是verilog中的一種時間尺度預編譯指令,用來定義仿真時的時間單位和時間精度,左邊是時間單位,右邊是時間精度,時間單位是用于編寫激勵文件,時間精度是顯示時的刻度,比如#100也就是100ns。時間精度不能大于時間單位,比如timescale 1 ns/1 ps是正確的,而
timescale 1 ps/1 ns是錯誤的。
(2)#({$random}%100)
首先,#代表延時,這個語句表示延時隨機的一個時間,結合`timescale 1 ns/1 ns是延時隨機的ns。
$random 是 verilog 中產生隨機數的系統函數,在調用時返回一個 32 位的隨機數,是帶符號的整形數。有幾種用法:
random 和random()意義一樣,都是產生隨機數;
$random%100 在-99 到 99 之間產生隨機數;
{$random}%100 采用位拼接符,在 0 到 100 之間產生隨機數;
如 seed =10, $random(seed) 根據 seed 值產生隨機數,而后 seed 值也會更新。
(3)add t0(.cin(cin), .a(a), .b(b), .sum(sum), .count(count));
例化的格式,先建立一個叫add的模塊(module),有5個引腳,分別是cin/a/b/sum/count,例化的模塊叫做t0,比較簡單的例化方式就是如上所示的,括號外的引腳與括號內的引腳名稱完全一致,無需區分。
實際上,括號外的引腳名稱代表的是模塊定義時的引腳,括號內的引腳是目前實際使用的引腳名稱,如可以將@大神袁的測試文件改為:
`timescale 1 ns/1 ns
module top_tb();
reg a1;
reg b1;
wire sum1;
wire count1;
initial
begin
a1 = 0;
b1 = 0;
forever
begin
#({$random}%100)
a1 = ~a1;
#({$random}%100)
b1 = ~b1;
end
end
top t0(.a(a1), .b(b1), .sum(sum1), .count(count1));
endmodule
(4)對于延時,可以采用直接賦值的延時,如#5,使用隨機延時目前暫時不常用。
當仿真到想結束時,可以在initial塊的最后加$finish(此處可參考@大神李),即調用系統函數結束仿真,否則,仿真在ModelSim中會一直進行下去,不方便觀察(在Vivado中設置的第一次仿真結束時間停止,默認1ns)。
此外,這里建議使用stop來代替finish,即停止仿真,在ModelSim中是暫停了仿真,而$finishi則可能會退出,看不到仿真波形。
-
全加器
+關注
關注
10文章
62瀏覽量
28452 -
半加器
+關注
關注
1文章
29瀏覽量
8776 -
Vivado
+關注
關注
19文章
808瀏覽量
66321 -
Verilog語言
+關注
關注
0文章
113瀏覽量
8213
發布評論請先 登錄
相關推薦
評論