Hi, I found an issue with running dv for gfmpw-1 s...
# caravel
p
Hi, I found an issue with running dv for gfmpw-1 shuttle. When running longer tests, caravel sets the wb_rst_i input signal to undefined state (and all other singals follow later). It happens at constant time of 32000 clock cylces. It doesn't change with delaying of setting I/O pins, but I found it only changes when .c file program length changes - looks like it dependent only on caravel. I can reproduce it even on provided user_proj_example with only I/O output and input clock from wb pins. Have anyone else encountered this issue? Or maybe someone had success with dv testing on gfmpw-1?
t
I don't know any way that
wb_rst_i
can go undefined; maybe if the external
RESETB
pin became undefined, since it directly drives that signal. You may want to check in
caravel --> caravel_core --> caravel_clocking
. The
wb_rst_i
comes from
resetb_sync
which itself comes from
resetb_async
which is derived from three individual resets
porb
,
resetb
, and
ext_reset
. Did any of those three become undefined? (
resetb
corresponds to the RESETB pin.
porb
is a power-on-reset, and
ext_reset
is a manual reset from the housekeeping SPI.)
p
Oh, and I forgot to say - it only happens on GL level. RTL works just fine
image.png
t
Okay, I know why this is happening
I have a fix, hold on
p
:0
t
You'd find upon closer look that undefined states have propagated throughout the entire caravel. I know why this is happening and the fix looks kindof odd, but works. Look at this firmware source: https://github.com/AvalonSemiconductors/gfmpw1-multi/blob/main/verilog/dv/qcpu/qcpu.c . Note how I am using a delay function after setting up the IOs, which is followed by some dead code (the delay is longer than any testbench I have, the function never returns). This dead code is the key to preventing the undefined state propagation, and you can just copy-paste my solution.
It may be possible to replace the call
delay(4000000);
with a
while(1);
, as long as the dead code is not optimized away by the compiler as a result.
p
ohh, it makes sense
i will try it in a moment
t
In detail (and this is just my theory): if there is no dead code, and the binary simply ends, the remaining space in the simulation model of the spiflash is either filled with undefined states, or 0s. Of course, this area is never executed from due to the
while(1);
, but that doesn't stop the processor from attempting to prefetch from that jump-to-self instruction the infinite loop compiles into. This introduces undefined states into the mgmt controller, either by directly reading them, or because 32'h00000000 is an illegal opcode in RISC-V.
Either way, the dead code causes the prefetch action to load technically valid bytecode, preventing issues.
I know that this problem also exists under sky130
t
Yes, I've seen that happen before with the prefetch on the VexRISC.
t
Its been around since forever. May be worth a GH issue.
t
A simple fix is just to add a line of zeros at the end of the hex file for the program.
p
It works, thank you very much!
I spent 2 days trying to trace this singal, tried while(1) but missed the dead code part for prefetch
t
Probably there is a better solution involving zeroing the contents of the SPI flash in the emulation model.
p
or because 32'h00000000 is an illegal opcode in RISC-V.
Would it work in that case? Maybe appending
unimp
opcode would be better?
but anyway flash should probably be zeroed
t
I actually tried zeroing the unused regions of flash, and it didn't help.
It appears it needs to be valid RISC-V opcodes
πŸ‘ 1
t
spiflash.v
line 107 and following, I think changing
Copy code
// 16 MB (128Mb) Flash
        reg [7:0] memory [0:16*1024*1024-1];

        initial begin
                $display("Memory 5 bytes = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
                        memory[1048576], memory[1048577], memory[1048578],
                        memory[1048579], memory[1048580]);
to
Copy code
// 16 MB (128Mb) Flash
        reg [7:0] memory [0:16*1024*1024-1];

        integer i;

        initial begin
                for (i=0; i < 16*1024*1024; i=i+1)
                    memory[i] = 0;

                $display("Memory 5 bytes = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
                        memory[1048576], memory[1048577], memory[1048578],
                        memory[1048579], memory[1048580]);
should fix the problem in a more permanent manner.
(Or, according to your last statement, maybe it needs to be something other than zero. But I would swear that I had solved the problem before with just making sure that the memory was zero and not undefined.)
p
i tested it now and it seems like zeroing the flash doesn't work for me 😞
t
@Piotro: Well, assuming that @Tholin is right, then it can't be set to zero but must be set to a valid RISCV opcode, which would be a bit more complicated because you'd need
i=i+4
followed by
memory[i] = ... ;  memory[i+1] = ...; ...;  memory[i+3] = ...
; then I'm not entirely sure about byte order, but assuming I can just copy the first instruction from the start section, it is probably
Copy code
for (i=0; i < 16*1024*1024; i=i+4) begin
    memory[i] = 8'h6f;
    memory[i+1] = 0;
    memory[i+2] = 0;
    memory[i+3] = 8'h0b;
end
But I admit this is starting to feel like stabbing around in the dark.
p
hmm i tried
Copy code
memory[i] = 8'h13;
    memory[i+1] = 0;
    memory[i+2] = 0;
    memory[i+3] = 8'h00;
and
Copy code
memory[i] = 8'h13;
    memory[i+1] = 0;
    memory[i+2] = 0;
    memory[i+3] = 8'h13;
for noop (0x00000013) and none of it works
eh, I was editing the
caravel/
spiflash.v instead of
mgmt_core_wrapper
one
t
Stick a syntax error into it to make sure you've got the right one.
p
yes, I did that this time
zeroing the flash works
t
Good to know! I can make a pull request for that fix. In the
mgmt_core_wrapper
repository, of course. : )
πŸ‘ 1
p
of course : )
thanks for help @Tim Edwards @Tholin
t
I have made pull requests on the
caravel_mgmt_soc_litex
repository and the equivalent GF repository in the hopes that nobody else will waste time trying to track down this particular non-issue.
πŸ‘ 1