過程連續(xù)賦值是過程賦值的一種。這種賦值語句能夠替換其他所有 wire 或 reg 的賦值,改寫了 wire 或 reg 型變量的當前值。
與過程賦值不同的是,過程連續(xù)賦值的表達式能被連續(xù)的驅(qū)動到 wire 或 reg 型變量中,即過程連續(xù)賦值發(fā)生作用時,右端表達式中任意操作數(shù)的變化都會引起過程連續(xù)賦值語句的重新執(zhí)行。
過程連續(xù)性賦值主要有 2 種,?assign-deassign
? 和 ?force-release
?。
?assign
?(過程賦值操作)與 ?deassign
? (取消過程賦值操作)表示第一類過程連續(xù)賦值語句。賦值對象只能是寄存器或寄存器組,而不能是 wire 型變量。
賦值過程中對寄存器連續(xù)賦值,寄存器中的值被保留直到被重新賦值。
例如,一個帶復(fù)位端的 D 觸發(fā)器可以用下面代碼描述:
module dff_normal(
input rstn,
input clk,
input D,
output reg Q
);
always @(posedge clk or negedge rstn) begin
if(!rstn) begin //Q = 0 after reset effective
Q <= 1'b0 ;
end
else begin
Q <= D ; //Q = D at posedge of clock
end
end
endmodule
下面,用 ?assign
? 與 ?deassign
? 改寫,完成相同的功能。
即在復(fù)位信號為 0 時,Q 端被 ?assign
? 語句賦值,始終輸出為 0。
復(fù)位信號為 1 時,Q 端被 ?deassign
? 語句取消賦值,在時鐘上升沿被重新賦值。
module dff_assign(
input rstn,
input clk,
input D,
output reg Q
);
always @(posedge clk) begin
Q <= D ; //Q = D at posedge of clock
end
always @(negedge rstn) begin
if(!rstn) begin
assign Q = 1'b0 ; //change Q value when reset effective
end
else begin //cancel the Q value overlay,
deassign Q ; //and Q remains 0-value until the coming of clock posedge
end
end
endmodule
?force
? (強制賦值操作)與 ?release
?(取消強制賦值)表示第二類過程連續(xù)賦值語句。
使用方法和效果,和 ?assign
? 與 ?deassign
? 類似,但賦值對象可以是 reg 型變量,也可以是 wire 型變量。
因為是無條件強制賦值,一般多用于交互式調(diào)試過程,不要在設(shè)計模塊中使用。
當 ?force
? 作用在寄存器上時,寄存器當前值被覆蓋;release 時該寄存器值將繼續(xù)保留強制賦值時的值。之后,該寄存器的值可以被原有的過程賦值語句改變。
當 ?force
? 作用在線網(wǎng)上時,線網(wǎng)值也會被強制賦值。但是,一旦 ?release
? 該線網(wǎng)型變量,其值馬上變?yōu)樵械尿?qū)動值。
為直觀的觀察兩種類型變量強制賦值的區(qū)別,利用第一節(jié)中的計數(shù)器 counter10 作為設(shè)計模塊,testbench 設(shè)計如下。
`timescale 1ns/1ns
module test ;
reg rstn ;
reg clk ;
reg [3:0] cnt ;
wire cout ;
counter10 u_counter (
.rstn (rstn),
.clk (clk),
.cnt (cnt),
.cout (cout));
initial begin
clk = 0 ;
rstn = 0 ;
#10 ;
rstn = 1'b1 ;
wait (test.u_counter.cnt_temp == 4'd4) ;
@(negedge clk) ;
force test.u_counter.cnt_temp = 4'd6 ;
force test.u_counter.cout = 1'b1 ;
#40 ;
@(negedge clk) ;
release test.u_counter.cnt_temp ;
release test.u_counter.cout ;
end
initial begin
clk = 0 ;
forever #10 clk = ~ clk ;
end
//finish the simulation
always begin
#1000;
if ($time >= 1000) $finish ;
end
endmodule // test
仿真結(jié)果如下。
由圖可知,在 ?cnt_temp
? 等于 4 時(80ns), ?cnt_temp
? 被強制賦值為 6,cout 被強制賦值為 1。
release 時(120ns), ?cnt_temp
? 為寄存器類型,仍然保持原有值不變,直到時鐘上升沿對其進行加法賦值操作,值才變?yōu)?nbsp;7 。
而 120ns 時,由于 cout 是線網(wǎng)型變量,其值不能保存。原碼 counter10 模型中存在驅(qū)動語句: ?assign cout = (cnt_temp==4'd9)
? ,所以 cout 值變?yōu)?nbsp;0 。
點擊這里下載源碼
更多建議: