關鍵詞:assign, 全加器
連續賦值語句是 Verilog 數據流建模的基本語句,用於對 wire 型變量進行賦值。:
格式如下
assign LHS_target = RHS_expression ;
LHS(left hand side) 指賦值操作的左側,RHS(right hand side)指賦值操作的右側。
assign 為關鍵詞,任何已經聲明 wire 變量的連續賦值語句都是以 assign 開頭,例如:
wire Cout, A, B ; assign Cout = A & B ; //實現計算A與B的功能
需要說明的是:
- LHS_target 必須是一個標量或者線型向量,而不能是寄存器類型。
- RHS_expression 的類型沒有要求,可以是標量或線型或存器向量,也可以是函數調用。
- 隻要 RHS_expression 表達式的操作數有事件發生(值的變化)時,RHS_expression 就會立刻重新計算,同時賦值給 LHS_target。
Verilog 還提供了另一種對 wire 型賦值的簡單方法,即在 wire 型變量聲明的時候同時對其賦值。wire 型變量隻能被賦值一次,因此該種連續賦值方式也隻能有一次。例如下麵賦值方式和上麵的賦值例子的賦值方式,效果都是一致的。
wire A, B ; wire Cout = A & B ;
全加器
下麵采用數據流描述方式,來設計一個 1bit 全加器。
設 Ai,Bi,Ci 分別為被加數、加數和相鄰低位的進位數,So, Co 分別為本位和與向相鄰高位的進位數。
真值表如下:
Input | Output | |||
---|---|---|---|---|
Ci | Ai | Bi | So | Co |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 | 1 |
全加器的表達式為:
So = Ai ⊕ Bi ⊕ Ci ; Co = AiBi + Ci(Ai+Bi)
rtl 代碼(full_adder1.v)如下:
實例
module full_adder1(
input Ai, Bi, Ci,
output So, Co);
assign So = Ai ^ Bi ^ Ci ;
assign Co = (Ai & Bi) | (Ci & (Ai | Bi));
endmodule
input Ai, Bi, Ci,
output So, Co);
assign So = Ai ^ Bi ^ Ci ;
assign Co = (Ai & Bi) | (Ci & (Ai | Bi));
endmodule
當然,更為貼近加法器的代碼描述可以為:
實例
module full_adder1(
input Ai, Bi, Ci
output So, Co);
assign {Co, So} = Ai + Bi + Ci ;
endmodule
input Ai, Bi, Ci
output So, Co);
assign {Co, So} = Ai + Bi + Ci ;
endmodule
testbench(test.sv)參考如下:
實例
`timescale 1ns/1ns
module test ;
reg Ai, Bi, Ci ;
wire So, Co ;
initial begin
{Ai, Bi, Ci} = 3'b0;
forever begin
#10 ;
{Ai, Bi, Ci} = {Ai, Bi, Ci} + 1'b1;
end
end
full_adder1 u_adder(
.Ai (Ai),
.Bi (Bi),
.Ci (Ci),
.So (So),
.Co (Co));
initial begin
forever begin
#100;
//$display("---gyc---%d", $time);
if ($time >= 1000) begin
$finish ;
end
end
end
endmodule
module test ;
reg Ai, Bi, Ci ;
wire So, Co ;
initial begin
{Ai, Bi, Ci} = 3'b0;
forever begin
#10 ;
{Ai, Bi, Ci} = {Ai, Bi, Ci} + 1'b1;
end
end
full_adder1 u_adder(
.Ai (Ai),
.Bi (Bi),
.Ci (Ci),
.So (So),
.Co (Co));
initial begin
forever begin
#100;
//$display("---gyc---%d", $time);
if ($time >= 1000) begin
$finish ;
end
end
end
endmodule
仿真結果如下: