我想为dsptools创建一些类似DspReal的新数字类型,例如DspPosit和DspQuire。 DspPosit基于posit,我有一些Java代码,而DspQuire基于quire,后者是posit的一种累加器。因为我现在只想模拟,所以我为它们的操作编写了许多ScalaBlackBox,例如DspReal。但是,我发现ScalaBlackBox无法构造顺序逻辑。例如,查询累加器的当前输出取决于其输入和最后一个输出。但是ScalaBlackBox无法获取输出值。另外,步骤(n)也影响输出。因为累加器将在每个时钟周期读取其输入。
我发现了踏板的一些系统问题。首先,ScalaBlackBox,twoOp和oneOp等功能将被多次调用。我不知道为什么其次,step(n)是PeekPokeTester的功能,ScalaBlackBox无法访问它。第三,我尝试读取当前输出,但系统给出了错误。
trait DspBlackBlackBoxImpl extends BlackBoxImplementation with ScalaBlackBox
abstract class DspQuireAccumulator extends DspBlackBlackBoxImpl {
lazy val accValue = Quire32() // initial value
/**
* sub-classes must implement this two argument function
*
* @param posit accumulate element
* @return quire operation result
*/
def accOp(posit: Posit32): Unit
def outputDependencies(outputName: String): Seq[(String)] = {
outputName match {
case "out" => Seq("in") // Seq("out", "in") gives errors
case _ => Seq.empty
}
}
def cycle(): Unit = {}
def execute(inputValues: Seq[Concrete], tpe: Type, outputName: String): Concrete = {
val arg1 :: _ = inputValues
val positArg = Posit32(arg1.value)
accOp(positArg)
val result = quire32ToBigInt(accValue)
ConcreteSInt(result, DspQuire.underlyingWidth, arg1.poisoned).asUInt
}
def getOutput(inputValues: Seq[BigInt], tpe: Type, outputName: String): BigInt = {
val arg1 :: _ = inputValues
val positArg = Posit32(arg1)
accOp(positArg)
quire32ToBigInt(accValue)
}
}
class DspQuireAddAcc(val name: String) extends DspQuireAccumulator {
def accOp(posit: Posit32): Unit = accValue += posit
}
class QuireBlackboxAccOperand extends BlackBox {
val io = IO(new Bundle() {
val in = Input(UInt(DspPosit.underlyingWidth.W))
val out = Output(UInt(DspQuire.underlyingWidth.W))
})
}
class BBQAddAcc extends QuireBlackboxAccOperand
class TreadleDspQuireFactory extends ScalaBlackBoxFactory {
def createInstance(instanceName: String, blackBoxName: String): Option[ScalaBlackBox] = {
blackBoxName match {
case "BBQAddAcc" => Some(add(new DspQuireAddAcc(instanceName)))
...
accOp将被调用多次。因此,如果我要累加List(1、2、3),结果可能是0 +1 +1 +1 2 2 ... 并且peek函数将再次调用accOp,这也让我感到困惑。
答案 0 :(得分:2)
我相信您目前的大多数问题是由两种不同的方法混合引起的。我认为您不应该使用BlackBoxImplmentation
,因为它是firrtl-interpreter中使用的较旧方案。只需使用ScalaBlackBox
并实现wiki页面Black Boxes and Treadle中所述和TreadleTest BlackBoxWithState中所示的方法即可。
不要使用outputDependencies
,而是使用getDependencies
指定输入和输出之间的任何依赖关系。每当更改输入IO时,就会调用inputChanged
。因此,在这种方法中,您要记录或更新黑匣子的内部状态。 clockChange
会在时钟改变时被调用,并会提供转换信息,因此您可以决定随后会发生什么。只要您不需要使用getOutput
,Treadle就会调用outputDependencies
,因为您不会使用lambda
,因此您可以忽略输入,而仅根据内部状态提供输出值。
我仍在这里尝试复制您的代码的运行版本,但是如果您可以尝试上面的建议并让我知道如何进行,这将是我一点时间将其组合在一起的方法。我有兴趣使Treadle的此功能更好,更易于使用,因此感谢所有反馈。