C++;支持三值逻辑的库:0,1,X 我正在做一个微处理器的模拟器,用C++编写。
我正在寻找一种方法来模拟刚通电但尚未以任何方式重置的硬件中的状态元素。实状态元素的未知值为0或1,但在软件模型中,这通常被建模为C++;支持三值逻辑的库:0,1,X 我正在做一个微处理器的模拟器,用C++编写。,c++,tribool,C++,Tribool,我正在寻找一种方法来模拟刚通电但尚未以任何方式重置的硬件中的状态元素。实状态元素的未知值为0或1,但在软件模型中,这通常被建模为X,表示未知 我正在寻找一个C++库,可以对这些代码< x >代码>值进行建模,包括它们的传播。也就是说,它必须知道如何使用Xes处理逻辑和算术运算: 1 AND X = X 0 AND X = 0 1 + X = X 等等 有没有这样的图书馆既稳定又快速 编辑: 我忘了提到我当前的代码是使用位向量的。更准确地说,我使用标准的uint_*t数据类型,这些是我想要替
X
,表示未知
我正在寻找一个C++库,可以对这些代码< x >代码>值进行建模,包括它们的传播。也就是说,它必须知道如何使用X
es处理逻辑和算术运算:
1 AND X = X
0 AND X = 0
1 + X = X
等等
有没有这样的图书馆既稳定又快速
编辑:
我忘了提到我当前的代码是使用位向量的。更准确地说,我使用标准的
uint_*t
数据类型,这些是我想要替换的数据类型。无论我使用什么库,它都必须支持算术、移位和逻辑运算符才能发挥作用。Boost有一个tribool库,但我无法评论它的质量,因为我从未使用过它:
试试看
tribool类与内置的bool
类型类似,但适用于三态布尔逻辑。这三种状态是:代码>真< /代码>,代码>虚伪< /代码>,和<代码>不确定< /C> >,其中前两个状态相当于C++ >代码> BOOL<代码>类型,最后一个状态表示未知布尔值(可能是代码>真< /COD>或<代码> false <代码>,我们不知道。
您可以看到该类支持的规则的和
Boost库的质量非常高,维护良好,所以您不必担心它的稳定性。和“快”。。。对于像这样的简单类来说,很难放慢速度:)。这些操作是通过2到3个整数与1或2
if
子句进行比较来实现的,因此应该足够有效。如果您尝试对硬件线路建模,您可能需要考虑允许三种以上的状态。以下是Altera在其FPGA模拟器中使用的内容:
- 1:强高电平(晶体管驱动至VDD)
- 0:强低(晶体管驱动至VSS)
- H:弱高(电阻上拉至VDD)
- L:弱低(电阻下拉至VSS)
- Z:高阻抗(未驱动线路)
- X:未知
- W:弱未知
- U:未初始化
- 华盛顿:不在乎
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;
}
};
模板类位向量
{私人:
枚举{NWords=(NBits+31)/32};
国际存储[NWords][2];
公众:
位向量运算符&(位向量和rhs)
{位向量结果;
for(无符号k=0;k
(注意:我还没有测试上面的代码,因此使用风险自负。)
如果允许的级别集发生更改,则必须重新执行所有这些操作。这就是为什么这些库往往过于专业化,无法放入像Boost这样的通用库中
EDIT2:我刚刚意识到BitVector模板类有少数几个重载逗号运算符的用例之一:
template<size_t NBitsR>
BitVector<NBits+NBitsR> operator ,(const BitVector<NBitsR>& rhs);
模板
位向量运算符(常量位向量和rhs);
这使您可以连接位向量:
BitVector<8> a("1110 0111");
BitVector<4> b("0000");
BitVector<12> c = (a, b); // == BitVector<12>("0000 1110 0111")
位向量a(“1110 0111”);
位向量b(“0000”);
位向量c=(a,b);//=位向量(“0000 1110 0111”)
。。。这似乎是将一个向量填充到另一个向量的大小(很容易证明这种填充不应该是隐式的)或将向量合并在一起的最直观的方法
EDIT3:我突然意识到(是的,我很慢),如果你真的想做一个通用的版本,你可以用:
结构TwoLevelLogic
{enum
{kNumPlanes=1
};
静态无效和(int32_t[]结果、int32_t[]左侧、int32_t[]右侧)
{result[0]=lhs[0]&rhs[0];
}
};
结构四层逻辑
{enum
{kNumPlanes=2
};
静态无效和(int32_t[]结果、int32_t[]左侧、int32_t[]右侧)
{int32_t x=lhs[1]&rhs[1];
结果[1]=x;
结果[0]=lhs[0]&rhs[0]&x;
}
};
模板
类位向量
{私人:
枚举{NWords=(NBits+31)/32};
int32_t存储[nWord][LogicType::kNumPlanes];
公众:
位向量运算符&(位向量和rhs)
{位向量结果;
对于(无符号k=0;
BitVector<8> a("1110 0111");
BitVector<4> b("0000");
BitVector<12> c = (a, b); // == BitVector<12>("0000 1110 0111")
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> {};
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));
}
};