这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » March-C算法

共1条 1/1 1 跳转至

March-C算法

院士
2026-05-27 01:15:56     打赏

March-C 算法是一种经典的存储器测试算法,主要用于检测 SRAM 和 DRAM 中的固定故障(Stuck-at Faults)、翻转故障(Transition Faults)以及耦合故障(Coupling Faults)。该算法的核心逻辑包含 6 个步骤(March Elements),通常表示为:{ ⇕(w0); ⇑(r0,w1); ⇑(r1,w0); ⇓(r0,w1); ⇓(r1,w0); ⇓(r0) }其中:

  • ⇕ 表示任意顺序(通常初始化为全0或全1)。

  • ⇑ 表示地址递增方向(从低地址到高地址)。

  • ⇓ 表示地址递减方向(从高地址到低地址)。

  • w0/w1 表示写入 0 或 1。

  • r0/r1 表示读取并验证是否为 0 或 1。

以下是基于标准 March-C 逻辑的 C 语言实现。为了通用性,这里假设被测试的内存是一个字节数组(uint8_t),如果是其他位宽(如 32 位 int),只需修改数据类型和写入/读取的掩码值即可。

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

/**
 * @brief 执行 March-C 算法测试
 * 
 * @param memory 指向被测内存区域的指针
 * @param size   内存区域的大小(字节数)
 * @return true  测试通过
 * @return false 测试失败
 */
bool march_c_test(uint8_t *memory, size_t size) {
    if (memory == NULL || size == 0) {
        return false;
    }

    uint8_t *start = memory;
    uint8_t *end = memory + size;
    uint8_t *ptr;

    // Step 1: ⇕(w0)
    // 将所有单元写入 0
    // 注意:在实际硬件测试中,这一步可能不需要验证,只是初始化
    memset(memory, 0x00, size);

    // Step 2: ⇑(r0, w1)
    // 地址递增:读取期望为0,然后写入1
    ptr = start;
    while (ptr < end) {
        if (*ptr != 0x00) {
            return false; // 读取错误,期望是0
        }
        *ptr = 0xFF;      // 写入1 (对于8位数据,全1即0xFF)
        ptr++;
    }

    // Step 3: ⇑(r1, w0)
    // 地址递增:读取期望为1,然后写入0
    ptr = start;
    while (ptr < end) {
        if (*ptr != 0xFF) {
            return false; // 读取错误,期望是1
        }
        *ptr = 0x00;      // 写入0
        ptr++;
    }

    // Step 4: ⇓(r0, w1)
    // 地址递减:读取期望为0,然后写入1
    ptr = end - 1;
    while (ptr >= start) {
        if (*ptr != 0x00) {
            return false; // 读取错误,期望是0
        }
        *ptr = 0xFF;      // 写入1
        if (ptr == start) break; // 防止无符号指针下溢死循环
        ptr--;
    }

    // Step 5: ⇓(r1, w0)
    // 地址递减:读取期望为1,然后写入0
    ptr = end - 1;
    while (ptr >= start) {
        if (*ptr != 0xFF) {
            return false; // 读取错误,期望是1
        }
        *ptr = 0x00;      // 写入0
        if (ptr == start) break; // 防止无符号指针下溢死循环
        ptr--;
    }

    // Step 6: ⇓(r0)
    // 地址递减:读取期望为0
    ptr = end - 1;
    while (ptr >= start) {
        if (*ptr != 0x00) {
            return false; // 读取错误,期望是0
        }
        if (ptr == start) break;
        ptr--;
    }

    return true;
}

// 示例主函数
int main() {
    #define TEST_SIZE 1024
    uint8_t test_memory[TEST_SIZE];

    printf("Starting March-C Test...\n");

    // 模拟正常内存
    bool result = march_c_test(test_memory, TEST_SIZE);
    
    if (result) {
        printf("Test PASSED: Memory is healthy.\n");
    } else {
        printf("Test FAILED: Memory fault detected.\n");
    }

    // 模拟一个故障:手动修改某个字节,使其在后续检查中失败
    // 注意:由于March-C会覆盖数据,要模拟故障通常需要在硬件层面注入,
    // 或者在软件模拟中Hook读写操作。这里仅演示接口调用。
    
    return 0;
}

代码逻辑解析

数据类型选择‌:

示例中使用 uint8_t(字节)作为基本单元。如果被测内存是 32 位系统上的 int 或 uint32_t,请将 uint8_t 替换为 uint32_t,并将写入/比较的值 0x00 和 0xFF 分别改为 0x00000000 和 0xFFFFFFFF。

地址遍历方向‌:

递增 (⇑)‌:使用指针从 start 向 end 移动 (ptr++)。

递减 (⇓)‌:使用指针从 end - 1 向 start 移动 (ptr--)。

注意‌:在使用无符号指针进行递减循环时,必须小心处理边界条件(如 ptr == start 时跳出循环),否则指针下溢会变成极大的正数,导致死循环或段错误。

读写操作 (r/w)‌:

March 算法的关键在于“读后写”。例如 r0, w1 意味着先读取当前值,判断是否为 0,如果正确则将其改写为 1。这种模式能有效检测‌翻转故障‌(即单元能否从 0 变 1 或从 1 变 0)和‌耦合故障‌(相邻单元的操作是否干扰了当前单元)。

复杂度‌:

March-C 的时间复杂度为 ‌O(N)‌,其中 N 是存储单元的数量。每个单元大约经历 10 次操作(1次初始化写 + 5次读 + 4次中间写 + 1次最终读,具体取决于实现细节,但总体线性)。这使得它非常适合嵌入式系统的上电自检(POST)或内置自测试(MBIST)。






关键词: March-C     算法    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]