在Verilog中,整型数的表示方式非常灵活,既可以使用简单的十进制格式,也可以使用基数格式来明确指定数值的位宽、符号性以及基数。
整型数
下面是对这些表示法的详细解释和补充。
1. 简单的十进制格式这种格式是最直观的,直接以十进制数的形式表示,可以包含可选的正负号。
32 表示十进制数32-15 表示十进制数-15负数在内部以二进制补码形式存储。-15在5位二进制补码形式中为10001,在6位中为110001。
2. 基数格式表示法基数格式允许你明确指定数值的位宽、符号性和基数。
其一般形式为:
[size]'[signed][base]value
注释:
size 是数值的位宽(以二进制位为单位)。
signed 是可选的,用于指定数值是有符号的还是无符号的,用小写s或大写S表示。
base 指定数值的基数,可以是o或O(八进制),b或B(二进制),d或D(十进制,但通常省略),h或H(十六进制)。
value 是基于指定基数的数值。
示例
5'O37 5位八进制数 4'D2 4位十进制数 4'B1x_01 4位二进制数 7'Hx 7位x(扩展的x),即xxxxcxxxx 4'hz 4位(扩展的z),即zzzz 8 'h 2A在位长和字符之间,以及基数和数值之间允许出现空格 8'sh51 8位有符号数 01010001 6so72 6位有符号数111010,它是十进制下的-6,等同于6'sh3A 5'b101 表示5位宽的二进制数101,即十进制中的5。 4'd2 表示4位宽的十进制数2(虽然十进制基数通常省略,但这里为了说明而显式给出)。 8'hFF 表示8位宽的十六进制数FF,即十进制中的255。 7'sx 表示7位宽的有符号数,其中x表示未知值,通常用于模拟或测试中的不确定状态。
(2+3)'b10 非法:位宽不能用表达式表示。
基数格式的数通常为无符号数。是否定义这种格式整型数的位宽是可选择的。若某整型数的位宽没有定义,则该数的位宽至少为32位。
下面是两个例子:
o721 32位八进制数,无符号 'hAF 32位十六进制数,无符号 sb1011 32位二进制数,有符号的-5
若定义的位宽比为常量指定的位宽大,对无符号数则在数的左边填0补齐,而对有符号数则在左边填符号位补齐。但是如果数最左边一位为x或,则相应地用z或z在左边补位。
10'b10 左边添0占位,0000000010 10'bx0x1 左边添x占位,xoaaoxocx0x1 8'sb101101 左边添符号位(1),11101101
若位宽定义得比数值小,则最左边的多余位被相应地截断。
举例说明如下
3'b1001 0011 等同于 3'b011 5'HOFFF 等同于 5'H1F 3'sb10100 等同于3'sb100
同样,若没有指定数的位宽,而需要的却是一个较大位宽的数,则对无符号数而言,只需要用0来填满即可;而对于有符号的数而言,则需要用最左边的那一位来填满多余的空位。若最
左边的那一位是x或者z,则左侧多余的空位分别用x或者z来填满
reg[15:0pbus_select;//左侧填0,即赋值 0000 0000 0000 0101 pbus select='h5 ;//左侧填x,即赋值xoxxxxaoa:0001 0001pbus select='hx11: pbus select='hz51://左侧填z,即赋值zzzzzzzz0101 0001
字符问号?可以用来代替数中z值。
实数
在Verilog中,实数(也称为浮点数)和整数之间的转换是隐式的,但需要注意这种转换可能会引入精度损失,特别是当实数被转换为整数时。转换规则通常是将实数四舍五入到最接近的整数。下面给出的实数及其对应整数转换的详细解释:十进制表示法 2.0 转换为整数是 2 5.678 转换为整数是 6(四舍五入) 11572.12 转换为整数是 11572 0.1 转换为整数是 0(因为小于0.5,所以向下取整) //非法:小数点两侧必须有数字 这不是一个有效的实数表示,因为它违反了实数的基本语法规则。
23 5.1e2 这里的空格使得它不是一个有效的科学记数法表示。如果忽略空格,5.1e2 表示 510.0,转换为整数是 510。 3.6E2 表示 360.0,转换为整数是 360 360.0(e与相同) 这不是一个有效的表示,但假设是 3.6E2 的误写,则转换为整数是 360。 5E-4 表示 0.0005,转换为整数是 0(因为小于0.5,所以向下取整) 0.0005 直接转换为整数也是 0
42.446 转换为整数是 42(因为小于0.5的部分被舍去) 42.45 转换为整数是 42(但严格来说,由于它是.5,四舍五入后应为43,但在某些实现中可能因精度问题而显示为42,这取决于具体的浮点数表示和转换实现) 92.5 转换为整数是 93(四舍五入) 92.699 转换为整数是 93(四舍五入) -15.62 转换为整数是 -16(四舍五入) -26.22 转换为整数是 -26(注意这里似乎有一个错误,因为-26.22四舍五入后应为-26,但按照四舍五入的规则,它实际上更接近-27,但通常我们取小于等于原数的最大整数,所以这里应该是-26,除非有特定的舍入规则被应用)
字符串
在Verilog中,字符串(string)的处理通常不是直接支持的,因为Verilog主要是用于硬件描述语言(HDL),它更侧重于硬件电路的描述和仿真,而不是像高级编程语言那样处理文本和字符串。Verilog确实支持类似字符串的文本常量,这些常量被用作参数、模块名、任务名等的标识符,或者在某些情况下,通过系统任务($display)来输出文本信息。在描述如何在Verilog中处理类似字符串的数据,以及如何使用ASCII码来表示字符。
关于字符串的存储,Verilog没有内置的字符串数据类型。但是,使用一个足够宽的寄存器数组(reg)或者更常见的是,使用字节(8位)宽的向量数组(reg [7:0] 类型的数组)来模拟字符串。存储字符串 "INTERNAL, ERROR",可以定义一个足够大的数组来容纳这个字符串的ASCII码值:
reg [7:0] message[0:13]; // 定义一个14个元素的数组,每个元素8位宽,用于存储ASCII码 // 初始化字符串(注意:这里只是示意,Verilog中不能直接这样初始化数组) // 实际上,需要在某个过程块中逐个赋值 initial begin message[0] = 8'h49; // 'I' message[1] = 8'h4E; // 'N' message[2] = 8'h54; // 'T' // ... 以此类推,为所有字符赋值 message[13] = 8'h52; // 'R'(注意字符串末尾没有'\0') end
关于反斜杠(\)字符在Verilog字符串(或更准确地说是文本常量)中的使用,实际上在Verilog的文本常量中并不直接支持像C语言那样的转义序列(\n表示换行符)。在Verilog的系统任务($display)中,可以使用转义序列来格式化输出。然而,这些转义序列并不是在字符串常量内部定义的,而是在系统任务调用时由系统任务解释的。对于提到的\206这样的八进制转义序列,在标准的Verilog中并不直接支持。在$display等系统任务中,可以使用%o格式说明符来以八进制形式输出整数,但这与在字符串中直接表示八进制字符不同。
总结:
Verilog提供了灵活的整型数表示方式,包括十进制和基数格式,后者允许明确指定数值的位宽、符号性和基数。基数格式中的非法示包含负号、空格或表达式作为位宽等都是不被允许的。对于未指定位宽的整型数,默认位宽至少为32位。实数(浮点数)与整数之间的转换是隐式的,但需注意精度损失。字符串在Verilog中不是直接支持的数据类型,但可以通过字节宽的向量数组来模拟,并逐字节存储字符串的ASCII码值。Verilog不支持字符串中的转义序列,但系统任务如$display支持格式化输出,包括转义序列。对于八进制等特殊表示,在标准Verilog字符串中不支持,但可通过系统任务格式化输出。Verilog提供了丰富的数据类型和灵活的表示方式,以适应复杂的硬件设计需求。