Open uenoku opened 2 years ago
With disallowLocalVariable option, Prepare swaps bpassign
and read_inout
which is obviously incorrect. So we have to fix this bug at Prepare.
; IR after Prepare
sv.always posedge %clock {
sv.bpassign %reg, %a : i8
sv.bpassign %reg, %b : i8
%0 = sv.read_inout %reg : !hw.inout<i8>
sv.fwrite %c-2147483646_i32, "%d"(%0) : i8
}
The general solution would be, as suggested by @darthscsi, to introduce a temporary register at Prepare so that we don't have to modify ExportVerilog a lot.
Is this introduced in https://github.com/llvm/circt/commit/300e24414e95a53bbf10ab10f50b836b7e31324a? That's the most recent change to read_inout ordering. I may have approved that PR to hastily.
+1 for introducing constructs in Prepare to Export can be simpler.
No, https://github.com/llvm/circt/commit/300e24414e95a53bbf10ab10f50b836b7e31324a is not source of this bug. I confirmed reordering happens before the commit as well. However, it seems https://github.com/llvm/circt/commit/300e24414e95a53bbf10ab10f50b836b7e31324a moves read_inout's position so this might be doing something incorrect. I think we have to check wether there is no blocking assignment in the same block.
I tried this on firtool sifive/0/0/1~sifive/0/6/0. It has never been compiled correctly:pensive:
Current output:
This is incorrect because the value of
a
should be printed. I guess we have to create a temporary register if we can't useautomatic
.