1
0

Support SFENCE.VMA rs1 argument

This one's a little invasive.  To flush a specific entry from the TLB, you
need to reuse its CAM port.  Since the TLB lookup can be on the critical
path, we wish to avoid muxing in another address.

This is simple on the data side, where the datapath already carries rs1 to
the TLB (it's the same path as the AMO address calculation).  It's trickier
for the I$, where the TLB lookup address comes from the fetch stage PC.
The trick is to temporarily redirect the PC to rs1, then redirect the PC
again to the instruction after SFENCE.VMA.
This commit is contained in:
Andrew Waterman
2017-03-14 13:54:49 -07:00
parent 797c18b8db
commit cf168e419b
10 changed files with 61 additions and 35 deletions

View File

@ -178,7 +178,6 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle
val cause = UInt(INPUT, xLen)
val pc = UInt(INPUT, vaddrBitsExtended)
val badaddr = UInt(INPUT, vaddrBitsExtended)
val fatc = Bool(OUTPUT)
val time = UInt(OUTPUT, xLen)
val fcsr_rm = Bits(OUTPUT, FPConstants.RM_SZ)
val fcsr_flags = Valid(Bits(width = FPConstants.FLAGS_SZ)).flip
@ -410,12 +409,10 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
val system_insn = io.rw.cmd === CSR.I
val opcode = UInt(1) << io.rw.addr(2,0)
val insn_rs2 = io.rw.addr(5)
val insn_call = system_insn && !insn_rs2 && opcode(0)
val insn_call = system_insn && opcode(0)
val insn_break = system_insn && opcode(1)
val insn_ret = system_insn && opcode(2)
val insn_wfi = system_insn && opcode(5)
val insn_sfence_vma = system_insn && insn_rs2
private def decodeAny(m: LinkedHashMap[Int,Bits]): Bool = m.map { case(k: Int, _: Bits) => io.decode.csr === k }.reduce(_||_)
val allow_wfi = Bool(!usingVM) || effective_prv > PRV.S || !reg_mstatus.tw
@ -447,7 +444,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
val delegate = Bool(usingVM) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), reg_mideleg(cause_lsbs), reg_medeleg(cause_lsbs))
val debugTVec = Mux(reg_debug, UInt(0x808), UInt(0x800))
val tvec = Mux(trapToDebug, debugTVec, Mux(delegate, reg_stvec.sextTo(vaddrBitsExtended), reg_mtvec))
io.fatc := insn_sfence_vma
io.evec := tvec
io.ptbr := reg_sptbr
io.eret := insn_call || insn_break || insn_ret