提交 00ad41d0 编写于 作者: Y Yinan Xu

roq: support RenameWidth <= CommitWidth

上级 4fcc0784
......@@ -49,7 +49,7 @@ class FreeList extends XSModule with HasFreeListConsts with HasCircularQueuePtrH
// do checkpoints
// val cpReqs = Vec(RenameWidth, Flipped(ValidIO(new BrqPtr)))
val walk = Flipped(ValidIO(UInt(log2Up(RenameWidth).W)))
val walk = Flipped(ValidIO(UInt(log2Up(CommitWidth + 1).W)))
// dealloc phy regs
val deallocReqs = Input(Vec(CommitWidth, Bool()))
......
......@@ -40,17 +40,17 @@ class Rename extends XSModule {
printRenameInfo(x, y)
}
val fpFreeList, intFreeList = Module(new FreeList).io
val fpRat = Module(new RenameTable(float = true)).io
val intFreeList, fpFreeList = Module(new FreeList).io
val intRat = Module(new RenameTable(float = false)).io
val fpRat = Module(new RenameTable(float = true)).io
val allPhyResource = Seq((intRat, intFreeList, false), (fpRat, fpFreeList, true))
fpFreeList.redirect := io.redirect
intFreeList.redirect := io.redirect
fpRat.redirect := io.redirect
intRat.redirect := io.redirect
fpRat.walkWen := io.roqCommits.isWalk
intRat.walkWen := io.roqCommits.isWalk
allPhyResource.map{ case (rat, freelist, _) =>
rat.redirect := io.redirect
rat.walkWen := io.roqCommits.isWalk
freelist.redirect := io.redirect
freelist.walk.valid := io.roqCommits.isWalk
}
def needDestReg[T <: CfCtrl](fp: Boolean, x: T): Bool = {
{if(fp) x.ctrl.fpWen else x.ctrl.rfWen && (x.ctrl.ldest =/= 0.U)}
......@@ -58,14 +58,15 @@ class Rename extends XSModule {
def needDestRegCommit[T <: RoqCommitInfo](fp: Boolean, x: T): Bool = {
{if(fp) x.fpWen else x.rfWen && (x.ldest =/= 0.U)}
}
fpFreeList.walk.valid := io.roqCommits.isWalk
intFreeList.walk.valid := io.roqCommits.isWalk
fpFreeList.walk.bits := PopCount((0 until CommitWidth).map(i => io.roqCommits.valid(i) && needDestRegCommit(true, io.roqCommits.info(i))))
intFreeList.walk.bits := PopCount((0 until CommitWidth).map(i => io.roqCommits.valid(i) && needDestRegCommit(false, io.roqCommits.info(i))))
fpFreeList.walk.bits := PopCount(io.roqCommits.valid.zip(io.roqCommits.info).map{case (v, i) => v && needDestRegCommit(true, i)})
intFreeList.walk.bits := PopCount(io.roqCommits.valid.zip(io.roqCommits.info).map{case (v, i) => v && needDestRegCommit(false, i)})
// walk has higher priority than allocation and thus we don't use isWalk here
fpFreeList.req.doAlloc := intFreeList.req.canAlloc && io.out(0).ready
intFreeList.req.doAlloc := fpFreeList.req.canAlloc && io.out(0).ready
/**
* Rename: allocate free physical register and update rename table
*/
val uops = Wire(Vec(RenameWidth, new MicroOp))
uops.foreach( uop => {
......@@ -84,7 +85,7 @@ class Rename extends XSModule {
val needIntDest = Wire(Vec(RenameWidth, Bool()))
val hasValid = Cat(io.in.map(_.valid)).orR
val canOut = io.out(0).ready && fpFreeList.req.canAlloc && intFreeList.req.canAlloc && !io.roqCommits.isWalk
for(i <- 0 until RenameWidth) {
for (i <- 0 until RenameWidth) {
uops(i).cf := io.in(i).bits.cf
uops(i).ctrl := io.in(i).bits.ctrl
uops(i).brTag := io.in(i).bits.brTag
......@@ -116,42 +117,17 @@ class Rename extends XSModule {
io.out(i).valid := io.in(i).valid && intFreeList.req.canAlloc && fpFreeList.req.canAlloc && !io.roqCommits.isWalk
io.out(i).bits := uops(i)
// write rename table
def writeRat(fp: Boolean) = {
val rat = if(fp) fpRat else intRat
val freeList = if(fp) fpFreeList else intFreeList
// speculative inst write
val specWen = freeList.req.allocReqs(i) && freeList.req.canAlloc && freeList.req.doAlloc && !io.roqCommits.isWalk
// walk back write
val commitDestValid = io.roqCommits.valid(i) && needDestRegCommit(fp, io.roqCommits.info(i))
val walkWen = commitDestValid && io.roqCommits.isWalk
rat.specWritePorts(i).wen := specWen || walkWen
rat.specWritePorts(i).addr := Mux(specWen, uops(i).ctrl.ldest, io.roqCommits.info(i).ldest)
rat.specWritePorts(i).wdata := Mux(specWen, freeList.req.pdests(i), io.roqCommits.info(i).old_pdest)
XSInfo(walkWen,
{if(fp) p"fp" else p"int "} + p"walk: " +
p" ldest:${rat.specWritePorts(i).addr} old_pdest:${rat.specWritePorts(i).wdata}\n"
)
rat.archWritePorts(i).wen := commitDestValid && !io.roqCommits.isWalk
rat.archWritePorts(i).addr := io.roqCommits.info(i).ldest
rat.archWritePorts(i).wdata := io.roqCommits.info(i).pdest
XSInfo(rat.archWritePorts(i).wen,
{if(fp) p"fp" else p"int "} + p" rat arch: ldest:${rat.archWritePorts(i).addr}" +
p" pdest:${rat.archWritePorts(i).wdata}\n"
)
// write speculative rename table
allPhyResource.map{ case (rat, freelist, _) =>
val specWen = freelist.req.allocReqs(i) && freelist.req.canAlloc && freelist.req.doAlloc && !io.roqCommits.isWalk
freeList.deallocReqs(i) := rat.archWritePorts(i).wen
freeList.deallocPregs(i) := io.roqCommits.info(i).old_pdest
rat.specWritePorts(i).wen := specWen
rat.specWritePorts(i).addr := uops(i).ctrl.ldest
rat.specWritePorts(i).wdata := freelist.req.pdests(i)
freelist.deallocReqs(i) := specWen
}
writeRat(fp = false)
writeRat(fp = true)
// read rename table
def readRat(lsrcList: List[UInt], ldest: UInt, fp: Boolean) = {
val rat = if(fp) fpRat else intRat
......@@ -204,4 +180,42 @@ class Rename extends XSModule {
(fpMatch || intMatch) && io.in(j).bits.ctrl.ldest === io.in(i).bits.ctrl.ldest
}).reverse)
}
/**
* Instructions commit: update freelist and rename table
*/
for (i <- 0 until CommitWidth) {
if (i >= RenameWidth) {
allPhyResource.map{ case (rat, _, _) =>
rat.specWritePorts(i).wen := false.B
rat.specWritePorts(i).addr := DontCare
rat.specWritePorts(i).wdata := DontCare
}
}
allPhyResource.map{ case (rat, freelist, fp) =>
// walk back write
val commitDestValid = io.roqCommits.valid(i) && needDestRegCommit(fp, io.roqCommits.info(i))
when (commitDestValid && io.roqCommits.isWalk) {
rat.specWritePorts(i).wen := true.B
rat.specWritePorts(i).addr := io.roqCommits.info(i).ldest
rat.specWritePorts(i).wdata := io.roqCommits.info(i).old_pdest
XSInfo({if(fp) p"fp" else p"int "} + p"walk: " +
p" ldest:${rat.specWritePorts(i).addr} old_pdest:${rat.specWritePorts(i).wdata}\n")
}
rat.archWritePorts(i).wen := commitDestValid && !io.roqCommits.isWalk
rat.archWritePorts(i).addr := io.roqCommits.info(i).ldest
rat.archWritePorts(i).wdata := io.roqCommits.info(i).pdest
XSInfo(rat.archWritePorts(i).wen,
{if(fp) p"fp" else p"int "} + p" rat arch: ldest:${rat.archWritePorts(i).addr}" +
p" pdest:${rat.archWritePorts(i).wdata}\n"
)
freelist.deallocReqs(i) := rat.archWritePorts(i).wen
freelist.deallocPregs(i) := io.roqCommits.info(i).old_pdest
}
}
}
......@@ -20,7 +20,7 @@ class RenameTable(float: Boolean) extends XSModule {
val redirect = Flipped(ValidIO(new Redirect))
val walkWen = Input(Bool())
val readPorts = Vec({if(float) 4 else 3} * RenameWidth, new RatReadPort)
val specWritePorts = Vec(RenameWidth, new RatWritePort)
val specWritePorts = Vec(CommitWidth, new RatWritePort)
val archWritePorts = Vec(CommitWidth, new RatWritePort)
})
......
......@@ -398,7 +398,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val walkFinished = walkCounter <= CommitWidth.U
// extra space is used when roq has no enough space, but mispredict recovery needs such info to walk regmap
val needExtraSpaceForMPR = VecInit((0 until CommitWidth).map(i => io.redirect.valid && io.enq.needAlloc(i)))
require(RenameWidth <= CommitWidth)
val needExtraSpaceForMPR = VecInit((0 until RenameWidth).map(i => io.redirect.valid && io.enq.needAlloc(i)))
val extraSpaceForMPR = Reg(Vec(RenameWidth, new RoqDispatchData))
val usedSpaceForMPR = Reg(Vec(RenameWidth, Bool()))
......@@ -427,8 +428,8 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
when (state === s_walk) {
io.commits.valid(i) := commit_v(i) && shouldWalkVec(i)
}.elsewhen(state === s_extrawalk) {
io.commits.valid(i) := usedSpaceForMPR(RenameWidth-i-1)
io.commits.info(i) := extraSpaceForMPR(RenameWidth-i-1)
io.commits.valid(i) := (if (i < RenameWidth) usedSpaceForMPR(RenameWidth-i-1) else false.B)
io.commits.info(i) := (if (i < RenameWidth) extraSpaceForMPR(RenameWidth-i-1) else DontCare)
state := s_walk
}
......
......@@ -180,7 +180,7 @@ int difftest_step(DiffState *s) {
// ref_difftest_exec(1);//TODO
}
else {
assert(s->commit > 0 && s->commit <= 6);
assert(s->commit > 0 && s->commit <= DIFFTEST_WIDTH);
for(int i = 0; i < s->commit; i++){
pc_wb_queue[wb_pointer] = s->wpc[i];
wen_wb_queue[wb_pointer] = selectBit(s->wen, i);
......
......@@ -5,6 +5,8 @@
#include <assert.h>
#include <string.h>
#define DIFFTEST_WIDTH 6
typedef uint64_t rtlreg_t;
typedef uint64_t paddr_t;
......
......@@ -2,8 +2,8 @@
#include "sdcard.h"
#include "difftest.h"
#include <getopt.h>
#include<signal.h>
#include<unistd.h>
#include <signal.h>
#include <unistd.h>
#include "ram.h"
#include "zlib.h"
#include "compress.h"
......@@ -178,21 +178,45 @@ inline void Emulator::read_wb_info(uint64_t *wpc, uint64_t *wdata, uint32_t *wds
#define dut_ptr_wpc(x) wpc[x] = dut_ptr->io_difftest_wpc_##x
#define dut_ptr_wdata(x) wdata[x] = dut_ptr->io_difftest_wdata_##x
#define dut_ptr_wdst(x) wdst[x] = dut_ptr->io_difftest_wdst_##x
dut_ptr_wpc(0); dut_ptr_wdata(0); dut_ptr_wdst(0);
dut_ptr_wpc(1); dut_ptr_wdata(1); dut_ptr_wdst(1);
dut_ptr_wpc(2); dut_ptr_wdata(2); dut_ptr_wdst(2);
dut_ptr_wpc(3); dut_ptr_wdata(3); dut_ptr_wdst(3);
dut_ptr_wpc(4); dut_ptr_wdata(4); dut_ptr_wdst(4);
dut_ptr_wpc(5); dut_ptr_wdata(5); dut_ptr_wdst(5);
#define dut_ptr_read_wb(x) dut_ptr_wpc(x); dut_ptr_wdata(x); dut_ptr_wdst(x);
#if DIFFTEST_WIDTH >= 13 || DIFFTEST_WIDTH < 6
#error "not supported difftest width"
#endif
dut_ptr_read_wb(0);
dut_ptr_read_wb(1);
dut_ptr_read_wb(2);
dut_ptr_read_wb(3);
dut_ptr_read_wb(4);
dut_ptr_read_wb(5);
#if DIFFTEST_WIDTH >= 7
dut_ptr_read_wb(6);
#endif
#if DIFFTEST_WIDTH >= 8
dut_ptr_read_wb(7);
#endif
#if DIFFTEST_WIDTH >= 9
dut_ptr_read_wb(8);
#endif
#if DIFFTEST_WIDTH >= 10
dut_ptr_read_wb(9);
#endif
#if DIFFTEST_WIDTH >= 11
dut_ptr_read_wb(10);
#endif
#if DIFFTEST_WIDTH >= 12
dut_ptr_read_wb(11);
#endif
}
inline void Emulator::read_store_info(uint64_t *saddr, uint64_t *sdata, uint8_t *smask) {
#define dut_ptr_saddr(x) saddr[x] = dut_ptr->io_difftest_storeAddr_##x
#define dut_ptr_sdata(x) sdata[x] = dut_ptr->io_difftest_storeData_##x
#define dut_ptr_smask(x) smask[x] = dut_ptr->io_difftest_storeMask_##x
dut_ptr_saddr(0); dut_ptr_saddr(1);
dut_ptr_sdata(0); dut_ptr_sdata(1);
dut_ptr_smask(0); dut_ptr_smask(1);
#define dut_ptr_read_store(x) dut_ptr_saddr(x); dut_ptr_sdata(x); dut_ptr_smask(x);
dut_ptr_read_store(0);
dut_ptr_read_store(1);
}
inline void Emulator::reset_ncycles(size_t cycles) {
......
......@@ -3,7 +3,6 @@
#include "VXSSimSoC.h"
#include <verilated_vcd_c.h> // Trace file format header
#define DIFFTEST_WIDTH 6
#define SNAPSHOT_INTERVAL 60 // unit: second
struct EmuArgs {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册