Chisel3 REPL Vec 分配到模块中仅在 eval 之后有效
Chisel3 REPL Vec assignment into module only works after eval
如果我们运行下面的Chisel3代码
class Controller extends Module {
val io = IO(new Bundle {
})
val sff = Module(new SFF)
val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
for(i <- 0 until ProcedureSpaceSize)
frame(i) := 99.U
sff.io.inputDataVector := frame
}
class SFF extends Module {
val io = IO(new Bundle {
val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
})
}
处于 REPL 调试模式。先做
reset;step
peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2
REPL returns
Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_1) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_2) returns value not found
然后做
eval sff.io_inputDataVector_0
这将是成功的,产生
...
resolve dependencies
evaluate sff.io_inputDataVector_0 <= frame_0
evaluated sff.io_inputDataVector_0 <= 99.U<32>
然后再次执行上面的 peek
peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2;
这次,returns
peek sff.io_inputDataVector_0 99
peek sff.io_inputDataVector_1 99
peek sff.io_inputDataVector_2 99
哪个更值得期待
为什么REPL会这样?还是我错过了什么?谢谢!
*chisel-iotesters
是版本 1.4.2
,chiseltest
是版本 0.2.2
。两者都应该是最新版本。
我认为您看到的问题是由于死代码消除,您所有的连线都被消除了。有几件事你应该尝试解决这个问题。
- 确保你的电线有有意义的连接。最终不会影响输出的硬件很可能会被淘汰。在您的示例中,您没有任何驱动顶级输出的东西
- 您可能需要您的电路使用这些寄存器计算一些东西。如果寄存器初始化为 99,则常量传播可能会消除它们。我不确定你想让电路做什么,所以很难给出具体的建议。
如果您完成上述操作,我认为 repl 将按预期工作。我对你使用的 repl 有疑问(有两个:firrtl-interpreter 和 treadle)我建议使用后者。它更现代并且得到更好的支持。它还有两个有用的命令
show lofirrtl
将向您显示降低的 firrtl,这就是您可以看到 chisel3 发出的高 firrtl 中的很多内容已更改的方式。
symbol .
显示电路中的所有符号(.
是匹配所有内容的正则表达式。
这是根据您的 frame
Vec
驱动和输出的电路的随机编辑。该电路将生成 firrtl,它不会消除您要查看的电线。
class Controller extends Module {
val io = IO(new Bundle {
val out = Output(UInt(32.W))
})
val sff = Module(new SFF)
val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
when(reset.asBool()) {
for (i <- 0 until ProcedureSpaceSize) {
frame(i) := 99.U
}
}
frame.zipWithIndex.foreach { case (element, index) => element := element + index.U }
sff.io.inputDataVector := frame
io.out := sff.io.outputDataVector.reduce(_ + _)
}
class SFF extends Module {
val io = IO(new Bundle {
val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
val outputDataVector: Vec[UInt] = Output(Vec(ProcedureSpaceSize, Integer32Bit))
})
io.outputDataVector <> io.inputDataVector
}
firrtl 解释器 REPL 不一定计算或存储未使用的 mux
分支上的值。这可能会导致上述问题,如
Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found
.
eval
可用于强制对未使用的分支进行评估。 REPL 是一个实验性功能,还没有太多用处。
treadle 是更现代的凿子 scala-based 模拟器。它比解释器得到更好的支持并且更快。它有自己的 REPL,但没有 executeFirrtlRepl
等价物。
必须通过根目录中的./treadle.sh脚本从命令行运行。还可以 运行 sbt assembly
创建一个更快的启动 jar,它被放置在 utils/bin 中。这个 REPL 也没有被大量使用,但我对反馈感兴趣,这将使它更好、更容易使用。
如果我们运行下面的Chisel3代码
class Controller extends Module {
val io = IO(new Bundle {
})
val sff = Module(new SFF)
val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
for(i <- 0 until ProcedureSpaceSize)
frame(i) := 99.U
sff.io.inputDataVector := frame
}
class SFF extends Module {
val io = IO(new Bundle {
val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
})
}
处于 REPL 调试模式。先做
reset;step
peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2
REPL returns
Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_1) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_2) returns value not found
然后做
eval sff.io_inputDataVector_0
这将是成功的,产生
...
resolve dependencies
evaluate sff.io_inputDataVector_0 <= frame_0
evaluated sff.io_inputDataVector_0 <= 99.U<32>
然后再次执行上面的 peek
peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2;
这次,returns
peek sff.io_inputDataVector_0 99
peek sff.io_inputDataVector_1 99
peek sff.io_inputDataVector_2 99
哪个更值得期待
为什么REPL会这样?还是我错过了什么?谢谢!
*chisel-iotesters
是版本 1.4.2
,chiseltest
是版本 0.2.2
。两者都应该是最新版本。
我认为您看到的问题是由于死代码消除,您所有的连线都被消除了。有几件事你应该尝试解决这个问题。
- 确保你的电线有有意义的连接。最终不会影响输出的硬件很可能会被淘汰。在您的示例中,您没有任何驱动顶级输出的东西
- 您可能需要您的电路使用这些寄存器计算一些东西。如果寄存器初始化为 99,则常量传播可能会消除它们。我不确定你想让电路做什么,所以很难给出具体的建议。
如果您完成上述操作,我认为 repl 将按预期工作。我对你使用的 repl 有疑问(有两个:firrtl-interpreter 和 treadle)我建议使用后者。它更现代并且得到更好的支持。它还有两个有用的命令
show lofirrtl
将向您显示降低的 firrtl,这就是您可以看到 chisel3 发出的高 firrtl 中的很多内容已更改的方式。symbol .
显示电路中的所有符号(.
是匹配所有内容的正则表达式。
这是根据您的 frame
Vec
驱动和输出的电路的随机编辑。该电路将生成 firrtl,它不会消除您要查看的电线。
class Controller extends Module {
val io = IO(new Bundle {
val out = Output(UInt(32.W))
})
val sff = Module(new SFF)
val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
when(reset.asBool()) {
for (i <- 0 until ProcedureSpaceSize) {
frame(i) := 99.U
}
}
frame.zipWithIndex.foreach { case (element, index) => element := element + index.U }
sff.io.inputDataVector := frame
io.out := sff.io.outputDataVector.reduce(_ + _)
}
class SFF extends Module {
val io = IO(new Bundle {
val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
val outputDataVector: Vec[UInt] = Output(Vec(ProcedureSpaceSize, Integer32Bit))
})
io.outputDataVector <> io.inputDataVector
}
firrtl 解释器 REPL 不一定计算或存储未使用的 mux
分支上的值。这可能会导致上述问题,如
Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found
.
eval
可用于强制对未使用的分支进行评估。 REPL 是一个实验性功能,还没有太多用处。
treadle 是更现代的凿子 scala-based 模拟器。它比解释器得到更好的支持并且更快。它有自己的 REPL,但没有 executeFirrtlRepl
等价物。
必须通过根目录中的./treadle.sh脚本从命令行运行。还可以 运行 sbt assembly
创建一个更快的启动 jar,它被放置在 utils/bin 中。这个 REPL 也没有被大量使用,但我对反馈感兴趣,这将使它更好、更容易使用。