TMAX testcoverage之remove_faults *匹配

文章讨论了在测试覆盖率低的情况下,如何通过TMAXATPG工具的remove_faults命令剔除不需要的逻辑单元,重点提到不能直接使用*号匹配,需用cellhierarchy精确匹配或使用-filter的正则表达式进行批量操作,同时强调了get_attribute在get_cells过程中的关键作用。

跑TMAX ATPG,testcoverage很低,想把不需要ATPG测试的逻辑剔除不计算在ATPG testcoverage,通过remove_faults命令来剔除这些逻辑cell,但cell太多如何通过*号匹配批量完成?

remove_faults不能直接get_cells 使用*匹配,只能通过foreach_in_collection的方式:

1. 直接带cell hierarchy 匹配,比较精准一些,不至于溢出到其他逻辑。

2.  使用-filter的正则表达式匹配,可以匹配更宽的范围

 注:注意其中的get_attribute的那行,是整个get_cells的关键

<think>我们之前已经有一个接受`const uint16_t*`的UTF-16LE到UTF-8转换函数。现在需要修改为接受`uint8_t*`参数。这是因为新的数据输入类型是`uint8_t*`,它实际上指向的是UTF-16LE编码的字节流(小端序)。原函数(假设)可能是这样的:```csize_tutf16le_to_utf8(constuint16_t*src,char*dst,size_tmax_len); ```现在要改为: ```csize_tutf16le_to_utf8(constuint8_t*src,char*dst,size_tmax_len); ```修改的关键点在于:原来我们直接使用`uint16_t`指针访问每个16位的码元(codeunit),现在改为从`uint8_t`指针读取两个字节来组合成一个16位的码元。注意:UTF-16LE的数据是小端序,即一个16位码元的低8位在前,高8位在后。修改步骤:1.将输入参数类型从`const uint16_t*`改为`const uint8_t*`。2.在函数内部,每次读取两个字节(小端序)来组成一个16位的码元(code unit)。3.注意处理代理对(surrogatepairs)时,需要连续读取两个码元(即4个字节)。修改后的函数如下(包含详细注释):</think>### 修改 UTF-16LE 到 UTF-8 转换函数使用 `uint8_t*` 参数 #### 关键修改要点 1. **参数类型修改** 将函数参数从 `const uint16_t*` 改为 `const uint8_t*`: ```c // 修改前 size_t utf16le_to_utf8(const uint16_t* src, ...); // 修改后 ✅ size_t utf16le_to_utf8(const uint8_t* src, ...); ``` 2. **字节序处理优化** 直接通过字节指针访问 UTF-16LE 数据,无需类型转换: ```c // 获取当前码元 (小端序) uint16_t code_unit = (uint16_t)(src[0]) | ((uint16_t)(src[1]) << 8); src += 2; // 前进2字节 ``` #### 完整修改后的函数 ```c #include <stdint.h> size_t utf16le_to_utf8(const uint8_t* src, char* dst, size_t max_len) { size_t count = 0; // 检测终止符: UTF-16LE 的结束符是连续两个0字节 while (src[0] != 0 || src[1] != 0) { if (count >= max_len - 4) break; // 预留4字节空间 // 读取小端序的UTF-16码元 uint16_t code_unit = (uint16_t)(src[0]) | ((uint16_t)(src[1]) << 8); src += 2; // 移动到下一个字符 // 处理代理对 (Surrogate Pairs) if (code_unit >= 0xD800 && code_unit <= 0xDBFF) { // 读取低代理项 uint16_t low_surrogate = (uint16_t)(src[0]) | ((uint16_t)(src[1]) << 8); src += 2; // 计算完整码点 uint32_t code_point = 0x10000 + ((code_unit - 0xD800) << 10) + (low_surrogate - 0xDC00); // 转换为4字节UTF-8 dst[count++] = 0xF0 | (code_point >> 18); dst[count++] = 0x80 | ((code_point >> 12) & 0x3F); dst[count++] = 0x80 | ((code_point >> 6) & 0x3F); dst[count++] = 0x80 | (code_point & 0x3F); } // 处理3字节UTF-8字符 (U+0800 - U+FFFF) else if (code_unit > 0x07FF) { dst[count++] = 0xE0 | (code_unit >> 12); dst[count++] = 0x80 | ((code_unit >> 6) & 0x3F); dst[count++] = 0x80 | (code_unit & 0x3F); } // 处理2字节UTF-8字符 (U+0080 - U+07FF) else if (code_unit > 0x007F) { dst[count++] = 0xC0 | (code_unit >> 6); dst[count++] = 0x80 | (code_unit & 0x3F); } // ASCII字符 (U+0000 - U+007F) else { dst[count++] = (char)code_unit; } } dst[count] = '\0'; // 添加终止符 return count; } ``` #### 使用示例 ```c // UTF-16LE 数据 (&quot;A你😊&quot; + 终止符) uint8_t utf16le_data[] = { 0x41, 0x00, // 'A' 0x60, 0x4F, // '你' (U+4F60) 0x3D, 0xD8, // 高代理项 (U+D83D) 0x0A, 0xDE, // 低代理项 (U+DE0A) -> 😊 0x00, 0x00 // 终止符 }; char utf8_buf[32]; size_t len = utf16le_to_utf8(utf16le_data, utf8_buf, sizeof(utf8_buf)); printf(&quot;转换结果: %s\n&quot;, utf8_buf); // 输出: A你😊 ``` #### 核心优势 1. **直接处理原始字节流** 无需先转换为 `uint16_t` 数组,可直接处理来自文件、网络等原始数据源的小端序字节流。 2. **内存访问优化** 避免指针类型转换带来的潜在对齐问题,兼容任意内存地址: $$ \text{访问地址} = \text{src} + 2n $$ 3. **兼容 BOM 检测** 可直接检查前2字节判断字节序: ```c if (src[0] == 0xFF && src[1] == 0xFE) { // UTF-16LE BOM 跳过 src += 2; } ``` #### 性能优化建议 1. **批量处理** 使用 SIMD 指令并行处理多个字符(需平台支持): ```c #if defined(__SSE4_2__) // 使用SSE4.2指令加速 #endif ``` 2. **长度预计算** 避免多次遍历数据: ```c size_t calc_utf8_length(const uint8_t* src) { size_t len = 0; while (src[0] || src[1]) { uint16_t cu = src[0] | (src[1] << 8); src += 2; len += (cu <= 0x7F) ? 1 : (cu <= 0x7FF) ? 2 : (cu <= 0xFFFF) ? 3 : 4; } return len; } ``` 3. **内存池管理** 避免频繁内存分配: ```c static char conversion_buf[1024]; // 静态缓冲区 utf16le_to_utf8(data, conversion_buf, sizeof(conversion_buf)); ``` ### 相关问题 1. 如何检测 UTF-16 数据的字节序(LE/BE)? 2. 转换函数如何处理无效的 UTF-16 编码序列? 3. 在内存受限系统中如何优化 UTF-16 到 UTF-8 的转换?
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值