整数可以用十进制(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是可选的。
最简单的整数是没有size、sign和base的十进制数,只用0~9,可选+或-,表示的是符号数(signed integer)。
sign必须和base一起使用。当base前面有sign标志时,表示的是符号数(signed integer);当base前面没有sign标志时,表示的是无符号数(unsigned integer)。
负数以2的补码形式表示。
x表示不可知值(unknown),z表示高阻值(Hiz),在十进制数中不能使用x和z。其中z可以用?代替,在使用casex和casez时,为了便于理解常用?代替z。
当z作为逻辑门的输入或在表达式中出现时,通常把z当做x处理,但是当z出现在MOS的原语(primitive)中,还是当做z,因为MOS可以传送高阻(HiZ)。
如果无符号数的位数小于size,那么就在左端扩展:如果最左边的位是0或1,左端就补0扩展;如果最左边的位是x,左端就补x扩展;如果最左边的位是z,左端就补z扩展。
如果无符号数的位数大于size,那么就在左端截去多余的位。
在Verilog-2001中,对于没有size限定的数,那么就在左端按照表达式的size根据最左边的位进行扩展(0、x或z),扩展多少位都没有问题。但是在Verilog-1995中,如果最左边位是x或z,那么x或z最多只能扩展到32位,超出的位按0扩展。
对于<sign>、<base>、a~f、x和z,大写和小写都可以使用(case insensitive)。
为了阅读方便,可以在数字之间加(下划线)分割数字。
-注意:当把带有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
27195000
16'b0011010100011111
32 'h 12abf001
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
====实数 (real)====
实数常数定义符合IEEE Std 754-1985标准,采用双精度浮点数(double-precision floating-point numbers)。实数有两种方式:十进制法和科学计数法。
例如:
1.2, 0.1, 2394.26331
1.2.E12, 1.30e-2, 0.1e-0, 23E10, 29E-2
236.123763e-12 underscores are ignored
当把实数赋给一个整数变量时,按四舍五入转换后赋值。
例如,35.7和35.5都转换成36,而35.2则转换成35。
例如,-1.5转换成-2,而1.5则转换成2.
====字符串 (string)====
字符串的定义规则如下。
-字符串是包含在两个“(双引号)之间的字符。
-字符串在表达式中或在赋值时,被当做一个由8-bit ASCII码序列组成的无符号数。
-字符串中可以使用如下的特殊字符:\n、\t、\\、\”和\ddd\,\ddd用于表示八进制数。
-使用reg变量操作字符串时,每8-bit存一个字符。
-因为字符串被当做无符号数,所以在用整数的补齐和截去规则,就是如果字符串的位长小于变量的位长,那么字符串做右对齐存放到变量的右侧,变量的左侧补0;如果字符串的位长大于变量的位长,那么字符串做右对齐存放到变量的右侧,多余的位截去。
—————
====标识符 (identifier)====
标识符就是模块、端口、任务、函数、变量、线网、参数、实例等的名字。
定义标识符要花一些心思,要含义清晰、简洁明了。