SV中的數據類型

Verilog-1995中規定的數據類型有:變量(reg), 線網(wire), 32位有符號數(integer), 64位無符號數(time), 浮點數(real)。express

 

SV擴展了reg類型爲logic,除了reg類型的功能外,能夠用在連續賦值,門單元和模塊所驅動。可是不能用在雙向總線建模,不能有多點驅動。數組

其餘數據類型:無符號雙狀態  bit,ide

                    有符號雙狀態32位   int,函數

                    有符號雙狀態8位     byte,                            //能夠用內置函數  $isunknownui

                    有符號四狀態32位   integer,scala

                    無符號四狀態64位   time,orm

                    有符號雙狀態浮點64位    real.遞歸

$isunknown()----在操做數中存在X、Z時,返回1。隊列

$bits(expression)----返回expression佔的位寬。ip

對於四狀態類型的數據,缺省值爲X,雙狀態類型的數據,缺省值是0.

不少SV仿真器在存放數據元素的時候都是使用32bit的字邊界。因此byte、shortint、int都是存放在一個字中,longint則存放在兩個字中。

對於四狀態的數據,SV仿真器一般使用兩個連續的字或更多的連續的雙字來存放它們的值,因此四狀態的變量會消耗雙倍的空間。

連續的雙字,一個字存放數據的0/1值,另外一個字存放x/z狀態。

 

foreach能夠進行多維數據的遞歸調用,foreach(A[i,j])

 

定寬數組:

        (pack)合併數組:將數組大小的定義放在等式左邊            bit [3:0][7:0] bytes;          //4個字節組成一個字,儲存空間一個字。

        (unpack)非合併數組:將數組大小的定義放在等式右邊         bit [7:0] bytes [4];            //4個字節,這個還是合併數組,可是4個存儲空間不連續,這是非合併數組

    unpacked array會被認爲是一個vector,packed array會被認爲是一個scalar。

    unpacked array的聲明有兩種方式:

      1. int array [0:7][0:31];  array delaration using ranges

      2. int array [8][32];        array delaration using size

        當須要和標量進行數據交換時,使用合併數組很方便,並且@操做符的數據只能是標量和合並數組。因此推薦使用合併數組,還節省空間。

        bit [3:0][7:0] barray[3];   //當使用@操做符時,只能使用@(barray[0] or barray[1] or barray[2])不能使用整個barray。

        bit [31:0] src[5] = `{0,1,2,3,4},   dst[5] = `{5,4,3,2,1};                       //數組的直接初始化

        if(src == dst)   $display("src==dst");                                                    //數組能夠直接進行總體的比較

        dst = src; src[0] = 5;                                                                           //數組能夠直接進行總體的賦值和單個的賦值。

        數組的系統函數sum, min, max, unique, with, reverse, sort, resort, shuffle

        int q[4] = ‘{1,3,5,7}, tq[10];

        tq = q.min();                  //{1}      

        tq = q.max();                   //{7}

        tq = q.unique();                 //{1,3,5,7}

        tq = q.find with (item > 3);          //{5,7}全部大於3的元素,item這裏是缺省值,也能夠顯式的指出。

        tq = q.find with(x) (x > 3);

        tq = q.find_index with (item > 3);    //{2,3}全部大於3的元素的index。

        tq = q.find_first with (item > 99);     //返回第一個大於99的元素,{}無

        tq = q.find_first_index with (item > 6);   //{3}

        tq = q.sum with (item > 6);             //{7}

        tq = q.reverse();                             //{7,5,3,1}

        tq = q.sort();                                  //{1,3,5,7}

        tq = q.resort();                               //{7,5,3,1} 

        tq = q.shuffle();                              //{3,5,1,7} 再隨機化一個          

 

動態數組:聲明時使用空[],位寬在編譯時不指出,在運行時動態分配。使用前必須用new[]來初始化並分配空間。系統函數size,delete

              int dyn[];

              dyn = new[5];

              dyn = new[20](dyn);   //分配20個空間,並複製原來的5位數據,放在新的20個空間的前五個。

              dyn.delete;        //刪除整個數組

              $size(dyn);        //動態數組的個數

 

隊列:在SV中結合了鏈表和數組的優勢,集插入與查詢的優勢於一體。聲明時使用美圓符號[$],系統函數insert, delete, push_front, push_back, pop_front,

         pop_back。推薦後邊的pop, push操做。

               int q[$] = {0,2,5};        //初始化,不須要‘

               q.insert(1,1);           //{0,1,2,5},在第一個元素以前,插入1

               q.delete(1);             //刪除第一個元素,{0,2,5}

               q.push_front(6);      //{6,0,2,5}在隊列前插入6

               q.push_back(8);      //{6,0,2,5,8}在隊列後插入8

               j = q.pop_front;      //pop出隊列的第一個元素,j=6 q={0,2,5,8}

               j = q.pop_back;      //pop出隊列的最後一個元素,j=8 q={0,2,5}

 

關聯數組:SV採用樹或哈希表的形式來保存,聲明時在方括號中放置數據類型,如[int], [bit[8:0]]。

              bit [63:0] assoc[bit[63:0]], idx =1;

              repeat(64)  begin                                   

                                    assoc[idx] = idx;      idx = idx<<1;          //賦值

                                end 

              foreach (assoc[i])     $display ("assoc[%h] =%h", i , assoc[i]);      //用foreach來遍歷

              if(assoc.first(idx))    begin

                                                do   $display("assoc[h] = %h",idx,assoc[idx]);       //do...while遍歷,first/next

                                                while(assoc.next(idx));

                                            end

              if(assoc.exists(idx) )                            //exists 系統函數

    num()函數和size(),返回哈希的個數,

 

枚舉類型:聲明包含一個常量名稱列表以及一個或多個變量。系統函數name(),由變量值返回字符串。first(), last(), next(), prev(),

         typedef enum {INIT, DECODE=2, IDLE} fsmtype_e;            //INIT的值爲0,IDLE的值爲2

         typedef enum {FIRST=1, SECOND, THILD} ordinal_e;    ordinal_e  position;   //枚舉類型默認會存儲爲int類型,缺省值爲0,因此FIRST只能是0

         typedef enum {FIRST=0, SECOND, THILD} ordinal_e;   right

         color = color.first;         do    begin

                                                        $display("Color = %d/%s",color,color.name);

                                                        color = color.next;

                                                    end   while(color != color.first);      //枚舉遍歷 

  num(),返回enum中的個數。

 

字符串:string類型能夠用來保存字符串,單個字符串是byte類型,採用動態分配的儲存方式,長度爲N的字符串,元素編號0-N-1,結尾不帶'\0'。

           系統函數getc(N), tolower(), putc(N,C), subtr(M,N), len(), toupper()

           string s = "IEEE";

           $display(s.getc(0));           //返回第零個字符 'I'

           $display(s.tolower() );          //顯示 'ieee'

           s.putc(s.len()-1,"-" );           //變爲 'IEEE-'

           s = {s, "P1800"};                //變爲  'ieee-P1800'           

 

typedef關鍵字:  typedef  reg[OPSIZE-1:0]opreg_t;                   opreg_t  op_a,op_b;

                        typedef  int  fixed_arrays5[5];                         fixed_arrays5    f5;   //5個數據的數組

struct關鍵字:     struct  {bit [7:0] r,g,b;}   pixel;                      只是聲明一個pixel變量;

                        typedef  struct packed {bit[7:0] r,g,b;}  pixel_p_s;          pixel_p_s  my_pixel;     //packed的方式,表示合併結構,緊湊的存儲方式

數據類型轉換:    靜態轉換 real j;   j=int '(10.1 - 0.1);                        //強制轉換爲整型。 

流操做符:          >>把數據從左至右變成流,<<把數據從右往左變成流。

                       bit [7:0] j[4] = '{8'ha, 8'hb, 8'hc, 8'hd};   int h;

                       h = {>>{j}};                 //把數據0a0b0c0d打包成整型。

                       h = {<<{j}};                 //把數據倒序b030d050打包成整型。

                       h = {<<byte{j}};           //0d0c0b0a字節倒序打包成整型。

                       {>>h} = j;                     //把j分散到四個字節變量中。

  在流操做符中,還能夠直接使用with,來動態的顯示參與運算的數組的區間

    {<< byte {header, len, payload with [0+:len],crc}} = stream;

    區間的表示能夠是[expression: expression],[expression+: expression],[expression-: expression]

 

SV中能夠設置參數化的module/class/interface/mailbox

module ma #(parameter p1 = 1, parameter type p2 = shortint)

                   (input logic [p1:0] i, output logic [p1:0] o);

..............

endmodule

interface quit_timer_checker #(parameter min_quiet = 0,

                                              parameter max_quiet = 0)

             (input logic clk, reset_n, [1:0]en);

endinterface

class vector #(size == 1);

           logic [size-1:0] v;

endclass

 

參數化的打印:sformatf(int_type, "string");

       psprintf("string", type); 

 

set membership operator,直接判斷某個expression是否在一個list中;

  if(a inside {b,c}) begin

  end

  if(ex inside {array}) begin   直接用在數組判斷中

  end

 

part select操做符

  +:a_vect[ o+: 8]   = a_vect[0:8]

  -: a_vect[15-:8] = a_vect[8:15]

{},能夠拼接字符串,和數值

n{var},表示n個var拼接

Assignment pattern:'{}來直接賦值

  1) index:value,   integer i = ‘{31:1, 23:1,15::1,8:1,default:0 };

          int a3[] = '{1, 2, 3}

  2) type:value, struct { int a;  time b; }  key[2];

         key = '{ '{a:1, b:2ns}, '{int:5, time:$time} };

  3) default:value,  int a[3] = '{default:1};

相關文章
相關標籤/搜索