4.8 Verilog Procedural Continuous Assignment
Category Verilog Tutorial
Keywords: deassign, force, release
Procedural continuous assignment is a type of procedural assignment. This assignment statement can override all other assignments to wires or regs, rewriting the current value of wire or reg type variables.
Unlike procedural assignments, the expression of procedural continuous assignment can be continuously driven into wire or reg type variables, that is, when the procedural continuous assignment takes effect, any change in the operands on the right side of the expression will cause the procedural continuous assignment statement to be re-executed.
There are mainly two types of procedural continuity assignments: assign-deassign and force-release.
assign, deassign
assign (procedural assignment operation) and deassign (cancel procedural assignment operation) represent the first type of procedural continuous assignment statements. The assignment object can only be a register or a group of registers, and cannot be a wire type variable.
During the assignment process, the value in the register is continuously assigned, and the value in the register is retained until it is reassigned.
For example, a D flip-flop with a reset end can be described with the following code:
Example
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
Next, rewrite with assign and deassign to achieve the same function.
That is, when the reset signal is 0, the Q end is assigned a value by the assign statement, always outputting 0.
When the reset signal is 1, the Q end is canceled by the deassign statement, and reassigned at the clock rising edge.
Example
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
force (force assignment operation) and release (cancel force assignment) represent the second type of procedural continuous assignment statements.
The usage and effect are similar to assign and deassign, but the assignment object can be a reg type variable or a wire type variable.
Because it is an unconditional forced assignment, it is generally used more in the interactive debugging process and should not be used in the design module.
When force is applied to a register, the current value of the register is overwritten; when released, the value of the register will continue to retain the value at the time of forced assignment. After that, the value of the register can be changed by the original procedural assignment statement.
When force is applied to a wire, the value of the wire will also be forcibly assigned. However, once the release of the wire type variable, its value immediately becomes the original driving value.
To intuitively observe the difference between the forced assignments of the two types of variables, use the counter10 in the first section as the design module, and the testbench is designed as follows.
Example
``
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'