Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
6886802e
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
12 个月 前同步成功
通知
1183
Star
3914
Fork
526
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
XiangShan
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6886802e
编写于
1月 27, 2021
作者:
L
LinJiawei
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master' into ftq
上级
33c5e073
d708b682
变更
35
隐藏空白更改
内联
并排
Showing
35 changed file
with
930 addition
and
382 deletion
+930
-382
src/main/scala/system/SoC.scala
src/main/scala/system/SoC.scala
+10
-2
src/main/scala/top/Parameters.scala
src/main/scala/top/Parameters.scala
+1
-1
src/main/scala/xiangshan/Bundle.scala
src/main/scala/xiangshan/Bundle.scala
+52
-0
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+26
-1
src/main/scala/xiangshan/backend/CtrlBlock.scala
src/main/scala/xiangshan/backend/CtrlBlock.scala
+20
-0
src/main/scala/xiangshan/backend/IntegerBlock.scala
src/main/scala/xiangshan/backend/IntegerBlock.scala
+28
-0
src/main/scala/xiangshan/backend/MemBlock.scala
src/main/scala/xiangshan/backend/MemBlock.scala
+22
-2
src/main/scala/xiangshan/backend/decode/DecodeUnit.scala
src/main/scala/xiangshan/backend/decode/DecodeUnit.scala
+1
-5
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
+10
-9
src/main/scala/xiangshan/backend/dispatch/Dispatch2Fp.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch2Fp.scala
+2
-2
src/main/scala/xiangshan/backend/dispatch/Dispatch2Int.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch2Int.scala
+3
-3
src/main/scala/xiangshan/backend/dispatch/Dispatch2Ls.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch2Ls.scala
+16
-10
src/main/scala/xiangshan/backend/exu/Exu.scala
src/main/scala/xiangshan/backend/exu/Exu.scala
+1
-1
src/main/scala/xiangshan/backend/exu/JumpExeUnit.scala
src/main/scala/xiangshan/backend/exu/JumpExeUnit.scala
+29
-0
src/main/scala/xiangshan/backend/fu/CSR.scala
src/main/scala/xiangshan/backend/fu/CSR.scala
+48
-1
src/main/scala/xiangshan/backend/regfile/Regfile.scala
src/main/scala/xiangshan/backend/regfile/Regfile.scala
+39
-0
src/main/scala/xiangshan/backend/rename/Rename.scala
src/main/scala/xiangshan/backend/rename/Rename.scala
+15
-2
src/main/scala/xiangshan/backend/rename/RenameTable.scala
src/main/scala/xiangshan/backend/rename/RenameTable.scala
+25
-0
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+68
-41
src/main/scala/xiangshan/cache/prefetch/BestOffsetPrefetch.scala
...n/scala/xiangshan/cache/prefetch/BestOffsetPrefetch.scala
+14
-6
src/main/scala/xiangshan/cache/prefetch/StreamPrefetch.scala
src/main/scala/xiangshan/cache/prefetch/StreamPrefetch.scala
+28
-19
src/main/scala/xiangshan/mem/lsqueue/LSQWrapper.scala
src/main/scala/xiangshan/mem/lsqueue/LSQWrapper.scala
+15
-0
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
+8
-21
src/main/scala/xiangshan/mem/lsqueue/LoadQueueData.scala
src/main/scala/xiangshan/mem/lsqueue/LoadQueueData.scala
+72
-19
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
+44
-36
src/main/scala/xiangshan/mem/lsqueue/StoreQueueData.scala
src/main/scala/xiangshan/mem/lsqueue/StoreQueueData.scala
+53
-42
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
+11
-1
src/main/scala/xiangshan/mem/sbuffer/NewSbuffer.scala
src/main/scala/xiangshan/mem/sbuffer/NewSbuffer.scala
+14
-0
src/main/scala/xiangshan/package.scala
src/main/scala/xiangshan/package.scala
+23
-10
src/test/csrc/common.cpp
src/test/csrc/common.cpp
+2
-0
src/test/csrc/difftest.cpp
src/test/csrc/difftest.cpp
+38
-38
src/test/csrc/difftest.h
src/test/csrc/difftest.h
+10
-10
src/test/csrc/emu.cpp
src/test/csrc/emu.cpp
+78
-60
src/test/csrc/emu.h
src/test/csrc/emu.h
+2
-0
src/test/scala/top/XSSim.scala
src/test/scala/top/XSSim.scala
+102
-40
未找到文件。
src/main/scala/system/SoC.scala
浏览文件 @
6886802e
...
...
@@ -8,7 +8,7 @@ import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
import
freechips.rocketchip.tilelink.
{
BankBinder
,
TLBuffer
,
TLBundleParameters
,
TLCacheCork
,
TLClientNode
,
TLFilter
,
TLFuzzer
,
TLIdentityNode
,
TLToAXI4
,
TLWidthWidget
,
TLXbar
}
import
utils.
{
DebugIdentityNode
,
DataDontCareNode
}
import
utils.XSInfo
import
xiangshan.
{
HasXSParameter
,
XSCore
,
HasXSLog
}
import
xiangshan.
{
HasXSParameter
,
XSCore
,
HasXSLog
,
DifftestBundle
}
import
sifive.blocks.inclusivecache.
{
CacheParameters
,
InclusiveCache
,
InclusiveCacheMicroParameters
}
import
freechips.rocketchip.diplomacy.
{
AddressSet
,
LazyModule
,
LazyModuleImp
}
import
freechips.rocketchip.devices.tilelink.
{
DevNullParams
,
TLError
}
...
...
@@ -162,7 +162,9 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
// val meip = Input(Vec(NumCores, Bool()))
val
ila
=
if
(
env
.
FPGAPlatform
&&
EnableILA
)
Some
(
Output
(
new
ILABundle
))
else
None
})
val
difftestIO0
=
IO
(
new
DifftestBundle
())
val
difftestIO1
=
IO
(
new
DifftestBundle
())
val
difftestIO
=
Seq
(
difftestIO0
,
difftestIO1
)
plic
.
module
.
io
.
extra
.
get
.
intrVec
<>
RegNext
(
RegNext
(
Cat
(
io
.
extIntrs
)))
for
(
i
<-
0
until
NumCores
)
{
...
...
@@ -172,6 +174,12 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
xs_core
(
i
).
module
.
io
.
externalInterrupt
.
meip
:=
plic
.
module
.
io
.
extra
.
get
.
meip
(
i
)
xs_core
(
i
).
module
.
io
.
l2ToPrefetcher
<>
l2cache
(
i
).
module
.
io
}
difftestIO0
<>
DontCare
difftestIO1
<>
DontCare
if
(
env
.
DualCoreDifftest
)
{
difftestIO0
<>
xs_core
(
0
).
module
.
difftestIO
difftestIO1
<>
xs_core
(
1
).
module
.
difftestIO
}
// do not let dma AXI signals optimized out
chisel3
.
dontTouch
(
dma
.
out
.
head
.
_1
)
chisel3
.
dontTouch
(
extDev
.
out
.
head
.
_1
)
...
...
src/main/scala/top/Parameters.scala
浏览文件 @
6886802e
...
...
@@ -24,7 +24,7 @@ object Parameters {
val
simParameters
=
Parameters
(
envParameters
=
EnviromentParameters
(
FPGAPlatform
=
false
))
// sim only, disable log
val
debugParameters
=
Parameters
(
envParameters
=
simParameters
.
envParameters
.
copy
(
EnableDebug
=
true
,
EnablePerfDebug
=
true
))
// open log
val
simDualCoreParameters
=
Parameters
(
socParameters
=
SoCParameters
(
NumCores
=
2
),
envParameters
=
EnviromentParameters
(
FPGAPlatform
=
fals
e
))
val
simDualCoreParameters
=
Parameters
(
socParameters
=
SoCParameters
(
NumCores
=
2
),
envParameters
=
EnviromentParameters
(
FPGAPlatform
=
true
,
DualCoreDifftest
=
tru
e
))
val
debugDualCoreParameters
=
Parameters
(
socParameters
=
SoCParameters
(
NumCores
=
2
),
envParameters
=
simParameters
.
envParameters
.
copy
(
EnableDebug
=
true
))
private
var
parameters
=
Parameters
()
// a default parameter, can be updated before use
...
...
src/main/scala/xiangshan/Bundle.scala
浏览文件 @
6886802e
...
...
@@ -449,3 +449,55 @@ class SfenceBundle extends XSBundle {
p
"valid:0x${Hexadecimal(valid)} rs1:${bits.rs1} rs2:${bits.rs2} addr:${Hexadecimal(bits.addr)}"
}
}
class
DifftestBundle
extends
XSBundle
{
val
fromSbuffer
=
new
Bundle
()
{
val
sbufferResp
=
Output
(
Bool
())
val
sbufferAddr
=
Output
(
UInt
(
64.
W
))
val
sbufferData
=
Output
(
Vec
(
64
,
UInt
(
8.
W
)))
val
sbufferMask
=
Output
(
UInt
(
64.
W
))
}
val
fromSQ
=
new
Bundle
()
{
val
storeCommit
=
Output
(
UInt
(
2.
W
))
val
storeAddr
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeData
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeMask
=
Output
(
Vec
(
2
,
UInt
(
8.
W
)))
}
val
fromXSCore
=
new
Bundle
()
{
val
r
=
Output
(
Vec
(
64
,
UInt
(
XLEN
.
W
)))
}
val
fromCSR
=
new
Bundle
()
{
val
intrNO
=
Output
(
UInt
(
64.
W
))
val
cause
=
Output
(
UInt
(
64.
W
))
val
priviledgeMode
=
Output
(
UInt
(
2.
W
))
val
mstatus
=
Output
(
UInt
(
64.
W
))
val
sstatus
=
Output
(
UInt
(
64.
W
))
val
mepc
=
Output
(
UInt
(
64.
W
))
val
sepc
=
Output
(
UInt
(
64.
W
))
val
mtval
=
Output
(
UInt
(
64.
W
))
val
stval
=
Output
(
UInt
(
64.
W
))
val
mtvec
=
Output
(
UInt
(
64.
W
))
val
stvec
=
Output
(
UInt
(
64.
W
))
val
mcause
=
Output
(
UInt
(
64.
W
))
val
scause
=
Output
(
UInt
(
64.
W
))
val
satp
=
Output
(
UInt
(
64.
W
))
val
mip
=
Output
(
UInt
(
64.
W
))
val
mie
=
Output
(
UInt
(
64.
W
))
val
mscratch
=
Output
(
UInt
(
64.
W
))
val
sscratch
=
Output
(
UInt
(
64.
W
))
val
mideleg
=
Output
(
UInt
(
64.
W
))
val
medeleg
=
Output
(
UInt
(
64.
W
))
}
val
fromRoq
=
new
Bundle
()
{
val
commit
=
Output
(
UInt
(
32.
W
))
val
thisPC
=
Output
(
UInt
(
XLEN
.
W
))
val
thisINST
=
Output
(
UInt
(
32.
W
))
val
skip
=
Output
(
UInt
(
32.
W
))
val
wen
=
Output
(
UInt
(
32.
W
))
val
wdata
=
Output
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
// set difftest width to 6
val
wdst
=
Output
(
Vec
(
CommitWidth
,
UInt
(
32.
W
)))
// set difftest width to 6
val
wpc
=
Output
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
// set difftest width to 6
val
isRVC
=
Output
(
UInt
(
32.
W
))
val
scFailed
=
Output
(
Bool
())
}
}
\ No newline at end of file
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
6886802e
...
...
@@ -22,6 +22,14 @@ import freechips.rocketchip.tile.HasFPUParameters
import
sifive.blocks.inclusivecache.PrefetcherIO
import
utils._
object
hartIdCore
extends
(()
=>
Int
)
{
var
x
=
0
def
apply
()
:
Int
=
{
x
=
x
+
1
x
-
1
}
}
case
class
XSCoreParameters
(
XLEN
:
Int
=
64
,
...
...
@@ -295,7 +303,8 @@ case class EnviromentParameters
(
FPGAPlatform
:
Boolean
=
true
,
EnableDebug
:
Boolean
=
false
,
EnablePerfDebug
:
Boolean
=
false
EnablePerfDebug
:
Boolean
=
false
,
DualCoreDifftest
:
Boolean
=
false
)
// object AddressSpace extends HasXSParameter {
...
...
@@ -356,6 +365,8 @@ class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer)
val
externalInterrupt
=
new
ExternalInterruptIO
val
l2ToPrefetcher
=
Flipped
(
new
PrefetcherIO
(
PAddrBits
))
})
val
difftestIO
=
IO
(
new
DifftestBundle
())
difftestIO
<>
DontCare
println
(
s
"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}"
)
AddressSpace
.
printMemmap
()
...
...
@@ -488,4 +499,18 @@ class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer)
ExcitingUtils
.
addSource
(
debugArchReg
,
"difftestRegs"
,
ExcitingUtils
.
Debug
)
}
if
(
env
.
DualCoreDifftest
)
{
val
id
=
hartIdCore
()
difftestIO
.
fromSbuffer
<>
memBlock
.
difftestIO
.
fromSbuffer
difftestIO
.
fromSQ
<>
memBlock
.
difftestIO
.
fromSQ
difftestIO
.
fromCSR
<>
integerBlock
.
difftestIO
.
fromCSR
difftestIO
.
fromRoq
<>
ctrlBlock
.
difftestIO
.
fromRoq
val
debugIntReg
,
debugFpReg
=
WireInit
(
VecInit
(
Seq
.
fill
(
32
)(
0.
U
(
XLEN
.
W
))))
ExcitingUtils
.
addSink
(
debugIntReg
,
s
"DEBUG_INT_ARCH_REG$id"
,
ExcitingUtils
.
Debug
)
ExcitingUtils
.
addSink
(
debugFpReg
,
s
"DEBUG_FP_ARCH_REG$id"
,
ExcitingUtils
.
Debug
)
val
debugArchReg
=
WireInit
(
VecInit
(
debugIntReg
++
debugFpReg
))
difftestIO
.
fromXSCore
.
r
:=
debugArchReg
}
}
src/main/scala/xiangshan/backend/CtrlBlock.scala
浏览文件 @
6886802e
...
...
@@ -178,6 +178,22 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
}
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
fromRoq
=
new
Bundle
()
{
val
commit
=
Output
(
UInt
(
32.
W
))
val
thisPC
=
Output
(
UInt
(
XLEN
.
W
))
val
thisINST
=
Output
(
UInt
(
32.
W
))
val
skip
=
Output
(
UInt
(
32.
W
))
val
wen
=
Output
(
UInt
(
32.
W
))
val
wdata
=
Output
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
// set difftest width to 6
val
wdst
=
Output
(
Vec
(
CommitWidth
,
UInt
(
32.
W
)))
// set difftest width to 6
val
wpc
=
Output
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
// set difftest width to 6
val
isRVC
=
Output
(
UInt
(
32.
W
))
val
scFailed
=
Output
(
Bool
())
}
})
difftestIO
<>
DontCare
val
ftq
=
Module
(
new
Ftq
)
val
decode
=
Module
(
new
DecodeStage
)
val
rename
=
Module
(
new
Rename
)
...
...
@@ -283,6 +299,10 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
io
.
toFpBlock
.
redirect
<>
backendRedirect
io
.
toLsBlock
.
redirect
<>
backendRedirect
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
fromRoq
<>
roq
.
difftestIO
}
dispatch
.
io
.
readPortIndex
.
intIndex
<>
io
.
toIntBlock
.
readPortIndex
dispatch
.
io
.
readPortIndex
.
fpIndex
<>
io
.
toFpBlock
.
readPortIndex
...
...
src/main/scala/xiangshan/backend/IntegerBlock.scala
浏览文件 @
6886802e
...
...
@@ -92,6 +92,31 @@ class IntegerBlock
val
sbuffer
=
new
FenceToSbuffer
// to mem
}
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
fromCSR
=
new
Bundle
()
{
val
intrNO
=
Output
(
UInt
(
64.
W
))
val
cause
=
Output
(
UInt
(
64.
W
))
val
priviledgeMode
=
Output
(
UInt
(
2.
W
))
val
mstatus
=
Output
(
UInt
(
64.
W
))
val
sstatus
=
Output
(
UInt
(
64.
W
))
val
mepc
=
Output
(
UInt
(
64.
W
))
val
sepc
=
Output
(
UInt
(
64.
W
))
val
mtval
=
Output
(
UInt
(
64.
W
))
val
stval
=
Output
(
UInt
(
64.
W
))
val
mtvec
=
Output
(
UInt
(
64.
W
))
val
stvec
=
Output
(
UInt
(
64.
W
))
val
mcause
=
Output
(
UInt
(
64.
W
))
val
scause
=
Output
(
UInt
(
64.
W
))
val
satp
=
Output
(
UInt
(
64.
W
))
val
mip
=
Output
(
UInt
(
64.
W
))
val
mie
=
Output
(
UInt
(
64.
W
))
val
mscratch
=
Output
(
UInt
(
64.
W
))
val
sscratch
=
Output
(
UInt
(
64.
W
))
val
mideleg
=
Output
(
UInt
(
64.
W
))
val
medeleg
=
Output
(
UInt
(
64.
W
))
}
})
difftestIO
<>
DontCare
val
redirect
=
io
.
fromCtrlBlock
.
redirect
...
...
@@ -219,6 +244,9 @@ class IntegerBlock
jmpExeUnit
.
csrio
<>
io
.
csrio
jmpExeUnit
.
fenceio
<>
io
.
fenceio
if
(
env
.
DualCoreDifftest
)
{
jmpExeUnit
.
difftestIO
.
fromCSR
<>
difftestIO
.
fromCSR
}
// read int rf from ctrl block
intRf
.
io
.
readPorts
.
zipWithIndex
.
map
{
case
(
r
,
i
)
=>
r
.
addr
:=
io
.
fromCtrlBlock
.
readRf
(
i
)
}
...
...
src/main/scala/xiangshan/backend/MemBlock.scala
浏览文件 @
6886802e
...
...
@@ -83,6 +83,21 @@ class MemBlockImp
val
toDCachePrefetch
=
DecoupledIO
(
new
MissReq
)
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
fromSbuffer
=
new
Bundle
()
{
val
sbufferResp
=
Output
(
Bool
())
val
sbufferAddr
=
Output
(
UInt
(
64.
W
))
val
sbufferData
=
Output
(
Vec
(
64
,
UInt
(
8.
W
)))
val
sbufferMask
=
Output
(
UInt
(
64.
W
))
}
val
fromSQ
=
new
Bundle
()
{
val
storeCommit
=
Output
(
UInt
(
2.
W
))
val
storeAddr
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeData
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeMask
=
Output
(
Vec
(
2
,
UInt
(
8.
W
)))
}
})
difftestIO
<>
DontCare
val
dcache
=
outer
.
dcache
.
module
val
uncache
=
outer
.
uncache
.
module
...
...
@@ -195,6 +210,10 @@ class MemBlockImp
io
.
ptw
<>
dtlb
.
io
.
ptw
dtlb
.
io
.
sfence
<>
io
.
sfence
dtlb
.
io
.
csr
<>
io
.
tlbCsr
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
fromSbuffer
<>
sbuffer
.
difftestIO
difftestIO
.
fromSQ
<>
lsq
.
difftestIO
.
fromSQ
}
// LoadUnit
for
(
i
<-
0
until
exuParameters
.
LduCnt
)
{
...
...
@@ -212,6 +231,7 @@ class MemBlockImp
// passdown to lsq
lsq
.
io
.
loadIn
(
i
)
<>
loadUnits
(
i
).
io
.
lsq
.
loadIn
lsq
.
io
.
ldout
(
i
)
<>
loadUnits
(
i
).
io
.
lsq
.
ldout
lsq
.
io
.
loadDataForwarded
(
i
)
<>
loadUnits
(
i
).
io
.
lsq
.
loadDataForwarded
}
// StoreUnit
...
...
@@ -271,8 +291,8 @@ class MemBlockImp
val
atomic_rs0
=
exuParameters
.
LduCnt
+
0
val
atomic_rs1
=
exuParameters
.
LduCnt
+
1
val
st0_atomics
=
reservationStations
(
atomic_rs0
).
io
.
deq
.
valid
&&
reservationStations
(
atomic_rs0
).
io
.
deq
.
bits
.
uop
.
ctrl
.
fuType
===
FuType
.
mou
val
st1_atomics
=
reservationStations
(
atomic_rs1
).
io
.
deq
.
valid
&&
reservationStations
(
atomic_rs1
).
io
.
deq
.
bits
.
uop
.
ctrl
.
fuType
===
FuType
.
mou
val
st0_atomics
=
reservationStations
(
atomic_rs0
).
io
.
deq
.
valid
&&
FuType
.
storeIsAMO
(
reservationStations
(
atomic_rs0
).
io
.
deq
.
bits
.
uop
.
ctrl
.
fuType
)
val
st1_atomics
=
reservationStations
(
atomic_rs1
).
io
.
deq
.
valid
&&
FuType
.
storeIsAMO
(
reservationStations
(
atomic_rs1
).
io
.
deq
.
bits
.
uop
.
ctrl
.
fuType
)
when
(
st0_atomics
)
{
reservationStations
(
atomic_rs0
).
io
.
deq
.
ready
:=
atomicsUnit
.
io
.
in
.
ready
...
...
src/main/scala/xiangshan/backend/decode/DecodeUnit.scala
浏览文件 @
6886802e
...
...
@@ -8,16 +8,12 @@ package xiangshan.backend.decode
import
chisel3._
import
chisel3.util._
import
freechips.rocketchip.config.Parameters
import
freechips.rocketchip.rocket.
{
RVCDecoder
,
ExpandedInstruction
}
import
freechips.rocketchip.rocket.
{
CSR
,
Causes
}
import
freechips.rocketchip.util.
{
uintToBitPat
,
UIntIsOneOf
}
import
xiangshan._
import
utils._
import
xiangshan.backend._
import
xiangshan.backend.decode.Instructions._
import
freechips.rocketchip.tile.RocketTile
/**
* Abstract trait giving defaults and other relevant values to different Decode constants/
...
...
@@ -422,7 +418,7 @@ class DecodeUnit extends XSModule with DecodeUnitConstants {
cs
.
fpu
:=
fpDecoder
.
io
.
fpCtrl
// read src1~3 location
cs
.
lsrc1
:=
Mux
(
ctrl_flow
.
instr
===
LUI
||
cs
.
src1Type
===
SrcType
.
pc
,
0.
U
,
ctrl_flow
.
instr
(
RS1_MSB
,
RS1_LSB
))
cs
.
lsrc1
:=
Mux
(
ctrl_flow
.
instr
===
LUI
,
0.
U
,
ctrl_flow
.
instr
(
RS1_MSB
,
RS1_LSB
))
cs
.
lsrc2
:=
ctrl_flow
.
instr
(
RS2_MSB
,
RS2_LSB
)
cs
.
lsrc3
:=
ctrl_flow
.
instr
(
RS3_MSB
,
RS3_LSB
)
// read dest location
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
浏览文件 @
6886802e
...
...
@@ -51,9 +51,10 @@ class Dispatch1 extends XSModule with HasExceptionNO {
!
req
.
bits
.
cf
.
pd
.
notCFI
||
FuType
.
isJumpExu
(
req
.
bits
.
ctrl
.
fuType
)
))
val
isFp
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isFpExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isLs
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isMemExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isMem
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isMemExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isLs
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isLoadStore
(
req
.
bits
.
ctrl
.
fuType
)))
val
isStore
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isStoreExu
(
req
.
bits
.
ctrl
.
fuType
)))
val
isAMO
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
req
.
bits
.
ctrl
.
fuType
===
FuType
.
mou
))
val
isAMO
=
VecInit
(
io
.
fromRename
.
map
(
req
=>
FuType
.
isAMO
(
req
.
bits
.
ctrl
.
fuType
)
))
val
isBlockBackward
=
VecInit
(
io
.
fromRename
.
map
(
_
.
bits
.
ctrl
.
blockBackward
))
val
isNoSpecExec
=
VecInit
(
io
.
fromRename
.
map
(
_
.
bits
.
ctrl
.
noSpecExec
))
...
...
@@ -69,7 +70,7 @@ class Dispatch1 extends XSModule with HasExceptionNO {
val
updatedOldPdest
=
Wire
(
Vec
(
RenameWidth
,
UInt
(
PhyRegIdxWidth
.
W
)))
for
(
i
<-
0
until
RenameWidth
)
{
updatedCommitType
(
i
)
:=
Cat
(
isLs
(
i
)
&&
!
isAMO
(
i
),
isStore
(
i
)
|
isBranch
(
i
))
updatedCommitType
(
i
)
:=
Cat
(
isLs
(
i
)
,
(
isStore
(
i
)
&&
!
isAMO
(
i
)
)
|
isBranch
(
i
))
updatedPsrc1
(
i
)
:=
io
.
fromRename
.
take
(
i
).
map
(
_
.
bits
.
pdest
)
.
zip
(
if
(
i
==
0
)
Seq
()
else
io
.
renameBypass
.
lsrc1_bypass
(
i
-
1
).
asBools
)
.
foldLeft
(
io
.
fromRename
(
i
).
bits
.
psrc1
)
{
...
...
@@ -100,7 +101,8 @@ class Dispatch1 extends XSModule with HasExceptionNO {
// update commitType
updatedUop
(
i
).
ctrl
.
commitType
:=
updatedCommitType
(
i
)
// update roqIdx, lqIdx, sqIdx
updatedUop
(
i
).
roqIdx
:=
io
.
enqRoq
.
resp
(
i
)
// updatedUop(i).roqIdx := io.enqRoq.resp(i)
XSError
(
io
.
fromRename
(
i
).
valid
&&
updatedUop
(
i
).
roqIdx
.
asUInt
=/=
io
.
enqRoq
.
resp
(
i
).
asUInt
,
"they should equal"
)
updatedUop
(
i
).
lqIdx
:=
io
.
enqLsq
.
resp
(
i
).
lqIdx
updatedUop
(
i
).
sqIdx
:=
io
.
enqLsq
.
resp
(
i
).
sqIdx
}
...
...
@@ -145,9 +147,8 @@ class Dispatch1 extends XSModule with HasExceptionNO {
io
.
enqRoq
.
req
(
i
).
bits
:=
updatedUop
(
i
)
XSDebug
(
io
.
enqRoq
.
req
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)} receives nroq ${io.enqRoq.resp(i)}\n"
)
val
shouldEnqLsq
=
isLs
(
i
)
&&
!
isAMO
(
i
)
io
.
enqLsq
.
needAlloc
(
i
)
:=
io
.
fromRename
(
i
).
valid
&&
shouldEnqLsq
io
.
enqLsq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
shouldEnqLsq
&&
thisCanActualOut
(
i
)
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
io
.
enqLsq
.
needAlloc
(
i
)
:=
io
.
fromRename
(
i
).
valid
&&
isLs
(
i
)
io
.
enqLsq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
isLs
(
i
)
&&
thisCanActualOut
(
i
)
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
io
.
enqLsq
.
req
(
i
).
bits
:=
updatedUop
(
i
)
io
.
enqLsq
.
req
(
i
).
bits
.
roqIdx
:=
io
.
enqRoq
.
resp
(
i
)
XSDebug
(
io
.
enqLsq
.
req
(
i
).
valid
,
...
...
@@ -166,9 +167,9 @@ class Dispatch1 extends XSModule with HasExceptionNO {
io
.
toFpDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
!
hasException
(
i
)
&&
isFp
(
i
)
&&
thisCanActualOut
(
i
)
&&
io
.
enqLsq
.
canAccept
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toLsDq
.
canAccept
io
.
toLsDq
.
needAlloc
(
i
)
:=
io
.
fromRename
(
i
).
valid
&&
is
Ls
(
i
)
io
.
toLsDq
.
needAlloc
(
i
)
:=
io
.
fromRename
(
i
).
valid
&&
is
Mem
(
i
)
io
.
toLsDq
.
req
(
i
).
bits
:=
updatedUop
(
i
)
io
.
toLsDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
!
hasException
(
i
)
&&
is
Ls
(
i
)
&&
thisCanActualOut
(
i
)
&&
io
.
toLsDq
.
req
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
!
hasException
(
i
)
&&
is
Mem
(
i
)
&&
thisCanActualOut
(
i
)
&&
io
.
enqLsq
.
canAccept
&&
io
.
enqRoq
.
canAccept
&&
io
.
toIntDq
.
canAccept
&&
io
.
toFpDq
.
canAccept
XSDebug
(
io
.
toIntDq
.
req
(
i
).
valid
,
p
"pc 0x${Hexadecimal(io.toIntDq.req(i).bits.cf.pc)} int index $i\n"
)
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch2Fp.scala
浏览文件 @
6886802e
...
...
@@ -22,13 +22,13 @@ class Dispatch2Fp extends XSModule {
* Part 1: generate indexes for reservation stations
*/
val
fmacIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
FpDqDeqWidth
,
exuParameters
.
FmacCnt
,
true
))
val
fmacCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
fmacExeUnitCfg
.
c
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
fmacCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
FuType
.
fmacC
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
fmacPriority
=
PriorityGen
((
0
until
exuParameters
.
FmacCnt
).
map
(
i
=>
io
.
numExist
(
i
)))
fmacIndexGen
.
io
.
validBits
:=
fmacCanAccept
fmacIndexGen
.
io
.
priority
:=
fmacPriority
val
fmiscIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
FpDqDeqWidth
,
exuParameters
.
FmiscCnt
,
true
))
val
fmiscCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
fmiscExeUnitCfg
.
c
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
fmiscCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
FuType
.
fmiscC
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
fmiscPriority
=
PriorityGen
((
0
until
exuParameters
.
FmiscCnt
).
map
(
i
=>
io
.
numExist
(
i
+
exuParameters
.
FmacCnt
)))
fmiscIndexGen
.
io
.
validBits
:=
fmiscCanAccept
fmiscIndexGen
.
io
.
priority
:=
fmiscPriority
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch2Int.scala
浏览文件 @
6886802e
...
...
@@ -26,9 +26,9 @@ class Dispatch2Int extends XSModule {
* Part 1: generate indexes for reservation stations
*/
assert
(
jmpCnt
==
1
)
val
jmpCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
jumpExeUnitCfg
.
c
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
mduCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
mulDivExeUnitCfg
.
c
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
aluCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
aluExeUnitCfg
.
c
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
jmpCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
FuType
.
jmpC
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
mduCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
FuType
.
mduC
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
aluCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
FuType
.
aluC
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
jmpIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
jmpCnt
,
false
))
val
mduIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
mduCnt
,
true
))
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch2Ls.scala
浏览文件 @
6886802e
...
...
@@ -13,8 +13,6 @@ class Dispatch2Ls extends XSModule {
val
fromDq
=
Flipped
(
Vec
(
dpParams
.
LsDqDeqWidth
,
DecoupledIO
(
new
MicroOp
)))
val
readIntRf
=
Vec
(
NRMemReadPorts
,
Output
(
UInt
(
PhyRegIdxWidth
.
W
)))
val
readFpRf
=
Vec
(
exuParameters
.
StuCnt
,
Output
(
UInt
(
PhyRegIdxWidth
.
W
)))
// val intRegAddr = Vec(NRMemReadPorts, Output(UInt(PhyRegIdxWidth.W)))
// val fpRegAddr = Vec(exuParameters.StuCnt, Output(UInt(PhyRegIdxWidth.W)))
val
readIntState
=
Vec
(
NRMemReadPorts
,
Flipped
(
new
BusyTableReadIO
))
val
readFpState
=
Vec
(
exuParameters
.
StuCnt
,
Flipped
(
new
BusyTableReadIO
))
val
numExist
=
Input
(
Vec
(
exuParameters
.
LsExuCnt
,
UInt
(
log2Ceil
(
IssQueSize
).
W
)))
...
...
@@ -25,13 +23,13 @@ class Dispatch2Ls extends XSModule {
* Part 1: generate indexes for reservation stations
*/
val
loadIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
LsDqDeqWidth
,
exuParameters
.
LduCnt
,
true
))
val
loadCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
ldExeUnitCfg
.
c
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
loadCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
FuType
.
loadC
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
loadPriority
=
PriorityGen
((
0
until
exuParameters
.
LduCnt
).
map
(
i
=>
io
.
numExist
(
i
)))
loadIndexGen
.
io
.
validBits
:=
loadCanAccept
loadIndexGen
.
io
.
priority
:=
loadPriority
val
storeIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
LsDqDeqWidth
,
exuParameters
.
StuCnt
,
true
))
val
storeCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
stExeUnitCfg
.
c
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
storeCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
FuType
.
storeC
anAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
storePriority
=
PriorityGen
((
0
until
exuParameters
.
StuCnt
).
map
(
i
=>
io
.
numExist
(
i
+
exuParameters
.
LduCnt
)))
storeIndexGen
.
io
.
validBits
:=
storeCanAccept
storeIndexGen
.
io
.
priority
:=
storePriority
...
...
@@ -51,20 +49,26 @@ class Dispatch2Ls extends XSModule {
assert
(
exuParameters
.
LduCnt
==
2
)
assert
(
exuParameters
.
StuCnt
==
2
)
val
readPort
=
Seq
(
0
,
1
,
2
,
4
)
val
firstStorePsrc2
=
PriorityMux
(
storeCanAccept
,
io
.
fromDq
.
map
(
_
.
bits
.
psrc2
))
val
secondStorePsrc2
=
PriorityMux
((
1
until
4
).
map
(
i
=>
Cat
(
storeCanAccept
.
take
(
i
)).
orR
&&
storeCanAccept
(
i
)),
io
.
fromDq
.
drop
(
1
).
map
(
_
.
bits
.
psrc2
))
for
(
i
<-
0
until
exuParameters
.
LsExuCnt
)
{
if
(
i
<
exuParameters
.
LduCnt
)
{
io
.
readIntRf
(
readPort
(
i
))
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc1
io
.
readIntState
(
readPort
(
i
)).
req
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc1
}
else
{
io
.
readFpRf
(
i
-
exuParameters
.
LduCnt
)
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc2
io
.
readIntRf
(
readPort
(
i
)
)
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc1
io
.
readIntRf
(
readPort
(
i
)+
1
)
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc2
io
.
readFpState
(
i
-
exuParameters
.
LduCnt
).
req
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc2
io
.
readIntState
(
readPort
(
i
)
).
req
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc1
io
.
readIntState
(
readPort
(
i
)+
1
).
req
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
.
psrc2
}
}
// src1 always needs srcState but only store's src2 needs srcState
for
(
i
<-
0
until
4
)
{
io
.
readIntState
(
i
).
req
:=
io
.
fromDq
(
i
).
bits
.
psrc1
}
io
.
readIntState
(
4
).
req
:=
firstStorePsrc2
io
.
readIntState
(
5
).
req
:=
secondStorePsrc2
io
.
readFpState
(
0
).
req
:=
firstStorePsrc2
io
.
readFpState
(
1
).
req
:=
secondStorePsrc2
/**
* Part 3: dispatch to reservation stations
...
...
@@ -80,13 +84,15 @@ class Dispatch2Ls extends XSModule {
enq
.
valid
:=
storeIndexGen
.
io
.
mapping
(
i
-
exuParameters
.
LduCnt
).
valid
&&
storeReady
}
enq
.
bits
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
enq
.
bits
.
src1State
:=
io
.
readIntState
(
readPort
(
i
)).
resp
enq
.
bits
.
src1State
:=
io
.
readIntState
(
indexVec
(
i
)).
resp
if
(
i
<
exuParameters
.
LduCnt
)
{
enq
.
bits
.
src2State
:=
DontCare
}
else
{
enq
.
bits
.
src2State
:=
Mux
(
io
.
fromDq
(
indexVec
(
i
)).
bits
.
ctrl
.
src2Type
===
SrcType
.
fp
,
io
.
readFpState
(
i
-
exuParameters
.
LduCnt
).
resp
,
io
.
readIntState
(
readPort
(
i
)
+
1
).
resp
)
Mux
(
storePriority
(
i
-
2
)
===
0.
U
,
io
.
readFpState
(
0
).
resp
,
io
.
readFpState
(
1
).
resp
),
Mux
(
storePriority
(
i
-
2
)
===
0.
U
,
io
.
readIntState
(
4
).
resp
,
io
.
readIntState
(
5
).
resp
)
)
}
enq
.
bits
.
src3State
:=
DontCare
...
...
src/main/scala/xiangshan/backend/exu/Exu.scala
浏览文件 @
6886802e
...
...
@@ -30,7 +30,7 @@ case class ExuParameters
def
NRFuType
=
9
def
FuOpWidth
=
7
def
FuOpWidth
=
6
}
case
class
ExuConfig
...
...
src/main/scala/xiangshan/backend/exu/JumpExeUnit.scala
浏览文件 @
6886802e
...
...
@@ -30,6 +30,31 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
val
fencei
=
Output
(
Bool
())
val
sbuffer
=
new
FenceToSbuffer
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
fromCSR
=
new
Bundle
()
{
val
intrNO
=
Output
(
UInt
(
64.
W
))
val
cause
=
Output
(
UInt
(
64.
W
))
val
priviledgeMode
=
Output
(
UInt
(
2.
W
))
val
mstatus
=
Output
(
UInt
(
64.
W
))
val
sstatus
=
Output
(
UInt
(
64.
W
))
val
mepc
=
Output
(
UInt
(
64.
W
))
val
sepc
=
Output
(
UInt
(
64.
W
))
val
mtval
=
Output
(
UInt
(
64.
W
))
val
stval
=
Output
(
UInt
(
64.
W
))
val
mtvec
=
Output
(
UInt
(
64.
W
))
val
stvec
=
Output
(
UInt
(
64.
W
))
val
mcause
=
Output
(
UInt
(
64.
W
))
val
scause
=
Output
(
UInt
(
64.
W
))
val
satp
=
Output
(
UInt
(
64.
W
))
val
mip
=
Output
(
UInt
(
64.
W
))
val
mie
=
Output
(
UInt
(
64.
W
))
val
mscratch
=
Output
(
UInt
(
64.
W
))
val
sscratch
=
Output
(
UInt
(
64.
W
))
val
mideleg
=
Output
(
UInt
(
64.
W
))
val
medeleg
=
Output
(
UInt
(
64.
W
))
}
})
difftestIO
<>
DontCare
val
jmp
=
supportedFunctionUnits
.
collectFirst
{
case
j
:
Jump
=>
j
...
...
@@ -58,6 +83,10 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
csr
.
csrio
.
externalInterrupt
<>
csrio
.
externalInterrupt
csr
.
csrio
.
tlb
<>
csrio
.
tlb
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
fromCSR
<>
csr
.
difftestIO
}
fenceio
.
sfence
<>
fence
.
sfence
fenceio
.
fencei
<>
fence
.
fencei
fenceio
.
sbuffer
<>
fence
.
toSbuffer
...
...
src/main/scala/xiangshan/backend/fu/CSR.scala
浏览文件 @
6886802e
...
...
@@ -145,6 +145,29 @@ class CSR extends FunctionUnit with HasCSRConst
// TLB
val
tlb
=
Output
(
new
TlbCsrBundle
)
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
intrNO
=
Output
(
UInt
(
64.
W
))
val
cause
=
Output
(
UInt
(
64.
W
))
val
priviledgeMode
=
Output
(
UInt
(
2.
W
))
val
mstatus
=
Output
(
UInt
(
64.
W
))
val
sstatus
=
Output
(
UInt
(
64.
W
))
val
mepc
=
Output
(
UInt
(
64.
W
))
val
sepc
=
Output
(
UInt
(
64.
W
))
val
mtval
=
Output
(
UInt
(
64.
W
))
val
stval
=
Output
(
UInt
(
64.
W
))
val
mtvec
=
Output
(
UInt
(
64.
W
))
val
stvec
=
Output
(
UInt
(
64.
W
))
val
mcause
=
Output
(
UInt
(
64.
W
))
val
scause
=
Output
(
UInt
(
64.
W
))
val
satp
=
Output
(
UInt
(
64.
W
))
val
mip
=
Output
(
UInt
(
64.
W
))
val
mie
=
Output
(
UInt
(
64.
W
))
val
mscratch
=
Output
(
UInt
(
64.
W
))
val
sscratch
=
Output
(
UInt
(
64.
W
))
val
mideleg
=
Output
(
UInt
(
64.
W
))
val
medeleg
=
Output
(
UInt
(
64.
W
))
})
difftestIO
<>
DontCare
val
cfIn
=
io
.
in
.
bits
.
uop
.
cf
val
cfOut
=
Wire
(
new
CtrlFlow
)
...
...
@@ -852,6 +875,8 @@ class CSR extends FunctionUnit with HasCSRConst
}
def
readWithScala
(
addr
:
Int
)
:
UInt
=
mapping
(
addr
).
_1
val
difftestIntrNO
=
Mux
(
raiseIntr
,
causeNO
,
0.
U
)
if
(!
env
.
FPGAPlatform
)
{
// display all perfcnt when nooptrap is executed
...
...
@@ -862,7 +887,6 @@ class CSR extends FunctionUnit with HasCSRConst
}
}
val
difftestIntrNO
=
Mux
(
raiseIntr
,
causeNO
,
0.
U
)
ExcitingUtils
.
addSource
(
difftestIntrNO
,
"difftestIntrNOfromCSR"
)
ExcitingUtils
.
addSource
(
causeNO
,
"difftestCausefromCSR"
)
ExcitingUtils
.
addSource
(
priviledgeMode
,
"difftestMode"
,
Debug
)
...
...
@@ -884,4 +908,27 @@ class CSR extends FunctionUnit with HasCSRConst
ExcitingUtils
.
addSource
(
mideleg
,
"difftestMideleg"
,
Debug
)
ExcitingUtils
.
addSource
(
medeleg
,
"difftestMedeleg"
,
Debug
)
}
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
intrNO
:=
RegNext
(
difftestIntrNO
)
difftestIO
.
cause
:=
RegNext
(
causeNO
)
difftestIO
.
priviledgeMode
:=
priviledgeMode
difftestIO
.
mstatus
:=
mstatus
difftestIO
.
sstatus
:=
mstatus
&
sstatusRmask
difftestIO
.
mepc
:=
mepc
difftestIO
.
sepc
:=
sepc
difftestIO
.
mtval
:=
mtval
difftestIO
.
stval
:=
stval
difftestIO
.
mtvec
:=
mtvec
difftestIO
.
stvec
:=
stvec
difftestIO
.
mcause
:=
mcause
difftestIO
.
scause
:=
scause
difftestIO
.
satp
:=
satp
difftestIO
.
mip
:=
mipReg
difftestIO
.
mie
:=
mie
difftestIO
.
mscratch
:=
mscratch
difftestIO
.
sscratch
:=
sscratch
difftestIO
.
mideleg
:=
mideleg
difftestIO
.
medeleg
:=
medeleg
}
}
src/main/scala/xiangshan/backend/regfile/Regfile.scala
浏览文件 @
6886802e
...
...
@@ -4,6 +4,22 @@ import chisel3._
import
chisel3.util._
import
xiangshan._
object
hartIdRFInt
extends
(()
=>
Int
)
{
var
x
=
0
def
apply
()
:
Int
=
{
x
=
x
+
1
x
-
1
}
}
object
hartIdRFFp
extends
(()
=>
Int
)
{
var
x
=
0
def
apply
()
:
Int
=
{
x
=
x
+
1
x
-
1
}
}
class
RfReadPort
(
len
:
Int
)
extends
XSBundle
{
val
addr
=
Input
(
UInt
(
PhyRegIdxWidth
.
W
))
val
data
=
Output
(
UInt
(
len
.
W
))
...
...
@@ -65,6 +81,29 @@ class Regfile
ExcitingUtils
.
Debug
)
}
if
(
env
.
DualCoreDifftest
)
{
val
id
=
if
(
hasZero
)
hartIdRFInt
()
else
hartIdRFFp
()
val
debugArchRat
=
WireInit
(
VecInit
(
Seq
.
fill
(
32
)(
0.
U
(
PhyRegIdxWidth
.
W
))))
ExcitingUtils
.
addSink
(
debugArchRat
,
if
(
hasZero
)
s
"DEBUG_INI_ARCH_RAT$id"
else
s
"DEBUG_FP_ARCH_RAT$id"
,
ExcitingUtils
.
Debug
)
val
debugArchReg
=
WireInit
(
VecInit
(
debugArchRat
.
zipWithIndex
.
map
(
x
=>
if
(
hasZero
){
if
(
x
.
_2
==
0
)
0.
U
else
mem
(
x
.
_1
)
}
else
{
ieee
(
mem
(
x
.
_1
))
}
)))
ExcitingUtils
.
addSource
(
debugArchReg
,
if
(
hasZero
)
s
"DEBUG_INT_ARCH_REG$id"
else
s
"DEBUG_FP_ARCH_REG$id"
,
ExcitingUtils
.
Debug
)
}
}
else
{
val
regfile
=
Module
(
new
regfile_160x64_10w16r_sim
)
...
...
src/main/scala/xiangshan/backend/rename/Rename.scala
浏览文件 @
6886802e
...
...
@@ -4,6 +4,7 @@ import chisel3._
import
chisel3.util._
import
xiangshan._
import
utils._
import
xiangshan.backend.roq.RoqPtr
class
RenameBypassInfo
extends
XSBundle
{
val
lsrc1_bypass
=
MixedVec
(
List
.
tabulate
(
RenameWidth
-
1
)(
i
=>
UInt
((
i
+
1
).
W
)))
...
...
@@ -12,7 +13,7 @@ class RenameBypassInfo extends XSBundle {
val
ldest_bypass
=
MixedVec
(
List
.
tabulate
(
RenameWidth
-
1
)(
i
=>
UInt
((
i
+
1
).
W
)))
}
class
Rename
extends
XSModule
{
class
Rename
extends
XSModule
with
HasCircularQueuePtrHelper
{
val
io
=
IO
(
new
Bundle
()
{
val
redirect
=
Flipped
(
ValidIO
(
new
Redirect
))
val
roqCommits
=
Flipped
(
new
RoqCommitIO
)
...
...
@@ -51,6 +52,7 @@ class Rename extends XSModule {
freelist
.
redirect
:=
io
.
redirect
freelist
.
walk
.
valid
:=
io
.
roqCommits
.
isWalk
}
val
canOut
=
io
.
out
(
0
).
ready
&&
fpFreeList
.
req
.
canAlloc
&&
intFreeList
.
req
.
canAlloc
&&
!
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
)}
...
...
@@ -64,6 +66,16 @@ class Rename extends XSModule {
fpFreeList
.
req
.
doAlloc
:=
intFreeList
.
req
.
canAlloc
&&
io
.
out
(
0
).
ready
intFreeList
.
req
.
doAlloc
:=
fpFreeList
.
req
.
canAlloc
&&
io
.
out
(
0
).
ready
// speculatively assign the instruction with an roqIdx
val
validCount
=
PopCount
(
io
.
in
.
map
(
_
.
valid
))
val
roqIdxHead
=
RegInit
(
0.
U
.
asTypeOf
(
new
RoqPtr
))
val
lastCycleMisprediction
=
RegNext
(
io
.
redirect
.
valid
&&
!
io
.
redirect
.
bits
.
isUnconditional
()
&&
!
io
.
redirect
.
bits
.
flushItself
())
val
roqIdxHeadNext
=
Mux
(
io
.
redirect
.
valid
,
Mux
(
io
.
redirect
.
bits
.
isUnconditional
(),
0.
U
.
asTypeOf
(
new
RoqPtr
),
io
.
redirect
.
bits
.
roqIdx
),
Mux
(
lastCycleMisprediction
,
roqIdxHead
+
1.
U
,
Mux
(
canOut
,
roqIdxHead
+
validCount
,
roqIdxHead
))
)
roqIdxHead
:=
roqIdxHeadNext
/**
* Rename: allocate free physical register and update rename table
*/
...
...
@@ -85,7 +97,6 @@ class Rename extends XSModule {
val
needFpDest
=
Wire
(
Vec
(
RenameWidth
,
Bool
()))
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
)
{
uops
(
i
).
cf
:=
io
.
in
(
i
).
bits
.
cf
uops
(
i
).
ctrl
:=
io
.
in
(
i
).
bits
.
ctrl
...
...
@@ -114,6 +125,8 @@ class Rename extends XSModule {
)
)
uops
(
i
).
roqIdx
:=
roqIdxHead
+
i
.
U
io
.
out
(
i
).
valid
:=
io
.
in
(
i
).
valid
&&
intFreeList
.
req
.
canAlloc
&&
fpFreeList
.
req
.
canAlloc
&&
!
io
.
roqCommits
.
isWalk
io
.
out
(
i
).
bits
:=
uops
(
i
)
...
...
src/main/scala/xiangshan/backend/rename/RenameTable.scala
浏览文件 @
6886802e
...
...
@@ -15,6 +15,22 @@ class RatWritePort extends XSBundle {
val
wdata
=
Input
(
UInt
(
PhyRegIdxWidth
.
W
))
}
object
hartIdRTInt
extends
(()
=>
Int
)
{
var
x
=
0
def
apply
()
:
Int
=
{
x
=
x
+
1
x
-
1
}
}
object
hartIdRTFp
extends
(()
=>
Int
)
{
var
x
=
0
def
apply
()
:
Int
=
{
x
=
x
+
1
x
-
1
}
}
class
RenameTable
(
float
:
Boolean
)
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
val
redirect
=
Flipped
(
ValidIO
(
new
Redirect
))
...
...
@@ -65,4 +81,13 @@ class RenameTable(float: Boolean) extends XSModule {
ExcitingUtils
.
Debug
)
}
if
(
env
.
DualCoreDifftest
)
{
val
id
=
if
(
float
)
hartIdRTFp
()
else
hartIdRTInt
()
ExcitingUtils
.
addSource
(
arch_table
,
if
(
float
)
s
"DEBUG_FP_ARCH_RAT$id"
else
s
"DEBUG_INI_ARCH_RAT$id"
,
ExcitingUtils
.
Debug
)
}
}
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
6886802e
...
...
@@ -211,6 +211,20 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val
csr
=
new
RoqCSRIO
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
commit
=
Output
(
UInt
(
32.
W
))
val
thisPC
=
Output
(
UInt
(
XLEN
.
W
))
val
thisINST
=
Output
(
UInt
(
32.
W
))
val
skip
=
Output
(
UInt
(
32.
W
))
val
wen
=
Output
(
UInt
(
32.
W
))
val
wdata
=
Output
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
// set difftest width to 6
val
wdst
=
Output
(
Vec
(
CommitWidth
,
UInt
(
32.
W
)))
// set difftest width to 6
val
wpc
=
Output
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
// set difftest width to 6
val
isRVC
=
Output
(
UInt
(
32.
W
))
val
scFailed
=
Output
(
Bool
())
})
difftestIO
<>
DontCare
// instvalid field
// val valid = RegInit(VecInit(List.fill(RoqSize)(false.B)))
val
valid
=
Mem
(
RoqSize
,
Bool
())
...
...
@@ -737,55 +751,55 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
instrCnt
:=
instrCnt
+
retireCounter
io
.
csr
.
perfinfo
.
retiredInstr
:=
RegNext
(
retireCounter
)
if
(!
env
.
FPGAPlatform
)
{
//difftest signals
val
firstValidCommit
=
(
deqPtr
+
PriorityMux
(
io
.
commits
.
valid
,
VecInit
(
List
.
tabulate
(
CommitWidth
)(
_
.
U
)))).
value
val
skip
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
wen
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
wdata
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
val
wdst
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
32.
W
)))
val
diffTestDebugLrScValid
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
wpc
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
val
trapVec
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
isRVC
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
for
(
i
<-
0
until
CommitWidth
){
// io.commits(i).valid
val
idx
=
deqPtrVec
(
i
).
value
val
uop
=
debug_microOp
(
idx
)
val
DifftestSkipSC
=
false
if
(!
DifftestSkipSC
){
skip
(
i
)
:=
(
debug_exuDebug
(
idx
).
isMMIO
||
debug_exuDebug
(
idx
).
isPerfCnt
)
&&
io
.
commits
.
valid
(
i
)
}
else
{
skip
(
i
)
:=
(
debug_exuDebug
(
idx
).
isMMIO
||
debug_exuDebug
(
idx
).
isPerfCnt
||
uop
.
ctrl
.
fuType
===
FuType
.
mou
&&
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_d
||
uop
.
ctrl
.
fuType
===
FuType
.
mou
&&
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_w
)
&&
io
.
commits
.
valid
(
i
)
}
wen
(
i
)
:=
io
.
commits
.
valid
(
i
)
&&
uop
.
ctrl
.
rfWen
&&
uop
.
ctrl
.
ldest
=/=
0.
U
wdata
(
i
)
:=
debug_exuData
(
idx
)
wdst
(
i
)
:=
uop
.
ctrl
.
ldest
diffTestDebugLrScValid
(
i
)
:=
uop
.
diffTestDebugLrScValid
wpc
(
i
)
:=
SignExt
(
uop
.
cf
.
pc
,
XLEN
)
trapVec
(
i
)
:=
io
.
commits
.
valid
(
i
)
&&
(
state
===
s_idle
)
&&
uop
.
ctrl
.
isXSTrap
isRVC
(
i
)
:=
uop
.
cf
.
pd
.
isRVC
//difftest signals
val
firstValidCommit
=
(
deqPtr
+
PriorityMux
(
io
.
commits
.
valid
,
VecInit
(
List
.
tabulate
(
CommitWidth
)(
_
.
U
)))).
value
val
skip
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
wen
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
wdata
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
val
wdst
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
32.
W
)))
val
diffTestDebugLrScValid
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
wpc
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
val
trapVec
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
val
isRVC
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
for
(
i
<-
0
until
CommitWidth
)
{
// io.commits(i).valid
val
idx
=
deqPtrVec
(
i
).
value
val
uop
=
debug_microOp
(
idx
)
val
DifftestSkipSC
=
false
if
(!
DifftestSkipSC
){
skip
(
i
)
:=
(
debug_exuDebug
(
idx
).
isMMIO
||
debug_exuDebug
(
idx
).
isPerfCnt
)
&&
io
.
commits
.
valid
(
i
)
}
else
{
skip
(
i
)
:=
(
debug_exuDebug
(
idx
).
isMMIO
||
debug_exuDebug
(
idx
).
isPerfCnt
||
uop
.
ctrl
.
fuType
===
FuType
.
mou
&&
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_d
||
uop
.
ctrl
.
fuType
===
FuType
.
mou
&&
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_w
)
&&
io
.
commits
.
valid
(
i
)
}
wen
(
i
)
:=
io
.
commits
.
valid
(
i
)
&&
uop
.
ctrl
.
rfWen
&&
uop
.
ctrl
.
ldest
=/=
0.
U
wdata
(
i
)
:=
debug_exuData
(
idx
)
wdst
(
i
)
:=
uop
.
ctrl
.
ldest
diffTestDebugLrScValid
(
i
)
:=
uop
.
diffTestDebugLrScValid
wpc
(
i
)
:=
SignExt
(
uop
.
cf
.
pc
,
XLEN
)
trapVec
(
i
)
:=
io
.
commits
.
valid
(
i
)
&&
(
state
===
s_idle
)
&&
uop
.
ctrl
.
isXSTrap
isRVC
(
i
)
:=
uop
.
cf
.
pd
.
isRVC
}
val
retireCounterFix
=
Mux
(
io
.
redirectOut
.
valid
,
1.
U
,
retireCounter
)
val
retirePCFix
=
SignExt
(
Mux
(
io
.
redirectOut
.
valid
,
debug_deqUop
.
cf
.
pc
,
debug_microOp
(
firstValidCommit
).
cf
.
pc
),
XLEN
)
val
retireInstFix
=
Mux
(
io
.
redirectOut
.
valid
,
debug_deqUop
.
cf
.
instr
,
debug_microOp
(
firstValidCommit
).
cf
.
instr
)
val
scFailed
=
!
diffTestDebugLrScValid
(
0
)
&&
debug_deqUop
.
ctrl
.
fuType
===
FuType
.
mou
&&
(
debug_deqUop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_d
||
debug_deqUop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_w
)
val
scFailed
=
!
diffTestDebugLrScValid
(
0
)
&&
debug_deqUop
.
ctrl
.
fuType
===
FuType
.
mou
&&
(
debug_deqUop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_d
||
debug_deqUop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_w
)
if
(!
env
.
FPGAPlatform
)
{
val
difftestIntrNO
=
WireInit
(
0.
U
(
XLEN
.
W
))
val
difftestCause
=
WireInit
(
0.
U
(
XLEN
.
W
))
ExcitingUtils
.
addSink
(
difftestIntrNO
,
"difftestIntrNOfromCSR"
)
ExcitingUtils
.
addSink
(
difftestCause
,
"difftestCausefromCSR"
)
XSDebug
(
difftestIntrNO
=/=
0.
U
,
"difftest intrNO set %x\n"
,
difftestIntrNO
)
val
retireCounterFix
=
Mux
(
io
.
redirectOut
.
valid
,
1.
U
,
retireCounter
)
val
retirePCFix
=
SignExt
(
Mux
(
io
.
redirectOut
.
valid
,
debug_deqUop
.
cf
.
pc
,
debug_microOp
(
firstValidCommit
).
cf
.
pc
),
XLEN
)
val
retireInstFix
=
Mux
(
io
.
redirectOut
.
valid
,
debug_deqUop
.
cf
.
instr
,
debug_microOp
(
firstValidCommit
).
cf
.
instr
)
ExcitingUtils
.
addSource
(
RegNext
(
retireCounterFix
),
"difftestCommit"
,
ExcitingUtils
.
Debug
)
ExcitingUtils
.
addSource
(
RegNext
(
retirePCFix
),
"difftestThisPC"
,
ExcitingUtils
.
Debug
)
//first valid PC
...
...
@@ -814,4 +828,17 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
ExcitingUtils
.
addSource
(
hitTrap
,
"XSTRAP"
,
ConnectionType
.
Debug
)
}
}
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
commit
:=
RegNext
(
retireCounterFix
)
difftestIO
.
thisPC
:=
RegNext
(
retirePCFix
)
difftestIO
.
thisINST
:=
RegNext
(
retireInstFix
)
difftestIO
.
skip
:=
RegNext
(
skip
.
asUInt
)
difftestIO
.
wen
:=
RegNext
(
wen
.
asUInt
)
difftestIO
.
wdata
:=
RegNext
(
wdata
)
difftestIO
.
wdst
:=
RegNext
(
wdst
)
difftestIO
.
wpc
:=
RegNext
(
wpc
)
difftestIO
.
isRVC
:=
RegNext
(
isRVC
.
asUInt
)
difftestIO
.
scFailed
:=
RegNext
(
scFailed
)
}
}
src/main/scala/xiangshan/cache/prefetch/BestOffsetPrefetch.scala
浏览文件 @
6886802e
...
...
@@ -167,7 +167,7 @@ class RecentRequestTable(p: BOPParameters) extends PrefetchModule {
rrTable
.
io
.
r
.
req
.
bits
.
setIdx
:=
idx
(
rAddr
)
rData
:=
rrTable
.
io
.
r
.
resp
.
data
(
0
)
val
rwConflict
=
io
.
w
.
fire
()
&&
io
.
r
.
req
.
fire
()
&&
idx
(
wAddr
)
===
idx
(
rAddr
)
val
rwConflict
=
io
.
w
.
fire
()
&&
io
.
r
.
req
.
fire
()
//
&& idx(wAddr) === idx(rAddr)
// when (rwConflict) {
// rrTable.io.r.req.valid := false.B
// }
...
...
@@ -295,7 +295,7 @@ class OffsetScoreTable(p: BOPParameters) extends PrefetchModule {
XSDebug
(
io
.
req
.
fire
(),
p
"receive req from L1. io.req.bits=0x${Hexadecimal(io.req.bits)}\n"
)
}
class
BestOffsetPrefetchEntry
(
p
:
BOPParameters
)
extends
PrefetchModule
{
class
BestOffsetPrefetchEntry
(
p
:
BOPParameters
)
extends
PrefetchModule
with
HasTlbConst
{
val
io
=
IO
(
new
Bundle
{
val
id
=
Input
(
UInt
(
p
.
totalWidth
.
W
))
val
prefetchOffset
=
Input
(
UInt
(
p
.
offsetWidth
.
W
))
...
...
@@ -305,19 +305,27 @@ class BestOffsetPrefetchEntry(p: BOPParameters) extends PrefetchModule {
})
def
blockBytes
=
p
.
blockBytes
def
getBlockAddr
(
addr
:
UInt
)
=
Cat
(
addr
(
PAddrBits
-
1
,
log2Up
(
blockBytes
)),
0.
U
(
log2Up
(
blockBytes
).
W
))
def
getBlock
(
addr
:
UInt
)
=
addr
(
PAddrBits
-
1
,
log2Up
(
blockBytes
))
def
getBlockAddr
(
addr
:
UInt
)
=
Cat
(
getBlock
(
addr
),
0.
U
(
log2Up
(
blockBytes
).
W
))
def
getPageNum
(
addr
:
UInt
)
=
addr
(
PAddrBits
-
1
,
offLen
)
val
s_idle
::
s_req
::
s_resp
::
s_write_recent_req
::
s_finish
::
Nil
=
Enum
(
5
)
val
state
=
RegInit
(
s_idle
)
val
req
=
RegInit
(
0.
U
.
asTypeOf
(
new
PrefetchReq
))
val
baseAddr
=
RegInit
(
0.
U
(
PAddrBits
.
W
))
val
baseBlock
=
getBlock
(
io
.
pft
.
train
.
bits
.
addr
)
val
nextBlock
=
baseBlock
+
io
.
prefetchOffset
val
nextAddr
=
Cat
(
nextBlock
,
0.
U
(
log2Up
(
blockBytes
).
W
))
val
crossPage
=
getPageNum
(
nextAddr
)
=/=
getPageNum
(
io
.
pft
.
train
.
bits
.
addr
)
when
(
state
===
s_idle
)
{
when
(
io
.
pft
.
train
.
valid
)
{
state
:=
s_req
req
.
addr
:=
getBlockAddr
(
io
.
pft
.
train
.
bits
.
addr
)
+
(
io
.
prefetchOffset
<<
log2Up
(
blockBytes
))
// state := s_req
state
:=
Mux
(
crossPage
,
s_idle
,
s_req
)
req
.
addr
:=
nextAddr
req
.
write
:=
io
.
pft
.
train
.
bits
.
write
baseAddr
:=
getBlockAddr
(
io
.
pft
.
train
.
bits
.
addr
)
XSDebug
(
crossPage
,
p
"prefetch addr 0x${nextAddr} cross page, ignore this!\n"
)
}
}
...
...
@@ -357,7 +365,7 @@ class BestOffsetPrefetchEntry(p: BOPParameters) extends PrefetchModule {
io
.
writeRRTable
.
valid
:=
state
===
s_write_recent_req
io
.
writeRRTable
.
bits
:=
baseAddr
// write this into recent request table
XSDebug
(
p
"bopEntry ${io.id}: state=${state} prefetchOffset=${io.prefetchOffset} inflight=${io.inflight.valid} 0x${Hexadecimal(io.inflight.bits)} writeRRTable: ${io.writeRRTable.valid} 0x${Hexadecimal(io.writeRRTable.bits)} baseAddr=0x${Hexadecimal(baseAddr)} req: ${req}\n"
)
XSDebug
(
p
"bopEntry ${io.id}: state=${state} prefetchOffset=${io.prefetchOffset} inflight=${io.inflight.valid} 0x${Hexadecimal(io.inflight.bits)} writeRRTable: ${io.writeRRTable.valid} 0x${Hexadecimal(io.writeRRTable.bits)} baseAddr=0x${Hexadecimal(baseAddr)}
nextAddr=0x${Hexadecimal(nextAddr)} crossPage=${crossPage}
req: ${req}\n"
)
XSDebug
(
p
"bopEntry ${io.id}: io.pft: ${io.pft}\n"
)
}
...
...
src/main/scala/xiangshan/cache/prefetch/StreamPrefetch.scala
浏览文件 @
6886802e
...
...
@@ -85,7 +85,7 @@ class StreamBufferAlloc(p: StreamPrefetchParameters) extends StreamPrefetchReq(p
}
class
StreamBuffer
(
p
:
StreamPrefetchParameters
)
extends
PrefetchModule
{
class
StreamBuffer
(
p
:
StreamPrefetchParameters
)
extends
PrefetchModule
with
HasTlbConst
{
val
io
=
IO
(
new
Bundle
{
val
streamBufId
=
Input
(
UInt
(
log2Up
(
streamCnt
).
W
))
val
addrs
=
Vec
(
p
.
streamSize
,
ValidIO
(
UInt
(
PAddrBits
.
W
)))
...
...
@@ -102,6 +102,7 @@ class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule {
def
blockBytes
=
p
.
blockBytes
// def getBlockAddr(addr: UInt) = addr & ~((blockBytes - 1).U(addr.getWidth.W))
def
getBlockAddr
(
addr
:
UInt
)
=
Cat
(
addr
(
PAddrBits
-
1
,
log2Up
(
p
.
blockBytes
)),
0.
U
(
log2Up
(
p
.
blockBytes
).
W
))
def
getPageNum
(
addr
:
UInt
)
=
addr
(
PAddrBits
-
1
,
offLen
)
val
baseReq
=
RegInit
(
0.
U
.
asTypeOf
(
Valid
(
new
PrefetchReq
)))
val
nextReq
=
RegInit
(
0.
U
.
asTypeOf
(
new
PrefetchReq
))
...
...
@@ -163,11 +164,17 @@ class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule {
}
// enqueue
val
nextAddrCrossPage
=
getPageNum
(
baseReq
.
bits
.
addr
)
=/=
getPageNum
(
nextReq
.
addr
)
when
(!
full
&&
baseReq
.
valid
&&
!
needRealloc
)
{
state
(
tail
)
:=
s_req
tail
:=
tail
+
1.
U
buf
(
tail
)
:=
nextReq
nextReq
.
addr
:=
nextReq
.
addr
+
blockBytes
.
U
when
(!
nextAddrCrossPage
)
{
state
(
tail
)
:=
s_req
tail
:=
tail
+
1.
U
buf
(
tail
)
:=
nextReq
nextReq
.
addr
:=
nextReq
.
addr
+
blockBytes
.
U
XSDebug
(
p
"enqueue 0x${nextReq.addr}\n"
)
}.
otherwise
{
XSDebug
(
p
"addr 0x${nextReq.addr} could not enqueue for crossing pages\n"
)
}
}
val
reqs
=
Wire
(
Vec
(
streamSize
,
Decoupled
(
new
StreamPrefetchReq
(
p
))))
...
...
@@ -259,7 +266,7 @@ class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule {
p
"deqLater: ${deqLater(i)} deqValid: ${deqValid(i)}\n"
)
}
XSDebug
(
s
"${p.cacheName} "
+
p
"StreamBuf ${io.streamBufId} head: ${head} tail: ${tail} full: ${full} empty: ${empty} nextHead: ${nextHead} blockBytes: ${blockBytes.U}\n"
)
XSDebug
(
s
"${p.cacheName} "
+
p
"StreamBuf ${io.streamBufId} baseReq: v=${baseReq.valid} ${baseReq.bits} nextReq: ${nextReq}\n"
)
XSDebug
(
s
"${p.cacheName} "
+
p
"StreamBuf ${io.streamBufId} baseReq: v=${baseReq.valid} ${baseReq.bits} nextReq: ${nextReq}
crossPage: ${nextAddrCrossPage}
\n"
)
XSDebug
(
needRealloc
,
s
"${p.cacheName} "
+
p
"StreamBuf ${io.streamBufId} needRealloc: ${needRealloc} reallocReq: ${reallocReq}\n"
)
XSDebug
(
s
"${p.cacheName} "
+
p
"StreamBuf ${io.streamBufId} prefetchPrior: "
)
(
0
until
streamSize
).
foreach
(
i
=>
XSDebug
(
false
,
true
.
B
,
p
"${prefetchPrior(i)} "
))
...
...
@@ -312,38 +319,40 @@ class StreamPrefetch(p: StreamPrefetchParameters) extends PrefetchModule {
// 1. streamBufs hit while l1i miss
val
hit
=
WireInit
(
false
.
B
)
val
hitVec
=
WireInit
(
VecInit
(
Seq
.
fill
(
streamCnt
*
streamSize
)(
false
.
B
)))
for
(
i
<-
0
until
streamCnt
)
{
for
(
j
<-
0
until
streamSize
)
{
when
(
io
.
train
.
valid
&&
addrValids
(
i
)(
j
)
&&
getBlockAddr
(
io
.
train
.
bits
.
addr
)
===
streamBufs
(
i
).
io
.
addrs
(
j
).
bits
)
{
hit
:=
true
.
B
// hit := true.B
hitVec
(
i
*
streamSize
+
j
)
:=
true
.
B
streamBufs
(
i
).
io
.
update
.
valid
:=
true
.
B
streamBufs
(
i
).
io
.
update
.
bits
.
hitIdx
:=
j
.
U
ages
(
i
)
:=
maxAge
}
}
}
hit
:=
ParallelOR
(
hitVec
)
// 2. streamBufs miss
val
allocIdx
=
Wire
(
UInt
(
log2Up
(
streamCnt
).
W
))
val
ageCmp
=
Seq
.
fill
(
streamCnt
)(
Wire
(
new
CompareBundle
(
ageWidth
)))
(
0
until
streamCnt
).
foreach
(
i
=>
ageCmp
(
i
).
bits
:=
ages
(
i
))
(
0
until
streamCnt
).
foreach
(
i
=>
ageCmp
(
i
).
idx
:=
i
.
U
)
when
((~
bufValids
.
asUInt
).
orR
)
{
allocIdx
:=
PriorityMux
(~
bufValids
.
asUInt
,
VecInit
(
List
.
tabulate
(
streamCnt
)(
_
.
U
)))
}.
otherwise
{
allocIdx
:=
ParallelMin
(
ageCmp
).
idx
}
when
(!
hit
&&
io
.
train
.
valid
)
{
(
0
until
streamCnt
).
foreach
(
i
=>
ages
(
i
)
:=
Mux
(
ages
(
i
)
=/=
0.
U
,
ages
(
i
)
-
1.
U
,
0.
U
))
// realloc an invalid or the eldest stream buffer with new one
val
idx
=
Wire
(
UInt
(
log2Up
(
streamCnt
).
W
))
when
((~
bufValids
.
asUInt
).
orR
)
{
idx
:=
PriorityMux
(~
bufValids
.
asUInt
,
VecInit
(
List
.
tabulate
(
streamCnt
)(
_
.
U
)))
}.
otherwise
{
val
ageCmp
=
Seq
.
fill
(
streamCnt
)(
Wire
(
new
CompareBundle
(
ageWidth
)))
(
0
until
streamCnt
).
foreach
(
i
=>
ageCmp
(
i
).
bits
:=
ages
(
i
))
(
0
until
streamCnt
).
foreach
(
i
=>
ageCmp
(
i
).
idx
:=
i
.
U
)
idx
:=
ParallelMin
(
ageCmp
).
idx
}
for
(
i
<-
0
until
streamCnt
)
{
streamBufs
(
i
).
io
.
alloc
.
valid
:=
i
dx
===
i
.
U
streamBufs
(
i
).
io
.
alloc
.
valid
:=
allocI
dx
===
i
.
U
streamBufs
(
i
).
io
.
alloc
.
bits
:=
DontCare
streamBufs
(
i
).
io
.
alloc
.
bits
.
addr
:=
io
.
train
.
bits
.
addr
streamBufs
(
i
).
io
.
alloc
.
bits
.
write
:=
io
.
train
.
bits
.
write
when
(
i
dx
===
i
.
U
)
{
ages
(
i
)
:=
maxAge
}
when
(
allocI
dx
===
i
.
U
)
{
ages
(
i
)
:=
maxAge
}
}
}
...
...
src/main/scala/xiangshan/mem/lsqueue/LSQWrapper.scala
浏览文件 @
6886802e
...
...
@@ -41,6 +41,7 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
val
brqRedirect
=
Input
(
Valid
(
new
Redirect
))
val
loadIn
=
Vec
(
LoadPipelineWidth
,
Flipped
(
Valid
(
new
LsPipelineBundle
)))
val
storeIn
=
Vec
(
StorePipelineWidth
,
Flipped
(
Valid
(
new
LsPipelineBundle
)))
val
loadDataForwarded
=
Vec
(
LoadPipelineWidth
,
Input
(
Bool
()))
val
sbuffer
=
Vec
(
StorePipelineWidth
,
Decoupled
(
new
DCacheWordReq
))
val
ldout
=
Vec
(
2
,
DecoupledIO
(
new
ExuOutput
))
// writeback int load
val
mmioStout
=
DecoupledIO
(
new
ExuOutput
)
// writeback uncached store
...
...
@@ -53,6 +54,15 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
val
exceptionAddr
=
new
ExceptionAddrIO
val
sqempty
=
Output
(
Bool
())
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
fromSQ
=
new
Bundle
()
{
val
storeCommit
=
Output
(
UInt
(
2.
W
))
val
storeAddr
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeData
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeMask
=
Output
(
Vec
(
2
,
UInt
(
8.
W
)))
}
})
difftestIO
<>
DontCare
val
loadQueue
=
Module
(
new
LoadQueue
)
val
storeQueue
=
Module
(
new
StoreQueue
)
...
...
@@ -82,6 +92,7 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
loadQueue
.
io
.
brqRedirect
<>
io
.
brqRedirect
loadQueue
.
io
.
loadIn
<>
io
.
loadIn
loadQueue
.
io
.
storeIn
<>
io
.
storeIn
loadQueue
.
io
.
loadDataForwarded
<>
io
.
loadDataForwarded
loadQueue
.
io
.
ldout
<>
io
.
ldout
loadQueue
.
io
.
commits
<>
io
.
commits
loadQueue
.
io
.
rollback
<>
io
.
rollback
...
...
@@ -106,6 +117,10 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
storeQueue
.
io
.
sqempty
<>
io
.
sqempty
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
fromSQ
<>
storeQueue
.
difftestIO
}
io
.
exceptionAddr
.
vaddr
:=
Mux
(
io
.
exceptionAddr
.
isStore
,
storeQueue
.
io
.
exceptionAddr
.
vaddr
,
loadQueue
.
io
.
exceptionAddr
.
vaddr
)
// naive uncache arbiter
...
...
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
浏览文件 @
6886802e
...
...
@@ -66,6 +66,7 @@ class LoadQueue extends XSModule
val
brqRedirect
=
Input
(
Valid
(
new
Redirect
))
val
loadIn
=
Vec
(
LoadPipelineWidth
,
Flipped
(
Valid
(
new
LsPipelineBundle
)))
val
storeIn
=
Vec
(
StorePipelineWidth
,
Flipped
(
Valid
(
new
LsPipelineBundle
)))
val
loadDataForwarded
=
Vec
(
LoadPipelineWidth
,
Input
(
Bool
()))
val
ldout
=
Vec
(
2
,
DecoupledIO
(
new
ExuOutput
))
// writeback int load
val
load_s1
=
Vec
(
LoadPipelineWidth
,
Flipped
(
new
LoadForwardQueryIO
))
val
commits
=
Flipped
(
new
RoqCommitIO
)
...
...
@@ -85,7 +86,6 @@ class LoadQueue extends XSModule
val
allocated
=
RegInit
(
VecInit
(
List
.
fill
(
LoadQueueSize
)(
false
.
B
)))
// lq entry has been allocated
val
datavalid
=
RegInit
(
VecInit
(
List
.
fill
(
LoadQueueSize
)(
false
.
B
)))
// data is valid
val
writebacked
=
RegInit
(
VecInit
(
List
.
fill
(
LoadQueueSize
)(
false
.
B
)))
// inst has been writebacked to CDB
val
commited
=
Reg
(
Vec
(
LoadQueueSize
,
Bool
()))
// inst has been writebacked to CDB
val
miss
=
Reg
(
Vec
(
LoadQueueSize
,
Bool
()))
// load inst missed, waiting for miss queue to accept miss request
// val listening = Reg(Vec(LoadQueueSize, Bool())) // waiting for refill result
val
pending
=
Reg
(
Vec
(
LoadQueueSize
,
Bool
()))
// mmio pending: inst is an mmio inst, it will not be executed until it reachs the end of roq
...
...
@@ -95,7 +95,6 @@ class LoadQueue extends XSModule
val
enqPtrExt
=
RegInit
(
VecInit
((
0
until
RenameWidth
).
map
(
_
.
U
.
asTypeOf
(
new
LqPtr
))))
val
deqPtrExt
=
RegInit
(
0.
U
.
asTypeOf
(
new
LqPtr
))
val
deqPtrExtNext
=
Wire
(
new
LqPtr
)
val
validCounter
=
RegInit
(
0.
U
(
log2Ceil
(
LoadQueueSize
+
1
).
W
))
val
allowEnqueue
=
RegInit
(
true
.
B
)
val
enqPtr
=
enqPtrExt
(
0
).
value
...
...
@@ -127,7 +126,6 @@ class LoadQueue extends XSModule
allocated
(
index
)
:=
true
.
B
datavalid
(
index
)
:=
false
.
B
writebacked
(
index
)
:=
false
.
B
commited
(
index
)
:=
false
.
B
miss
(
index
)
:=
false
.
B
// listening(index) := false.B
pending
(
index
)
:=
false
.
B
...
...
@@ -177,13 +175,13 @@ class LoadQueue extends XSModule
io
.
loadIn
(
i
).
bits
.
mmio
)}
val
loadWbIndex
=
io
.
loadIn
(
i
).
bits
.
uop
.
lqIdx
.
value
datavalid
(
loadWbIndex
)
:=
!
io
.
loadIn
(
i
).
bits
.
miss
&&
!
io
.
loadIn
(
i
).
bits
.
mmio
datavalid
(
loadWbIndex
)
:=
(!
io
.
loadIn
(
i
).
bits
.
miss
||
io
.
loadDataForwarded
(
i
))
&&
!
io
.
loadIn
(
i
).
bits
.
mmio
writebacked
(
loadWbIndex
)
:=
!
io
.
loadIn
(
i
).
bits
.
miss
&&
!
io
.
loadIn
(
i
).
bits
.
mmio
val
loadWbData
=
Wire
(
new
LQDataEntry
)
loadWbData
.
paddr
:=
io
.
loadIn
(
i
).
bits
.
paddr
loadWbData
.
mask
:=
io
.
loadIn
(
i
).
bits
.
mask
loadWbData
.
data
:=
io
.
loadIn
(
i
).
bits
.
data
// fwd data
loadWbData
.
data
:=
io
.
loadIn
(
i
).
bits
.
forwardData
.
asUInt
// fwd data
loadWbData
.
fwdMask
:=
io
.
loadIn
(
i
).
bits
.
forwardMask
dataModule
.
io
.
wbWrite
(
i
,
loadWbIndex
,
loadWbData
)
dataModule
.
io
.
wb
.
wen
(
i
)
:=
true
.
B
...
...
@@ -195,7 +193,7 @@ class LoadQueue extends XSModule
debug_mmio
(
loadWbIndex
)
:=
io
.
loadIn
(
i
).
bits
.
mmio
val
dcacheMissed
=
io
.
loadIn
(
i
).
bits
.
miss
&&
!
io
.
loadIn
(
i
).
bits
.
mmio
miss
(
loadWbIndex
)
:=
dcacheMissed
miss
(
loadWbIndex
)
:=
dcacheMissed
&&
!
io
.
loadDataForwarded
(
i
)
pending
(
loadWbIndex
)
:=
io
.
loadIn
(
i
).
bits
.
mmio
uop
(
loadWbIndex
).
debugInfo
.
issueTime
:=
io
.
loadIn
(
i
).
bits
.
uop
.
debugInfo
.
issueTime
}
...
...
@@ -554,7 +552,7 @@ class LoadQueue extends XSModule
// invalidate lq term using robIdx
val
needCancel
=
Wire
(
Vec
(
LoadQueueSize
,
Bool
()))
for
(
i
<-
0
until
LoadQueueSize
)
{
needCancel
(
i
)
:=
uop
(
i
).
roqIdx
.
needFlush
(
io
.
brqRedirect
)
&&
allocated
(
i
)
&&
!
commited
(
i
)
needCancel
(
i
)
:=
uop
(
i
).
roqIdx
.
needFlush
(
io
.
brqRedirect
)
&&
allocated
(
i
)
when
(
needCancel
(
i
))
{
allocated
(
i
)
:=
false
.
B
}
...
...
@@ -578,19 +576,9 @@ class LoadQueue extends XSModule
deqPtrExt
:=
deqPtrExtNext
val
lastLastCycleRedirect
=
RegNext
(
lastCycleRedirect
.
valid
)
val
trueValidCounter
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
)
validCounter
:=
Mux
(
lastLastCycleRedirect
,
trueValidCounter
,
validCounter
+
enqNumber
-
commitCount
)
allowEnqueue
:=
Mux
(
io
.
brqRedirect
.
valid
,
false
.
B
,
Mux
(
lastLastCycleRedirect
,
trueValidCounter
<=
(
LoadQueueSize
-
RenameWidth
).
U
,
validCounter
+
enqNumber
<=
(
LoadQueueSize
-
RenameWidth
).
U
)
)
val
validCount
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
)
allowEnqueue
:=
validCount
+
enqNumber
<=
(
LoadQueueSize
-
RenameWidth
).
U
// debug info
XSDebug
(
"enqPtrExt %d:%d deqPtrExt %d:%d\n"
,
enqPtrExt
(
0
).
flag
,
enqPtr
,
deqPtrExt
.
flag
,
deqPtr
)
...
...
@@ -609,7 +597,6 @@ class LoadQueue extends XSModule
PrintFlag
(
allocated
(
i
),
"a"
)
PrintFlag
(
allocated
(
i
)
&&
datavalid
(
i
),
"v"
)
PrintFlag
(
allocated
(
i
)
&&
writebacked
(
i
),
"w"
)
PrintFlag
(
allocated
(
i
)
&&
commited
(
i
),
"c"
)
PrintFlag
(
allocated
(
i
)
&&
miss
(
i
),
"m"
)
// PrintFlag(allocated(i) && listening(i), "l")
PrintFlag
(
allocated
(
i
)
&&
pending
(
i
),
"p"
)
...
...
src/main/scala/xiangshan/mem/lsqueue/LoadQueueData.scala
浏览文件 @
6886802e
...
...
@@ -106,6 +106,51 @@ class MaskModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule
}
}
class
Data8Module
(
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
XSModule
with
HasDCacheParameters
{
val
io
=
IO
(
new
Bundle
{
// read
val
raddr
=
Input
(
Vec
(
numRead
,
UInt
(
log2Up
(
numEntries
).
W
)))
val
rdata
=
Output
(
Vec
(
numRead
,
UInt
(
8.
W
)))
// address indexed write
val
wen
=
Input
(
Vec
(
numWrite
,
Bool
()))
val
waddr
=
Input
(
Vec
(
numWrite
,
UInt
(
log2Up
(
numEntries
).
W
)))
val
wdata
=
Input
(
Vec
(
numWrite
,
UInt
(
8.
W
)))
// masked write
val
mwmask
=
Input
(
Vec
(
blockWords
,
Vec
(
numEntries
,
Bool
())))
val
mwdata
=
Input
(
Vec
(
blockWords
,
UInt
(
8.
W
)))
})
val
data
=
Reg
(
Vec
(
numEntries
,
UInt
(
8.
W
)))
// read ports
for
(
i
<-
0
until
numRead
)
{
io
.
rdata
(
i
)
:=
data
(
RegNext
(
io
.
raddr
(
i
)))
}
// below is the write ports (with priorities)
for
(
i
<-
0
until
numWrite
)
{
when
(
io
.
wen
(
i
))
{
data
(
io
.
waddr
(
i
))
:=
io
.
wdata
(
i
)
}
}
// masked write
for
(
i
<-
0
until
blockWords
)
{
for
(
j
<-
0
until
numEntries
)
{
when
(
io
.
mwmask
(
i
)(
j
))
{
data
(
j
)
:=
io
.
mwdata
(
i
)
}
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for
(
i
<-
0
until
numWrite
)
{
for
(
j
<-
i
+
1
until
numWrite
)
{
assert
(!(
io
.
wen
(
i
)
&&
io
.
wen
(
j
)
&&
io
.
waddr
(
i
)
===
io
.
waddr
(
j
)))
}
}
}
class
CoredataModule
(
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
XSModule
with
HasDCacheParameters
{
val
io
=
IO
(
new
Bundle
{
// data io
...
...
@@ -131,20 +176,28 @@ class CoredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMod
val
paddrWen
=
Input
(
Vec
(
numWrite
,
Bool
()))
})
val
data
=
Reg
(
Vec
(
numEntries
,
UInt
(
XLEN
.
W
)))
val
data
8
=
Seq
.
fill
(
8
)(
Module
(
new
Data8Module
(
numEntries
,
numRead
,
numWrite
)))
val
fwdMask
=
Reg
(
Vec
(
numEntries
,
UInt
(
8.
W
)))
val
wordIndex
=
Reg
(
Vec
(
numEntries
,
UInt
((
blockOffBits
-
wordOffBits
).
W
)))
// read ports
for
(
i
<-
0
until
numRead
)
{
io
.
rdata
(
i
)
:=
data
(
RegNext
(
io
.
raddr
(
i
)))
for
(
j
<-
0
until
8
)
{
data8
(
j
).
io
.
raddr
(
i
)
:=
io
.
raddr
(
i
)
}
io
.
rdata
(
i
)
:=
VecInit
((
0
until
8
).
map
(
j
=>
data8
(
j
).
io
.
rdata
(
i
))).
asUInt
}
// below is the write ports (with priorities)
for
(
i
<-
0
until
numWrite
)
{
when
(
io
.
wen
(
i
))
{
data
(
io
.
waddr
(
i
))
:=
io
.
wdata
(
i
)
// write to data8
for
(
j
<-
0
until
8
)
{
data8
(
j
).
io
.
waddr
(
i
)
:=
io
.
waddr
(
i
)
data8
(
j
).
io
.
wdata
(
i
)
:=
io
.
wdata
(
i
)(
8
*(
j
+
1
)-
1
,
8
*
j
)
data8
(
j
).
io
.
wen
(
i
)
:=
io
.
wen
(
i
)
}
// write ctrl info
when
(
io
.
fwdMaskWen
(
i
))
{
fwdMask
(
io
.
waddr
(
i
))
:=
io
.
fwdMaskWdata
(
i
)
}
...
...
@@ -153,25 +206,25 @@ class CoredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMod
}
}
// write refilled data to data8
// masked write
// refill missed load
def
mergeRefillData
(
refill
:
UInt
,
fwd
:
UInt
,
fwdMask
:
UInt
)
:
UInt
=
{
val
res
=
Wire
(
Vec
(
8
,
UInt
(
8.
W
)))
(
0
until
8
).
foreach
(
i
=>
{
res
(
i
)
:=
Mux
(
fwdMask
(
i
),
fwd
(
8
*
(
i
+
1
)
-
1
,
8
*
i
),
refill
(
8
*
(
i
+
1
)
-
1
,
8
*
i
))
})
res
.
asUInt
}
// select refill data
// split dcache result into words
val
words
=
VecInit
((
0
until
blockWords
)
map
{
i
=>
io
.
refillData
(
DataBits
*
(
i
+
1
)
-
1
,
DataBits
*
i
)})
// select refill data according to wordIndex (paddr)
for
(
i
<-
0
until
8
)
{
for
(
j
<-
0
until
blockWords
)
{
data8
(
i
).
io
.
mwdata
(
j
)
:=
words
(
j
)(
8
*(
i
+
1
)-
1
,
8
*
i
)
}
}
// refill data according to matchMask, refillMask and refill.vald
for
(
j
<-
0
until
numEntries
)
{
when
(
io
.
mwmask
(
j
))
{
val
refillData
=
words
(
wordIndex
(
j
))
// TODO
data
(
j
)
:=
mergeRefillData
(
refillData
,
data
(
j
),
fwdMask
(
j
))
// gen refill wmask
for
(
j
<-
0
until
blockWords
)
{
for
(
k
<-
0
until
numEntries
)
{
val
wordMatch
=
wordIndex
(
k
)
===
j
.
U
for
(
i
<-
0
until
8
)
{
data8
(
i
).
io
.
mwmask
(
j
)(
k
)
:=
wordMatch
&&
io
.
mwmask
(
k
)
&&
!
fwdMask
(
k
)(
i
)
}
}
}
...
...
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
浏览文件 @
6886802e
...
...
@@ -46,11 +46,21 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val
sqempty
=
Output
(
Bool
())
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
storeCommit
=
Output
(
UInt
(
2.
W
))
val
storeAddr
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeData
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeMask
=
Output
(
Vec
(
2
,
UInt
(
8.
W
)))
})
difftestIO
<>
DontCare
// data modules
val
uop
=
Reg
(
Vec
(
StoreQueueSize
,
new
MicroOp
))
// val data = Reg(Vec(StoreQueueSize, new LsqEntry))
val
dataModule
=
Module
(
new
StoreQueueData
(
StoreQueueSize
,
numRead
=
StorePipelineWidth
,
numWrite
=
StorePipelineWidth
,
numForward
=
StorePipelineWidth
))
dataModule
.
io
:=
DontCare
val
paddrModule
=
Module
(
new
SQPaddrModule
(
StoreQueueSize
,
numRead
=
StorePipelineWidth
,
numWrite
=
StorePipelineWidth
,
numForward
=
StorePipelineWidth
))
paddrModule
.
io
:=
DontCare
val
vaddrModule
=
Module
(
new
AsyncDataModuleTemplate
(
UInt
(
VAddrBits
.
W
),
StoreQueueSize
,
numRead
=
1
,
numWrite
=
StorePipelineWidth
))
vaddrModule
.
io
:=
DontCare
...
...
@@ -66,7 +76,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
require
(
StoreQueueSize
>
RenameWidth
)
val
enqPtrExt
=
RegInit
(
VecInit
((
0
until
RenameWidth
).
map
(
_
.
U
.
asTypeOf
(
new
SqPtr
))))
val
deqPtrExt
=
RegInit
(
VecInit
((
0
until
StorePipelineWidth
).
map
(
_
.
U
.
asTypeOf
(
new
SqPtr
))))
val
validCounter
=
RegInit
(
0.
U
(
log2Ceil
(
LoadQueueSize
+
1
).
W
))
val
allowEnqueue
=
RegInit
(
true
.
B
)
val
enqPtr
=
enqPtrExt
(
0
).
value
...
...
@@ -86,9 +95,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
deqPtrExt
)
))
val
dataModuleRead
=
dataModule
.
io
.
rdata
for
(
i
<-
0
until
StorePipelineWidth
)
{
dataModule
.
io
.
raddr
(
i
)
:=
deqPtrExtNext
(
i
).
value
paddrModule
.
io
.
raddr
(
i
)
:=
deqPtrExtNext
(
i
).
value
}
vaddrModule
.
io
.
raddr
(
0
)
:=
io
.
exceptionAddr
.
lsIdx
.
sqIdx
.
value
...
...
@@ -129,6 +138,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
*/
for
(
i
<-
0
until
StorePipelineWidth
)
{
dataModule
.
io
.
wen
(
i
)
:=
false
.
B
paddrModule
.
io
.
wen
(
i
)
:=
false
.
B
vaddrModule
.
io
.
wen
(
i
)
:=
false
.
B
when
(
io
.
storeIn
(
i
).
fire
())
{
val
stWbIndex
=
io
.
storeIn
(
i
).
bits
.
uop
.
sqIdx
.
value
...
...
@@ -138,13 +148,17 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val
storeWbData
=
Wire
(
new
SQDataEntry
)
storeWbData
:=
DontCare
storeWbData
.
paddr
:=
io
.
storeIn
(
i
).
bits
.
paddr
storeWbData
.
mask
:=
io
.
storeIn
(
i
).
bits
.
mask
storeWbData
.
data
:=
io
.
storeIn
(
i
).
bits
.
data
dataModule
.
io
.
waddr
(
i
)
:=
stWbIndex
dataModule
.
io
.
wdata
(
i
)
:=
storeWbData
dataModule
.
io
.
wen
(
i
)
:=
true
.
B
paddrModule
.
io
.
waddr
(
i
)
:=
stWbIndex
paddrModule
.
io
.
wdata
(
i
)
:=
io
.
storeIn
(
i
).
bits
.
paddr
paddrModule
.
io
.
wen
(
i
)
:=
true
.
B
vaddrModule
.
io
.
waddr
(
i
)
:=
stWbIndex
vaddrModule
.
io
.
wdata
(
i
)
:=
io
.
storeIn
(
i
).
bits
.
vaddr
vaddrModule
.
io
.
wen
(
i
)
:=
true
.
B
...
...
@@ -193,15 +207,13 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
)
// do real fwd query
dataModule
.
io
.
forwardQuery
(
numForward
=
i
,
paddr
=
io
.
forward
(
i
).
paddr
,
needForward1
=
needForward1
,
needForward2
=
needForward2
)
dataModule
.
io
.
needForward
(
i
)(
0
)
:=
needForward1
&
paddrModule
.
io
.
forwardMmask
(
i
).
asUInt
dataModule
.
io
.
needForward
(
i
)(
1
)
:=
needForward2
&
paddrModule
.
io
.
forwardMmask
(
i
).
asUInt
paddrModule
.
io
.
forwardMdata
(
i
)
:=
io
.
forward
(
i
).
paddr
io
.
forward
(
i
).
forwardMask
:=
dataModule
.
io
.
forward
(
i
).
forwardMask
io
.
forward
(
i
).
forwardData
:=
dataModule
.
io
.
forward
(
i
).
forwardData
io
.
forward
(
i
).
forwardMask
:=
dataModule
.
io
.
forward
Mask
(
i
)
io
.
forward
(
i
).
forwardData
:=
dataModule
.
io
.
forward
Data
(
i
)
}
/**
...
...
@@ -221,13 +233,13 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
!
io
.
commits
.
isWalk
io
.
uncache
.
req
.
bits
.
cmd
:=
MemoryOpConstants
.
M_XWR
io
.
uncache
.
req
.
bits
.
addr
:=
dataModule
.
io
.
rdata
(
0
).
paddr
// data(deqPtr) -> rdata(0)
io
.
uncache
.
req
.
bits
.
addr
:=
paddrModule
.
io
.
rdata
(
0
)
// data(deqPtr) -> rdata(0)
io
.
uncache
.
req
.
bits
.
data
:=
dataModule
.
io
.
rdata
(
0
).
data
io
.
uncache
.
req
.
bits
.
mask
:=
dataModule
.
io
.
rdata
(
0
).
mask
io
.
uncache
.
req
.
bits
.
meta
.
id
:=
DontCare
io
.
uncache
.
req
.
bits
.
meta
.
vaddr
:=
DontCare
io
.
uncache
.
req
.
bits
.
meta
.
paddr
:=
dataModule
.
io
.
rdata
(
0
).
paddr
io
.
uncache
.
req
.
bits
.
meta
.
paddr
:=
paddrModule
.
io
.
rdata
(
0
)
io
.
uncache
.
req
.
bits
.
meta
.
uop
:=
uop
(
deqPtr
)
io
.
uncache
.
req
.
bits
.
meta
.
mmio
:=
true
.
B
io
.
uncache
.
req
.
bits
.
meta
.
tlb_miss
:=
false
.
B
...
...
@@ -256,7 +268,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
io
.
mmioStout
.
valid
:=
allocated
(
deqPtr
)
&&
datavalid
(
deqPtr
)
&&
!
writebacked
(
deqPtr
)
io
.
mmioStout
.
bits
.
uop
:=
uop
(
deqPtr
)
io
.
mmioStout
.
bits
.
uop
.
sqIdx
:=
deqPtrExt
(
0
)
io
.
mmioStout
.
bits
.
data
:=
dataModule
Read
(
0
).
data
// dataModuleRead
.read(deqPtr)
io
.
mmioStout
.
bits
.
data
:=
dataModule
.
io
.
rdata
(
0
).
data
// dataModule.io.rdata
.read(deqPtr)
io
.
mmioStout
.
bits
.
redirectValid
:=
false
.
B
io
.
mmioStout
.
bits
.
redirect
:=
DontCare
io
.
mmioStout
.
bits
.
debug
.
isMMIO
:=
true
.
B
...
...
@@ -290,9 +302,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
// if sbuffer.fire(), read next
io
.
sbuffer
(
i
).
valid
:=
allocated
(
ptr
)
&&
commited
(
ptr
)
&&
!
mmio
(
ptr
)
io
.
sbuffer
(
i
).
bits
.
cmd
:=
MemoryOpConstants
.
M_XWR
io
.
sbuffer
(
i
).
bits
.
addr
:=
dataModuleRead
(
i
).
paddr
io
.
sbuffer
(
i
).
bits
.
data
:=
dataModule
Read
(
i
).
data
io
.
sbuffer
(
i
).
bits
.
mask
:=
dataModule
Read
(
i
).
mask
io
.
sbuffer
(
i
).
bits
.
addr
:=
paddrModule
.
io
.
rdata
(
i
)
io
.
sbuffer
(
i
).
bits
.
data
:=
dataModule
.
io
.
rdata
(
i
).
data
io
.
sbuffer
(
i
).
bits
.
mask
:=
dataModule
.
io
.
rdata
(
i
).
mask
io
.
sbuffer
(
i
).
bits
.
meta
:=
DontCare
io
.
sbuffer
(
i
).
bits
.
meta
.
tlb_miss
:=
false
.
B
io
.
sbuffer
(
i
).
bits
.
meta
.
uop
:=
DontCare
...
...
@@ -308,17 +320,23 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
assert
(
io
.
sbuffer
(
0
).
fire
())
}
if
(!
env
.
FPGAPlatform
)
{
val
storeCommit
=
PopCount
(
io
.
sbuffer
.
map
(
_
.
fire
()))
val
waddr
=
VecInit
(
io
.
sbuffer
.
map
(
req
=>
SignExt
(
req
.
bits
.
addr
,
64
)))
val
wdata
=
VecInit
(
io
.
sbuffer
.
map
(
req
=>
req
.
bits
.
data
&
MaskExpand
(
req
.
bits
.
mask
)))
val
wmask
=
VecInit
(
io
.
sbuffer
.
map
(
_
.
bits
.
mask
))
val
storeCommit
=
PopCount
(
io
.
sbuffer
.
map
(
_
.
fire
()))
val
waddr
=
VecInit
(
io
.
sbuffer
.
map
(
req
=>
SignExt
(
req
.
bits
.
addr
,
64
)))
val
wdata
=
VecInit
(
io
.
sbuffer
.
map
(
req
=>
req
.
bits
.
data
&
MaskExpand
(
req
.
bits
.
mask
)))
val
wmask
=
VecInit
(
io
.
sbuffer
.
map
(
_
.
bits
.
mask
))
if
(!
env
.
FPGAPlatform
)
{
ExcitingUtils
.
addSource
(
RegNext
(
storeCommit
),
"difftestStoreCommit"
,
ExcitingUtils
.
Debug
)
ExcitingUtils
.
addSource
(
RegNext
(
waddr
),
"difftestStoreAddr"
,
ExcitingUtils
.
Debug
)
ExcitingUtils
.
addSource
(
RegNext
(
wdata
),
"difftestStoreData"
,
ExcitingUtils
.
Debug
)
ExcitingUtils
.
addSource
(
RegNext
(
wmask
),
"difftestStoreMask"
,
ExcitingUtils
.
Debug
)
}
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
storeCommit
:=
RegNext
(
storeCommit
)
difftestIO
.
storeAddr
:=
RegNext
(
waddr
)
difftestIO
.
storeData
:=
RegNext
(
wdata
)
difftestIO
.
storeMask
:=
RegNext
(
wmask
)
}
// Read vaddr for mem exception
io
.
exceptionAddr
.
vaddr
:=
vaddrModule
.
io
.
rdata
(
0
)
...
...
@@ -351,19 +369,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val
lastLastCycleRedirect
=
RegNext
(
lastCycleRedirect
)
val
dequeueCount
=
Mux
(
io
.
sbuffer
(
1
).
fire
(),
2.
U
,
Mux
(
io
.
sbuffer
(
0
).
fire
()
||
io
.
mmioStout
.
fire
(),
1.
U
,
0.
U
))
val
trueValidCounter
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
(
0
))
validCounter
:=
Mux
(
lastLastCycleRedirect
,
trueValidCounter
-
dequeueCount
,
validCounter
+
enqNumber
-
dequeueCount
)
allowEnqueue
:=
Mux
(
io
.
brqRedirect
.
valid
,
false
.
B
,
Mux
(
lastLastCycleRedirect
,
trueValidCounter
<=
(
StoreQueueSize
-
RenameWidth
).
U
,
validCounter
+
enqNumber
<=
(
StoreQueueSize
-
RenameWidth
).
U
)
)
val
validCount
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
(
0
))
allowEnqueue
:=
validCount
+
enqNumber
<=
(
StoreQueueSize
-
RenameWidth
).
U
// io.sqempty will be used by sbuffer
// We delay it for 1 cycle for better timing
...
...
@@ -384,7 +392,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
for
(
i
<-
0
until
StoreQueueSize
)
{
if
(
i
%
4
==
0
)
XSDebug
(
""
)
XSDebug
(
false
,
true
.
B
,
"%x
[%x] "
,
uop
(
i
).
cf
.
pc
,
dataModule
.
io
.
debug
(
i
).
paddr
)
XSDebug
(
false
,
true
.
B
,
"%x
"
,
uop
(
i
).
cf
.
pc
)
PrintFlag
(
allocated
(
i
),
"a"
)
PrintFlag
(
allocated
(
i
)
&&
datavalid
(
i
),
"v"
)
PrintFlag
(
allocated
(
i
)
&&
writebacked
(
i
),
"w"
)
...
...
src/main/scala/xiangshan/mem/lsqueue/StoreQueueData.scala
浏览文件 @
6886802e
...
...
@@ -11,12 +11,52 @@ import xiangshan.mem._
import
xiangshan.backend.roq.RoqPtr
// Data module define
// These data modules are like SyncDataModuleTemplate, but support cam-like ops
class
SQPaddrModule
(
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
,
numForward
:
Int
)
extends
XSModule
with
HasDCacheParameters
{
val
io
=
IO
(
new
Bundle
{
val
raddr
=
Input
(
Vec
(
numRead
,
UInt
(
log2Up
(
numEntries
).
W
)))
val
rdata
=
Output
(
Vec
(
numRead
,
UInt
((
PAddrBits
).
W
)))
val
wen
=
Input
(
Vec
(
numWrite
,
Bool
()))
val
waddr
=
Input
(
Vec
(
numWrite
,
UInt
(
log2Up
(
numEntries
).
W
)))
val
wdata
=
Input
(
Vec
(
numWrite
,
UInt
((
PAddrBits
).
W
)))
val
forwardMdata
=
Input
(
Vec
(
numForward
,
UInt
((
PAddrBits
).
W
)))
val
forwardMmask
=
Output
(
Vec
(
numForward
,
Vec
(
numEntries
,
Bool
())))
})
val
data
=
Reg
(
Vec
(
numEntries
,
UInt
((
PAddrBits
).
W
)))
// read ports
for
(
i
<-
0
until
numRead
)
{
io
.
rdata
(
i
)
:=
data
(
RegNext
(
io
.
raddr
(
i
)))
}
// below is the write ports (with priorities)
for
(
i
<-
0
until
numWrite
)
{
when
(
io
.
wen
(
i
))
{
data
(
io
.
waddr
(
i
))
:=
io
.
wdata
(
i
)
}
}
// content addressed match
for
(
i
<-
0
until
numForward
)
{
for
(
j
<-
0
until
numEntries
)
{
io
.
forwardMmask
(
i
)(
j
)
:=
io
.
forwardMdata
(
i
)(
PAddrBits
-
1
,
3
)
===
data
(
j
)(
PAddrBits
-
1
,
3
)
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for
(
i
<-
0
until
numWrite
)
{
for
(
j
<-
i
+
1
until
numWrite
)
{
assert
(!(
io
.
wen
(
i
)
&&
io
.
wen
(
j
)
&&
io
.
waddr
(
i
)
===
io
.
waddr
(
j
)))
}
}
}
class
SQDataEntry
extends
XSBundle
{
// val vaddr = UInt(VAddrBits.W) // TODO: need opt
val
paddr
=
UInt
(
PAddrBits
.
W
)
// val paddr = UInt(PAddrBits.W)
val
mask
=
UInt
(
8.
W
)
val
data
=
UInt
(
XLEN
.
W
)
// val exception = UInt(16.W) // TODO: opt size
}
class
StoreQueueData
(
size
:
Int
,
numRead
:
Int
,
numWrite
:
Int
,
numForward
:
Int
)
extends
XSModule
with
HasDCacheParameters
with
HasCircularQueuePtrHelper
{
...
...
@@ -29,13 +69,8 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
val
debug
=
Vec
(
size
,
Output
(
new
SQDataEntry
))
val
needForward
=
Input
(
Vec
(
numForward
,
Vec
(
2
,
UInt
(
size
.
W
))))
val
forward
=
Vec
(
numForward
,
Flipped
(
new
LoadForwardQueryIO
))
def
forwardQuery
(
numForward
:
Int
,
paddr
:
UInt
,
needForward1
:
Data
,
needForward2
:
Data
)
:
Unit
=
{
this
.
needForward
(
numForward
)(
0
)
:=
needForward1
this
.
needForward
(
numForward
)(
1
)
:=
needForward2
this
.
forward
(
numForward
).
paddr
:=
paddr
}
val
forwardMask
=
Vec
(
numForward
,
Output
(
Vec
(
8
,
Bool
())))
val
forwardData
=
Vec
(
numForward
,
Output
(
Vec
(
8
,
UInt
(
8.
W
))))
})
io
:=
DontCare
...
...
@@ -72,32 +107,7 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
// entry with larger index should have higher priority since it's data is younger
(
0
until
numForward
).
map
(
i
=>
{
val
forwardMask1
=
WireInit
(
VecInit
(
Seq
.
fill
(
8
)(
false
.
B
)))
val
forwardData1
=
WireInit
(
VecInit
(
Seq
.
fill
(
8
)(
0.
U
(
8.
W
))))
val
forwardMask2
=
WireInit
(
VecInit
(
Seq
.
fill
(
8
)(
false
.
B
)))
val
forwardData2
=
WireInit
(
VecInit
(
Seq
.
fill
(
8
)(
0.
U
(
8.
W
))))
for
(
j
<-
0
until
size
)
{
val
needCheck
=
io
.
forward
(
i
).
paddr
(
PAddrBits
-
1
,
3
)
===
data
(
j
).
paddr
(
PAddrBits
-
1
,
3
)
(
0
until
XLEN
/
8
).
foreach
(
k
=>
{
when
(
needCheck
&&
data
(
j
).
mask
(
k
))
{
when
(
io
.
needForward
(
i
)(
0
)(
j
))
{
forwardMask1
(
k
)
:=
true
.
B
forwardData1
(
k
)
:=
data
(
j
).
data
(
8
*
(
k
+
1
)
-
1
,
8
*
k
)
}
when
(
io
.
needForward
(
i
)(
1
)(
j
))
{
forwardMask2
(
k
)
:=
true
.
B
forwardData2
(
k
)
:=
data
(
j
).
data
(
8
*
(
k
+
1
)
-
1
,
8
*
k
)
}
XSDebug
(
io
.
needForward
(
i
)(
0
)(
j
)
||
io
.
needForward
(
i
)(
1
)(
j
),
p
"forwarding $k-th byte ${Hexadecimal(data(j).data(8 * (k + 1) - 1, 8 * k))} "
+
p
"from ptr $j\n"
)
}
})
}
// parallel fwd logic
val
paddrMatch
=
Wire
(
Vec
(
size
,
Bool
()))
val
matchResultVec
=
Wire
(
Vec
(
size
*
2
,
new
FwdEntry
))
def
parallelFwd
(
xs
:
Seq
[
Data
])
:
Data
=
{
...
...
@@ -113,13 +123,14 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
})
}
for
(
j
<-
0
until
size
)
{
paddrMatch
(
j
)
:=
io
.
forward
(
i
).
paddr
(
PAddrBits
-
1
,
3
)
===
data
(
j
).
paddr
(
PAddrBits
-
1
,
3
)
}
// paddrMatch is now included in io.needForward
// for (j <- 0 until size) {
// paddrMatch(j) := io.forward(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
// }
for
(
j
<-
0
until
size
)
{
val
needCheck0
=
RegNext
(
paddrMatch
(
j
)
&&
io
.
needForward
(
i
)(
0
)(
j
))
val
needCheck1
=
RegNext
(
paddrMatch
(
j
)
&&
io
.
needForward
(
i
)(
1
)(
j
))
val
needCheck0
=
RegNext
(
io
.
needForward
(
i
)(
0
)(
j
))
val
needCheck1
=
RegNext
(
io
.
needForward
(
i
)(
1
)(
j
))
(
0
until
XLEN
/
8
).
foreach
(
k
=>
{
matchResultVec
(
j
).
mask
(
k
)
:=
needCheck0
&&
data
(
j
).
mask
(
k
)
matchResultVec
(
j
).
data
(
k
)
:=
data
(
j
).
data
(
8
*
(
k
+
1
)
-
1
,
8
*
k
)
...
...
@@ -130,8 +141,8 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
val
parallelFwdResult
=
parallelFwd
(
matchResultVec
).
asTypeOf
(
new
FwdEntry
)
io
.
forward
(
i
).
forwardMask
:=
parallelFwdResult
.
mask
io
.
forward
(
i
).
forwardData
:=
parallelFwdResult
.
data
io
.
forward
Mask
(
i
)
:=
parallelFwdResult
.
mask
io
.
forward
Data
(
i
)
:=
parallelFwdResult
.
data
})
...
...
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
浏览文件 @
6886802e
...
...
@@ -12,6 +12,7 @@ import xiangshan.backend.LSUOpType
class
LoadToLsqIO
extends
XSBundle
{
val
loadIn
=
ValidIO
(
new
LsPipelineBundle
)
val
ldout
=
Flipped
(
DecoupledIO
(
new
ExuOutput
))
val
loadDataForwarded
=
Output
(
Bool
())
val
forward
=
new
LoadForwardQueryIO
}
...
...
@@ -141,6 +142,7 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper {
val
dcacheResp
=
Flipped
(
DecoupledIO
(
new
DCacheWordResp
))
val
lsq
=
new
LoadForwardQueryIO
val
sbuffer
=
new
LoadForwardQueryIO
val
dataForwarded
=
Output
(
Bool
())
})
val
s2_uop
=
io
.
in
.
bits
.
uop
...
...
@@ -194,10 +196,17 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper {
io
.
out
.
bits
:=
io
.
in
.
bits
io
.
out
.
bits
.
data
:=
rdataPartialLoad
// when exception occurs, set it to not miss and let it write back to roq (via int port)
io
.
out
.
bits
.
miss
:=
s2_cache_miss
&&
!
fullForward
&&
!
s2_exception
io
.
out
.
bits
.
miss
:=
s2_cache_miss
&&
!
s2_exception
io
.
out
.
bits
.
uop
.
ctrl
.
fpWen
:=
io
.
in
.
bits
.
uop
.
ctrl
.
fpWen
&&
!
s2_exception
io
.
out
.
bits
.
mmio
:=
s2_mmio
// For timing reasons, we can not let
// io.out.bits.miss := s2_cache_miss && !s2_exception && !fullForward
// We use io.dataForwarded instead. It means forward logic have prepared all data needed,
// and dcache query is no longer needed.
// Such inst will be writebacked from load queue.
io
.
dataForwarded
:=
s2_cache_miss
&&
fullForward
&&
!
s2_exception
io
.
in
.
ready
:=
io
.
out
.
ready
||
!
io
.
in
.
valid
// merge forward result
...
...
@@ -259,6 +268,7 @@ class LoadUnit extends XSModule with HasLoadHelper {
load_s2
.
io
.
lsq
.
forwardMask
<>
io
.
lsq
.
forward
.
forwardMask
load_s2
.
io
.
sbuffer
.
forwardData
<>
io
.
sbuffer
.
forwardData
load_s2
.
io
.
sbuffer
.
forwardMask
<>
io
.
sbuffer
.
forwardMask
load_s2
.
io
.
dataForwarded
<>
io
.
lsq
.
loadDataForwarded
XSDebug
(
load_s0
.
io
.
out
.
valid
,
p
"S0: pc ${Hexadecimal(load_s0.io.out.bits.uop.cf.pc)}, lId ${Hexadecimal(load_s0.io.out.bits.uop.lqIdx.asUInt)}, "
+
...
...
src/main/scala/xiangshan/mem/sbuffer/NewSbuffer.scala
浏览文件 @
6886802e
...
...
@@ -114,6 +114,13 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val
empty
=
Output
(
Bool
())
}
// sbuffer flush
})
val
difftestIO
=
IO
(
new
Bundle
()
{
val
sbufferResp
=
Output
(
Bool
())
val
sbufferAddr
=
Output
(
UInt
(
64.
W
))
val
sbufferData
=
Output
(
Vec
(
64
,
UInt
(
8.
W
)))
val
sbufferMask
=
Output
(
UInt
(
64.
W
))
})
difftestIO
<>
DontCare
val
buffer
=
Mem
(
StoreBufferSize
,
new
SbufferLine
)
val
stateVec
=
RegInit
(
VecInit
(
Seq
.
fill
(
StoreBufferSize
)(
s_invalid
)))
...
...
@@ -376,6 +383,13 @@ class NewSbuffer extends XSModule with HasSbufferCst {
XSDebug
(
p
"recv cache resp: id=[$respId]\n"
)
}
if
(
env
.
DualCoreDifftest
)
{
difftestIO
.
sbufferResp
:=
WireInit
(
io
.
dcache
.
resp
.
fire
())
difftestIO
.
sbufferAddr
:=
WireInit
(
getAddr
(
tagRead
(
respId
)))
difftestIO
.
sbufferData
:=
WireInit
(
bufferRead
(
respId
).
data
.
asTypeOf
(
Vec
(
CacheLineBytes
,
UInt
(
8.
W
))))
difftestIO
.
sbufferMask
:=
WireInit
(
bufferRead
(
respId
).
mask
)
}
val
needSpace
=
(
io
.
in
(
0
).
fire
&&
!
canMerge
(
0
))
+&
(
io
.
in
(
1
).
fire
&&
!
canMerge
(
1
)
&&
!
sameTag
)
invalidCount
:=
invalidCount
-
needSpace
+
io
.
dcache
.
resp
.
fire
()
validCount
:=
validCount
+
needSpace
-
prepareValid
...
...
src/main/scala/xiangshan/package.scala
浏览文件 @
6886802e
...
...
@@ -21,10 +21,10 @@ package object xiangshan {
}
object
SrcState
{
def
busy
=
"b0
0
"
.
U
def
rdy
=
"b
0
1"
.
U
def
specRdy
=
"b10"
.
U
// speculative ready, for future use
def
apply
()
=
UInt
(
2
.
W
)
def
busy
=
"b0"
.
U
def
rdy
=
"b1"
.
U
//
def specRdy = "b10".U // speculative ready, for future use
def
apply
()
=
UInt
(
1
.
W
)
}
object
FuType
extends
HasXSParameter
{
...
...
@@ -33,18 +33,18 @@ package object xiangshan {
def
jmp
=
"b0000"
.
U
def
i2f
=
"b0001"
.
U
def
csr
=
"b0010"
.
U
def
alu
=
"b0
011
"
.
U
def
alu
=
"b0
110
"
.
U
def
mul
=
"b0100"
.
U
def
div
=
"b0101"
.
U
def
fence
=
"b0
110
"
.
U
def
fence
=
"b0
011
"
.
U
def
fmac
=
"b1000"
.
U
def
fmisc
=
"b10
0
1"
.
U
def
fmisc
=
"b10
1
1"
.
U
def
fDivSqrt
=
"b1010"
.
U
def
ldu
=
"b1100"
.
U
def
stu
=
"b1101"
.
U
def
mou
=
"b111
0
"
.
U
// for amo, lr, sc, fence
def
mou
=
"b111
1
"
.
U
// for amo, lr, sc, fence
def
apply
()
=
UInt
(
log2Up
(
num
).
W
)
...
...
@@ -52,8 +52,21 @@ package object xiangshan {
def
isJumpExu
(
fuType
:
UInt
)
=
fuType
===
jmp
def
isFpExu
(
fuType
:
UInt
)
=
fuType
(
3
,
2
)
===
"b10"
.
U
def
isMemExu
(
fuType
:
UInt
)
=
fuType
(
3
,
2
)
===
"b11"
.
U
def
isLoadExu
(
fuType
:
UInt
)
=
fuType
===
ldu
||
fuType
===
mou
def
isStoreExu
(
fuType
:
UInt
)
=
fuType
===
stu
def
isLoadStore
(
fuType
:
UInt
)
=
isMemExu
(
fuType
)
&&
!
fuType
(
1
)
def
isStoreExu
(
fuType
:
UInt
)
=
isMemExu
(
fuType
)
&&
fuType
(
0
)
def
isAMO
(
fuType
:
UInt
)
=
fuType
(
1
)
def
jmpCanAccept
(
fuType
:
UInt
)
=
!
fuType
(
2
)
def
mduCanAccept
(
fuType
:
UInt
)
=
fuType
(
2
)
&&
!
fuType
(
1
)
def
aluCanAccept
(
fuType
:
UInt
)
=
fuType
(
2
)
&&
fuType
(
1
)
def
fmacCanAccept
(
fuType
:
UInt
)
=
!
fuType
(
1
)
def
fmiscCanAccept
(
fuType
:
UInt
)
=
fuType
(
1
)
def
loadCanAccept
(
fuType
:
UInt
)
=
!
fuType
(
0
)
def
storeCanAccept
(
fuType
:
UInt
)
=
fuType
(
0
)
def
storeIsAMO
(
fuType
:
UInt
)
=
fuType
(
1
)
val
functionNameMap
=
Map
(
jmp
.
litValue
()
->
"jmp"
,
...
...
src/test/csrc/common.cpp
浏览文件 @
6886802e
...
...
@@ -21,5 +21,7 @@ extern "C" void xs_assert(long long line) {
}
void
sig_handler
(
int
signo
)
{
if
(
signal_num
!=
0
)
exit
(
0
);
signal_num
=
signo
;
}
src/test/csrc/difftest.cpp
浏览文件 @
6886802e
...
...
@@ -12,19 +12,19 @@
#define DEBUG_RETIRE_TRACE_SIZE 16
#define DEBUG_WB_TRACE_SIZE 16
void
(
*
ref_difftest_memcpy_from_dut
)(
paddr_t
dest
,
void
*
src
,
size_t
n
)
=
NULL
;
void
(
*
ref_difftest_memcpy_from_ref
)(
void
*
dest
,
paddr_t
src
,
size_t
n
)
=
NULL
;
void
(
*
ref_difftest_getregs
)(
void
*
c
)
=
NULL
;
void
(
*
ref_difftest_setregs
)(
const
void
*
c
)
=
NULL
;
void
(
*
ref_difftest_get_mastatus
)(
void
*
s
)
=
NULL
;
void
(
*
ref_difftest_set_mastatus
)(
const
void
*
s
)
=
NULL
;
void
(
*
ref_difftest_get_csr
)(
void
*
c
)
=
NULL
;
void
(
*
ref_difftest_set_csr
)(
const
void
*
c
)
=
NULL
;
vaddr_t
(
*
ref_disambiguate_exec
)(
void
*
disambiguate_para
)
=
NULL
;
int
(
*
ref_difftest_store_commit
)(
uint64_t
*
saddr
,
uint64_t
*
sdata
,
uint8_t
*
smask
)
=
NULL
;
static
void
(
*
ref_difftest_exec
)(
uint64_t
n
)
=
NULL
;
static
void
(
*
ref_difftest_raise_intr
)(
uint64_t
NO
)
=
NULL
;
static
void
(
*
ref_isa_reg_display
)(
vo
id
)
=
NULL
;
void
(
*
ref_difftest_memcpy_from_dut
)(
paddr_t
dest
,
void
*
src
,
size_t
n
,
int
coreid
)
=
NULL
;
void
(
*
ref_difftest_memcpy_from_ref
)(
void
*
dest
,
paddr_t
src
,
size_t
n
,
int
coreid
)
=
NULL
;
void
(
*
ref_difftest_getregs
)(
void
*
c
,
int
coreid
)
=
NULL
;
void
(
*
ref_difftest_setregs
)(
const
void
*
c
,
int
coreid
)
=
NULL
;
void
(
*
ref_difftest_get_mastatus
)(
void
*
s
,
int
coreid
)
=
NULL
;
void
(
*
ref_difftest_set_mastatus
)(
const
void
*
s
,
int
coreid
)
=
NULL
;
void
(
*
ref_difftest_get_csr
)(
void
*
c
,
int
coreid
)
=
NULL
;
void
(
*
ref_difftest_set_csr
)(
const
void
*
c
,
int
coreid
)
=
NULL
;
vaddr_t
(
*
ref_disambiguate_exec
)(
void
*
disambiguate_para
,
int
coreid
)
=
NULL
;
int
(
*
ref_difftest_store_commit
)(
uint64_t
*
saddr
,
uint64_t
*
sdata
,
uint8_t
*
smask
,
int
coreid
)
=
NULL
;
static
void
(
*
ref_difftest_exec
)(
uint64_t
n
,
int
coreid
)
=
NULL
;
static
void
(
*
ref_difftest_raise_intr
)(
uint64_t
NO
,
int
coreid
)
=
NULL
;
static
void
(
*
ref_isa_reg_display
)(
int
core
id
)
=
NULL
;
static
bool
is_skip_ref
;
static
bool
is_skip_dut
;
...
...
@@ -41,7 +41,7 @@ void difftest_skip_ref() {
void
difftest_skip_dut
()
{
if
(
is_skip_dut
)
return
;
ref_difftest_exec
(
1
);
ref_difftest_exec
(
1
,
0
);
is_skip_dut
=
true
;
}
...
...
@@ -51,49 +51,49 @@ void init_difftest() {
puts
(
"Using "
REF_SO
" for difftest"
);
assert
(
handle
);
ref_difftest_memcpy_from_dut
=
(
void
(
*
)(
paddr_t
,
void
*
,
size_t
))
dlsym
(
handle
,
"difftest_memcpy_from_dut"
);
ref_difftest_memcpy_from_dut
=
(
void
(
*
)(
paddr_t
,
void
*
,
size_t
,
int
))
dlsym
(
handle
,
"difftest_memcpy_from_dut"
);
assert
(
ref_difftest_memcpy_from_dut
);
ref_difftest_memcpy_from_ref
=
(
void
(
*
)(
void
*
,
paddr_t
,
size_t
))
dlsym
(
handle
,
"difftest_memcpy_from_ref"
);
ref_difftest_memcpy_from_ref
=
(
void
(
*
)(
void
*
,
paddr_t
,
size_t
,
int
))
dlsym
(
handle
,
"difftest_memcpy_from_ref"
);
assert
(
ref_difftest_memcpy_from_ref
);
ref_difftest_getregs
=
(
void
(
*
)(
void
*
))
dlsym
(
handle
,
"difftest_getregs"
);
ref_difftest_getregs
=
(
void
(
*
)(
void
*
,
int
))
dlsym
(
handle
,
"difftest_getregs"
);
assert
(
ref_difftest_getregs
);
ref_difftest_setregs
=
(
void
(
*
)(
const
void
*
))
dlsym
(
handle
,
"difftest_setregs"
);
ref_difftest_setregs
=
(
void
(
*
)(
const
void
*
,
int
))
dlsym
(
handle
,
"difftest_setregs"
);
assert
(
ref_difftest_setregs
);
ref_difftest_get_mastatus
=
(
void
(
*
)(
void
*
))
dlsym
(
handle
,
"difftest_get_mastatus"
);
ref_difftest_get_mastatus
=
(
void
(
*
)(
void
*
,
int
))
dlsym
(
handle
,
"difftest_get_mastatus"
);
assert
(
ref_difftest_get_mastatus
);
ref_difftest_set_mastatus
=
(
void
(
*
)(
const
void
*
))
dlsym
(
handle
,
"difftest_set_mastatus"
);
ref_difftest_set_mastatus
=
(
void
(
*
)(
const
void
*
,
int
))
dlsym
(
handle
,
"difftest_set_mastatus"
);
assert
(
ref_difftest_set_mastatus
);
ref_difftest_get_csr
=
(
void
(
*
)(
void
*
))
dlsym
(
handle
,
"difftest_get_csr"
);
ref_difftest_get_csr
=
(
void
(
*
)(
void
*
,
int
))
dlsym
(
handle
,
"difftest_get_csr"
);
assert
(
ref_difftest_get_csr
);
ref_difftest_set_csr
=
(
void
(
*
)(
const
void
*
))
dlsym
(
handle
,
"difftest_set_csr"
);
ref_difftest_set_csr
=
(
void
(
*
)(
const
void
*
,
int
))
dlsym
(
handle
,
"difftest_set_csr"
);
assert
(
ref_difftest_set_csr
);
ref_disambiguate_exec
=
(
vaddr_t
(
*
)(
void
*
))
dlsym
(
handle
,
"disambiguate_exec"
);
ref_disambiguate_exec
=
(
vaddr_t
(
*
)(
void
*
,
int
))
dlsym
(
handle
,
"disambiguate_exec"
);
assert
(
ref_disambiguate_exec
);
ref_difftest_store_commit
=
(
int
(
*
)(
uint64_t
*
,
uint64_t
*
,
uint8_t
*
))
dlsym
(
handle
,
"difftest_store_commit"
);
ref_difftest_store_commit
=
(
int
(
*
)(
uint64_t
*
,
uint64_t
*
,
uint8_t
*
,
int
))
dlsym
(
handle
,
"difftest_store_commit"
);
assert
(
ref_difftest_store_commit
);
ref_difftest_exec
=
(
void
(
*
)(
uint64_t
))
dlsym
(
handle
,
"difftest_exec"
);
ref_difftest_exec
=
(
void
(
*
)(
uint64_t
,
int
))
dlsym
(
handle
,
"difftest_exec"
);
assert
(
ref_difftest_exec
);
ref_difftest_raise_intr
=
(
void
(
*
)(
uint64_t
))
dlsym
(
handle
,
"difftest_raise_intr"
);
ref_difftest_raise_intr
=
(
void
(
*
)(
uint64_t
,
int
))
dlsym
(
handle
,
"difftest_raise_intr"
);
assert
(
ref_difftest_raise_intr
);
ref_isa_reg_display
=
(
void
(
*
)(
void
))
dlsym
(
handle
,
"isa_reg_display"
);
ref_isa_reg_display
=
(
void
(
*
)(
int
))
dlsym
(
handle
,
"isa_reg_display"
);
assert
(
ref_isa_reg_display
);
void
(
*
ref_difftest_init
)(
void
)
=
(
void
(
*
)(
void
))
dlsym
(
handle
,
"difftest_init"
);
void
(
*
ref_difftest_init
)(
int
)
=
(
void
(
*
)(
int
))
dlsym
(
handle
,
"difftest_init"
);
assert
(
ref_difftest_init
);
ref_difftest_init
();
ref_difftest_init
(
0
);
}
static
const
char
*
reg_name
[
DIFFTEST_NR_REG
]
=
{
...
...
@@ -140,7 +140,7 @@ void difftest_display(uint8_t mode) {
j
,
pc_wb_queue
[
j
],
wen_wb_queue
[
j
]
!=
0
,
wdst_wb_queue
[
j
],
wdata_wb_queue
[
j
],
(
j
==
((
wb_pointer
-
1
)
%
DEBUG_WB_TRACE_SIZE
))
?
"<--"
:
""
);
}
printf
(
"
\n
============== Reg Diff ==============
\n
"
);
ref_isa_reg_display
();
ref_isa_reg_display
(
0
);
printf
(
"priviledgeMode: %d
\n
"
,
mode
);
}
...
...
@@ -171,12 +171,12 @@ int difftest_step(DiffState *s) {
struct
SyncState
sync
;
sync
.
lrscValid
=
0
;
sync
.
lrscAddr
=
0
;
ref_difftest_set_mastatus
((
uint64_t
*
)
&
sync
);
// sync lr/sc microarchitectural regs
ref_difftest_set_mastatus
((
uint64_t
*
)
&
sync
,
0
);
// sync lr/sc microarchitectural regs
}
// single step difftest
if
(
s
->
intrNO
)
{
ref_difftest_raise_intr
(
s
->
intrNO
);
ref_difftest_raise_intr
(
s
->
intrNO
,
0
);
// ref_difftest_exec(1);//TODO
}
else
{
...
...
@@ -191,14 +191,14 @@ int difftest_step(DiffState *s) {
// MMIO accessing should not be a branch or jump, just +2/+4 to get the next pc
// printf("SKIP %d\n", i);
// to skip the checking of an instruction, just copy the reg state to reference design
ref_difftest_getregs
(
&
ref_r
);
ref_difftest_getregs
(
&
ref_r
,
0
);
ref_r
[
DIFFTEST_THIS_PC
]
+=
selectBit
(
s
->
isRVC
,
i
)
?
2
:
4
;
if
(
selectBit
(
s
->
wen
,
i
)){
if
(
s
->
wdst
[
i
]
!=
0
){
ref_r
[
s
->
wdst
[
i
]]
=
s
->
wdata
[
i
];
}
}
ref_difftest_setregs
(
ref_r
);
ref_difftest_setregs
(
ref_r
,
0
);
}
else
{
// single step exec
// IPF, LPF, SPF
...
...
@@ -208,14 +208,14 @@ int difftest_step(DiffState *s) {
ds
.
exceptionNo
=
s
->
cause
;
ds
.
mtval
=
s
->
reg_scala
[
DIFFTEST_MTVAL
];
ds
.
stval
=
s
->
reg_scala
[
DIFFTEST_STVAL
];
ref_disambiguate_exec
(
&
ds
);
ref_disambiguate_exec
(
&
ds
,
0
);
}
else
{
ref_difftest_exec
(
1
);
ref_difftest_exec
(
1
,
0
);
}
}
}
}
ref_difftest_getregs
(
&
ref_r
);
ref_difftest_getregs
(
&
ref_r
,
0
);
uint64_t
next_pc
=
ref_r
[
DIFFTEST_THIS_PC
];
pc_retire_pointer
=
(
pc_retire_pointer
+
1
)
%
DEBUG_RETIRE_TRACE_SIZE
;
...
...
@@ -255,5 +255,5 @@ int difftest_step(DiffState *s) {
}
int
difftest_store_step
(
uint64_t
*
saddr
,
uint64_t
*
sdata
,
uint8_t
*
smask
)
{
return
ref_difftest_store_commit
(
saddr
,
sdata
,
smask
);
return
ref_difftest_store_commit
(
saddr
,
sdata
,
smask
,
0
);
}
src/test/csrc/difftest.h
浏览文件 @
6886802e
...
...
@@ -82,16 +82,16 @@ struct DisambiguationState {
uint64_t
stval
;
};
extern
void
(
*
ref_difftest_memcpy_from_dut
)(
paddr_t
dest
,
void
*
src
,
size_t
n
);
extern
void
(
*
ref_difftest_memcpy_from_ref
)(
void
*
dest
,
paddr_t
src
,
size_t
n
);
extern
void
(
*
ref_difftest_getregs
)(
void
*
c
);
extern
void
(
*
ref_difftest_setregs
)(
const
void
*
c
);
extern
void
(
*
ref_difftest_get_mastatus
)(
void
*
s
);
extern
void
(
*
ref_difftest_set_mastatus
)(
const
void
*
s
);
extern
void
(
*
ref_difftest_get_csr
)(
void
*
c
);
extern
void
(
*
ref_difftest_set_csr
)(
const
void
*
c
);
extern
vaddr_t
(
*
ref_disambiguate_exec
)(
void
*
disambiguate_para
);
extern
int
(
*
ref_difftest_store_commit
)(
uint64_t
*
saddr
,
uint64_t
*
sdata
,
uint8_t
*
smask
);
extern
void
(
*
ref_difftest_memcpy_from_dut
)(
paddr_t
dest
,
void
*
src
,
size_t
n
,
int
coreid
);
extern
void
(
*
ref_difftest_memcpy_from_ref
)(
void
*
dest
,
paddr_t
src
,
size_t
n
,
int
coreid
);
extern
void
(
*
ref_difftest_getregs
)(
void
*
c
,
int
coreid
);
extern
void
(
*
ref_difftest_setregs
)(
const
void
*
c
,
int
coreid
);
extern
void
(
*
ref_difftest_get_mastatus
)(
void
*
s
,
int
coreid
);
extern
void
(
*
ref_difftest_set_mastatus
)(
const
void
*
s
,
int
coreid
);
extern
void
(
*
ref_difftest_get_csr
)(
void
*
c
,
int
coreid
);
extern
void
(
*
ref_difftest_set_csr
)(
const
void
*
c
,
int
coreid
);
extern
vaddr_t
(
*
ref_disambiguate_exec
)(
void
*
disambiguate_para
,
int
coreid
);
extern
int
(
*
ref_difftest_store_commit
)(
uint64_t
*
saddr
,
uint64_t
*
sdata
,
uint8_t
*
smask
,
int
coreid
);
void
init_difftest
();
int
difftest_step
(
DiffState
*
s
);
...
...
src/test/csrc/emu.cpp
浏览文件 @
6886802e
...
...
@@ -276,19 +276,26 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
extern
uint32_t
uptime
(
void
);
uint32_t
lasttime_poll
=
0
;
uint32_t
lasttime_snapshot
=
0
;
uint64_t
lastcommit
=
max_cycle
;
uint64_t
instr_left_last_cycle
=
max_instr
;
uint64_t
lastcommit
[
NumCore
]
;
uint64_t
instr_left_last_cycle
[
NumCore
]
;
const
int
stuck_limit
=
2000
;
uint64_t
core_max_instr
[
NumCore
];
uint32_t
wdst
[
NumCore
][
DIFFTEST_WIDTH
];
uint64_t
wdata
[
NumCore
][
DIFFTEST_WIDTH
];
uint64_t
wpc
[
NumCore
][
DIFFTEST_WIDTH
];
uint64_t
reg
[
NumCore
][
DIFFTEST_NR_REG
];
DiffState
diff
[
NumCore
];
for
(
int
i
=
0
;
i
<
NumCore
;
i
++
)
{
diff
[
i
].
reg_scala
=
reg
[
i
];
diff
[
i
].
wpc
=
wpc
[
i
];
diff
[
i
].
wdata
=
wdata
[
i
];
diff
[
i
].
wdst
=
wdst
[
i
];
lastcommit
[
i
]
=
max_cycle
;
instr_left_last_cycle
[
i
]
=
max_cycle
;
core_max_instr
[
i
]
=
max_instr
;
}
uint32_t
wdst
[
DIFFTEST_WIDTH
];
uint64_t
wdata
[
DIFFTEST_WIDTH
];
uint64_t
wpc
[
DIFFTEST_WIDTH
];
uint64_t
reg
[
DIFFTEST_NR_REG
];
DiffState
diff
;
diff
.
reg_scala
=
reg
;
diff
.
wpc
=
wpc
;
diff
.
wdata
=
wdata
;
diff
.
wdst
=
wdst
;
#if VM_COVERAGE == 1
// we dump coverage into files at the end
...
...
@@ -298,8 +305,10 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
#endif
while
(
!
Verilated
::
gotFinish
()
&&
trapCode
==
STATE_RUNNING
)
{
if
(
!
(
max_cycle
>
0
&&
max_instr
>
0
&&
instr_left_last_cycle
>=
max_instr
/* handle overflow */
))
{
trapCode
=
STATE_LIMIT_EXCEEDED
;
if
(
!
(
max_cycle
>
0
&&
core_max_instr
[
0
]
>
0
&&
instr_left_last_cycle
[
0
]
>=
core_max_instr
[
0
]))
{
trapCode
=
STATE_LIMIT_EXCEEDED
;
/* handle overflow */
break
;
}
if
(
assert_count
>
0
)
{
...
...
@@ -319,7 +328,7 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
if
(
dut_ptr
->
io_trap_valid
)
trapCode
=
dut_ptr
->
io_trap_code
;
if
(
trapCode
!=
STATE_RUNNING
)
break
;
if
(
lastcommit
-
max_cycle
>
stuck_limit
&&
hascommit
)
{
if
(
lastcommit
[
0
]
-
max_cycle
>
stuck_limit
&&
hascommit
)
{
eprintf
(
"No instruction commits for %d cycles, maybe get stuck
\n
"
"(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)
\n
"
,
stuck_limit
,
stuck_limit
);
...
...
@@ -329,57 +338,66 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
if
(
!
hascommit
&&
dut_ptr
->
io_difftest_commit
&&
dut_ptr
->
io_difftest_thisPC
==
0x80000000u
)
{
hascommit
=
1
;
read_emu_regs
(
reg
);
read_emu_regs
(
reg
[
0
]
);
void
*
get_img_start
();
long
get_img_size
();
ref_difftest_memcpy_from_dut
(
0x80000000
,
get_img_start
(),
get_img_size
());
ref_difftest_setregs
(
reg
);
ref_difftest_memcpy_from_dut
(
0x80000000
,
get_img_start
(),
get_img_size
()
,
0
);
ref_difftest_setregs
(
reg
[
0
],
0
);
printf
(
"The first instruction has commited. Difftest enabled.
\n
"
);
}
// difftest
if
(
dut_ptr
->
io_difftest_commit
&&
hascommit
)
{
read_emu_regs
(
reg
);
read_wb_info
(
wpc
,
wdata
,
wdst
);
diff
.
commit
=
dut_ptr
->
io_difftest_commit
;
diff
.
this_inst
=
dut_ptr
->
io_difftest_thisINST
;
diff
.
skip
=
dut_ptr
->
io_difftest_skip
;
diff
.
isRVC
=
dut_ptr
->
io_difftest_isRVC
;
diff
.
wen
=
dut_ptr
->
io_difftest_wen
;
diff
.
intrNO
=
dut_ptr
->
io_difftest_intrNO
;
diff
.
cause
=
dut_ptr
->
io_difftest_cause
;
diff
.
priviledgeMode
=
dut_ptr
->
io_difftest_priviledgeMode
;
diff
.
sync
.
scFailed
=
dut_ptr
->
io_difftest_scFailed
;
if
(
difftest_step
(
&
diff
))
{
trapCode
=
STATE_ABORT
;
}
lastcommit
=
max_cycle
;
// update instr_cnt
instr_left_last_cycle
=
max_instr
;
max_instr
-=
diff
.
commit
;
}
for
(
int
i
=
0
;
i
<
NumCore
;
i
++
)
{
if
(
dut_ptr
->
io_difftest_commit
&&
hascommit
)
{
read_emu_regs
(
reg
[
i
]);
read_wb_info
(
wpc
[
i
],
wdata
[
i
],
wdst
[
i
]);
diff
[
i
].
commit
=
dut_ptr
->
io_difftest_commit
;
diff
[
i
].
this_inst
=
dut_ptr
->
io_difftest_thisINST
;
diff
[
i
].
skip
=
dut_ptr
->
io_difftest_skip
;
diff
[
i
].
isRVC
=
dut_ptr
->
io_difftest_isRVC
;
diff
[
i
].
wen
=
dut_ptr
->
io_difftest_wen
;
diff
[
i
].
intrNO
=
dut_ptr
->
io_difftest_intrNO
;
diff
[
i
].
cause
=
dut_ptr
->
io_difftest_cause
;
diff
[
i
].
priviledgeMode
=
dut_ptr
->
io_difftest_priviledgeMode
;
diff
[
i
].
sync
.
scFailed
=
dut_ptr
->
io_difftest_scFailed
;
if
(
i
==
0
)
{
if
(
difftest_step
(
&
diff
[
i
]))
{
trapCode
=
STATE_ABORT
;
}
}
lastcommit
[
i
]
=
max_cycle
;
if
(
dut_ptr
->
io_difftest_storeCommit
)
{
read_store_info
(
diff
.
store_addr
,
diff
.
store_data
,
diff
.
store_mask
);
for
(
int
i
=
0
;
i
<
dut_ptr
->
io_difftest_storeCommit
;
i
++
)
{
auto
addr
=
diff
.
store_addr
[
i
];
auto
data
=
diff
.
store_data
[
i
];
auto
mask
=
diff
.
store_mask
[
i
];
if
(
difftest_store_step
(
&
addr
,
&
data
,
&
mask
))
{
difftest_display
(
dut_ptr
->
io_difftest_priviledgeMode
);
printf
(
"Mismatch for store commits:
\n
"
);
printf
(
"REF commits addr 0x%lx, data 0x%lx, mask 0x%x
\n
"
,
addr
,
data
,
mask
);
printf
(
"DUT commits addr 0x%lx, data 0x%lx, mask 0x%x
\n
"
,
diff
.
store_addr
[
i
],
diff
.
store_data
[
i
],
diff
.
store_mask
[
i
]);
trapCode
=
STATE_ABORT
;
break
;
// update instr_cnt
instr_left_last_cycle
[
i
]
=
core_max_instr
[
i
];
core_max_instr
[
i
]
-=
diff
[
i
].
commit
;
}
#ifdef DIFFTEST_STORE_COMMIT
for
(
int
core
=
0
;
core
<
NumCore
;
core
++
)
{
if
(
dut_ptr
->
io_difftest_storeCommit
)
{
read_store_info
(
diff
[
core
].
store_addr
,
diff
[
core
].
store_data
,
diff
[
core
].
store_mask
);
for
(
int
i
=
0
;
i
<
dut_ptr
->
io_difftest_storeCommit
;
i
++
)
{
auto
addr
=
diff
[
core
].
store_addr
[
i
];
auto
data
=
diff
[
core
].
store_data
[
i
];
auto
mask
=
diff
[
core
].
store_mask
[
i
];
if
(
difftest_store_step
(
&
addr
,
&
data
,
&
mask
))
{
difftest_display
(
dut_ptr
->
io_difftest_priviledgeMode
);
printf
(
"Mismatch for store commits:
\n
"
);
printf
(
"REF commits addr 0x%lx, data 0x%lx, mask 0x%x
\n
"
,
addr
,
data
,
mask
);
printf
(
"DUT commits addr 0x%lx, data 0x%lx, mask 0x%x
\n
"
,
diff
[
core
].
store_addr
[
i
],
diff
[
core
].
store_data
[
i
],
diff
[
core
].
store_mask
[
i
]);
trapCode
=
STATE_ABORT
;
break
;
}
}
}
}
#endif
}
uint32_t
t
=
uptime
();
...
...
@@ -504,23 +522,23 @@ void Emulator::snapshot_save(const char *filename) {
stream
.
unbuf_write
(
get_ram_start
(),
size
);
uint64_t
ref_r
[
DIFFTEST_NR_REG
];
ref_difftest_getregs
(
&
ref_r
);
ref_difftest_getregs
(
&
ref_r
,
0
);
stream
.
unbuf_write
(
ref_r
,
sizeof
(
ref_r
));
uint64_t
nemu_this_pc
=
get_nemu_this_pc
();
stream
.
unbuf_write
(
&
nemu_this_pc
,
sizeof
(
nemu_this_pc
));
char
*
buf
=
(
char
*
)
mmap
(
NULL
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_ANON
|
MAP_PRIVATE
,
-
1
,
0
);
ref_difftest_memcpy_from_ref
(
buf
,
0x80000000
,
size
);
ref_difftest_memcpy_from_ref
(
buf
,
0x80000000
,
size
,
0
);
stream
.
unbuf_write
(
buf
,
size
);
munmap
(
buf
,
size
);
struct
SyncState
sync_mastate
;
ref_difftest_get_mastatus
(
&
sync_mastate
);
ref_difftest_get_mastatus
(
&
sync_mastate
,
0
);
stream
.
unbuf_write
(
&
sync_mastate
,
sizeof
(
struct
SyncState
));
uint64_t
csr_buf
[
4096
];
ref_difftest_get_csr
(
csr_buf
);
ref_difftest_get_csr
(
csr_buf
,
0
);
stream
.
unbuf_write
(
&
csr_buf
,
sizeof
(
csr_buf
));
long
sdcard_offset
;
...
...
@@ -553,7 +571,7 @@ void Emulator::snapshot_load(const char *filename) {
char
*
buf
=
(
char
*
)
mmap
(
NULL
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_ANON
|
MAP_PRIVATE
,
-
1
,
0
);
stream
.
read
(
buf
,
size
);
ref_difftest_memcpy_from_dut
(
0x80000000
,
buf
,
size
);
ref_difftest_memcpy_from_dut
(
0x80000000
,
buf
,
size
,
0
);
munmap
(
buf
,
size
);
struct
SyncState
sync_mastate
;
...
...
src/test/csrc/emu.h
浏览文件 @
6886802e
...
...
@@ -7,6 +7,8 @@
#include <verilated_vcd_c.h> // Trace file format header
#define SNAPSHOT_INTERVAL 60 // unit: second
#define DIFFTEST_STORE_COMMIT
#define NumCore 1
struct
EmuArgs
{
uint32_t
seed
;
...
...
src/test/scala/top/XSSim.scala
浏览文件 @
6886802e
...
...
@@ -53,6 +53,11 @@ class DiffTestIO extends XSBundle {
val
storeAddr
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeData
=
Output
(
Vec
(
2
,
UInt
(
64.
W
)))
val
storeMask
=
Output
(
Vec
(
2
,
UInt
(
8.
W
)))
val
sbufferResp
=
Output
(
Bool
())
val
sbufferAddr
=
Output
(
UInt
(
64.
W
))
val
sbufferData
=
Output
(
Vec
(
64
,
UInt
(
8.
W
)))
val
sbufferMask
=
Output
(
UInt
(
64.
W
))
}
class
LogCtrlIO
extends
Bundle
{
...
...
@@ -112,11 +117,13 @@ class XSSimSoC(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
lazy
val
module
=
new
LazyModuleImp
(
this
)
{
val
io
=
IO
(
new
Bundle
{
val
difftest
=
new
DiffTestIO
val
difftest
=
new
DiffTestIO
val
difftest2
=
new
DiffTestIO
val
logCtrl
=
new
LogCtrlIO
val
trap
=
new
TrapIO
val
uart
=
new
UARTIO
})
io
.
difftest2
<>
DontCare
dontTouch
(
io
.
difftest
)
dontTouch
(
io
.
logCtrl
)
...
...
@@ -129,47 +136,97 @@ class XSSimSoC(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
soc
.
module
.
io
.
extIntrs
(
i
)
:=
false
.
B
}
val
difftest
=
WireInit
(
0.
U
.
asTypeOf
(
new
DiffTestIO
))
val
difftest
=
Seq
(
WireInit
(
0.
U
.
asTypeOf
(
new
DiffTestIO
)),
WireInit
(
0.
U
.
asTypeOf
(
new
DiffTestIO
)))
if
(!
env
.
FPGAPlatform
)
{
ExcitingUtils
.
addSink
(
difftest
.
commit
,
"difftestCommit"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
thisPC
,
"difftestThisPC"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
thisINST
,
"difftestThisINST"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
skip
,
"difftestSkip"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
isRVC
,
"difftestIsRVC"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
wen
,
"difftestWen"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
wdata
,
"difftestWdata"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
wdst
,
"difftestWdst"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
wpc
,
"difftestWpc"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
intrNO
,
"difftestIntrNO"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
cause
,
"difftestCause"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
r
,
"difftestRegs"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
priviledgeMode
,
"difftestMode"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mstatus
,
"difftestMstatus"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
sstatus
,
"difftestSstatus"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mepc
,
"difftestMepc"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
sepc
,
"difftestSepc"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mtval
,
"difftestMtval"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
stval
,
"difftestStval"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mtvec
,
"difftestMtvec"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
stvec
,
"difftestStvec"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mcause
,
"difftestMcause"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
scause
,
"difftestScause"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
satp
,
"difftestSatp"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mip
,
"difftestMip"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mie
,
"difftestMie"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mscratch
,
"difftestMscratch"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
sscratch
,
"difftestSscratch"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
mideleg
,
"difftestMideleg"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
medeleg
,
"difftestMedeleg"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
scFailed
,
"difftestScFailed"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
storeCommit
,
"difftestStoreCommit"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
storeAddr
,
"difftestStoreAddr"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
storeData
,
"difftestStoreData"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
.
storeMask
,
"difftestStoreMask"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
commit
,
"difftestCommit"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
thisPC
,
"difftestThisPC"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
thisINST
,
"difftestThisINST"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
skip
,
"difftestSkip"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
isRVC
,
"difftestIsRVC"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
wen
,
"difftestWen"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
wdata
,
"difftestWdata"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
wdst
,
"difftestWdst"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
wpc
,
"difftestWpc"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
intrNO
,
"difftestIntrNO"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
cause
,
"difftestCause"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
r
,
"difftestRegs"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
priviledgeMode
,
"difftestMode"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mstatus
,
"difftestMstatus"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
sstatus
,
"difftestSstatus"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mepc
,
"difftestMepc"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
sepc
,
"difftestSepc"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mtval
,
"difftestMtval"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
stval
,
"difftestStval"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mtvec
,
"difftestMtvec"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
stvec
,
"difftestStvec"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mcause
,
"difftestMcause"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
scause
,
"difftestScause"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
satp
,
"difftestSatp"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mip
,
"difftestMip"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mie
,
"difftestMie"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mscratch
,
"difftestMscratch"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
sscratch
,
"difftestSscratch"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
mideleg
,
"difftestMideleg"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
medeleg
,
"difftestMedeleg"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
scFailed
,
"difftestScFailed"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
storeCommit
,
"difftestStoreCommit"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
storeAddr
,
"difftestStoreAddr"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
storeData
,
"difftestStoreData"
,
Debug
)
ExcitingUtils
.
addSink
(
difftest
(
0
).
storeMask
,
"difftestStoreMask"
,
Debug
)
}
if
(
env
.
DualCoreDifftest
)
{
for
(
i
<-
0
until
NumCores
)
{
difftest
(
i
).
commit
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
commit
difftest
(
i
).
thisPC
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
thisPC
difftest
(
i
).
thisINST
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
thisINST
difftest
(
i
).
skip
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
skip
difftest
(
i
).
isRVC
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
isRVC
difftest
(
i
).
wen
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
wen
difftest
(
i
).
wdata
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
wdata
difftest
(
i
).
wdst
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
wdst
difftest
(
i
).
wpc
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
wpc
difftest
(
i
).
scFailed
:=
soc
.
module
.
difftestIO
(
i
).
fromRoq
.
scFailed
difftest
(
i
).
r
:=
soc
.
module
.
difftestIO
(
i
).
fromXSCore
.
r
difftest
(
i
).
intrNO
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
intrNO
difftest
(
i
).
cause
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
cause
difftest
(
i
).
priviledgeMode
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
priviledgeMode
difftest
(
i
).
mstatus
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mstatus
difftest
(
i
).
sstatus
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
sstatus
difftest
(
i
).
mepc
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mepc
difftest
(
i
).
sepc
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
sepc
difftest
(
i
).
mtval
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mtval
difftest
(
i
).
stval
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
stval
difftest
(
i
).
mtvec
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mtvec
difftest
(
i
).
stvec
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
stvec
difftest
(
i
).
mcause
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mcause
difftest
(
i
).
scause
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
scause
difftest
(
i
).
satp
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
satp
difftest
(
i
).
mip
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mip
difftest
(
i
).
mie
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mie
difftest
(
i
).
mscratch
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mscratch
difftest
(
i
).
sscratch
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
sscratch
difftest
(
i
).
mideleg
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
mideleg
difftest
(
i
).
medeleg
:=
soc
.
module
.
difftestIO
(
i
).
fromCSR
.
medeleg
difftest
(
i
).
storeCommit
:=
soc
.
module
.
difftestIO
(
i
).
fromSQ
.
storeCommit
difftest
(
i
).
storeAddr
:=
soc
.
module
.
difftestIO
(
i
).
fromSQ
.
storeAddr
difftest
(
i
).
storeData
:=
soc
.
module
.
difftestIO
(
i
).
fromSQ
.
storeData
difftest
(
i
).
storeMask
:=
soc
.
module
.
difftestIO
(
i
).
fromSQ
.
storeMask
difftest
(
i
).
sbufferResp
:=
soc
.
module
.
difftestIO
(
i
).
fromSbuffer
.
sbufferResp
difftest
(
i
).
sbufferAddr
:=
soc
.
module
.
difftestIO
(
i
).
fromSbuffer
.
sbufferAddr
difftest
(
i
).
sbufferData
:=
soc
.
module
.
difftestIO
(
i
).
fromSbuffer
.
sbufferData
difftest
(
i
).
sbufferMask
:=
soc
.
module
.
difftestIO
(
i
).
fromSbuffer
.
sbufferMask
}
io
.
difftest2
:=
difftest
(
1
)
}
// BoringUtils.addSink(difftest.lrscAddr, "difftestLrscAddr")
io
.
difftest
:=
difftest
io
.
difftest
:=
difftest
(
0
)
val
trap
=
WireInit
(
0.
U
.
asTypeOf
(
new
TrapIO
))
if
(!
env
.
FPGAPlatform
)
{
...
...
@@ -213,14 +270,19 @@ class XSSimTop(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
lazy
val
module
=
new
LazyModuleImp
(
this
)
{
val
io
=
IO
(
new
Bundle
{
val
difftest
=
new
DiffTestIO
val
difftest
=
new
DiffTestIO
val
difftest2
=
new
DiffTestIO
val
logCtrl
=
new
LogCtrlIO
val
trap
=
new
TrapIO
val
uart
=
new
UARTIO
val
memAXI
=
if
(
axiSim
)
chiselTypeOf
(
axiSimRam
.
module
.
io
)
else
Input
(
Bool
())
})
io
.
difftest2
<>
DontCare
io
.
difftest
<>
dut
.
module
.
io
.
difftest
io
.
difftest
<>
dut
.
module
.
io
.
difftest
if
(
env
.
DualCoreDifftest
)
{
io
.
difftest2
<>
dut
.
module
.
io
.
difftest2
}
io
.
logCtrl
<>
dut
.
module
.
io
.
logCtrl
io
.
trap
<>
dut
.
module
.
io
.
trap
io
.
uart
<>
dut
.
module
.
io
.
uart
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录