首页 > 解决方案 > 什么可能是 C 中 SystemVerilog 中 casex 语句的等效方法

问题描述

一些背景:我目前正在编写一个模拟器。我正在尝试实现具有类似行为的解码器,例如 SystemVerilog 上的“casex”语句。

举一些例子,这些是一些说明。

BNE_ENCODING        0b100011xx
BRK_ENCODING        0b10101100
CMP_ENCODING        0b01110000
DEC_ENCODING        0b1001xxxx

我尝试了什么:我尝试用零替换 x。但这没有用。

我不明白如何忽略 C 的最后一点,而不创建冲突的 case 语句。x 表示忽略的位。我试图通过查看从 Quartus 生成的 RTL 输出来了解一些实现(我知道 RTL 与 C 无关,只是为了让我了解我可以实现的布尔表达式)。解码器是用 NOR 门实现的。

System Verilog 上的解码器的一部分。

casex(op)
        8'b100011xx: /* Do something */;
        8'b10101100: /* Do something */;
        8'b01110000: /* Do something */;
        8'b1001xxxx: /* Do something */;
endcase

问题:在 C 中实现这种解码器的正确方法是什么?解码器是指与 Verilog 语句具有相似行为的 switchcasex语句。

标签: csystem-verilog

解决方案


忽略某些位可以通过按位与运算屏蔽它们来完成。

if ((op & 0xFC) == 0x8C) {
    /* 8'b100011xx */
} else if ((op & 0xFF) == 0xAC) {
    /* 8'b10101100 */
} else if ((op & 0xFF) == 0x70) {
    /* 8'b01110000 */
} else if ((op & 0xF0) == 0x90) {
    /* 8'b1001xxxx */
}

如果您坚持使用switch语句,则可以使用多个级别的语句。

switch (op & 0xF0) {
    case 0x80: /* 8'b1000xxxx */
        switch (op & 0x0C) {
            case 0x0C: /* 8'bxxxx11xx (8'b100011xx) */
                break;
        }
        break;
    case 0xA0: /* 8'b1010xxxx */
        switch (op & 0x0F) {
            case 0x0C: /* 8'bxxxx1100 (8'b10101100) */
                break;
        }
        break;
    case 0x70: /* 8'b0111xxxx */
        switch (op & 0x0F) {
            case 0x00: /* 8'bxxxx0000 (8'b01110000) */
                break;
        }
        break;
    case 0x90: /* 8'b1001xxxx */
        break;
}

推荐阅读