Verilog常数赋值、字符串、标识符

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://bestfpga.blog.csdn.net/article/details/102604599
————————————————
版权声明:本文为CSDN博主「FPGADesigner」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://bestfpga.blog.csdn.net/article/details/102604599
1.整数赋值

按照Verilog 2005的标准:0-9、a-f、z、x称作数字位(digit)
表示数字正负的’+‘和’-‘视作一元操作符(unary operator)
常说的二进制、八进制、十进制、十六进制称作数字的基(base)
其在Verilog中的表示’b’、‘o’、‘d’、'h’称作基格式(base format)字符;
表示常数的bit数称作
size
。Verilog使用到的字符都是不区分大小写的。

另外要明白二进制数本身的运算规则与一个数是signed还是unsigned、小数点在哪个位置没有任何关系,这些只是设计者人为的规定。但是在代码设计时,要标识清楚数据是signed或unsigned,目的有两个:(1).对设计者的提示;(2).一些操作符、IP核的数据端口,对数据是signed或unsigned的“身份”有要求。

如果一个数是负数(前面加了’-’),那么它必定采用的是二进制补码形式。

方式1

常数赋值有两种,一种为直接赋值(符号+一串数字位),采用这种方式赋值时,默认数据是sigend形式。如下面一个简单的示例:

在这里插入代码片
module test
(
    input clk,
    output reg [31:0] c
);

wire [31:0] a, b;

assign a = -595;
assign b = -10;

always @ (posedge clk)
    c <= a + b;

endmodule 

对两个带符号数做加法运算,结果仍然是带符号数,Vivado中仿真时,将Radix设置为Signed Decimal,可以看到变量C的结果为-605。

方式2

另一种则是常见的基常数赋值方法(符号+size+单引号+基格式字符+一串数字位),如"assign a = +16’d53;", 符号和size是可有可无的。

如果在基格式字符(b、o、d、h)前加上’s’,表示这是个带符号数signed;没有加’s’则表示是不带符号数unsigend。如果前面加了符号位“-”,会自动用二进制补码的形式。

如下面的简单示例:

在这里插入代码片`timescale 1ns / 1ps

module test
(
    input clk,
    output reg [31:0] c
);

wire [31:0] a, b;

assign a = -32'd595;   // 加上size,省去s
assign b = -'sd10;      // 省略size,加上s

always @ (posedge clk)
    c <= a + b;

endmodule 

仿真结果与第一个示例相同。

位宽扩展

这里先不讨论将低位宽的数据赋值给高位宽数据的问题,比如将12bit的a赋值给16bit的b。先讨论直接将低位宽的常数赋值给高位宽的数据时,位宽扩展遵循怎样的标准(不考虑x和z)。

以下面的测试代码为例,将12bit的常数赋值给16bit的数据:

在这里插入代码片wire [15:0] a = 12'd565;
wire [15:0] b = -12'd565;
wire [15:0] c = -12'sd565;
reg [15:0] d = -12'sd565;

仿真结果如下,分别展示了赋值结果的2进制和10进制:
在这里插入图片描述

对于正数,赋值结果为高位补0。**对于负数(二进制补码),无论是reg还是wire型、加s声明为带符号数或者不加s,结果都是高位补符号位。可见位宽扩展只与数据的正、负有关。**Verilog HDL的位宽扩展机制可以确保设计者安全、便捷地完成程序设计。

“负数”与“带符号数”的区别

由于负数必须需要符号’-'来规定,所以第一感觉就是将负数和带符号数二者等同。**其实两者并不完全相同,如果只加负号,不加s,虽然软件工具会将其用二进制补码表示,但仍不会将其当作带符号数signed看待。**看下面的示例代码:

在这里插入代码片
module test
(
    input clk,
    output reg [15:0] a,b,c,d
);

always @ (posedge clk) begin
    a <= -12 / 3;
    b <= -'sd12 / 3;
    c <= -'d12 / 3;
    d <= -4'sd12 / 3;
end

endmodule

仿真结果如下图:
在这里插入图片描述
对于a:在没有规定大小和基格式时,-12和3都视作带符号数,因此结果为正确的-4;

对于b:-'sd12使用字符’s’声明这是个带符号数,结果同样是正确的-4;

对于c:-'d12虽然声明这是个负数,但没有加-s,软件仍然不会将其视作带符号数,运算结果与预期不符;

具体分析:+12为00……1100,取反为11……0011(共32位),加1得11……0100,由于没有申明为负数,因此做除法时,软件将其视为无符号数‭4,294,967,284‬,除以3得1,431,655,761‬,二进制存储为‭101 0101 0101 0101 0101 0101 0101 0001‬,由于定义为16位,仅保留低16位0101 0101 0101 0001‬,即十进制21841

对于d:-4’sd12同时还指定了大小,但4’sd12已经超过了4bit带符号数的表示范围,它的值12(1100)实际意义上是-4(最高位符号位表示负数,二进制补码),前面再加’-'为正4,除以3,近似为整数后值为1。

2.实常数赋值

Verilog HDL本身是支持在代码中使用小数、科学计数法的,只不过赋值给整数型数据时,会发生隐式转换,转换为整数。看下面的示例:

在这里插入代码片
wire [15:0] a = 1e4;
wire [15:0] b = 12.1;
wire [15:0] c = 12.5;
reg [15:0] d = -12.5;

仿真结果如下:
在这里插入图片描述
数据a用科学计数法进行赋值。隐式转换的规则是:(1). 转换为最接近的整数;(2).中间值.5转换时,向远离0的方向进行。如数据c,12.5 => 13;数据d,-12.5 => -13。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目 录 译者序 前言 第1章 简介 1 1.1 什么是Verilog HDL? 1 1.2 历史 1 1.3 主要能力 1 第2章 HDL指南 4 2.1 模块 4 2.2 时延 5 2.3 数据流描述方式 5 2.4 行为描述方式 6 2.5 结构化描述形式 8 2.6 混合设计描述方式 9 2.7 设计模拟 10 第3章 Verilog语言要素 14 3.1 标识符 14 3.2 注释 14 3.3 格式 14 3.4 系统任务和函数 15 3.5 编译指令 15 3.5.1 `define和`undef 15 3.5.2 `ifdef、`else 和`endif 16 3.5.3 `default_nettype 16 3.5.4 `include 16 3.5.5 `resetall 16 3.5.6 `timescale 16 3.5.7 `unconnected_drive和 `nounconnected_drive 18 3.5.8 `celldefine 和 `endcelldefine 18 3.6 值集合 18 3.6.1 整型数 18 3.6.2 实数 19 3.6.3 字符串 20 3.7 数据类型 20 3.7.1 线网类型 20 3.7.2 未说明的线网 23 3.7.3 向量和标量线网 23 3.7.4 寄存器类型 23 3.8 参数 26 第4章 表达式 28 4.1 操作数 28 4.1.1 常数 28 4.1.2 参数 29 4.1.3 线网 29 4.1.4 寄存器 29 4.1.5 位选择 29 4.1.6 部分选择 29 4.1.7 存储器单元 30 4.1.8 函数调用 30 4.2 操作符 30 4.2.1 算术操作符 31 4.2.2 关系操作符 33 4.2.3 相等关系操作符 33 4.2.4 逻辑操作符 34 4.2.5 按位操作符 35 4.2.6 归约操作符 36 4.2.7 移位操作符 36 4.2.8 条件操作符 37 4.2.9 连接和复制操作 37 4.3 表达式种类 38 第5章 门电平模型化 39 5.1 内置基本门 39 5.2 多输入门 39 5.3 多输出门 41 5.4 三态门 41 5.5 上拉、下拉电阻 42 5.6 MOS开关 42 5.7 双向开关 44 5.8 门时延 44 5.9 实例数组 45 5.10 隐式线网 45 5.11 简单示例 46 5.12 2-4解码器举例 46 5.13 主从触发器举例 47 5.14 奇偶电路 47 第6章 用户定义的原语 49 6.1 UDP的定义 49 6.2 组合电路UDP 49 6.3 时序电路UDP 50 6.3.1 初始化状态寄存器 50 6.3.2 电平触发的时序电路UDP 50 6.3.3 边沿触发的时序电路UDP 51 6.3.4 边沿触发和电平触发的混合行为 51 6.4 另一实例 52 6.5 表项汇总 52 第7章 数据流模型化 54 7.1 连续赋值语句 54 7.2 举例 55 7.3 线网说明赋值 55 7.4 时延 55 7.5 线网时延 57 7.6 举例 57 7.6.1 主从触发器 57 7.6.2 数值比较器 58 第8章 行为建模 59 8.1 过程结构 59 8.1.1 initial 语句 59 8.1.2 always语句 61 8.1.3 两类语句在模块中的使用 62 8.2 时序控制 63 8.2.1 时延控制 63 8.2.2 事件控制 64 8.3 语句块 65 8.3.1 顺序语句块 66 8.3.2 并行语句块 67 8.4 过程性赋值 68 8.4.1 语句内部时延 69 8.4.2 阻塞性过程赋值 70 8.4.3 非阻塞性过程赋值 71 8.4.4 连续赋值与过程赋值的比较 72 8.5 if 语句 73 8.6 case语句 74 8.7 循环语句 76 8.7.1 forever 循环语句 76 8.7.2 repeat 循环语句 76 8.7.3 while 循环语句 77 8.7.4 for 循环语句 77 8.8 过程性连续赋值 78 8.8.1 赋值—重新赋值 78 8.8.2 force与release 79 8.9 握手协议实例 80 第9章 结构建模 83 9.1 模块 83 9.2 端口 83 9.3 模块实例语句 83 9.3.1 悬空端口 84 9.3.2 不同的端口长度 85 9.3.3 模块参数值 85 9.4 外部端口 87 9.5 举例 89 第10章 其他论题 91 10.1 任务 91 10.1.1 任务定义 91 10.1.2 任务调用 92 10.2 函数 93 10.2.1 函数说明部分 93 10.2.2 函数调用 94 10.3 系统任务和系统函数 95 10.3.1 显示任务 95 10.3.2 文件输入/输出任务 97 10.3.3 时间标度任务 99 10.3.4 模拟控制任务 99 10.3.5 定时校验任务 100 10.3.6 模拟时间函数 101 10.3.7 变换函数 102 10.3.8 概率分布函数 102 10.4 禁止语句 103 10.5 命名事件 104 10.6 结构描述方式和行为描述方式的 混合使用 106 10.7 层次路径名 107 10.8 共享任务和函数 108 10.9 值变转储文件 110 10.9.1 举例 111 10.9.2 VCD文件格式 112 10.10 指定程序块 113 10.11 强度 114 10.11.1 驱动强度 114 10.11.2 电荷强度 115 10.12 竞争状态 116 第11章 验证 118 11.1 编写测试验证程序 118 11.2 波形产生 118 11.2.1 值序列 118 11.2.2 重复模式 119 11.3 测试验证程序实例 123 11.3.1 解码器 123 11.3.2 触发器 124 11.4 从文本文件中读取向量 126 11.5 向文本文件中写入向量 127 11.6 其他实例 128 11.6.1 时钟分频器 128 11.6.2 阶乘设计 130 11.6.3 时序检测器 132 第12章 建模实例 136 12.1 简单元件建模 136 12.2 建模的不同方式 138 12.3 时延建模 139 12.4 条件操作建模 141 12.5 同步时序逻辑建模 142 12.6 通用移位寄存器 145 12.7 状态机建模 145 12.8 交互状态机 147 12.9 Moore有限状态机建模 150 12.10 Mealy型有限状态机建模 151 12.11 简化的21点程序 153 附录 语法参考 157 参考文献 172

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值