1. 程式人生 > >modelsim中用非阻塞賦值模擬遇到的問題

modelsim中用非阻塞賦值模擬遇到的問題

這是對rom初始化並讀取的原始碼

module rom_nxm(rom_data,rom_addr,clk,rd,load);
    parameter M=8,N=4;
    input clk,rd;
    input load;
    input [N-1:0] rom_addr;
    output reg [M-1:0] rom_data;
    reg[M-1:0]memory[0:2**N-1];
    [email protected](posedge load)
    begin:init
    integer i;
    for(i=0;i<(2**N);i=i+1)
    memory[i]=i+1;
end
[email protected]
(posedge clk) end [email protected](posedge clk) begin:read if(rd) rom_data=memory[rom_addr]; end endmodule
testbench為
`timescale 1ns/100ps 
module rom_nxm_tb  ; 

parameter M  = 8 ;
parameter N  = 4 ; 
  reg    load   ;
  reg  [N-1:0]  rom_addr   ; 
  reg    rd   ; 
  reg    clk   ; 
  wire  [M-1:0]  rom_data   ; 
  rom_nxm    #( M , N  )
   DUT  ( 
       .load (load ) ,
      .rom_addr (rom_addr ) ,
      .rd (rd ) ,
      .clk (clk ) ,
      .rom_data (rom_data ) ); 
      initial
      begin
      clk=0;
      load=0;
      rd=0;

  end
  initial
  begin 
  #10 load=1;
  #10 rd=1;
  rom_addr=0;
  
  end
  always #10 clk=~clk;
 
  
[email protected]
(posedge clk) begin $display("addr:%d,data:%d",rom_addr,rom_data); if(rom_addr==15) rom_addr=0;//rom_addr<=0 else rom_addr= rom_addr+1;//rom_addr<= rom_addr+1 end initial #35 $strobe($time,"addr:%d,data:%d",rom_addr,rom_data); endmodule

阻塞賦值的模擬結果:

addr: x,data:  x

# addr: 0,data:  x

#                   35addr: 1,data:  2

# addr: 1,data:  2

# addr: 2,data:  3

# addr: 3,data:  4

非阻塞賦值的結果:

addr: x,data:  x

# addr: 0,data:  x

#                   35addr: 1,data:  1

# addr: 1,data:  1

# addr: 2,data:  2

# addr: 3,data:  3

modelsim的testbench中對[email protected](posedge)模組的阻塞賦值是在posedge clk之前delta時間進行賦值,而非阻塞賦值是在posedge clk之後delta時間進行賦值,且一般暫存器的取樣在時鐘前delta時間,而賦值在時鐘後delta時間

若為阻塞賦值,在第二個上升沿的時侯,addr在posedge clk前的delta時間進行賦值變為0001,然後memory取樣的是posedge clk之前delta時間的值即0001(雖然顯示為0000,),則addr顯示為0001的時候,memory顯示的是memory【0001】。這時addr與memory對應。

但若用非阻塞賦值的話,在第二個上升沿的時侯,addr的顯示與阻塞賦值是一樣的,但差別是非阻塞賦值是在posedge clk之後delta時間進行賦值,則memory取樣仍是在clk之前,就變成memory【0000】。這時,從圖上看,彷彿addr與memory不對應。

但是在testbench中將阻塞賦值用非阻塞賦值替代是有好處的,尤其是你的verilig原始檔中有非阻塞賦值(存在暫存器或觸發器)的情況,這樣才能在時序圖中體現非阻塞賦值的功能(因非阻塞的本質是讀取觸發前的狀態,而testbench中的非阻塞賦值起到了延時的作用,不要死板的認為是在下一個時鐘觸發時才賦值),但你要將testbench中的非阻塞賦值當做阻塞賦值對待,深刻理解modelsim是模擬,可參考:

有高手說:

寫tb時注意訊號的生成不要在pos clk的同時用阻塞賦值(當你的模組是pos clk時)。這就是多事件同時發生:如果都是非阻塞賦值就不存在問題。但阻塞賦值時,不同模擬器的處理順序不一樣,會導致結果差異。可用3種方式:1:neg clk 和阻塞賦值;2:pos clk和非阻塞賦值;3:pos clk +單位延時 + 阻塞賦值。

 若用testbench中用阻塞賦值,

載入測試向量時,避免在時鐘的上下沿變化

為了模擬真實器件的行為,載入測試向量時,避免在時鐘的上下沿變化,而是在時鐘的上升沿延時一個時間單位後,載入的測試向量發生變化。如:

assign #5 c="a"^b

……

@(posedge clk) #(0.1*`cycle) A=1;

相關推薦

modelsim中用阻塞模擬遇到的問題

這是對rom初始化並讀取的原始碼 module rom_nxm(rom_data,rom_addr,clk,rd,load); parameter M=8,N=4; input clk,rd; input load; input [N-1:0

阻塞阻塞

under ati always tex ilog 進程 成才 含義 initial 2017-12-01 在Verilog語言中,賦值語句經常使用,阻塞賦值和非阻塞賦值經常帶給我們很多困擾。在此討論兩種賦值方式的差異性。 首先根據表面含義深刻理解阻塞和非阻塞

關於veriolg中阻塞阻塞問題

觸發 改變 希望 到來 決定 工作 執行 為什麽 個人 在一開始學到阻塞和非阻塞的時候,所被告知的兩者的區別就在於阻塞是串行的,非阻塞是並行的。但是雖然知道這個不同點,有些時候還是很難真正區分用兩者電路的區別,在這就通過幾個例子來解釋一下。 以一個簡單的串行流水線寄存器為例

RTL基本知識:阻塞阻塞

ini 規則 rac init 基本知識 monitor 當前 並且 ima 0 醜話說在前邊 RHS:運算符(= or <=)右側的表達式 LHS:運算符(= or <=)左側的表達式 競爭(Race Condition):在同一仿真時間槽(time-slot

verilog中阻塞阻塞的區別

非阻塞(Non_Blocking)賦值方式( 如 b <= a; ), 塊結束後才完成賦值操作,值並不是立刻就改變的, 這是一種比較常用的賦值方法。(特別在編寫可綜合模組時)。 阻塞(Blocking)賦值方式( 如 b = a; ),  賦值語句執行完後,塊才

Verilog HDL 初級入門知識簡單講解(wire 和 reg 型別的區別, always 和 assign 的區別,“阻塞 和 “阻塞”的區別 )

本文轉載自原作者:姚紀元,原文地址已失效        很多剛學Verilog HDL (硬體描述語言)的朋友肯定會對阻塞賦值和非阻塞賦值比較疑惑,那我們就一起來拋開這層迷霧吧。首先我們要理解兩種變數型別 Net Type(連線型)和 

阻塞的內部延時和外部延時

學習verilog有一段時間了,從字面上理解,阻塞和非阻塞的區別很直白。 前者是序列,主要用於描述組合邏輯,和軟體中的賦值類似;後者是並行,主要用於描述時序邏輯。 但是和內部延時、外部延時混用在一起的時候,各種意想不到的情況就會發生。 下面將介紹,對於非阻塞賦值,內部延遲和

阻塞阻塞的再分析

在Verilog HDL設計中,經常會遇到阻塞賦值與非阻塞賦值,這是學習邏輯設計時最基礎的知識點。設計者經常會在書中看到一些建議:什麼時候該用阻塞賦值,什麼情況下使用非阻塞賦值。可是,如果僅僅按照這樣的設計推薦來進行設計的話,經常會碰到一頭霧水的情況。本文就對阻塞賦值和非阻

阻塞(=)和阻塞(

就知道在Verilog HDL中阻塞賦值"="和非阻塞賦值"<="有著很大的不同。   對於我這樣的初學者而言,首先要掌握可綜合風格的Verilog模組程式設計的7個原則,並且牢記,才能在綜合佈局佈線的模擬中避免出現競爭冒險現象。   (1)  時序電路建模時,用非阻

Verilog十大基本功0(阻塞阻塞

需求說明:Verilog設計基礎 內容       :阻塞賦值和非阻塞賦值 來自       :時間的詩 前言: 阻塞與非阻塞賦值是 Verilog 語言中最基本的部分,也是讓大部分 Verilog 新手最困惑的地方。 關於阻塞與非阻塞的著作文章可謂汗牛充棟,

關於Verilog HDL中阻塞阻塞形象理解

關於Verilog 中阻塞與非阻塞賦值的幾點理解 相信很多剛開始學習Verilog的童鞋對阻塞、非阻塞賦值理解得不是很明白,或者說是一頭霧水。確實,Verilog中阻塞、非阻塞一直就是一個難點,很多具備很久開發經驗的工程師仍是不得要領,在分析程式碼,看模擬時還

關於verilog裡阻塞阻塞的個人理解

        最近在做數字的東西,因此一直在學習verilog的語法,看的是夏宇聞老師的《verilog數字系統設計教程》這本書,在看到第14章深入理解阻塞與非阻塞賦值的不同時,結合書後面的誓言RISC_CPU,關於時序問題,產生了一些疑問,因此寫了一個簡單的程式,探索一

深入分析 verilog 阻塞阻塞

越是看似簡單、經常接觸的。我們越是不知其所以然。這就是我寫本文的原因。         阻塞和非阻塞賦值一般使用在程序中,包括always和initial程序、assign賦值等操作中。         在Verilog HDL中,描述程序的基本語句是always和initial。always過程反覆執行其

FPGA學習一:阻塞阻塞的理解

賦值語句共有兩種,即非阻塞賦值,和阻塞賦值。 (1)非阻塞賦值    非阻塞賦值方式所賦值的變數不能立即就為下面語句所用,只有當塊結束後才能得到上一次所附的值,這種賦值方式是編寫可綜合的時序邏輯時常用的賦值方式。例如 實際上,上面的非阻塞賦值的RTL是一個移位暫存器

Verilog中阻塞阻塞區別

1、阻塞賦值操作符用等號(即 = )表示。“阻塞”是指在程序語句(initial和always)中,當前的賦值語句阻斷了其後的語句,也就是說後面的語句必須等到當前的賦值語句執行完畢才能執行。而且阻塞賦值可以看成是一步完成的,即:計算等號右邊的值並同時賦給左邊變數。例如:

Verilog 初級入門概念講解(wire 和 reg 型別的區別, always 和 assign 的區別,“阻塞 和 “阻塞”的區別 )

    很多剛學Verilog HDL (硬體描述語言)的朋友肯定會對阻塞賦值和非阻塞賦值比較疑惑,那我們就一起來拋開這層迷霧吧。     首先我們要理解兩種變數型別 Net Type(連線型)和 Register Type (暫存器型)。(有些參考書上有分為3種類型,這個無關緊要)     Net Ty

深入理解Verilog HDL中阻塞阻塞的不同

非阻塞賦值操作符用小於等於號 (即 <= )表示。在賦值操作時刻開始時計算非阻塞賦值符的RHS表示式,賦值操作時刻結束時更新LHS。在計算非阻塞賦值的RHS表示式和更新LHS期間,其他的Verilog語句,包括其他的Verilog非阻塞賦值語句都能同時計算RHS表示式和更新LHS。非阻塞賦值允許其他的

Verilog堵塞堵塞

解決 ont mark con 原理 inpu 特點 全部 cal verilog設計進階 時間:2014年5月6日星期二 主要收獲: 1.堵塞賦值與非堵塞賦值; 2.代碼測試; 3.組合邏輯電路和時序邏輯電路。

阻塞(=)阻塞

  對於我這樣的初學者而言,首先要掌握可綜合風格的Verilog模組程式設計的8個原則,並且牢記,才能在綜合佈局佈線的模擬中避免出現競爭冒險現象。   (1)  時序電路建模時,用非阻塞賦值。   (2)  鎖存器電路建模時,用非阻塞賦值。   (3)  用always塊建立組合邏輯模型時,用阻塞賦

常量指針不能作為右常量指針

賦值 () using ret 一個 常量指針 err invalid 限定符 #include<iostream> using namespace std; int main(){ int b[4]={1,2,3,4}; const int*