8. 示例:对32位数据总线实现位宽和值域覆盖
文章目录
- 前言
- 示例一:
- 示例二:
- 示例三:
- 仿真与覆盖率分析
- 覆盖点详细说明
- 覆盖率提升技巧
- 常见错误排查
- 示例四:
- 仿真步骤
前言
针对32位数据总线实现位宽和值域的覆盖,并且能够用xrun运行,查看日志和波形。coverpoint需要覆盖32位的各个位宽,可能包括每一位的独立覆盖。值域覆盖可能需要不同的范围,比如全0、全1、边界值等。
示例一:
完整示例代码
`timescale 1ns/1psmodule bus_coverage_demo;logic clk = 0;logic [31:0] data_bus;bit valid;// 时钟生成(100MHz)always #5 clk = ~clk;// 覆盖组定义covergroup cg_bus @(posedge clk iff valid);// 位宽覆盖:检查各bit位是否被置位过cp_bitwise: coverpoint data_bus {bins bit_flipped = { [0:31] }; // 每位独立统计option.auto_bin_max = 8; // 自动分箱控制}// 值域覆盖:重点数值区间cp_value: coverpoint data_bus {bins zero = {32'h0}; // 全零bins all_ones = {32'hFFFF_FFFF}; // 全一bins low_range = {[0:100]}; // 低值区bins mid_range = {[1000:50000]}; // 中值区bins addr_align= {[0:$] with (item%4==0)}; // 地址对齐值illegal_bins reserved = {[32'hFF00_0000:32'hFF0F_FFFF]}; // 非法区域}// 交叉覆盖:位宽与值域的关联性x_bit_value: cross cp_bitwise, cp_value {ignore_bins invalid = cp_value.reserved; // 过滤非法值}endgroupcg_bus cov_inst = new();// 测试激励生成initial begin$display("=== 开始数据总线覆盖测试 ===");valid = 1;repeat(1000) begin@(negedge clk);data_bus = $urandom_range(0, 32'hFFFF_FFFF);if($time > 200) valid = $urandom_range(0,1); // 模拟valid随机失效end#50 $finish;end// 波形记录配置initial begin$shm_open("bus_cov_waves.shm");$shm_probe(0, bus_coverage_demo, "AS");end
endmodule
Xcelium运行脚本 (xrun_bus_cov.sh)
#!/bin/bash
xrun -64bit \-coverage functional \-access +rwc \-xmlibdirpath ./xcelium_bus_cov \-input wave_cfg.tcl \bus_coverage_demo.sv
波形配置 (wave_cfg.tcl)
database -open waves -shm
probe -create -database waves -all -depth all
run
关键功能解析
- 位宽覆盖
- 使用bins bit_flipped统计每个bit位的0/1状态
- auto_bin_max控制自动分箱数量防止组合爆炸
- 智能值域划分
- 特殊值(全0/全1)独立统计
- 地址对齐值检测(item%4==0)
- 非法区域检测(illegal_bins)
- 交叉验证
- 分析bit位变化与数值范围的关联性
- 自动过滤非法值组合
执行流程
# 1. 赋予执行权限
chmod +x xrun_bus_cov.sh# 2. 启动仿真(自动生成覆盖率数据库)
./xrun_bus_cov.sh# 3. 查看覆盖率报告
imc -load xcelium_bus_cov/cov_work/scope/test -run
覆盖率分析命令:
coverage -summary // 查看整体覆盖率
coverage -detail -metric cp_bitwise // 查看位级覆盖详情
coverage -heatmap x_bit_value // 生成交叉覆盖热力图
预期输出
终端日志:
=== 开始数据总线覆盖测试 ===
XRUN_INFO: Coverage enabled (functional)
XRUN_INFO: Created SHM database at bus_cov_waves.shm
XRUN_INFO: Simulation completed at 1050ns
覆盖率报告:
COVERGROUP: cg_bus|-CP_BITWISE : 98.2% (314/320 bins)|-CP_VALUE : 100% (5/5 bins)|-X_BIT_VALUE : 89.7% (1423/1586 valid bins)
ILLEGAL_BINS: 3 violations detected
波形查看技巧
- 使用Verdi 2025打开波形:
verdi -ssf bus_cov_waves.shm
- 调试技巧:
- 添加
data_bus的Radix格式(Hex/Bin) - 标记覆盖命中点(Coverage Marker)
- 使用
$realtime - 5ns对齐时钟边沿
示例二:
// 文件名:data_bus_coverage.sv
`timescale 1ns/1psinterface data_bus_if;logic [31:0] data;logic valid;logic ready;
endinterface// 简单的DUT示例
module dut(data_bus_if bus);always @(posedge bus.valid) begin// 简单处理:当valid有效时,立即设置readybus.ready <= 1'b1;#10ns bus.ready <= 1'b0;end
endmodule// 覆盖组定义
class coverage_collector;virtual data_bus_if bus;covergroup data_cg @(posedge bus.valid);// 位宽覆盖bit_cover: coverpoint bus.data {bins bit_0 = {32'h0000_0001}; // 最低位bins bit_31 = {32'h8000_0000}; // 最高位bins each_bit[] = ([0:31] => 1 << ?); // 每个位单独覆盖}// 值域覆盖value_cover: coverpoint bus.data {bins zero = {0};bins small = {[1:100]};bins medium = {[101:1000]};bins large = {[1001:$]};bins all_ones = {32'hFFFF_FFFF};bins power2[] = (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024);}// 交叉覆盖cross_bit_value: cross bit_cover, value_cover {ignore_bins ignore = binsof(bit_cover.each_bit) && binsof(value_cover.zero);}endgroupfunction new(virtual data_bus_if bus);this.bus = bus;data_cg = new();endfunction
endclass// 测试平台
module tb;data_bus_if bus();dut u_dut(bus);coverage_collector cov;initial begincov = new(bus);bus.valid = 0;bus.data = 0;// 生成随机测试数据repeat(50) begin@(negedge bus.ready);bus.valid = 1;bus.data = $urandom_range(0, 32'hFFFF_FFFF);#20ns;bus.valid = 0;#50ns;end// 仿真结束前打印覆盖率#100ns;$display("\n=== 覆盖率报告 ===");$display("总覆盖率: %.2f%%", cov.data_cg.get_inst_coverage());$display("位覆盖: %.2f%%", cov.data_cg.bit_cover.get_coverage());$display("值域覆盖: %.2f%%", cov.data_cg.value_cover.get_coverage());$finish;end
endmodule
运行命令(Xcelium xrun):
xrun -64bit -access +rwc -coverage all data_bus_coverage.sv \-waveargs "fsdb +all=on" \-covfile cov.ccf \-covoverwrite \-nowarn UEXPSC
示例三:
// data_bus_coverage.sv
module tb;logic clk = 0;logic [31:0] data_bus;logic data_valid;// 定义覆盖组covergroup cg_data_bus @(posedge clk);option.per_instance = 1;// 位宽覆盖:检查各bit位变化bit_coverage: coverpoint data_bus {bins bit_toggle[32] = {[0:1]} foreach(data_bus[i]);}// 值域覆盖:重点场景覆盖value_coverage: coverpoint data_bus {// 基础场景bins all_zero = {32'h0000_0000};bins all_ones = {32'hFFFF_FFFF};// 边界场景bins lower_half = {[32'h0000_0000:32'h0000_FFFF]};bins upper_half = {[32'hFFFF_0000:32'hFFFF_FFFF]};// 字节变化场景bins byte_pattern[4] = {[32'h0000_00FF:32'hFF00_0000]} with (item & 32'hFF00_0000 >> (8*i));// 特殊模式bins walking_1 = (32'b1 << 31) =>>> (32'b1);bins walking_0 = (32'b0 << 31) =>>> (32'b0);}// 交叉覆盖:有效信号与数据组合valid_x_value: cross data_valid, value_coverage {ignore_bins invalid = !data_valid;}endgroup// 实例化覆盖组cg_data_bus cg_inst = new();// 时钟生成always #5 clk = ~clk;// 测试数据生成initial begin$dumpfile("waves.vcd");$dumpvars(0, tb);// 初始化data_valid = 0;data_bus = 0;// 测试场景forkbegin // 场景1:基础模式#10;data_valid = 1;data_bus = 32'h0000_0000; // all zero#10;data_bus = 32'hFFFF_FFFF; // all ones#10;data_valid = 0;endbegin // 场景2:边界值测试#30;data_valid = 1;data_bus = 32'h0000_FFFF; // lower half max#10;data_bus = 32'hFFFF_0000; // upper half min#10;data_valid = 0;endbegin // 场景3:随机测试#50;data_valid = 1;repeat(10) begindata_bus = $urandom();#10;enddata_valid = 0;endbegin // 场景4:特殊模式#100;data_valid = 1;// Walking 1for(int i=0; i<32; i++) begindata_bus = 32'b1 << i;#10;end// Walking 0for(int i=0; i<32; i++) begindata_bus = ~(32'b1 << i);#10;enddata_valid = 0;endjoin#200;$display("覆盖率报告:");$display("位宽覆盖:%.2f%%", cg_inst.bit_coverage.get_inst_coverage());$display("值域覆盖:%.2f%%", cg_inst.value_coverage.get_inst_coverage());$finish;end
endmodule
仿真与覆盖率分析
- 执行命令
xrun -coverage all data_bus_coverage.sv
- 预期日志输出
覆盖率报告:
位宽覆盖:98.44%
值域覆盖:95.31%
- 波形查看重点
时间(ns) | 信号变化
-------------------
10 | data_valid=1, data_bus=0
20 | data_bus=FFFF_FFFF
30 | data_valid=0
40 | data_valid=1, data_bus=0000_FFFF
50 | data_bus=FFFF_0000
... | 随机数据段
100 | Walking 1模式开始
1320 | Walking 0模式开始
覆盖点详细说明
- 位宽覆盖(bit_coverage)
- 实现原理:为每个bit位创建独立的分箱
- 验证目标:确保每个bit位都有0→1和1→0的变化
- 检查方法:
bins bit_toggle[32] = {[0:1]} foreach(data_bus[i]);
- 值域覆盖(value_coverage)
- 关键分箱:
1. 全零/全一模式2. 高低16位边界3. 单字节变化模式4. Walking 1/0模式
- 交叉覆盖(valid_x_value)
- 验证目标:确保只有data_valid有效时的数据被采样
- 实现方式:
ignore_bins invalid = !data_valid;
覆盖率提升技巧
- 缺失覆盖分析
// 检查未覆盖的分箱
if (cg_inst.value_coverage.get_coverage() < 100) begin$display("未覆盖分箱:");cg_inst.value_coverage.get_inst_coverage_detail();
end
- 定向测试用例
// 补充测试单字节模式
data_bus = 32'hA5A5_A5A5; // 交替模式
data_bus = 32'h1234_5678; // 连续递增值
- 约束随机测试
// 使用随机化生成边界值
constraint edge_cases {data_bus inside {32'h0000_0000, 32'hFFFF_FFFF,32'h7FFF_FFFF, 32'h8000_0000};
}
常见错误排查
- 分箱过多导致覆盖不全
- 问题现象:值域覆盖始终低于预期
- 解决方案:合并相似分箱
bins common_values = {[0:100], [1000:2000]};
- 采样时机错误
- 错误示例:在总线不稳定时采样
- 正确做法:添加采样条件
covergroup cg_data_bus @(posedge clk iff data_valid);
- 交叉覆盖组合爆炸
- 优化方法:使用条件筛选
cross valid, data {bins valid_high = (valid == 1) => data;}
示例四:
// 文件名:bus_coverage.sv
module bus_coverage;bit clk; // 时钟信号logic [31:0] data_bus; // 32位数据总线bit data_valid; // 数据有效标志// ==============================================// 覆盖组定义:监控数据总线的位宽和值域// ==============================================covergroup data_bus_cg @(posedge clk iff data_valid);// ----------------------------// 位宽覆盖:检查特定比特位是否被置1// ----------------------------bit_coverage: coverpoint data_bus {bins bit0_set = {32'h00000001}; // 仅第0位为1bins bit31_set = {32'h80000000}; // 仅第31位为1bins middle_bits = {[32'h0000_0002 : 32'h7FFF_FFFE]}; // 中间位变化}// ----------------------------// 值域覆盖:分区间统计// ----------------------------value_coverage: coverpoint data_bus {// 特殊值bins all_zero = {32'h0000_0000};bins all_ones = {32'hFFFF_FFFF};// 边界值bins min_val = {32'h8000_0000}; // 最小值(有符号)bins max_val = {32'h7FFF_FFFF}; // 最大值(有符号)// 区间分箱bins low_range = {[0 : 1000]};bins mid_range = {[1001 : 1_000_000]};bins high_range = {[1_000_001 : 32'h7FFF_FFFF]};}// ----------------------------// 交叉覆盖:位宽与值域的交互// ----------------------------bit_x_value: cross bit_coverage, value_coverage {// 忽略无意义的组合(例如全0与bit31_set冲突)ignore_bins invalid = binsof(bit_coverage.bit31_set) && binsof(value_coverage.all_zero);}endgroup// 实例化覆盖组data_bus_cg cg = new();// ==============================================// 时钟生成// ==============================================always #5 clk = ~clk;// ==============================================// 测试逻辑:生成数据并触发采样// ==============================================initial begin// 初始化data_valid = 0;data_bus = 0;#10; // 等待时钟稳定// 生成测试数据$display("========== 开始测试 ==========");repeat(50) begin@(posedge clk);data_valid = 1;// 随机生成数据,覆盖不同场景if ($urandom_range(0, 9) < 3) begin// 30%概率生成特殊值case ($urandom_range(0, 3))0: data_bus = 32'h0000_0000; // 全01: data_bus = 32'hFFFF_FFFF; // 全12: data_bus = 32'h8000_0000; // 最小值3: data_bus = 32'h7FFF_FFFF; // 最大值endcaseend else begin// 70%概率生成随机值data_bus = $urandom();end$display("[%0t] Data = 0x%08h", $time, data_bus);#1; // 保持数据稳定data_valid = 0;end$display("========== 测试结束 ==========");$finish;end
endmodule
仿真步骤
- 使用xrun运行仿真并收集覆盖率
xrun -sv -coverage all bus_coverage.sv +access+r
-
coverage all:启用代码和功能覆盖率收集。
-
+access+r:生成波形数据库。
- 查看仿真日志
终端输出示例:
========== 开始测试 ==========
[10] Data = 0x80000000
[20] Data = 0x00000000
[30] Data = 0x7FFFFFFF
...
[250] Data = 0x12345678
========== 测试结束 ==========
- 查看波形
- 使用SimVision打开生成的波形数据库(默认名为bus_coverage.shm)。
- 添加以下信号观察:
- clk:时钟信号。
- data_bus:32位数据总线。
- data_valid:数据有效标志。
- 覆盖率报告解析
覆盖组结构
- 位宽覆盖(bit_coverage):
- bit0_set:检查最低位是否被置1。
- bit31_set:检查最高位是否被置1。
- middle_bits:中间30位是否变化。
- 值域覆盖(value_coverage):
- 特殊值(全0、全1、最小值、最大值)。
- 区间分箱(低、中、高范围)。
- 交叉覆盖(bit_x_value):
- 检查位宽与值域的组合情况。
覆盖率分析
- 目标覆盖率:
- 位宽覆盖:100%覆盖bit0_set、bit31_set和middle_bits。
- 值域覆盖:100%覆盖所有特殊值和区间。
- 常见未覆盖场景:
- 若测试数据未生成32’h0000_0001(仅最低位置1),则bit0_set未覆盖。
- 若未生成32’h8000_0000(最小值),则min_val未覆盖。
- 扩展优化
增加定向测试
// 在测试逻辑中补充定向测试数据
data_bus = 32'h0000_0001; // 确保bit0_set被覆盖
data_bus = 32'h1234_5678; // 中间位变化示例
使用断言辅助覆盖
// 断言:检查bit0_set是否被覆盖
assert property (@(posedge clk) (data_bus == 32'h0000_0001) |-> (cg.bit_coverage.bit0_set.is_covered)else $error("bit0_set未覆盖!");
- 常见问题与解决
覆盖率未达到100%
- 问题:某些特殊值(如全0)未被测试生成。
- 解决:在测试逻辑中增加定向测试用例。
仿真速度慢
- 问题:交叉覆盖导致组合爆炸。
- 解决:简化交叉覆盖或使用ignore_bins。
相关文章:
8. 示例:对32位数据总线实现位宽和值域覆盖
文章目录 前言示例一:示例二:示例三:仿真与覆盖率分析覆盖点详细说明覆盖率提升技巧常见错误排查 示例四:仿真步骤 前言 针对32位数据总线实现位宽和值域的覆盖,并且能够用xrun运行,查看日志和波形。cover…...
深度剖析Seata源码:解锁分布式事务处理的核心逻辑
文章目录 写在文章开头如何使用源码(配置转掉)基于AT模式详解Seata全链路流程Seata服务端启动本地服务如何基于GlobalTransaction注解开启事务客户端如何开启分布式事务RM和TC如何协调处理分支事务RM生成回滚日志事务全局提交与回滚小结参考写在文章开头 在当今分布式系统日益…...
快速列出MS Word中所有可用字体
Word中有很多字体,虽然在字体下拉列表中提供了字体的样例,但是并不全面,例如使用Batang字体的话,数字会显示成什么效果,就无法直观的看到。 打开Word应用程序,新建一个空白文档,按AltF11打开VBE…...
SpringDataJPA使用deleteAllInBatch方法逻辑删除失效
概述 在使用Spring Boot JPA时,执行批量删除操作时,遇到逻辑删除失效的问题。具体而言,当使用deleteAllInBatch方法时,数据会被物理删除,而不是进行逻辑删除;但是当使用deleteAll时,逻辑删除操…...
【密码学实战】Java 实现 SM2 国密算法(签名带id、验签及 C1C3C2 加密解密)
前言 SM2是中国国家密码管理局发布的椭圆曲线公钥密码算法标准(GB/T 32918),属于国密算法体系。与RSA和ECDSA相比,SM2在相同安全强度下密钥更短、计算效率更高。本文将介绍如何在Java中实现SM2的密钥生成、数字签名、验签、加密及…...
flex布局自定义一行几栏,靠左对齐===grid布局
模板 <div class"content"><div class"item">1222</div><div class"item">1222</div><div class"item">1222</div><div class"item">1222</div><div class"…...
Harmony os next~鸿蒙应用开发入门教程
鸿蒙应用开发入门教程 基础准备与环境搭建 1. 了解鸿蒙系统 1.1 核心理念学习 HarmonyOS(鸿蒙系统)是华为推出的全场景分布式操作系统,其核心特点如下: 分布式能力 设备协同:手机、平板、智能手表、IoT设备等可无…...
使用 Ansys Discovery 高效创建角焊缝
概括 Ansys Discovery 2024R1 中的焊缝功能是一项重大改进,旨在简化和精简工程模拟中焊缝的分配过程。此功能集成了间歇焊缝等高级工具和功能,以更直观、更高效的方式促进焊缝的准备和分配。 该功能为工程师提供了无缝的工作流程,以准备和分…...
Rk3568驱动开发_新字符设备驱动原理_7
1.申请设备号: 之前用的是register_chrdev(LED_MAJOR, LED_NAME, &led_fops);手动申请很不方便 使用alloc_chrdev_region函数申请设备号,手动申请的话要先查询是否有空余的设备号,很不方便,用此函数内核会自动将将空余设备号…...
ESP32-S3 42引脚 语音控制模块、设备运转展示 GOOUUU TECH 果云科技S3-N16R8 控制舵机 LED开关 直流电机
最近还是想玩了下esp32,基于原来的开发板,看见佬做了一个语音识别的项目,通过这个语音识别可以控制LED开关和直流电机这些,详情可见视频(推荐)具体硬件就在下方。 信泰微】ESP32-S3 42引脚 语音控制模块、…...
2025年光电科学与智能传感国际学术会议(ICOIS 2025)
重要信息 官网:www.ic-icois.org 时间:2025年3月14-16日 地点:中国-长春 简介 2025年光电科学与智能传感国际学术会议(ICOIS 2025)将于2025年3月14-16日在中国-长春隆重召开。会议将围绕“光学光电”、“智能传感”…...
高性能PHP框架webman爬虫引擎插件,如何爬取数据
文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons:JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram,自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 ? 5 IDEA必装的插件&…...
三大主流负载均衡器之对比(Comparison of the Three Mainstream Load balancers)
【 Linux 】三大主流软件负载均衡器对比(LVS、Nginx、HAproxy) 三大主流软件负载均衡器对比(LVS、Nginx、HAproxy) (资料来自网络,做了部分的补充说明) LVS: 1. 抗负载能力强,性能高,能达到F5的60%,对…...
深入探索Python机器学习算法:监督学习(线性回归,逻辑回归,决策树与随机森林,支持向量机,K近邻算法)
文章目录 深入探索Python机器学习算法:监督学习一、线性回归二、逻辑回归三、决策树与随机森林四、支持向量机五、K近邻算法 深入探索Python机器学习算法:监督学习 在机器学习领域,Python凭借其丰富的库和简洁的语法成为了众多数据科学家和机…...
Qt跨线程信号槽调用:为什么信号不能像普通函数那样调用
1. 信号与槽机制的基本原理 在 Qt 中,信号与槽机制是一种事件驱动的通信方式,用于对象之间的解耦交互。其关键特点如下: 信号不能直接调用 信号只是一个声明,并没有实际的函数实现。它们通过 emit 关键字在对象内部被触发&…...
Ubuntu+deepseek+Dify本地部署
1.deepseek本地部署 在Ollama官网下载 需要魔法下载 curl -fsSL https://ollama.com/install.sh | sh 在官网找到需要下载的deepseek模型版本 复制命令到终端 ollama run deepseek-r1:7b 停止ollama服务 sudo systemctl stop ollama # sudo systemctl stop ollama.servi…...
【LLM】DeepSeek开源技术汇总
note 一、FlashMLA:MLA解码内核 二、DeepEP:针对MoE和EP的通信库 三、DeepGEMM:FP8 通用矩阵乘法(GEMM)库 四、DualPipe、EPLB:双向管道并行算法 五、3FS:一种高性能分布式文件系统 文章目录 n…...
PostgreSQL10 逻辑复制实战:构建高可用数据同步架构!
PostgreSQL10 逻辑复制实战:打造高可用数据同步架构! 概述 PostgreSQL 10 引入了逻辑复制(Logical Replication),为数据库高可用和数据同步提供了更灵活的选择。PostgreSQL 复制机制主要分为物理复制和逻辑复制两种&…...
springboot之HTML与图片生成
背景 后台需要根据字段动态生成HTML,并生成图片,发送邮件到给定邮箱 依赖 <!-- freemarker模板引擎--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifa…...
455. 分发饼干(LeetCode)
题目来源: 455. 分发饼干 - 力扣(LeetCode) 题目内容: 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i]…...
go设计模式
刘:https://www.bilibili.com/video/BV1kG411g7h4 https://www.bilibili.com/video/BV1jyreYKE8z 1. 单例模式 2. 简单工厂模式 代码逻辑: 原始:业务逻辑层 —> 基础类模块工厂:业务逻辑层 —> 工厂模块 —> 基础类模块…...
基于STM32的智能家居能源管理系统
1. 引言 传统家庭能源管理存在能耗监控粗放、设备联动不足等问题,难以适应绿色低碳发展需求。本文设计了一款基于STM32的智能家居能源管理系统,通过多源能耗监测、负荷预测与优化调度技术,实现家庭能源的精细化管理与智能优化,提…...
win11编译pytorchaudio cuda128版本流程
1. 前置条件 本篇续接自 win11编译pytorch cuda128版本流程,阅读前请先参考上一篇配置环境。 访问https://kkgithub.com/pytorch/audio/archive/refs/tags/v2.6.0.tar.gz下载源码,下载后解压; 2. 编译 在visual studio 2022安装目录下查找…...
Rust学习总结之-match
Rust 有一个叫做 match 的极为强大的控制流运算符,它允许我们将一个值与一系列的模式相比较,并根据相匹配的模式执行相应代码。模式可由字面量、变量、通配符和许多其他内容构成。 一:match定义 可以把 match 表达式想象成某种硬币分类器&a…...
基于Three.js的3D赛车游戏开发实战详解
目录 一、项目效果预览二、核心技术架构2.1 三维场景构建2.2 赛道与车辆模型2.3 光照系统三、核心运动系统3.1 车辆运动控制3.2 物理模拟公式3.3 边界限制四、摄像机控制系统4.1 第三人称视角数学原理4.2 鼠标交互实现五、星空背景特效5.1 点云生成算法5.2 动态闪烁效果六、性能…...
51单片机中reg52.h与regx52.h在进行位操作时的不同
reg52.h中不能使用例如 P2_0;这样的定义 而只能使用 P2^0;这样的定义 但是都不可以对位进行直接赋值操作; 而 regx52.h中可以使用 P2_0和P2^0;但是只有使用下划线的才可以对位进行赋值操作 例如P2_0 1; 但不可以是P2^0 1; 在 C 语言中,…...
Git GitHub基础
git是什么? Git是一个分布式版本控制系统,用于管理源代码的变更。它允许多个开发者在同一个项目上协作,同时跟踪每个修改的历史记录。 关键词: 分布式版本控制软件 软件 安装到我们电脑上的一个工具 版本控制 例如论文&…...
【Excel】 Power Query抓取多页数据导入到Excel
抓取多页数据想必大多数人都会,只要会点编程技项的人都不会是难事儿。那么,如果只是单纯的利用Excel软件,我还真的没弄过。昨天,我就因为这个在网上找了好久发好久。 1、在数据-》新建查询-》从其他源-》自网站 ,如图 …...
视频批量分段工具
参考原文:视频批量分段工具 选择视频文件 当您启动这款视频批量分段工具程序后,有两种便捷的方式来选择要处理的视频文件。其一,您可以点击程序界面中的 “文件” 菜单,在下拉选项里找到 “选择视频文件” 按钮并点击;…...
Redis 源码分析-内部数据结构 robj
Redis 源码分析-内部数据结构 robj Redis 中,一个 database 内的这个映射关系是用一个 dict 来维护的(ht[0])。dict 的 key 固定用一种数据结构来表达就够了,即动态字符串 sds。而 value 则比较复杂,为了在同一个 dic…...
