Spot repeated requests with same address in ICache memory monitor

Without this, you get test failures if there are two back-to-back
branches to the same address that happen at the same time as a seed
update. The problem is that you only see one request transaction (with
the first seed), and the two memory responses both come back with the
first seed, when the second should have had the second seed.
This commit is contained in:
Rupert Swarbrick 2020-06-02 16:07:37 +01:00 committed by Rupert Swarbrick
parent e79e6b58ca
commit 608ad2dfbc

View file

@ -47,12 +47,30 @@ class ibex_icache_mem_monitor
// request appeared.
task automatic collect_requests();
forever begin
// Wait for either a posedge on req or any change to the address
@(posedge cfg.vif.req or cfg.vif.addr);
// At this point, req will be low. Wait for a posedge (the first request).
@(posedge cfg.vif.req);
// There will now be 1 or more "request events" while the request line remains high. Report
// each to the sequence.
while (cfg.vif.req) begin
// Wait between seeing the request and looking for a seed. It's a bit sad not to have a
// cleverer bit of synchronization, but the problem is that the core can decide to send us a
// new seed and do the second of 2 back-to-back branches to the same address, both at the
// same time. Without this delay, we might get here (via the grant event) before the core
// sends the new seed.
#1step;
// Check that the request didn't go away while we were waiting.
if (!cfg.vif.req) break;
// If the req line is high, pass the "new address" request to the driver
if (cfg.vif.req)
new_request(cfg.vif.addr);
// Now wait for the end of the request, which is caused by a drop in req, a change in
// address or the request being seen (positive clock edge with gnt=1). In the final case,
// this should be treated as a back-to-back request.
@(negedge cfg.vif.req or cfg.vif.addr or posedge cfg.vif.clk);
end
end
endtask
@ -63,8 +81,9 @@ class ibex_icache_mem_monitor
logic pending_req = 1'b0;
forever begin
if (cfg.vif.monitor_cb.req & cfg.vif.monitor_cb.gnt & !cfg.vif.monitor_cb.pmp_err)
if (cfg.vif.monitor_cb.req && cfg.vif.monitor_cb.gnt && !cfg.vif.monitor_cb.pmp_err) begin
new_grant(cfg.vif.monitor_cb.addr);
end
@(cfg.vif.monitor_cb);
end