我正在为用C ++编写的微处理器制作模拟器。

我正在寻找一种在硬件中建模状态元素的方法,这些元素刚刚被电源供电,并且尚未以任何方式重置。真实的状态元素将具有0或1的未知值,但是在软件模型中,通常将其建模为 X, , 意义 未知.

我正在寻找C ++的库,可以建模这些 X 价值,包括它们的传播。也就是说,它必须知道如何处理逻辑和算术操作 XES:

1 AND X = X
0 AND X = 0
1  +  X = X

ETC...

是否有既稳定又快速的库?

编辑:

我忽略了我当前的代码与BitVectors一起使用。更准确地说,我使用标准 uint_*t 数据类型,这些是我要替换的数据类型。我使用的任何图书馆, 必须 支持算术,转移和逻辑运算符,以使其有用。

有帮助吗?

解决方案

如果您试图建模硬件线,您可能想考虑允许三个以上的状态。这是Altera在其FPGA模拟器中使用的内容:

  • 1:高高(晶体管驱动到VDD)
  • 0:强低(晶体管驱动到VSS)
  • h:弱高(电阻卷发到VDD)
  • L:弱低(电阻下拉到VSS)
  • Z:高阻抗(未发行线)
  • X:未知
  • W:虚弱的未知
  • u:非初始化
  • DC:不在乎

您可能不需要W,U和DC。如果您的公共汽车总是被驾驶,则可以抛弃H,L和Z。

Verilog使用更多级别 门级建模, ,每个逻辑水平具有七个驱动力强度。附加级别对信号线的电容效应。这可能比您需要的要多。

编辑: 由于您提到了零碎的矢量,因此我不得不说,恕我直言,您不会在公共使用中找到这样的图书馆,并且要保持最新状态,因为1)并不是太多的程序员需要这样的事情,以及2)即使在其中,由于上述建模线级别的选项,几乎没有兼容性。 Boost的Tribool可以被压入服务,但不会快速,因为操作将是逐元元素,并且不会优化存储,但是如果有人过敏,它们可能是您唯一的选择确实做您需要的。

例如,假设您想要一个代表具有四个可能级别的位的载体:1、0,x和z。 = 10,1 = 11; x被选择为重置状态)

对于每个操作,您都必须写出真相表,最好是 Karnaugh地图 形式:

op: &  | X (00) | Z (01) | 1 (11) | 0 (10)
-------+--------+--------+--------+--------
X (00) | X (00) | X (00) | X (00) | X (00)
-------+--------+--------+--------+--------
Z (01) | X (00) | X (00) | X (00) | X (00)
-------+--------+--------+--------+--------
1 (11) | X (00) | X (00) | 1 (11) | 0 (10)
-------+--------+--------+--------+--------
0 (10) | X (00) | X (00) | 0 (10) | 0 (10)

(请注意,X赢了很多。对于大多数操作,这是正确的。)

然后从k-map中计算出布尔方程:

C = A & B
=> C1 = A1 & B1
   C0 = A1 & B1 & A0 & B0 = C1 & A0 & B0

最后,将其转换为C ++:

template<size_t NBits> class BitVector
{private:
    enum { NWords = (NBits+31)/32 };
    int32_t storage[NWords][2];
public:
    BitVector<NBits> operator &(BitVector<NBits>& rhs)
    {    BitVector<NBits> result;
         for(unsigned k = 0; k < NWords; ++k)
         {   int32_t x = storage[k][1] & rhs.storage[k][0];
             result.storage[k][1] = x;
             result.storage[k][0] = storage[k][0] & rhs.storage[k][0] & x;
         }
         return result;
    }
};   

(注意:我尚未测试上述代码,因此请自行使用。)

全部 如果允许的级别更改,则必须重做。这就是为什么这些图书馆往往太专业而无法放入像Boost这样的通用库中的原因。

edit2: 我刚刚意识到,BitVector模板类具有少数用的用例之一:逗号运算符有意义:

template<size_t NBitsR>
BitVector<NBits+NBitsR> operator ,(const BitVector<NBitsR>& rhs);

这使您可以连接位矢量:

BitVector<8> a("1110 0111");
BitVector<4> b("0000");
BitVector<12> c = (a, b); // == BitVector<12>("0000 1110 0111")

...这似乎是将一个向量填充到另一个矢量的最直观的方法(很容易证明这种填充应该应该 不是 隐含 曾经)或将向量合并在一起。

edit3: 它只是在我身上突然出现(是的,我很慢),如果你 真的 想要做一个通用版本,您可以使用 基于政策的设计:

struct TwoLevelLogic
{   enum
    {   kNumPlanes = 1
    };
    static void And(int32_t[] result, int32_t[] lhs, int32_t[] rhs)
    {    result[0] = lhs[0] & rhs[0];
    }
};

struct FourLevelLogic
{   enum
    {   kNumPlanes = 2
    };
    static void And(int32_t[] result, int32_t[] lhs, int32_t[] rhs)
    {    int32_t x = lhs[1] & rhs[1];
         result[1] = x;
         result[0] = lhs[0] & rhs[0] & x;
    }
};

template<typename LogicType, size_t NBits>
class BitVector
{private:
    enum { NWords = (NBits+31)/32 };
    int32_t storage[NWords][LogicType::kNumPlanes];
public:
    BitVector<LogicType, NBits> operator &(BitVector<LogicType, NBits>& rhs)
    {    BitVector<LogicType, NBits> result;
         for(unsigned k = 0; k < NWords; ++k)
             LogicType::And(result.storage[k], storage[k], rhs.storage[k]);
         return result;
    }
};

template<size_t NBits> 
class BitVector4L: public BitVector<FourLevelLogic, NBits> {};

然后,如果您想使用不同的逻辑表示形式,例如九个级别,甚至两个级别,则可以定义新的政策以支持这些格式。此外,您可以在问题的不同域中使用不同的策略计算(例如,董事会的4个级别,芯片9级,处理器模拟器的2个),并定义转换功能以弥合间隙。

同样,我没有尝试构建这个,因此我不确定这是否完美地优化。

其他提示

尝试 boost.tribool.

tribool 类似于内置的班级 bool 类型,但适用于三态布尔逻辑。这三个州是 true, false, , 和 indeterminate, ,前两个状态等同于C ++的状态 bool 类型和最后一个状态代表未知的布尔值(可能是 true 或者 false, ,我们不知道)。

你可以看到 测试西服标题文档 对于规则,该课程支持。

提升图书馆的质量非常高,维护得很好,因此您不必担心其稳定性。和“快速” ...对于这样的简单课程,很难慢慢:)。该操作以2到3个整数比较与1或2进行了实施 if 条款应足够高效。

Boost有一个Tribool图书馆,但我无法评论其质量,因为我从未使用过:

http://www.boost.org/doc/libs/1_44_0/doc/html/tribool.html

我不熟悉上面提到的Boost库,但似乎仅支持一个布尔值,而不是Bitfield。您可以使用以下技术来无需太多大惊小怪地做到这一点:

class Logic
{
    unsigned x, xu;

public:
    Logic(unsigned x, unsigned xu)
    {
        this->x = x;
        this->xu = xu;
    }

    Logic operator&(const Logic &rhs) const
    {
        return Logic(
            x & rhs.x,
            xu & (rhs.x | rhs.xu) | rhs.xu & (x | xu));
    }

    Logic operator|(const Logic &rhs) const
    {
        return Logic(
            x | rhs.x,
            xu & (~rhs.x | rhs.xu) | rhs.xu & (~x | xu));
    }
};

免责声明 - 这需要验证!

如果您打算一次执行许多此类操作,那么最好使用64位整数而不是单个Tribools。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top