整数 (integer)

整数常数的定义规则如下。

  1. 整数可以用十进制(decimal)、十六进制(hexadecimal)、八进制(octal)、二进制(binary)形式表示,表现形式为:

<null|+|→<size><sign:s|S><base: d|D|h|H|o|O|b|B><0~9|0~f|0~7|0~1|x|z>,其中size、sign和base是可选的。

  1. 最简单的整数是没有size、sign和base的十进制数,只用0~9,可选+或-,表示的是符号数(signed integer)。
  2. sign必须和base一起使用。当base前面有sign标志时,表示的是符号数(signed integer);当base前面没有sign标志时,表示的是无符号数(unsigned integer)。
  3. 负数以2的补码形式表示。
  4. x表示不可知值(unknown),z表示高阻值(Hiz),在十进制数中不能使用x和z。其中z可以用?代替,在使用casex和casez时,为了便于理解常用?代替z。
    当z作为逻辑门的输入或在表达式中出现时,通常把z当做x处理,但是当z出现在MOS的原语(primitive)中,还是当做z,因为MOS可以传送高阻(HiZ)。
  5. 如果无符号数的位数小于size,那么就在左端扩展:如果最左边的位是0或1,左端就补0扩展;如果最左边的位是x,左端就补x扩展;如果最左边的位是z,左端就补z扩展。
  6. 如果无符号数的位数大于size,那么就在左端截去多余的位。
  7. 在Verilog-2001中,对于没有size限定的数,那么就在左端按照表达式的size根据最左边的位进行扩展(0、x或z),扩展多少位都没有问题。但是在Verilog-1995中,如果最左边位是x或z,那么x或z最多只能扩展到32位,超出的位按0扩展。
  8. 对于<sign>、<base>、a~f、x和z,大写和小写都可以使用(case insensitive)。
  9. 为了阅读方便,可以在数字之间加_(下划线)分割数字。
  10. 注意:当把带有size 的负常数(sized signed constant numbers)赋给一个reg类型的变量时,不管这个变量是否是signed,对这个负常数做符号扩展(sign-extend)。


例子:

  //1. Unsized constant numbers
  659         // is a decimal number
  'h 837FF    // is a hexadecimal number
  'o7460      // is an octal number
  4af         // is illegal (hexadecimal format requires 'h)
 
  //2. Sized constant numbers
  4'b1001     // is a 4-bit binary number
  5 'D 3      // is a 5-bit decimal number
  3'b01x      // is a 3-bit number with the least significant bit unknown
  12'hx       // is a 12-bit unknown number
  16'hz       // is a 16-bit hign-impedance number
 
  //3. Using sign with constant numbers
  8 'd -6     // this is illegal syntax
  -8 'd 6     // this defines the two's complement of 6,
              // held in 8 bits-equivalent to -(8'd 6)
  4 'shf      // this denotes the 4-bit number '1111', to be
              // interpreted as a 2's complement number, or '-1'.
              // This is equivalent to -4'h 1
  -4 'sd15    // this is equivalent to -(-4'd 1), or '0001'
  16'sd?      //the same as 16'sbz
 
  //4. Automatic left padding
  reg [11:0] a, b, c, d;
  initial begin
   a = 'h x;        // yields xxx
   b = 'h 3x;       // yields 03x
   c = 'h z3;       // yields zz3
   c = 'h 0z3;      // yields 0z3
  end
 
  reg [84:0] e, f, g;
  e = 'h5;          // yields {82{1'b0},3'b101}
  f = 'hx;          // yields {85{1'bx}}
  g = 'hz;          // yields {85{1'bz}}
 
  //5. Use _
  27_195_000
  16'b0011_0101_0001_1111
  32 'h 12ab_f001
 
  //6. sign-extend
  reg signed [15:0] h;
  reg [15:0] m;
  h = -12'h123;    //16'FEDD
  h = 12'shEDD;    //16'FEDD
  m = -12'h123;    //16'FEDD
  m = 12'shEDD;    //16'FEDD

我们要避免如下书写错误:

  case (sel[1:0])
   00: y = a;
   01: y = a;
   10: y = a;    //not execute
   11: y = a;    //not execute
  endcase