Verilog 過(guò)程連續(xù)賦值

2022-05-17 11:16 更新

關(guān)鍵詞:deassign,force,release

過(guò)程連續(xù)賦值是過(guò)程賦值的一種。這種賦值語(yǔ)句能夠替換其他所有 wire 或 reg 的賦值,改寫了 wire 或 reg 型變量的當(dāng)前值。

與過(guò)程賦值不同的是,過(guò)程連續(xù)賦值的表達(dá)式能被連續(xù)的驅(qū)動(dòng)到 wire 或 reg 型變量中,即過(guò)程連續(xù)賦值發(fā)生作用時(shí),右端表達(dá)式中任意操作數(shù)的變化都會(huì)引起過(guò)程連續(xù)賦值語(yǔ)句的重新執(zhí)行。

過(guò)程連續(xù)性賦值主要有 2 種,?assign-deassign? 和 ?force-release?。

assign, deassign

?assign?(過(guò)程賦值操作)與 ?deassign? (取消過(guò)程賦值操作)表示第一類過(guò)程連續(xù)賦值語(yǔ)句。賦值對(duì)象只能是寄存器或寄存器組,而不能是 wire 型變量。

賦值過(guò)程中對(duì)寄存器連續(xù)賦值,寄存器中的值被保留直到被重新賦值。

例如,一個(gè)帶復(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ù)位信號(hào)為 0 時(shí),Q 端被 ?assign? 語(yǔ)句賦值,始終輸出為 0。

復(fù)位信號(hào)為 1 時(shí),Q 端被 ?deassign? 語(yǔ)句取消賦值,在時(shí)鐘上升沿被重新賦值。

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? (強(qiáng)制賦值操作)與 ?release?(取消強(qiáng)制賦值)表示第二類過(guò)程連續(xù)賦值語(yǔ)句。

使用方法和效果,和 ?assign? 與 ?deassign? 類似,但賦值對(duì)象可以是 reg 型變量,也可以是 wire 型變量。

因?yàn)槭菬o(wú)條件強(qiáng)制賦值,一般多用于交互式調(diào)試過(guò)程,不要在設(shè)計(jì)模塊中使用。

當(dāng) ?force? 作用在寄存器上時(shí),寄存器當(dāng)前值被覆蓋;release 時(shí)該寄存器值將繼續(xù)保留強(qiáng)制賦值時(shí)的值。之后,該寄存器的值可以被原有的過(guò)程賦值語(yǔ)句改變。

當(dāng) ?force? 作用在線網(wǎng)上時(shí),線網(wǎng)值也會(huì)被強(qiáng)制賦值。但是,一旦 ?release? 該線網(wǎng)型變量,其值馬上變?yōu)樵械尿?qū)動(dòng)值。

為直觀的觀察兩種類型變量強(qiáng)制賦值的區(qū)別,利用第一節(jié)中的計(jì)數(shù)器 counter10 作為設(shè)計(jì)模塊,testbench 設(shè)計(jì)如下。

`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 時(shí)(80ns), ?cnt_temp? 被強(qiáng)制賦值為 6,cout 被強(qiáng)制賦值為 1。

release 時(shí)(120ns), ?cnt_temp? 為寄存器類型,仍然保持原有值不變,直到時(shí)鐘上升沿對(duì)其進(jìn)行加法賦值操作,值才變?yōu)?nbsp;7 。

而 120ns 時(shí),由于 cout 是線網(wǎng)型變量,其值不能保存。原碼 counter10 模型中存在驅(qū)動(dòng)語(yǔ)句: ?assign cout = (cnt_temp==4'd9)? ,所以 cout 值變?yōu)?nbsp;0 。


點(diǎn)擊這里下載源碼


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)