【轉】NB的specify


specify block用來描述從源點(source:input/inout port)到終點(destination:output/inout port)的路徑延時(path delay),由specify開始,到endspecify結束,並且只能在模塊內部聲明,具有精確性(accuracy)和模塊性(modularity)的特點。specify block可以用來執行以下三個任務:
一、描述橫穿整個模塊的各種路徑及其延時。(module path delay)
二、脈沖過濾限制。(pulse filtering limit)
三、時序檢查。(timing check)
specify block有一個專用的關鍵字specparam用來進行參數聲明,用法和parameter一樣,不同點是兩者的作用域不同:specparam只能在specify block內部聲明及使用,而parameter只能在specify block外部聲明及使用。
////////////////////////////////////////////////////////////////////////////////
第一個任務:模塊路徑延時(module path delay)
一條模塊路徑可以是一條簡單的路徑(simple path),或者是一條邊緣敏感的路徑(edge sensitive path),或者是一條狀態依賴的路徑(state dependent path)。
//------------------------------------------------------------------------------
一、simple path,可以由以下兩種格式中的任意一種來聲明:
1)、並行連接(patallel connection):source => destination
2)、全連接(full connection):      source *> destination
例:    (a, b => q, qn) = 1; 等價於:
            (a => q) = 1; (b => qn) = 1;
而(a, b *> q, qn) = 1; 等價於:
            (a => q) = 1; (b => q) = 1; (a => qn) = 1; (b => qn) = 1;


//------------------------------------------------------------------------------
二、edge sensitive path,是那些源點(source)使用邊沿觸發的路徑,並使用邊緣標示符指明觸發條件(posedge/negedge),如果沒有指明的話,那么就是任何變化都會觸發終點(destination)的變化。
例1:(posedge clk => (out +: in)) = (1,2);
在clk的上升沿,從clk到out的模塊路徑,其上升延時是1,下降延時是2,從in到out的數據路徑是同向傳輸,即out = in。
例2:(negedge clk => (out -: in)) = (1,2);
在clk的下降沿,從clk到out的模塊路徑,其上升延時是1,下降延時是2,從in到out的數據路徑是反向傳輸,即out = ~in。
例3:(clk => (out : in)) = (1,2);
clk的任何變化,從clk到out的模塊路徑,其上升延時是1,下降延時是2,從in到out的數據路徑的傳輸是不可預知的,同向或者反向或者不變。
Note:模塊路徑的極性(module path polarity):未知極性(unknown polarity,無),正極性(positive polarity,+),負極性(negative polarity,-)。
//------------------------------------------------------------------------------
三、state dependent path,是那些源點(source)以來指定條件狀態的路徑,使用if語句(不帶else)。在條件=1 or X or Z的情況下,認為條件成立。如果有一條路經,存在多個條件同時成立的情況,那么使用延時最小值的那條限制。
例1: specify
        if(a)     (b => out) = (1,2);
        if(~a)    (b => out) = (2,3);
        if(b)     (a => out) = (1,2);
        if(~b)    (a => out) = (2,3);
      endspecify
例2: specify
        if(rst)   (posedge clk => (q +: data)) = (1,2);
        if(~rst)  (posedge clk => (q +: data)) = (2,3);
      endspecify
需要注意的是,所有輸入狀態都應該說明,否則沒有說明的路徑使用分布延時(distributed delay),如果也沒有聲明分布延時(distributed delay)的話,那么使用零延時(zero delay)。如果路徑延時和分布延時同時聲明的話,則選擇最大的延時作為路徑延時。另外,也可以使用ifnone語句,在其它所有條件都不滿足的情況下,說明一個缺省的狀態依賴路徑延時。
例3: specify
        (posedge clk => (q +: data)) = (1,2);
        ifnone (clk => q) = (2,3);
      endspecify

////////////////////////////////////////////////////////////////////////////////
第二個任務,脈沖過濾限制(pulse filtering limit)
由於每條傳播路徑都具有一定的電容性和電阻性,電荷無法在一瞬間積累或消散,所以信號變化的物理特性是具有慣性的。為了更准確地描述這種能力,使用慣性延時(inertial delay),它可以抑制持續信號比傳播延時短的輸入信號的變化。
例1:1ns寬度的窄脈寬通過一個傳輸延時為2ns的BUFFER

兩個脈寬限制值:e-limit(error limit)和r-limit(rejection limit),並且要求e-limit >= r-limit,否則報錯。當pulse width >= e-limit時,輸出相應的邏輯值;當e-limit > pulse width >= r-limit時,輸出X值;當r-limit > pulse width時,輸出不發生變化。默認情況下,e-limit = r-limit = module transition delay,也可以使用以下3種控制方式中的任意一種改變路徑脈沖限制值:
1、使用verilog提供的PATHPULSE$參數,有些仿真器還要求同時使能相應的選項:比如VCS,添加+pathpulse選項。
          PATHPULSE$ = (<reject-limit>, <error-limit>);
          PATHPULSE$<path_source>$<path_destination> = (<reject-limit>, <error-limit>);
例:   specify
            (en => q) = 12;
            (data => q) = 10;
            (clr, pre *> q) = 4;
            specparam
            PATHPULSE$ = 3, PATHPULSE$en$q = (2,9), PATHPULSE$clr$q = 1;
        endspecify
            en => q的路徑:reject-limit = 2, error-limit =9;
            clr => q和pre => q的路徑:reject-limit = error-limit = 1;
            data => q的路徑:reject-limit = error-limit = 3;
2、使用仿真器專用的編譯指導。比如VCS,+pulse_r/20(取20%)和+pulse_e/80(取80%),需要注意的是,這個選項要求放在讀入RTL網表文件之后,否則設置無效。
3、使用SDF文件反標,並且SDF文件中的延時信息具有最高的優先級。SDF文件格式將在后面介紹。

脈沖過濾限制的默認格式存在兩個缺點:
    1、X狀態的持續時間比較短。
    2、在上升延時和下降延時不相等的情況下,如果脈沖過窄,那么可能出現跟隨邊緣(trailing edge)先於或等於導引邊緣(leading edge)的現象,這時就會淹沒X狀態。
可以通過修改默認格式,加以改善,具體如下:
on-event vs on-detect:

negative width pulse detection:

需要注意的是,showcancelled  list_path_of_outputs,必須在模塊路徑之前使用,才可以約束到該模塊路徑。

////////////////////////////////////////////////////////////////////////////////

第三個任務,時序檢查(timing check)
描述設計要求的時序性能,所有的時序檢查有一個參考事件(reference event)和一個數據事件(data event),它們通過一個布爾表達式相聯接,還包括一個可選的notifier寄存器選項,這個寄存器用來打印錯誤信息或者傳播X狀態。
這里把時序檢查分成兩組來說明:
第一組,檢查時序窗口的穩定性,包括:setup、hold、recovery和removal。
setup:$setup (data_event, reference_event, limit, notifier);
當reference_event time - limit < data_event time < reference_event time時,就會報告setup time violations。
hold:  $hold   (reference_event, data_event, limit, notifier);
當reference_event time < data_event time < reference_event time + limit時,就會報告hold time violations。
setup/hold:$setuphold (reference_event, data_event, setup_limit, hold_limit, notifier);
   $setuphold是$setup和$hold兩者的聯合。例如:
   $setuphold (posedge clk, negedge d, 2, 1, notifier); 等於
   $setup (negedge d, posedge clk, 2, notifier); 和 $hold (posedge clk, negedge d, 1, notifier);
數據事件常常是數據信號,而參考事件常常是時鍾信號,如下圖:

recovery:$recovery (reference_event, data_event, limit, notifier);
當data_event time - limit < reference_event time < data_event time時,就會報告recovery time violations。
removal: $removal (reference_event, data_event, limit, notifier);
當data_event time < reference_event time < data_event time + limit時,就會報告removal time violations。
recovery/removal:$recrem (reference_event, data_event, recovery_limit, removal_limit, notifier);
   $recrem是$recovery和$removal兩者的聯合。
   $recrem (posedge clr, posedge clk, 2, 3, notifier); 等於
   $recovery (posedge clr, posedge clk, 2, notifier); 和 $removal (posedge clr, posedge clk, 3, notifier);
數據事件常常是時鍾信號,而參考事件常常是控制信號,比如清除信號或者置位信號,如下圖:

$setuphold和$recrem可以接受負值,同時需要激活仿真器的負值時序檢查選項(比如VCS:+neg_tchk),同時還有一個限制:
   setup_limit + hold_limit > 仿真精度(simulation unit of precision),
   recovery_limit + removal_limit > 仿真精度(simulation unit of precision),
否則仿真器會把負值當成0處理。


第二組,檢查時鍾和控制信號在指定事件之間的時間間隔,包括:skew、width、period和nochange。
skew:$skew (reference_event, data_event, limit, notifier);  限制最大偏斜
    $skew (posedge clk1, posedge clk2, 1, notifier);
當data_event time - reference_event > limit,則會報告skew time violations。
$skew是基於事件(event-based)的,如果監測到一個reference_event,那么就開始評估脈寬,只要監測到一個data_event,就會生成相應的報告,直到監測到下一個reference_event,才重新開始新的監測。如果在監測到一個data_event之前,又監測到一個reference_event,那么就放棄本次評估,重新開始新的評估。
width:$width (controlled_reference_event, limit, threshold, notifier);  限制最小脈寬
           $width (posedge in, 2, notifier);
這里data_event是隱含的,它等於reference_event的相反邊緣,當width < limit時,就會報告width time violations。
period:$period (controlled_reference_event, limit, notifier);  限制最小周期
           $period (negedge clk, 10, notifier);
這里data_event是隱含的,它等於reference_event的相同邊緣,當period < limit時,就會報告period time violations。
nochange:$nochange (reference_event, data_event, start_edge_offset, end_edge_offset, notifier);
當leading reference event time - start_edge_offset < data_event < trailing reference event time + end_edge_offset時,就會報告nochange time violations。例如:
          $nochange (posedge clk, data, 0 , 0);
當在clk高電平期間,data發生任何變化,就會報告nochange time violations。

有時候,路徑上的時序檢查是在一定條件成立的前提下進行的,這就需要引入條件操作符:&&&。需要注意的是,當存在兩個及以上的條件時,要求這些條件首先在specify塊外部經過適當的組合邏輯產生一個新的控制信號,然后再引入到specify塊內部使用。
例如:
    and u1 (clr_and_set, clr, set);
    specify
       $setup (negedge data, posedge clk &&& clr_and_set, 3, notifier);
    endspecify

////////////////////////////////////////////////////////////////////////////////

SDF文件簡述:
SDF文件包含指定路徑延時(specify path delay),參數值(specparam values),時序檢查約束(timing check constraints),互連線延時(interconnect delay),以及一些和仿真不相關的說明信息。反標SDF文件的過程,也算是更新specify block相對應信息的過程,如果SDF文件沒有包含某些信息,則參考specify block中的相應信息。
SDF時序信息在CELL內部描述,可以包含一個或多個DELAY、TIMINGCHECK和LABEL。DELAY部分包含指定路徑的傳播延時(specify path delay)和互連線延時(interconnect delay);TIMINGCHECK部分包含時序檢查約束信息(timing check constraint);LABEL部分包含新的參數值(specparam)。


DELAY部分:

例1:SDF文件:(IOPATH  in  out  (1.1::1.3)  (1.5::1.7));
verilog specify path:(in => out) = (2, 3);
例2:SDF文件:(COND  en==1'b1  (IOPATH  in  out  (1.2)  (1.6));
verilog specify path:if (en) (in => out) = (1, 2);
例3:互連線延時:(INTERCONNECT  source_port  load_port  delay_values)
SDF文件:(INTERCONNECT  u1/out  u2/in  (1.2::1.4)  (1.4::1.6));

 TIMINGCHECK部分:

例4: SDF文件: (SETUP (posedge data) (posedge clk) (3::4));
                (HOLD  (posedge data) (posedge clk) (1::2));
verilog timing checks: $setup (posedge data, posedge clk, 1);
                        $hold   (posedge clk, posedge data, 2);

例5: SDF文件: (SETUP (posedge data) (COND rb==1'b1 (posedge clk)) (3::4));
                (HOLD  (posedge data) (COND rb==1'b1 (posedge clk)) (1::2));
verilog timing checks: $setup (posedge data, posedge clk &&& rb, 1);
                        $hold   (posedge clk &&& rb, posedge data, 2);
LABEL部分:
例6:
SDF文件:(LABEL
                  (ABSOLUTE
                      (dh 60)
                      (dl  40)))
verilog文件:specparam dh = 60, dl=40;
SDF文件反標是一個有序的過程,這就意味着對於同一對source/load,后續的信息可能修改(INCREMENT)或者覆蓋(ABSOLUTE)前面已經聲明過的信息,這在反標($sdf_annotate)多個SDF文件時,就很可能發生的。
例7:覆蓋前面的延時信息
(DELAY
    (ABSOLUTE
    (IOPATH A Z (1) (2))
    (IOPATH A Z (2) (3))))



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM