目录
前言
[一. 基数基础](#一. 基数基础)
[1.1 基数介绍](#1.1 基数介绍)
[2.1 基数符号](#2.1 基数符号)
[3.1 二进制数](#3.1 二进制数)
[二. 二进制与十进制数](#二. 二进制与十进制数)
[三. 二进制数](#三. 二进制数)
[3.1 定义寄存器类型变量](#3.1 定义寄存器类型变量)
[3.2 定义线网类型变量](#3.2 定义线网类型变量)
[3.3 赋值操作](#3.3 赋值操作)
[3.4 解析二进制数为十进制数](#3.4 解析二进制数为十进制数)
[四. 代码示例](#四. 代码示例)
[五. 注意事项](#五. 注意事项)
[六. 更多操作](#六. 更多操作)
前言
在Verilog中,基数(radix)用于指定数字的进制。Verilog 支持多种基数表示法,包括二进制(binary)、八进制(octal)、十进制(decimal)和十六进制(hexadecimal)。这些不同的基数表示法,使得我们可以方便地使用最适合当前上下文的数值表示方式。
因此在数字逻辑设计和FPGA开发中,理解二进制数及其与十进制数之间的关系是至关重要的。本文将详细介绍4位二进制数,可以表示的范围,以及它们如何映射到无符号整数,并通过具体的Verilog代码示例来说明这些概念。此外,我们还将探讨一些编程时需要注意的事项,帮助我们避免常见的错误。
一. 基数基础
基数与二进制数,基础知识
1.1 基数介绍
在Verilog中,基数(或称数制)是用来表示数字常量的一种方式。Verilog 支持几种不同的基数,包括二进制、八进制、十进制和十六进制。这些基数可以用于定义整型数值,并且可以在代码中通过特定的前缀来标识。
以下是 Verilog 中使用不同基数表示数字常量的方法:
二进制 (Binary) : 使用
b
或B
作为后缀。
- 示例:
4'b0011
表示一个4位宽的二进制数,值为3。八进制 (Octal) : 使用
o
或O
作为后缀。
- 示例:
3'o5
表示一个3位宽的八进制数,其值为5(即十进制中的5)。十进制 (Decimal) : 可以直接书写数字,或者使用
d
或D
作为后缀。
- 示例:
8
或4'd8
表示一个4位宽的十进制数,值为8。如果宽度不足以容纳该值,则会发生截断或填充。十六进制 (Hexadecimal) : 使用
h
或H
作为后缀。
- 示例:
8'hAA
表示一个8位宽的十六进制数,值为170(AA是十六进制表示)。
当指定一个带宽度的常量时,格式为**<width>'<radix><value>**,其中:
- <width> 是一个正整数,指定了该数值的位宽。
- <radix> 是表示基数的字母(如 b, o, d, h)。
- <value> 是根据所选基数的实际数值。
例如:
8'b1100_1100
表示一个8位宽的二进制数,值为204(允许下划线以提高可读性)。16'hFFFF
表示一个16位宽的十六进制数,所有位均为1。
如果没有明确给出宽度,那么默认的宽度将取决于上下文,或者是工具设定的默认值。对于十进制数,如果不指定基数,可以直接写成纯数字形式,如 123
,它会被认为是一个十进制数。
2.1 基数符号
- 二进制 (Binary): b 或 B
- 八进制 (Octal): o 或 O
- 十进制 (Decimal): d 或 D (但通常可以省略)
- 十六进制 (Hexadecimal): h 或 H
这些符号直接跟在宽度说明之后、数值之前使用。例如,4'b1010
表示一个4位宽的二进制数。
3.1 二进制数
这里来着重说一下二进制,二进制是一种基于2的计数系统,它使用0和1两个符号来表示数值。每个二进制位(bit)都可以处于两种状态之一:0 或 1。对于一个n位的二进制数,它可以表示 2n 种不同的值。具体来说,4位二进制数,能够表示从 0 (0000) 到 15 (1111) 的无符号整数,总共16种不同的值。
二进制 (Binary)(4位二进制数) | 十进制 (Decimal) |
---|---|
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
1000 | 8 |
1001 | 9 |
1010 | 10 |
1011 | 11 |
1100 | 12 |
1101 | 13 |
1110 | 14 |
1111 | 15 |
二. 二进制与十进制数
解析二进制数为十进制数
要解析一个4位二进制数为十进制数,你可以将每个二进制位乘以其权重,并将结果相加。权重是2的幂次方,从右向左递增,最低位(最右边的一位)的权重是 2020,最高位(最左边的一位)的权重是 2(n−1)2(n−1),其中 nn 是位数。对于4位二进制数,权重如下:
- 第0位(最右边):20=120=1
- 第1位:21=221=2
- 第2位:22=422=4
- 第3位(最左边):23=823=8
例如,对于二进制数 1101
:
- 第0位(最右边)是
1
,其权重是 20=120=1,所以 1×1=11×1=1 - 第1位是
0
,其权重是 21=221=2,所以 0×2=00×2=0 - 第2位是
1
,其权重是 22=422=4,所以 1×4=41×4=4 - 第3位(最左边)是
1
,其权重是 23=823=8,所以 1×8=81×8=8
将这些结果相加:1+0+4+8=131+0+4+8=13,因此二进制数 1101
对应的十进制数是 13
。
计算方式总结:
十进制值=b3×23+b2×22+b1×21+b0×20十进制值=b3×23+b2×22+b1×21+b0×20
其中 bibi 表示第 ii 位的二进制值(0或1)。
图例:
三. 二进制数
Verilog 中的4位二进制数
在Verilog中,我们可以定义不同类型的变量,来存储二进制数据,最常用的是 reg 和 wire 类型。下面我们将介绍,如何在Verilog中定义、赋值和操作4位二进制数。
3.1 定义寄存器类型变量
cpp
// 定义一个4位宽的寄存器,用于保存二进制数
reg [3:0] myRegister;
[3:0]
表示这是一个4位宽的寄存器。myRegister
是变量名。
3.2 定义线网类型变量
cpp
// 定义一个4位宽的线网,用于连接组合逻辑或模块输出
wire [3:0] myWire;
- 注意,
wire
类型不能保存状态,必须由其他逻辑驱动。
3.3 赋值操作
cpp
// 使用过程赋值给寄存器
always @(posedge clk) begin // 在时钟上升沿触发
myRegister <= 4'b1101; // 给myRegister赋值为二进制1101(即十进制13)
end
// 使用连续赋值给线网
assign myWire = 4'b0011; // 给myWire赋值为二进制0011(即十进制3)
- 过程赋值使用
<=
,而连续赋值使用=
. clk
是时钟信号,posedge
表示在时钟上升沿触发。
3.4 解析二进制数为十进制数
cpp
// 计算二进制1101对应的十进制值
integer decimalValue;
always @(*) begin // 组合逻辑块
decimalValue = 8 * myRegister[3] + 4 * myRegister[2] + 2 * myRegister[1] + 1 * myRegister[0];
end
- 这里使用了组合逻辑块
@(*)
来确保每当输入发生变化时都会重新计算。 integer
类型用于存储较大的数值,如十进制结果。
四. 代码示例
以下是一个完整的Verilog代码示例,展示了如何定义、赋值和解析4位二进制数。
cpp
module binaryToDecimal(
input wire clk, // 时钟信号
output reg [3:0] myRegister, // 寄存器输出
output wire [3:0] myWire, // 线网输出
output integer decimalValue // 十进制输出
);
// 给寄存器赋值
always @(posedge clk) begin
myRegister <= 4'b1101; // 在时钟上升沿更新寄存器值
end
// 给线网赋值
assign myWire = 4'b0011;
// 解析二进制数为十进制
always @(*) begin
decimalValue = 8 * myRegister[3] + 4 * myRegister[2] + 2 * myRegister[1] + 1 * myRegister[0];
end
endmodule
这段代码创建了一个简单的模块,其中包含了寄存器和线网的定义、赋值,以及将寄存器内的4位二进制数解析为十进制的过程。注意,这里为了简化演示,省略了复位逻辑和其他可能需要的功能。在实际应用中,您应该根据需求添加适当的控制逻辑。
五. 注意事项
- 不要混淆
reg
和wire
:虽然它们可以有相同的位宽,但用途不同,reg
用于保存状态,而wire
必须由其他逻辑驱动。 - 初始化问题 :在仿真环境中,未初始化的
reg
变量默认为未知状态'x'
,这可能导致意外行为。 - 溢出处理:当对寄存器进行算术运算时,请确保不会超出其位宽所能表示的最大值,否则会导致溢出。
- 资源优化:合理规划位宽可以节省硬件资源,在FPGA上尤为重要。
本文总结
理解和正确使用二进制数是数字逻辑设计的基础。通过本文,希望你能更好地掌握4位二进制数在Verilog中的表示方法及应用技巧。无论是学习还是实际项目开发中,都应牢记上述注意事项,以编写高效且可靠的代码。
六. 更多操作
早期,之前的基数介绍,请看
FPGA 9 ,Verilog 中的关键字和基数https://blog.csdn.net/weixin_65793170/article/details/141625021完整FPGA系列,请看
FPGA系列,文章目录https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501