支持3值逻辑的C++库:0,1,X

Nat*_*man 6 c++ tribool

我正在使用C++编写的微处理器模拟器.

我正在寻找一种方法来模拟刚刚启动但尚未以任何方式重置的硬件中的状态元素.真实的状态元素将具有0或1的未知值,但在软件模型中,这通常被建模为a X,意思是未知的.

我正在寻找一个C++库,可以模拟这些X值,包括它们的传播.也就是说,它必须知道如何使用Xes 处理逻辑和算术运算:

1 AND X = X
0 AND X = 0
1  +  X = X
Run Code Online (Sandbox Code Playgroud)

等等...

有没有这样既稳定又快速的图书馆?

编辑:

我忽略了提到我当前的代码适用于bitvectors.更准确地说,我使用标准uint_*t数据类型,这些是我想要替换的.无论我使用哪种库,它都必须支持算术,移位和逻辑运算符才能使用它.

ken*_*ytm 12

试试Boost.Tribool.

所述tribool类作用就像内置bool型,但是对于三态布尔逻辑.这三个状态是true,, falseindeterminate,其中前两个状态等同于C++ bool类型的状态,最后一个状态表示未知的布尔值(可能是true或者false,我们不知道).

您可以查看此类支持的规则的测试套件标头文档.

Boost库质量非常高,维护良好,因此您无需担心其稳定性.并且"快速"......对于像这样的简单类来说,很难慢.这些操作通过2到3个整数比较与1或2个if子句实现,因此它应该足够有效.


Mik*_*one 7

如果您正在尝试对硬件线进行建模,您可能想要考虑允许三个以上的状态.以下是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的tribools可以投入使用,但它们不会很快,因为操作将逐个元素并且存储将不会被优化,但如果有人对编写内部库而过敏,它们可能是您唯一的选择.完全符合你的需要.

例如,假设您想要一个表示具有四个可能级别的位向量的类:1,0,X和Z.首先,您必须为每个级别定义等效位模式(例如,X = 00,Z = 01,0 = 10,1 = 11;选择X作为复位状态)

对于每个操作,您必须写出真值表,最好以卡诺图形式:

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)
Run Code Online (Sandbox Code Playgroud)

(注意X赢了很多.大多数操作都是如此.)

然后计算出K-map中的布尔方程:

C = A & B
=> C1 = A1 & B1
   C0 = A1 & B1 & A0 & B0 = C1 & A0 & B0
Run Code Online (Sandbox Code Playgroud)

最后,将其转换为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;
    }
};   
Run Code Online (Sandbox Code Playgroud)

(注意:我没有测试上面的代码,因此使用风险自负.)

如果允许的级别更改,则必须重做所有这些操作.这就是为什么这些库往往太专业化而无法放入像Boost这样的通用库中.

编辑2:我突然意识到BitVector模板类具有少数几个用于重载逗号运算符的用例之一:

template<size_t NBitsR>
BitVector<NBits+NBitsR> operator ,(const BitVector<NBitsR>& rhs);
Run Code Online (Sandbox Code Playgroud)

这使您可以连接位向量:

BitVector<8> a("1110 0111");
BitVector<4> b("0000");
BitVector<12> c = (a, b); // == BitVector<12>("0000 1110 0111")
Run Code Online (Sandbox Code Playgroud)

......这似乎是最直观的方式来填充一个向量最多的另一个大小(它很容易证明这种填充应该不会是隐式的,永远)或合并载体在一起.

编辑3:突然意识到(是的,我很慢),如果你真的想做一个通用版本,你可以用基于策略的设计来做到这一点:

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> {};
Run Code Online (Sandbox Code Playgroud)

然后,如果您想使用不同的逻辑表示,比如说九个级别,甚至两个级别,那么您可以定义新的策略来支持这些格式.此外,您可以在问题的不同域中使用不同的策略进行计算(例如,电路板的4个级别,芯片的9个级别,处理器模拟器的2个级别),并定义转换功能以弥补差距.

同样,我还没有尝试构建这个,所以我不确定这是否完美优化.


Let*_*_Be 5

Boost有一个tribool库,但由于我从未使用它,因此无法对其质量发表评论:

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