Renode/verilator: issues with proj/proj_template_v
tcal-x opened this issue · comments
proj_template_v
has a very simple CFU: if the low bit of the function is '0', then it returns the first operand, otherwise it returns the second operand. Executing on the board, with menu selections "3 g", function=0 is used, and we get this output, which is what we expect (just returning the first operand 'a'):
a b--> 0 1 2 3 4 5
-------------------------------------------------------
0 0 0 0 0 0 0
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
4 4 4 4 4 4 4
5 5 5 5 5 5 5
In Renode/Verilator though, we get the following output, and also timeout errors on the terminal.
a b--> 0 1 2 3 4 5
-------------------------------------------------------
0 107452251610745224511074522451107452245110745224511074522451
1 107452251610745224511074522451107452245110745224511074522451
2 107452251610745224511074522451107452245110745224511074522451
3 107452251610745224511074522451107452245110745224511074522451
4 107452251610745224511074522451107452245110745224511074522451
5 107452251610745224511074522451107452245110745224511074522451
The function unit is combinational -- it returns the result at the clock edge immediately. Perhaps this is unexpected in the simulation?
My Renode version is Renode, version 1.12.0.2504 (e082694a-202110060123)
. I'm at commit 22555b4 in CFU Playground.
Hi @tcal-x -- It is indeed caused by how CFU is implemented in simulation.
CPU does not assert rsp_ready
if CFU does not assert rsp_valid
. In this case CPU waits for CFU to assert cmd_ready
but it never happens because it looks like a following in proj_template_v
:
assign cmd_ready = rsp_ready;
So since CPU does not see cmd_ready
asserted it will also never assert rsp_ready
which means cmd_ready
will also never be asserted and pipeline falls in an infinite loop where both CPU and CFU are waiting for each other to assert a signal.
This issue is related to recent change in Renode. rsp_ready
is no longer asserted whole time. It was necessary change to make kws_micro_accel
work, #301 (there is proper handshake).
I wonder how to approach this, do we want to handle handshake like that? I'm not sure yet how to do that without breaking more complex CFUs (like kws_micro_accel
) but I can investigate it if that's needed.
Thanks @robertszczepanski , I haven't yet had time to dig into this. I hope to get to it soon.
Hi @robertszczepanski , I found that the VexRiscv does keep rsp_ready
asserted (high) by default. It doesn't mean that the CPU is trying to pull a result before one is ready; it's just a promise to the CFU that when it produces a result, the CPU will accept it immediately.
So we want to imitate that behavior in the Renode interface.
It's ok if it takes a simulation cycle for the rsp_ready
high to propagate to cmd_ready
; things should still work correctly.
Hi @robertszczepanski , @PiotrZierhoffer -- in all handshakes, we should assume that "ready" is asserted by default, not just after "valid" is asserted. You should expect that behavior in other components, and you should implement that behavior in the components that you imlement.
The only time "ready" should be low is if the receiver really cannot accept another payload. And you should expect that eventually "ready" will be re-asserted on its own (not in response to the "valid" being asserted).