diff --git a/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv b/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv index f17bb98..dbdf7c1 100644 --- a/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv +++ b/src_Core/RISCY_OOO/procs/lib/GlobalSpecUpdate.bsv @@ -1,6 +1,6 @@ // Copyright (c) 2017 Massachusetts Institute of Technology -// +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -8,10 +8,10 @@ // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -26,6 +26,13 @@ import HasSpecBits::*; import GetPut::*; import Vector::*; import ReorderBuffer::*; +import FIFO::*; + +typedef struct { + Bool kill_all; + SpecTag spec_tag; + InstTag inst_tag; +} IncorrectSpec deriving(Bits, Eq, FShow); interface GlobalSpecUpdate#(numeric type correctSpecPortNum, numeric type conflictWrongSpecPortNum); interface Vector#(correctSpecPortNum, Put#(SpecTag)) correctSpec; @@ -50,6 +57,9 @@ module mkGlobalSpecUpdate#( Vector#(correctSpecPortNum, RWire#(void)) spec_conflict <- replicateM(mkRWire); // let the caller of conflictWrongSpec to be conflict with wrong spec Vector#(conflictWrongSpecPortNum, RWire#(void)) wrongSpec_conflict <- replicateM(mkRWire); + // must be a single-element fifo to ensure all pushing rules cannot fire while we are waiting + // to kill. + FIFO#(IncorrectSpec) incorrectSpec_ff <- mkFIFO1; (* fire_when_enabled, no_implicit_conditions *) rule canon_correct_spec; @@ -63,6 +73,20 @@ module mkGlobalSpecUpdate#( rob.correctSpeculation(mask); endrule + rule do_incorrect_spec; + IncorrectSpec x <- toGet(incorrectSpec_ff).get; + ifc.incorrectSpeculation(x.kill_all, x.spec_tag); + rob.incorrectSpeculation(x.kill_all, x.spec_tag, x.inst_tag); + // conflict with correct spec + for(Integer i = 0; i < valueof(correctSpecPortNum); i = i+1) begin + spec_conflict[i].wset(?); + end + // conflict with the caller of conflictWrongSpec + for(Integer i = 0; i < valueof(conflictWrongSpecPortNum); i = i+1) begin + wrongSpec_conflict[i].wset(?); + end + endrule + Vector#(correctSpecPortNum, Put#(SpecTag)) correctVec = ?; for(Integer i = 0; i < valueof(correctSpecPortNum); i = i+1) begin correctVec[i] = (interface Put; @@ -85,18 +109,8 @@ module mkGlobalSpecUpdate#( interface correctSpec = correctVec; - method Action incorrectSpec(Bool kill_all, SpecTag spec_tag, InstTag inst_tag); - ifc.incorrectSpeculation(kill_all, spec_tag); - rob.incorrectSpeculation(kill_all, spec_tag, inst_tag); - // conflict with correct spec - for(Integer i = 0; i < valueof(correctSpecPortNum); i = i+1) begin - spec_conflict[i].wset(?); - end - // conflict with the caller of conflictWrongSpec - for(Integer i = 0; i < valueof(conflictWrongSpecPortNum); i = i+1) begin - wrongSpec_conflict[i].wset(?); - end - endmethod + method Action incorrectSpec(Bool kill_all, SpecTag spec_tag, InstTag inst_tag) + = incorrectSpec_ff.enq(IncorrectSpec{kill_all: kill_all, spec_tag: spec_tag, inst_tag: inst_tag}); interface conflictWrongSpec = conflictWrongVec; endmodule