SystemVerilog 3.1a语法速查手册:设计效率提升必学的10大技巧

发布时间: 2024-12-17 15:01:23 阅读量: 5 订阅数: 6
ZIP

SystemVerilog3.1a中文参考手册.zip

![SystemVerilog 3.1a语法速查手册:设计效率提升必学的10大技巧](https://img-blog.csdnimg.cn/49ff7f1d4d2e41338480e8657f0ebc32.png) 参考资源链接:[SystemVerilog 3.1a语言参考手册:PDF中文版详解与特性概览](https://wenku.csdn.net/doc/6412b73bbe7fbd1778d498e8?spm=1055.2635.3001.10343) # 1. SystemVerilog 3.1a基础语法入门 SystemVerilog是一种基于Verilog并对其进行了大量扩展的硬件描述和硬件验证语言,是目前主流的硬件验证语言之一。在学习SystemVerilog之前,我们需要了解其基础语法,这是理解后续高级特性的基石。 ## 1.1 SystemVerilog的变量和常量 在SystemVerilog中,变量和常量的声明与Verilog类似,但增加了更多数据类型支持。基本变量类型如`bit`和`logic`可以用来表示二进制值。常量可以通过关键字`parameter`或者`localparam`定义,并且可以被指定为常量函数。 例如,声明一个8位宽的逻辑变量可以使用以下语法: ```systemverilog logic [7:0] my_variable; ``` ## 1.2 SystemVerilog的模块和端口 SystemVerilog的模块和Verilog非常相似,提供了模块化设计的能力。模块可以定义输入、输出或者双向端口。对于端口的定义,SystemVerilog支持更灵活的命名方式。 ```systemverilog module my_module(input logic clk, input logic [3:0] data_in, output logic [7:0] data_out); // 模块的内部逻辑 endmodule ``` 在这个模块定义中,`clk`、`data_in`和`data_out`是端口列表中的元素,它们被指定为模块的输入或输出。 ## 1.3 SystemVerilog的注释和可综合性提示 SystemVerilog允许使用`//`和`/* */`两种类型的注释,这和许多其他编程语言相同。这使得代码更加易于阅读和维护。此外,SystemVerilog还引入了可综合性提示(synthesis directive),这对于编写可综合设计尤为重要。 例如,使用`// synthesis translate_off`可以关闭某个代码段的综合: ```systemverilog // synthesis translate_off always_comb begin // 这部分代码将不会被综合 end // synthesis translate_on ``` 在以上基础语法介绍后,我们将进一步探索SystemVerilog的编程技巧、数据类型、类、断言和约束等高级特性,以及其在设计验证中的应用。本章将为读者铺平学习SystemVerilog的路,帮助你快速入门并深入理解这一强大的硬件验证语言。 # 2. SystemVerilog编程技巧之数据类型和操作 ### 2.1 SystemVerilog的数据类型 #### 2.1.1 简单数据类型 SystemVerilog中,简单数据类型包括了基本的整数、实数以及布尔类型,它们是构建更复杂数据结构的基础。整数类型主要分为有符号和无符号两类,通过不同的关键字如`int`, `logic`等来声明。这些基本类型用于执行算术运算以及逻辑运算。 ```sv int signedVar; // 有符号整数类型 logic unsignedVar; // 无符号逻辑类型 real realVar; // 实数类型 ``` 逻辑类型`logic`在SystemVerilog中占据了重要位置,它不仅能表示传统的二进制值0和1,还能表示X(不确定值)和Z(高阻值),非常适合硬件描述和仿真。 #### 2.1.2 复杂数据类型 在硬件设计和验证中,经常需要使用复杂的数据类型来表示大规模的信号和数据结构。SystemVerilog提供了如向量和数组等复杂数据类型,可以有效地对这些数据进行操作和管理。 ```sv bit [7:0] byteVar; // 8位宽的位向量 int arrayVar[10]; // 10元素的整数数组 ``` 向量可以表示为位串,支持位运算和位选择操作,非常适合处理并行数据。数组则可以用来存储大量相同类型的数据元素,并且可以是一维或多维的。数组的声明和操作在处理数据集合时提供了便利。 ### 2.2 SystemVerilog的操作符和表达式 #### 2.2.1 常用操作符 SystemVerilog不仅继承了传统编程语言中的操作符,如算术运算符、关系运算符、逻辑运算符和位运算符,还加入了用于硬件设计特有的操作符,比如拼接、缩放和选择操作符。这些操作符使硬件描述和验证的表达更加直观和精确。 ```sv int a, b, sum; a = 5; b = 3; sum = a + b; // 算术加法操作符 ``` #### 2.2.2 表达式与优先级 在SystemVerilog中,表达式的计算遵循特定的优先级规则。算术运算符具有最高优先级,其次是关系和逻辑运算符,最后是位运算符。在实际应用中,合理地使用括号可以明确操作的顺序,防止优先级导致的逻辑错误。 ```sv int result; result = (a + b) * c + (d & e); // 使用括号明确计算顺序 ``` ### 2.3 SystemVerilog的数组和队列 #### 2.3.1 数组的声明与使用 数组在SystemVerilog中用来存储同一类型的一系列数据。SystemVerilog支持静态数组和动态数组,以及队列等复合数据类型。这些数组类型为设计复杂硬件结构提供了便利。 ```sv int staticArray[10]; // 静态数组 int dynamicArray[]; // 动态数组,默认为空 int queue[$]; // 队列,可以动态增长或缩减 ``` 动态数组和队列类型是在仿真过程中特别有用的类型,它们可以根据需要动态地分配和回收内存空间。 #### 2.3.2 队列的操作和应用 队列是一种特殊的数组类型,允许数据的先进先出(FIFO)操作。在硬件设计的仿真测试中,队列可以被用于缓冲数据流,例如验证数据缓冲区的行为。 ```sv int queue[$]; // 向队列添加元素 queue.push_back(10); queue.push_back(20); // 从队列中取出元素 int poppedValue = queue.pop_front(); ``` 队列的操作包括了`push_back()`和`pop_front()`等方法,可以方便地在队列的尾部添加元素或在队列头部删除元素。这一功能在仿真过程中对于管理数据流和测试缓冲区非常有用。 通过本章节的介绍,读者可以对SystemVerilog的基本数据类型和操作有了基础的了解,为深入掌握SystemVerilog编程技巧奠定了良好的基础。接下来的章节将带领读者探索类与对象的概念,以及它们在SystemVerilog中的应用。 # 3. SystemVerilog编程技巧之类与对象 ## 3.1 SystemVerilog类的定义和使用 ### 3.1.1 类的声明和实例化 在SystemVerilog中,类是一种复杂数据类型,用于封装数据和操作数据的方法。类的声明类似于其他面向对象编程语言,可以包含属性(数据成员)和方法(成员函数)。类的实例化是指在系统中创建类的对象。 ```systemverilog class Point; int x, y; function new(int xval, int yval); x = xval; y = yval; endfunction function void display(); $display("Point(%0d, %0d)", x, y); endfunction endclass module test_class; initial begin Point p1 = new(10, 20); // 实例化对象p1 p1.display(); // 调用对象的方法 end endmodule ``` #### 参数解释: - `class Point;` 定义一个名为Point的类。 - `int x, y;` 定义了两个属性,用于存储x和y坐标。 - `function new(int xval, int yval);` 定义了一个名为new的构造函数,用于初始化对象。 - `function void display();` 定义了一个名为display的方法,用于显示点的坐标。 - `Point p1 = new(10, 20);` 创建一个名为p1的Point类对象,并调用构造函数初始化。 ### 3.1.2 类的构造函数和析构函数 SystemVerilog支持类的构造函数和析构函数,分别用于初始化和销毁对象。 ```systemverilog class ComplexNumber; real part1, part2; function new(real p1, real p2); part1 = p1; part2 = p2; endfunction function void display(); $display("Complex number: %0.2f + %0.2fi", part1, part2); endfunction function void delete(); $display("Deleting ComplexNumber object"); endfunction endclass module test_constructor_destructor; initial begin ComplexNumber cn1 = new(2.5, 3.7); cn1.display(); // 在这里会自动调用delete()函数来释放对象 end endmodule ``` #### 参数解释: - `function new(real p1, real p2);` 这是一个构造函数,用于创建ComplexNumber对象并初始化它的两个部分。 - `function void delete();` 这是一个析构函数,它会在对象不再被使用时自动调用,用于执行清理工作。 ## 3.2 SystemVerilog的继承和多态 ### 3.2.1 继承的概念和语法 继承允许创建一个类(派生类)来继承另一个类(基类)的属性和方法。SystemVerilog支持单继承,并允许使用`extends`关键字来实现。 ```systemverilog class Shape; int width, height; function void display(); $display("Width: %0d, Height: %0d", width, height); endfunction endclass class Rectangle extends Shape; int length; function new(int w, int h, int l); super.new(w, h); // 调用基类构造函数 length = l; endfunction function void display(); // 重写基类display方法 $display("Rectangle: Width: %0d, Height: %0d, Length: %0d", width, height, length); endfunction endclass module test_inheritance; initial begin Rectangle rect = new(10, 20, 30); rect.display(); // 调用Rectangle重写的display方法 end endmodule ``` #### 参数解释: - `class Rectangle extends Shape;` 创建一个名为Rectangle的类,它继承自Shape类。 - `function new(int w, int h, int l);` Rectangle类的构造函数,它不仅初始化自己的属性,还通过`super.new(w, h);`调用基类的构造函数。 - `function void display();` Rectangle类重写了Shape类的display方法。 ### 3.2.2 多态的实现和应用 多态允许不同类的对象以统一的方式被处理。在SystemVerilog中,多态是通过覆盖基类方法实现的。 ```systemverilog class Animal; virtual function void makeSound(); $display("Animal makes a sound"); endfunction endclass class Dog extends Animal; function void makeSound(); // 覆盖基类的方法 $display("Dog barks"); endfunction endclass class Cat extends Animal; function void makeSound(); // 覆盖基类的方法 $display("Cat meows"); endfunction endclass module test_polymorphism; Animal myAnimal; myAnimal = new Dog(); // 多态赋值 myAnimal.makeSound(); // 调用Dog的makeSound方法 myAnimal = new Cat(); myAnimal.makeSound(); // 调用Cat的makeSound方法 endmodule ``` #### 参数解释: - `virtual function void makeSound();` 在Animal基类中声明makeSound为虚拟方法。 - `function void makeSound();` 在Dog和Cat类中覆盖基类的makeSound方法。 - `myAnimal = new Dog();` 在这里,我们对Animal类型的指针进行多态赋值,从而可以通过这个指针调用相应子类的方法。 ## 3.3 SystemVerilog的封装和访问控制 ### 3.3.1 封装的原理和实现 封装是将数据和操作数据的代码捆绑在一起,并且隐藏对象的实现细节,只通过接口来暴露操作。在SystemVerilog中,通过类和访问修饰符来实现封装。 ```systemverilog class Vehicle; protected int speed; // 仅类内部可见 function void setSpeed(int s); speed = s; endfunction function int getSpeed(); return speed; endfunction endclass class Car extends Vehicle; function void displaySpeed(); $display("Car speed: %0d", getSpeed()); endfunction endclass module test_encapsulation; Car myCar = new(); myCar.setSpeed(60); myCar.displaySpeed(); // 输出汽车的速度 endmodule ``` #### 参数解释: - `protected int speed;` 在这里,speed是被保护的,只能在Vehicle类及其子类中被访问。 - `function void setSpeed(int s);` 提供了一个公共接口来设置速度。 - `function int getSpeed();` 提供了一个公共接口来获取速度。 ### 3.3.2 访问控制的关键字和用法 SystemVerilog提供了多个访问控制关键字,如`public`, `protected`, `private`,以及新的访问级别`local`,用于控制类成员的访问范围。 ```systemverilog class BankAccount; private int balance = 0; // 私有属性,仅类内部可见 function new(input int initialBalance); if (initialBalance > 0) balance = initialBalance; else $display("Invalid balance."); endfunction function void deposit(input int amount); if (amount > 0) balance = balance + amount; else $display("Invalid deposit amount."); endfunction function int getBalance(); return balance; endfunction endclass module test_access_control; BankAccount myAccount = new(1000); $display("Account balance: %0d", myAccount.getBalance()); // 可访问,因为getBalance是public endmodule ``` #### 参数解释: - `private int balance = 0;` balance属性被声明为私有,无法从类外部访问,确保封装性。 - `function new(input int initialBalance);` 类的构造函数是公开的,允许外部创建对象。 - `function void deposit(input int amount);` deposit方法是公开的,允许外部增加余额。 - `function int getBalance();` getBalance方法是公开的,允许外部查询余额。 通过访问控制关键字和类的使用,SystemVerilog允许设计者创建出既灵活又具有强内聚性的代码结构,这对于大型系统设计验证来说,是至关重要的。 # 4. SystemVerilog编程技巧之断言和约束 SystemVerilog 不仅在数据类型和类结构上提供了强大的支持,而且在验证方面也引入了断言和约束这两个关键特性。这些特性极大地提高了设计验证的效率和质量。本章节将深入探讨 SystemVerilog 中断言和约束的使用方法,帮助读者更好地理解和掌握这些高级编程技巧。 ## 4.1 SystemVerilog断言的使用 ### 4.1.1 顺序断言 顺序断言主要用于检查信号在一系列时间点上的行为。它们对于检查复杂的协议规范特别有用。SystemVerilog 的顺序断言可以分为两种:`assert` 和 `assume`。 以下是一个使用 `assert` 序列的例子: ```systemverilog module seq_assertions_example; logic clk; logic reset; logic [3:0] data; logic valid; always #5 clk = ~clk; initial begin clk = 0; reset = 1; #10 reset = 0; #100; $finish; end // Sequence assertion property p_valid_data; @(posedge clk) not reset |=> ##[10:20] valid ##[0:10] data == 4'b1010; endproperty assert property (p_valid_data) $display("Valid data sequence passed."); else $display("Valid data sequence failed."); endmodule ``` 在这个例子中,`p_valid_data` 定义了一个属性,要求在 `reset` 变为低电平后,`valid` 信号在接下来的 10 到 20 个时钟周期内保持高电平,然后 `data` 信号必须在接下来的 0 到 10 个时钟周期内等于 `4'b1010`。 ### 4.1.2 并行断言 并行断言(也称为立即断言)不考虑时间序列,它在单个仿真周期内进行检查,类似于布尔表达式。 以下是一个使用 `assert` 语句的例子: ```systemverilog property p_parallel_assertion; logic [3:0] a, b, c; @ (posedge clk) disable iff (reset) (a == 4'b1010) && (b == 4'b0101) |-> c == 4'b1111; endproperty assert property (p_parallel_assertion) else $error("Parallel assertion failed."); ``` 这个例子中的断言会在每个时钟上升沿检查,如果 `a` 等于 `4'b1010` 且 `b` 等于 `4'b0101`,那么 `c` 必须等于 `4'b1111`。 ## 4.2 SystemVerilog约束的编写和应用 ### 4.2.1 约束的基本语法 约束用于在仿真中生成具有特定属性的随机数据。SystemVerilog 提供了 `constraint` 关键字来定义变量应该如何被约束。 ```systemverilog class packet; rand bit [3:0] addr; rand bit [7:0] data; constraint c_addr { addr > 4; // 地址范围是 5 到 15 } constraint c_data { soft data inside {[0:127]}; } endclass module constraint_example; packet p; initial begin p = new(); p.randomize(); $display("Address: %0d, Data: %0d", p.addr, p.data); end endmodule ``` 在这个例子中,`packet` 类有两个随机变量 `addr` 和 `data`。`c_addr` 约束确保 `addr` 大于 4,而 `c_data` 约束软约束 `data` 的值在 0 到 127 之间。 ### 4.2.2 高级约束技术 SystemVerilog 的约束系统非常灵活,支持使用更复杂的约束表达式和约束优先级控制。 ```systemverilog constraint c_addr_weighted { addr dist {5:=1, 6:=2, [7:10]:=3}; } ``` 上面的约束使用了分布语法,以不同的权重赋予 `addr` 某些值。 SystemVerilog 的约束还可以通过优先级控制来处理更复杂的情况: ```systemverilog constraint c_priority { addr < 10 -> data < 64; addr == 6 -> data == 32; } ``` 在这个例子中,如果 `addr` 小于 10,则 `data` 必须小于 64。但如果 `addr` 等于 6,则 `data` 必须等于 32,这表示后者具有更高的优先级。 通过使用这些高级技术,设计者可以创建复杂的、具有丰富约束条件的测试用例,从而更有效地发现设计中的问题。 通过本章节的介绍,我们已经深入探讨了 SystemVerilog 断言和约束的基本概念和应用。这些工具是现代设计验证不可或缺的一部分,掌握它们将大大提升验证工程师在项目中的效率和效果。 # 5. SystemVerilog在设计验证中的实践应用 随着设计验证领域的不断进步,SystemVerilog已经成为该领域内不可或缺的工具。本章节将深入探讨SystemVerilog在设计验证中的实践应用,揭示其在测试平台开发、覆盖率分析及仿真调试中的关键作用。 ## 5.1 SystemVerilog的测试平台开发 测试平台开发是验证过程的核心,它确保设计符合规格要求。SystemVerilog通过其丰富的测试结构和功能支持复杂测试平台的快速构建。 ### 5.1.1 测试用例的编写 在测试平台开发中,测试用例是基本单元。SystemVerilog提供了一套完整的测试用例编写机制,包括以下关键元素: - 测试模块:包含`initial`和`always`块,用于初始化和产生激励。 - 功能覆盖率:通过检查不同场景下设计行为,保证设计的正确性。 - 断言:用于验证设计的预期行为。 **示例代码**展示了一个简单的测试用例: ```systemverilog module testbench; // 设计的实例化 dut my_dut(...); // 测试序列 initial begin // 初始化信号 // ... // 循环或条件测试序列 for (int i = 0; i < 10; i++) begin // 产生激励 // ... #10; // 等待一段时间 end // 测试结束 $finish; end // 功能覆盖率点定义 covergroup my_coverage; option.per_instance = 1; cg_item: coverpoint my_dut.item; cg_data: coverpoint my_dut.data; endgroup initial begin my_coverage = new(); forever begin // 通过驱动信号收集覆盖率 // ... #10; my_coverage.sample(); end end endmodule ``` ### 5.1.2 测试环境的搭建和配置 测试环境的搭建通常包括测试激励的生成、响应检查、数据记录等。配置部分通常涉及对测试用例的参数化处理,以便在不同的条件下重复使用。 **参数化测试用例**可以借助SystemVerilog的宏定义、参数、或`rand`/`randc`随机变量来实现,以适应不同的测试场景。 ## 5.2 SystemVerilog的功能覆盖率分析 覆盖率分析是验证过程中不可或缺的一部分,它帮助验证工程师理解测试用例是否充分。SystemVerilog提供了覆盖率分析的支持,包括多种覆盖率类型。 ### 5.2.1 覆盖率类型的介绍 SystemVerilog定义了几种覆盖率类型,其中包括: - 代码覆盖率:包括语句覆盖率、条件覆盖率、分支覆盖率等。 - 功能覆盖率:基于设计特性的覆盖率,如状态机状态、数据范围等。 功能覆盖率的定义和收集通常在测试平台的`covergroup`块中进行。上面的示例代码中已经定义了一个简单的功能覆盖率。 ### 5.2.2 覆盖率收集和报告 在仿真执行过程中,通过SystemVerilog的覆盖率收集命令,可实现对覆盖率数据的实时追踪和分析。最终生成的覆盖率报告,将为评估测试质量和指导后续测试提供依据。 ## 5.3 SystemVerilog的仿真和调试 仿真和调试是验证过程中保证设计正确性的最后环节。SystemVerilog提供了强大的仿真控制命令和调试工具,以便快速定位和解决问题。 ### 5.3.1 仿真控制命令 SystemVerilog提供了一整套仿真控制命令,用于控制仿真进程、查看波形和信号值等,如`$stop`、`$monitor`、`$dumpfile`和`$dumpvars`等。 ### 5.3.2 调试技巧和工具使用 SystemVerilog的调试工具包括波形查看器、代码覆盖率分析器、断言检查器等。通过这些工具,验证工程师能够有效分析和诊断问题。 此外,SystemVerilog还支持在线调试和波形录制回放功能。例如,使用`$display`和`$write`等系统任务来输出信号值,或使用`$fopen`和`$fwrite`进行日志记录。 SystemVerilog在设计验证中的实践应用,不仅涵盖以上所述的测试平台开发、功能覆盖率分析和仿真调试等方面,还包括诸如断言和约束的高级使用、UVM(Universal Verification Methodology)等验证方法学的深入应用,这些将在后续章节中进行详细讨论。随着技术的不断发展,SystemVerilog的验证方法和实践将更加多样化,为数字设计的验证提供强有力的支撑。
corwn 最低0.47元/天 解锁专栏
买1年送1年
点击查看下一篇
profit 百万级 高质量VIP文章无限畅学
profit 千万级 优质资源任意下载
profit C知道 免费提问 ( 生成式Al产品 )

相关推荐

SW_孙维

开发技术专家
知名科技公司工程师,开发技术领域拥有丰富的工作经验和专业知识。曾负责设计和开发多个复杂的软件系统,涉及到大规模数据处理、分布式系统和高性能计算等方面。

专栏目录

最低0.47元/天 解锁专栏
买1年送1年
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
C知道 免费提问 ( 生成式Al产品 )

最新推荐

深入理解TeX格式化算法:掌握布局之美,用The TeXbook提升专业技能

![深入理解TeX格式化算法:掌握布局之美,用The TeXbook提升专业技能](https://www.learnui.design/img/font-alternatives/inter-vs-helvetica.png) 参考资源链接:[ LaTeX 进阶指南:《The TeXbook》中文译本](https://wenku.csdn.net/doc/6v72jsqjkt?spm=1055.2635.3001.10343) # 1. TeX格式化算法概述 TeX是一种功能强大的排版系统,由高德纳教授于1978年设计,旨在生成高质量的印刷文档。其核心是一个复杂的格式化算法,它能够将文

【双编码器同步技术揭秘】:如何在西门子S120中实现第二编码器完美同步

![【双编码器同步技术揭秘】:如何在西门子S120中实现第二编码器完美同步](https://res.cloudinary.com/rsc/image/upload/b_rgb:FFFFFF,c_pad,dpr_2.625,f_auto,h_214,q_auto,w_380/c_pad,h_214,w_380/Y2434009-01?pgw=1) 参考资源链接:[西门子S120伺服驱动器配置第二编码器指南](https://wenku.csdn.net/doc/6412b6babe7fbd1778d47c30?spm=1055.2635.3001.10343) # 1. 双编码器同步技术概述

高级技巧揭秘,让你的小程序播放器更上一层楼

![微信小程序使用 video 组件播放视频功能示例](https://developer.qcloudimg.com/http-save/yehe-1069749/0437854fb462a9e10a6a6de4c09dbb8e.jpg) 参考资源链接:[微信小程序使用video组件播放视频功能示例【附源码下载】](https://wenku.csdn.net/doc/6401ad31cce7214c316eea18?spm=1055.2635.3001.10343) # 1. 小程序播放器基础与优化原理 在数字化时代,用户对于内容消费的需求日益增长,视频作为最具吸引力的媒体形式之一,其

【新手必备】DMU遗传评估软件:全面入门指南与功能解析

![【新手必备】DMU遗传评估软件:全面入门指南与功能解析](https://www.mugansbiologypage.com/images/genetics_simulation_software.bmp) 参考资源链接:[DMU遗传评估软件使用指南](https://wenku.csdn.net/doc/7g8ic3wzdu?spm=1055.2635.3001.10343) # 1. DMU遗传评估软件概述 ## 1.1 DMU遗传评估软件简介 DMU软件是一款专业化的遗传评估工具,用于动物种群遗传性能的评估与分析。其具有强大的数据处理能力、精确的计算精度以及用户友好的操作界面,旨

【数据中心节能新武器】:DELL T7920技术革新的秘密

参考资源链接:[DELL T7920的节能证书 CQC20701240525(1).pdf](https://wenku.csdn.net/doc/6401ac16cce7214c316ea964?spm=1055.2635.3001.10343) # 1. 数据中心能耗现状与挑战 随着信息技术的飞速发展,数据中心已成为现代社会不可或缺的基础设施。然而,数据中心的能耗问题也日益凸显,成为业界关注的焦点。数据中心的能耗不仅关乎运行成本,还直接影响环境可持续性。当前数据中心的能耗现状表现为高能耗和低效率,这主要是由于庞大的设备数量、连续运行需求、以及缺乏高效的能源管理系统。在这一背景下,数据中心

Advanced Installer进阶手册:零基础到专家的全方位路径

![Advanced Installer进阶手册:零基础到专家的全方位路径](https://opengraph.githubassets.com/172d1aaddca7074a97eeb194a060ccc1f33f33398b8d8347cd65aef7293a2fa8/kurtanr/WiXInstallerExamples) 参考资源链接:[使用Advanced Installer将exe转换为MSI安装包](https://wenku.csdn.net/doc/3xzcmmxiby?spm=1055.2635.3001.10343) # 1. Advanced Installer

【BF7612CMXX-MCU通信协议与安全性集成】:UART、SPI、I2C配置与防护措施

![【BF7612CMXX-MCU通信协议与安全性集成】:UART、SPI、I2C配置与防护措施](https://prod-1251541497.cos.ap-guangzhou.myqcloud.com/zixun_pc/zixunimg/img4/o4YBAF9HfvWAG8tBAAB2SOeAXJM785.jpg) 参考资源链接:[BF7612CMXX:高速8051内核触控MCU规格详解](https://wenku.csdn.net/doc/6401ac02cce7214c316ea4bf?spm=1055.2635.3001.10343) # 1. MCU通信协议基础 在嵌入式

旅游者规划问题:云服务与边缘计算在旅游路线优化中的应用

![旅游者规划问题:云服务与边缘计算在旅游路线优化中的应用](https://ucc.alicdn.com/pic/developer-ecology/5cswve2ky2ieu_d4f9c3db8e6442599b834dccc535c628.png?x-oss-process=image/resize,s_500,m_lfit) 参考资源链接:[全国研究生数学建模竞赛:旅游路线规划研究](https://wenku.csdn.net/doc/7hy9qxikyu?spm=1055.2635.3001.10343) # 1. 旅游者规划问题概述 在当今快节奏的社会中,旅游者规划问题已经成

专栏目录

最低0.47元/天 解锁专栏
买1年送1年
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
C知道 免费提问 ( 生成式Al产品 )