[Libre-soc-dev] [OpenPOWER-HDL-Cores] microwatt dcache potential bug (overlap r0 and r1)

Luke Kenneth Casson Leighton lkcl at lkcl.net
Fri Jan 14 23:25:02 GMT 2022


On Fri, Jan 14, 2022 at 10:26 PM lkcl <luke.leighton at gmail.com> wrote:

> >The VHDL certainly is designed to be able to handle a store coming in
> >while r1.full = 0 and the state machine is in RELOAD_WAIT_ACK state.
>
> hmm then i need to look at that closely.

arrrgh, i think i've got it.

everything's "good"... the RELOAD_WAIT_ACKs completed, set
r1.state == IDLE, no problem.

this here tries to set r1.full = 1, again, looks like it's fine:

                    -- Note that r1.full = 1 implies req_op = OP_NONE
                    if req_op = OP_LOAD_MISS or req_op = OP_LOAD_NC or
                        req_op = OP_STORE_MISS or req_op = OP_STORE_HIT then
                        r1.req <= req;
                        r1.full <= '1';
                    end if;

but... butbutbut... down below, bear in mind r1.state is currently
RELOAD_WAIT_ACK, and bear in mind ld_stbs_done=true, this
code *also* activates:

                        if req.valid = '1' and req.same_tag = '1' and
                            ((r1.dcbz = '1' and req.dcbz = '1') or
                             (r1.dcbz = '0' and req.op = OP_LOAD_MISS)) and
                            r1.store_row = get_row(req.real_addr) then
                            r1.full <= '0';

and it *overwrites* r1.full back to zero.

that's it.

it's easily solved by adding a variable, in case r1.state==IDLE:

                    r1_next_cycle := 0;
                    if req_op = OP_LOAD_MISS or req_op = OP_LOAD_NC or
                        req_op = OP_STORE_MISS or req_op = OP_STORE_HIT then
                        r1.req <= req;
                        r1.full <= '1';
                        r1_next_cycle := 1;
                    end if;

and using it in the case r1.state==STORE_WAIT_ACK:

                        if req.valid = '1' and req.same_tag = '1' and
                            ((r1.dcbz = '1' and req.dcbz = '1') or
                             (r1.dcbz = '0' and req.op = OP_LOAD_MISS)) and
                            r1.store_row = get_row(req.real_addr) then
                            r1.full <= r1_next_cycle;

that i think should do the trick.

l.



More information about the Libre-soc-dev mailing list