SystemVerilog语法(2)-基本数据类型
文章目录
1、核心概念
1.1 四种逻辑值与线网强度
SystemVerilog 使用 4 态逻辑值系统:
| 值 | 含义 | 说明 |
|---|---|---|
0 |
逻辑低 | 低电平、假 |
1 |
逻辑高 | 高电平、真 |
x |
未知 | 未初始化或多驱动冲突 |
z |
高阻 | 三态、无驱动悬空 |
线网(net)类型支持驱动强度,多驱动时强度高者胜出,强度从高到低:
supply > strong > pull > large > weak > medium > small > highz
- 连续赋值
assign默认:strong强度 supply0/supply1:supply最高强度- 变量(variable)不支持强度模型
1.2 net(线网)与 variable(变量)本质区别
| 特性 | net(线网) | variable(变量) |
|---|---|---|
| 存储特性 | 不存储值(trireg 除外) |
赋值后保持值,直到下次赋值 |
| 驱动方式 | 支持多驱动,自动决议 | 单驱动,禁止多驱动 |
| 赋值方式 | 连续赋值 / 门驱动 / 端口驱动 | 过程赋值(initial/always) |
| 默认值 | z(trireg 默认 x) |
4 态=x,2 态=0 |
| 强度支持 | 支持驱动/电荷强度 | 不支持强度 |
net 与 variable 分属不同命名空间,同名不冲突,但工程中不建议同名。
1.3 4 态类型与 2 态类型
- 4 态类型:
logic/reg/integer/time,含0/1/x/z,适合设计建模 - 2 态类型:
bit/byte/shortint/int/longint,仅0/1,仿真更快,适合验证平台
1.4 单一类型与聚合类型
- 单一类型(singular):基础类型、打包类型、
string、句柄(单个值) - 聚合类型(aggregate):非打包数组/结构体/联合体(值集合)
2、内建线网(net)类型
线网类型速查表
| 类型 | 功能说明 |
|---|---|
wire / tri |
通用线网,多驱动自动决议 |
uwire |
单驱动线网,多驱动直接报错 |
wand / triand |
线与逻辑,任一驱动 0 则输出 0 |
wor / trior |
线或逻辑,任一驱动 1 则输出 1 |
trireg |
电容存储,无驱动保持最后值 |
tri0 |
无驱动默认输出 0 |
tri1 |
无驱动默认输出 1 |
supply0 / supply1 |
电源/地,最高强度 |
interconnect |
无类型连接,自动推导类型 |
下面详细解释 SystemVerilog中各种线网(net)类型的功能、行为特点和典型使用场景。
2.1 wire / tri
-
功能:标准线网类型,支持多个驱动源,通过线网决议函数计算最终值。
-
决议规则:

-
wire与tri:功能完全等价,tri强调可能被多个三态驱动。 -
使用场景:模块间连接、组合逻辑输出。
-
赋值限制:只能通过
assign、门输出、模块端口驱动,禁止在initial/always中直接赋值。
示例:
wire w1, w2;
assign w1 = 1'b1;
assign w1 = 1'b0; // 冲突 → x
assign w2 = 1'b1;
assign w2 = 1'bz; // 1 与 z → 1
tri t1, t2;
assign t1 = 1'b1;
assign t1 = 1'b0; // 冲突 → x
assign t2 = 1'b0;
assign t2 = 1'bz; // 0 与 z → 0
2.2 uwire
- 功能:单驱动线网,强制要求只有一个驱动源。
- 用途:在编译/详细设计阶段发现意外的多驱动错误。
- 注意:
uwire是 SystemVerilog 引入的特性。
示例:
uwire u1;
assign u1 = 1'b1;
// assign u1 = 1'b0; // 错误!多驱动报错
2.3 wand / triand
- 功能:线与逻辑,最终值为所有驱动值的逻辑与。
- 决议规则:

示例:
wand w_and;
assign w_and = 1'b1;
assign w_and = 1'b1; // 1 & 1 = 1
assign w_and = 1'bz; // 高阻忽略
triand t_and;
assign t_and = 1'b1;
assign t_and = 1'b0; // 0 & 1 = 0
2.4 wor / trior
- 功能:线或逻辑,最终值为所有驱动值的逻辑或。
- 决议规则:

示例:
wor w_or;
assign w_or = 1'b0;
assign w_or = 1'b0; // 0 | 0 = 0
assign w_or = 1'bz; // 高阻忽略
trior t_or;
assign t_or = 1'b0;
assign t_or = 1'b1; // 1 | 0 = 1
2.5 trireg
- 功能:电容存储线网。当所有驱动为
z时,保持上一个有效逻辑值。 - 电荷强度:可指定
(small)、(medium)、(large)表示衰减时间,默认无限保持。 - 使用场景:建模动态节点、总线保持电路,主要用于模拟/混合信号仿真。
示例:
trireg (large) cap_node;
reg driver_en, data_val;
assign cap_node = driver_en ? data_val : 1'bz;
initial begin
driver_en = 1; data_val = 1; #10; // cap_node = 1
driver_en = 0; // 驱动关闭,cap_node 保持 1
#10 $display("%b", cap_node); // 输出 1
end
2.6 tri0
- 功能:弱下拉线网。所有驱动为
z时,输出0(内置弱下拉电阻)。 - 使用场景:确保总线未驱动时有确定值。

示例:
tri0 t0;
assign t0 = 1'b1; // 强驱动 1,结果为 1
// assign t0 = 1'bz; // 若所有驱动为 z,结果为 0
2.7 tri1
- 功能:弱上拉线网。所有驱动为
z时,输出1。 - 使用场景:模拟上拉电阻。

示例:
tri1 t1;
assign t1 = 1'b0; // 强驱动 0,结果为 0
// assign t1 = 1'bz; // 若所有驱动为 z,结果为 1
2.8 supply0 / supply1
- 功能:电源/地线网,恒定输出
0/1,具有最高supply强度。 - 使用场景:门级仿真中的 VSS/VDD 网络,测试平台中强制覆盖信号。
示例 1:supply0 覆盖 strong 驱动
supply0 gnd;
supply1 vcc;
wire sig;
assign sig = 1'b1; // strong 强度,值 1
assign sig = gnd; // supply 强度,值 0 → 结果 0
示例 2:supply1 覆盖 strong 驱动
supply1 vcc;
wire sig;
assign sig = vcc; // supply 强度,值 1
assign sig = 1'b0; // strong 强度,值 0 → 结果 1
示例 3:两个 supply 级驱动冲突
supply1 vcc;
supply0 gnd;
wire sig;
assign sig = vcc; // supply 强度,值 1
assign sig = gnd; // supply 强度,值 0
// 强度相同,值不同 → 结果为 x
2.9 interconnect
- 功能:无类型连接线网,类型由连接的信号自动推导。
- 限制:不能用于连续赋值右侧或门级输出,仅用于连接。
- 注意:需工具支持 IEEE 1800-2012 或更新标准。
示例:
module top;
logic a;
wire b;
interconnect ic1, ic2;
sub u_sub (.port_a(ic1), .port_b(ic2));
assign ic1 = a; // ic1 获得 logic 类型
assign ic2 = b; // ic2 获得 wire 类型
// assign ic1 = 1'b1; // 错误!
endmodule
3、变量定义
3.1 变量概述
变量是数据存储元素的抽象,用于在两次赋值之间保持其值。过程内的赋值语句会触发变量值的更新。
3.2 变量声明方式
3.2.1 传统形式
直接使用数据类型后跟变量名。
int i;
logic [7:0] data;
shortint s1, s2[0:9];
已为您优化如下:
3.2.2 var 关键字形式
以 var 开头,数据类型可选,省略时默认为 logic。
var byte my_byte; // 等价于 byte my_byte;
var v; // var logic v;
var [15:0] vw; // var logic [15:0] vw;
var enum bit {clear, error} status;
input var logic data_in; // 模块端口中使用
var reg r; // 合法但不推荐
3.3 数据类型分类
| 类别 | 包含类型 |
|---|---|
| 2 态整型向量 | bit |
| 4 态整型向量 | logic, reg |
| 2 态整型原子 | byte, shortint, int, longint |
| 4 态整型原子 | integer, time |
| 非整型 | shortreal, real, realtime |
| 特殊类型 | void, chandle, string, event, 虚接口, 类句柄 |
| 枚举 | enum |
3.4 标量与向量
3.4.1 打包 vs 非打包
- 打包维度(左侧):数据连续紧凑存储,可综合、支持位选/部分选,等价于 Verilog 向量
- 非打包维度(右侧):数据独立分段存储,仿真易用,部分可综合
bit [7:0] a; // 打包:8 位向量(硬件标准写法)
bit b [7:0]; // 非打包:8 个独立 1bit(数组)
bit [7:0] c [3:0]; // 4 个 8 位向量的数组(最常用)
3.4.2 向量范围指定
- 格式:
[msb_constant_expression : lsb_constant_expression] - msb 和 lsb 必须是常量整数表达式,可为任意整数值(正、负、零)。
- lsb 值可以大于、等于或小于 msb 值。
- 禁止包含
x或z位。
示例:
logic [3:0] v; // 4 位,v[3] 最高位,v[0] 最低位
logic [-1:4] b; // 6 位,有效索引 -1、0、1、2、3、4
logic [4:0] x, y, z; // 三个 5 位向量
3.4.3 向量算术规则
- 向量遵循模 2 n 2^n 2n 的算术规则, n n n 为向量位数。
- 默认视为无符号量,除非用
signed显式声明或连接到有符号端口。
3.4.4 向量长度限制
- 工具对向量最大长度的限制至少为 65536( 2 16 2^{16} 216)位。
3.4.5 vectored 与 scalared 关键字
- 可选关键字,仅用于向量线网声明。
vectored:可能禁止位选/部分选,PLI 视为未展开。scalared:允许位选/部分选,PLI 视为已展开。
tri1 scalared [63:0] bus64; // 展开的总线
tri vectored [31:0] data; // 可能不展开
3.5 变量生命周期(static / automatic)
static:静态存储,全局/模块级变量默认,仿真全程存在。automatic:自动存储,函数/任务内变量默认,调用时创建、退出时销毁。
function automatic int calc(input int a);
int temp = a * 2; // 每次调用重新初始化
return temp;
endfunction
3.6 变量初始化
3.6.1 显式初始化
声明时使用 = 初始值,初始值可以是运行时表达式。
int i = 0;
static mailbox mbx = new();
static int rand_val = $urandom;
3.6.2 初始化时机
- 静态变量的初始化发生在所有
initial和always过程启动之前。
3.6.3 默认初始值
| 类型 | 默认初始值 |
|---|---|
4 态整型 (logic, reg, integer, time) |
'x |
2 态整型 (bit, byte, shortint, int, longint) |
'0 |
real, shortreal |
0.0 |
string |
""(空字符串) |
event |
新事件对象 |
类句柄 / chandle / 虚接口 |
null |
| 枚举 | 基类型的默认初始值 |
3.7 有符号/无符号规则
| 默认有符号类型 | 默认无符号类型 |
|---|---|
byte, shortint, int, longint |
bit, logic, reg |
integer |
time |
- 可使用
signed或unsigned显式覆盖。
bit signed [7:0] signed_byte;
logic unsigned [31:0] u32;
3.8 整数类型速查表
3.8.1 2 态整数类型
| 类型 | 位宽 | 默认符号 |
|---|---|---|
bit |
自定义 | 无符号 |
byte |
8 bit | 有符号 |
shortint |
16 bit | 有符号 |
int |
32 bit | 有符号 |
longint |
64 bit | 有符号 |
3.8.2 4 态整数类型
| 类型 | 位宽 | 默认符号 |
|---|---|---|
logic / reg |
自定义 | 无符号 |
integer |
32 bit | 有符号 |
time |
64 bit | 无符号 |
3.9 特殊变量类型
| 类型 | 说明 |
|---|---|
void |
无数据类型,仅用于函数返回值 |
chandle |
DPI-C 接口中传递 C 指针的不透明句柄,默认 null |
虚接口 (virtual interface) |
验证平台中连接 DUT 的接口句柄 |
| 类句柄 | 指向 class 对象的引用,默认 null |
3.10 类型转换
3.10.1 静态转换
编译时检查,语法 type'(expr)。
int i = 10;
real r = real'(i); // int → real
logic [3:0] b = 4'(8'hFF); // 截断高位,b = 4'hF
3.10.2 动态转换
运行时检查,语法 $cast(target, source),主要用于类句柄转换。
parent_class p;
child_class c;
if ($cast(c, p)) begin
// 转换成功
end
3.10.3 类型兼容性规则
- 2 态 → 4 态:自动转换,
0/1保持。 - 4 态 → 2 态:
x/z自动转为0。 - 位宽不匹配:赋值时自动截断或补零。
3.11 示例汇总
// 标量声明
logic a;
// 向量声明
tri [15:0] busa;
logic [3:0] v;
logic signed [3:0] signed_reg;
logic [-1:4] b;
// 批量声明
wire w1, w2;
logic [4:0] x, y, z;
// 变量初始化
int i = 0;
string msg = "Hello";
4、常用数据类型扩展
4.1 string 类型常用方法
| 方法 | 功能说明 |
|---|---|
s.len() |
返回字符串长度 |
s[i] / s.getc(i) |
获取第 i 个字符 |
s.putc(i, c) |
修改第 i 个字符 |
s.toupper() |
转换为大写 |
s.tolower() |
转换为小写 |
s.atoi() |
字符串转整数 |
s.atoreal() |
字符串转实数 |
示例:
module string_example;
initial begin
string s = "Hello";
$display("s[1] = %c", s[1]); // 输出 'e'
s.putc(1, "a"); // s 变为 "Hallo"
$display("upper: %s", s.toupper()); // "HALLO"
end
endmodule
4.2 event 事件基本用法
| 语法 | 功能说明 |
|---|---|
event e; |
声明事件 |
-> e; |
触发事件 |
@e; |
等待事件在后续时间步触发(边缘敏感) |
wait(e.triggered); |
等待事件在当前时间步已触发(电平敏感) |
@e 与 wait(e.triggered) 区别:
@e:若事件在等待前已触发,会错过。wait(e.triggered):只要当前时间步曾触发即满足。
示例:
event e;
initial begin
#10 -> e;
$display("e triggered");
end
initial begin
@e $display("received via @");
end
initial begin
#5;
wait(e.triggered) $display("received via wait");
end
4.3 typedef 自定义类型
typedef 为现有类型创建别名,提高可读性。
typedef int my_type;
typedef logic [31:0] addr_t;
typedef enum {IDLE, READ, WRITE} state_t;
typedef struct packed {
addr_t addr;
my_type data;
} transaction_t;
4.4 枚举类型(enum)
枚举定义一组命名的常量。
// 基础枚举
enum {IDLE, READ, WRITE} state;
// 显式指定基类型和值
enum bit [1:0] {
RED = 2'b00,
GREEN = 2'b01,
BLUE = 2'b10
} color;
// 类型安全枚举
typedef enum logic [2:0] {
S_IDLE = 3'b001,
S_START = 3'b010,
S_WAIT = 3'b100
} state_t;
state_t curr = S_IDLE;
$display("State: %s", curr.name()); // 输出 "S_IDLE"
// 枚举内置方法
curr = curr.first(); // 首个枚举值
curr = curr.last(); // 最后一个枚举值
curr = curr.next(); // 下一个值(循环)
curr = curr.prev(); // 上一个值(循环)
4.5 ref 参数传递
ref 用于任务/函数中按引用传递参数,避免大数组拷贝。
// 按值传递(拷贝整个数组)
function int sum_copy(int arr[10]);
// arr 是副本
endfunction
// 按引用传递(不拷贝)
function int sum_ref(ref int arr[10]);
arr[0] = 0; // 影响外部实参
endfunction
// const ref:只读引用
function void print(const ref int arr[10]);
foreach (arr[i]) $display("%0d", arr[i]);
endfunction
5、工程常见易错点与编码建议
5.1 reg / logic / bit 核心区别
| 类型 | 推荐度 | 说明 |
|---|---|---|
reg |
不推荐 | Verilog 遗留,无语法优势,建议用 logic 替代 |
logic |
强烈推荐 | 4 态标准类型,支持变量和线网(单驱动),替代 reg |
bit |
推荐 | 2 态类型,仿真更快,适合复位/控制信号,注意无 x/z |
5.2 wire 与 logic 混用规则
| 场景 | 推荐类型 |
|---|---|
| 模块输入端口 | wire 或 logic 均可 |
| 模块输出端口(单驱动) | logic |
| 模块输出端口(多驱动,如三态总线) | wire |
| 组合逻辑输出 | 优先 logic,避免多驱动 |
5.3 多驱动错误排查
- 使用
uwire替代wire,编译器直接报错多驱动源。 - 检查
assign、门输出、模块端口是否重复驱动同一信号。
5.4 隐式线网声明
- 未声明的信号默认生成
wire。 - 可通过
`default_nettype uwire强制单驱动,或`default_nettype none禁止隐式声明。
5.5 初始化差异
- 仿真:变量默认值按类型,net 默认
z。 - 综合:忽略声明时的初始化值,仅复位信号有效。
5.6 向量范围
- 允许
lsb > msb(如logic [0:7] a),位序仅影响位选索引,不改变实际硬件位宽。
5.7 编码规范推荐
- 设计代码:单驱动信号用
logic,多驱动三态总线用wire - 验证代码:优先
bit(2 态)提升仿真速度 - 状态机:强烈推荐用
enum定义,避免硬编码数字。enum可提高可读性、可维护性,支持类型检查与调试显示状态名;硬编码语法上允许,但团队协作时不推荐。 - 跨模块信号:一律显式声明类型,禁止依赖隐式线网。
6、仿真验证示例
为验证前文所述的线网(net)类型决议规则以及字符串(string)常用方法,本章提供两个独立的 SystemVerilog Testbench,可直接用 VCS 仿真验证。
6.1 线网类型仿真验证
6.1.1 Testbench 代码
// filename: net_types_tb.sv
// 功能: 验证 SystemVerilog 线网决议规则
module net_types_tb;
// ========== 1. wire / tri 静态决议 ==========
wire w1, w2;
tri t1, t2;
assign w1 = 1'b1;
assign w1 = 1'b0; // 1 与 0 -> x
assign w2 = 1'b1;
assign w2 = 1'bz; // 1 与 z -> 1
assign t1 = 1'b1;
assign t1 = 1'b0; // 1 与 0 -> x
assign t2 = 1'b0;
assign t2 = 1'bz; // 0 与 z -> 0
// ========== 2. wand / triand (线与) ==========
wand wand_sig;
assign wand_sig = 1'b1;
assign wand_sig = 1'b1; // 1 & 1 -> 1
wand wand2;
assign wand2 = 1'b0;
assign wand2 = 1'b1; // 0 & 1 -> 0
wand wand3;
assign wand3 = 1'bz;
assign wand3 = 1'b1; // z & 1 -> 1
// ========== 3. wor / trior (线或) ==========
wor wor_sig;
assign wor_sig = 1'b0;
assign wor_sig = 1'b0; // 0 | 0 -> 0
wor wor2;
assign wor2 = 1'b1;
assign wor2 = 1'b0; // 1 | 0 -> 1
wor wor3;
assign wor3 = 1'bz;
assign wor3 = 1'b0; // z | 0 -> 0
// ========== 4. trireg (电容存储) ==========
trireg (large) cap_node;
// ========== 5. tri0 / tri1 ==========
tri0 tri0_sig; // 弱下拉,默认 0
tri1 tri1_sig; // 弱上拉,默认 1
// ========== 6. supply0 / supply1 强度测试 ==========
supply0 gnd;
supply1 vcc;
// 6.1 顺序 force 演示覆盖关系
wire test_strong, test_supply;
// 6.2 静态多 assign 演示同时冲突 (两个 supply 驱动同一线网)
wire test_both;
assign test_both = gnd;
assign test_both = vcc;
// 测试控制 (initial 块)
initial begin
$display("==========================================");
$display(" SystemVerilog Net Types Testbench");
$display(" (Static assign + dynamic force/release)");
$display("==========================================\n");
// ----- 1. wire / tri (静态决议) -----
$display("--- 1. wire / tri (static multiple assign) ---");
#1;
$display("wire w1 (1 and 0) = %b (expect x)", w1);
$display("wire w2 (1 and z) = %b (expect 1)", w2);
$display("tri t1 (1 and 0) = %b (expect x)", t1);
$display("tri t2 (0 and z) = %b (expect 0)\n", t2);
// ----- 2. wand / triand -----
$display("--- 2. wand / triand (static multiple assign) ---");
$display("wand (1 & 1) = %b (expect 1)", wand_sig);
$display("wand (0 & 1) = %b (expect 0)", wand2);
$display("wand (z & 1) = %b (expect 1)\n", wand3);
// ----- 3. wor / trior -----
$display("--- 3. wor / trior (static multiple assign) ---");
$display("wor (0 | 0) = %b (expect 0)", wor_sig);
$display("wor (1 | 0) = %b (expect 1)", wor2);
$display("wor (z | 0) = %b (expect 0)\n", wor3);
// ----- 4. trireg (电容存储, 使用 force/release) -----
$display("--- 4. trireg (force/release) ---");
force cap_node = 1'b1;
#1;
$display("trireg forced to 1 = %b", cap_node);
release cap_node; // 释放后应保持之前的值(电容特性)
#1;
$display("trireg after release (hold) = %b (expect 1)", cap_node);
force cap_node = 1'b0;
#1;
$display("trireg forced to 0 = %b", cap_node);
release cap_node;
#1;
$display("trireg after release again = %b (expect 0)\n", cap_node);
// ----- 5. tri0 / tri1 (弱上/下拉, 使用 force/release) -----
$display("--- 5. tri0 / tri1 (force/release) ---");
// tri0: 强1驱动覆盖弱下拉
force tri0_sig = 1'b1;
#1;
$display("tri0 forced to strong 1 = %b (expect 1)", tri0_sig);
release tri0_sig; // 释放后弱下拉生效 -> 0
#1;
$display("tri0 after release (pull-down) = %b (expect 0)", tri0_sig);
// tri1: 强0驱动覆盖弱上拉
force tri1_sig = 1'b0;
#1;
$display("tri1 forced to strong 0 = %b (expect 0)", tri1_sig);
release tri1_sig; // 释放后弱上拉生效 -> 1
#1;
$display("tri1 after release (pull-up) = %b (expect 1)\n", tri1_sig);
// ----- 6. supply0 / supply1 强度测试 -----
$display("--- 6. supply0 / supply1 strength ---");
// 6.1 顺序 force 演示覆盖关系
$display("--- 6.1 Sequential force override ---");
// supply0 覆盖 strong1
force test_strong = 1'b1;
#1;
$display("After strong1 alone: test_strong = %b", test_strong);
force test_strong = gnd; // supply0 覆盖
#1;
$display("After supply0 overrides strong1: test_strong = %b (expect 0)", test_strong);
release test_strong;
// supply1 覆盖 strong0
force test_supply = 1'b0;
#1;
$display("After strong0 alone: test_supply = %b", test_supply);
force test_supply = vcc; // supply1 覆盖
#1;
$display("After supply1 overrides strong0: test_supply = %b (expect 1)", test_supply);
release test_supply;
// 6.2 静态多 assign 演示同时冲突
$display("--- 6.2 Simultaneous multiple assign (supply0 vs supply1) ---");
#1;
$display("supply0 vs supply1 (static) = %b (expect x)", test_both);
$display("\n==========================================");
$display(" Testbench completed.");
$display("==========================================");
$finish;
end
endmodule
6.1.2 仿真输出

6.2 字符串类型使用示例
string 是 SystemVerilog 中常用的验证/仿真辅助类型,支持动态长度、内置方法。以下示例演示常用方法(长度访问、字符修改、大小写转换、类型转换等)。
6.2.1 Testbench 代码
// filename: string_demo.sv
// 功能: 演示 SystemVerilog string 类型常用方法
// 仿真命令: vcs -sverilog string_demo.sv -R
module string_demo;
initial begin
string s, t, u;
int int_val;
real real_val;
$display("==========================================");
$display(" SystemVerilog String Methods Demo");
$display("==========================================\n");
// ----- 1. 字符串基本操作 -----
s = "Hello";
$display("1. 原始字符串: \"%s\"", s);
$display(" 长度: %0d", s.len());
$display(" 第1个字符(s[1]): '%c'", s[1]); // 注意索引从0开始?实际上s[0]='H', s[1]='e'
// 更正: 索引从0开始,s[0]='H', s[1]='e'
$display(" 第0个字符(s[0]): '%c'", s[0]);
// ----- 2. 修改字符 -----
s.putc(1, "a"); // 将索引1的字符改为'a'
$display("\n2. putc(1, 'a') 后: \"%s\" (期望 \"Hallo\")", s);
// ----- 3. 大小写转换 -----
s = "Hello World";
$display("\n3. 原始: \"%s\"", s);
$display(" toupper(): \"%s\"", s.toupper());
$display(" tolower(): \"%s\"", s.tolower());
// ----- 4. 字符串拼接与比较 -----
t = "Hello";
u = " World";
s = {t, u}; // 拼接
$display("\n4. 拼接 \"%s\" + \"%s\" = \"%s\"", t, u, s);
$display(" compare(\"%s\", \"%s\") = %0d", t, u, t.compare(u));
// ----- 5. 字符串转整数/实数 -----
s = "123";
int_val = s.atoi();
$display("\n5. atoi(\"%s\") = %0d", s, int_val);
s = "3.1415";
real_val = s.atoreal();
$display(" atoreal(\"%s\") = %0.4f", s, real_val);
// ----- 6. 整数/实数转字符串 -----
int_val = 456;
s = $sformatf("%0d", int_val);
$display("\n6. $sformatf(\"%%0d\", %0d) = \"%s\"", int_val, s);
real_val = 2.71828;
s = $sformatf("%0.3f", real_val);
$display(" $sformatf(\"%%0.3f\", %0.5f) = \"%s\"", real_val, s);
// ----- 7. 子串提取 -----
s = "abcdefgh";
t = s.substr(2, 5); // 索引2到5,包含两端
$display("\n7. substr(2,5) of \"%s\" = \"%s\" (期望 \"cdef\")", s, t);
$display("\n==========================================");
$display(" Demo completed.");
$display("==========================================");
$finish;
end
endmodule
6.2.2 预期仿真输出日志

6.2.4 注意事项
string索引从 0 开始(s[0]是第一个字符)。putc(i, c)修改索引i处的字符,索引超出范围会导致运行时错误。substr(i, j)提取从索引i到j(含两端)的子串。atoi()和atoreal()遇到非数字字符会停止转换,不会报错。$sformatf()是系统函数,返回格式化后的字符串,类似 C 的sprintf,仅用于仿真,不可综合。string类型不可综合,仅用于测试平台、验证环境。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)