Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
67ef08a8
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
10 个月 前同步成功
通知
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,体验更适合开发者的 AI 搜索 >>
提交
67ef08a8
编写于
11月 13, 2021
作者:
Z
zoujr
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into bpu-timing
上级
b9e1a5f8
beebba64
变更
20
隐藏空白更改
内联
并排
Showing
20 changed file
with
305 addition
and
180 deletion
+305
-180
Makefile
Makefile
+7
-5
difftest
difftest
+1
-1
fudian
fudian
+1
-1
ready-to-run
ready-to-run
+1
-1
src/main/scala/top/Top.scala
src/main/scala/top/Top.scala
+1
-1
src/main/scala/utils/PipelineConnect.scala
src/main/scala/utils/PipelineConnect.scala
+1
-1
src/main/scala/utils/ResetGen.scala
src/main/scala/utils/ResetGen.scala
+1
-1
src/main/scala/xiangshan/Bundle.scala
src/main/scala/xiangshan/Bundle.scala
+1
-1
src/main/scala/xiangshan/Parameters.scala
src/main/scala/xiangshan/Parameters.scala
+1
-0
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+5
-3
src/main/scala/xiangshan/backend/Scheduler.scala
src/main/scala/xiangshan/backend/Scheduler.scala
+2
-2
src/main/scala/xiangshan/backend/exu/WbArbiter.scala
src/main/scala/xiangshan/backend/exu/WbArbiter.scala
+18
-1
src/main/scala/xiangshan/backend/fu/CSR.scala
src/main/scala/xiangshan/backend/fu/CSR.scala
+5
-3
src/main/scala/xiangshan/backend/fu/fpu/FDivSqrt.scala
src/main/scala/xiangshan/backend/fu/fpu/FDivSqrt.scala
+23
-91
src/main/scala/xiangshan/backend/rename/Rename.scala
src/main/scala/xiangshan/backend/rename/Rename.scala
+1
-1
src/main/scala/xiangshan/backend/rob/Rob.scala
src/main/scala/xiangshan/backend/rob/Rob.scala
+71
-15
src/main/scala/xiangshan/cache/mmu/PTW.scala
src/main/scala/xiangshan/cache/mmu/PTW.scala
+15
-9
src/main/scala/xiangshan/cache/mmu/PageTableCache.scala
src/main/scala/xiangshan/cache/mmu/PageTableCache.scala
+31
-20
src/main/scala/xiangshan/cache/mmu/PageTableWalker.scala
src/main/scala/xiangshan/cache/mmu/PageTableWalker.scala
+11
-11
src/main/scala/xiangshan/cache/mmu/Repeater.scala
src/main/scala/xiangshan/cache/mmu/Repeater.scala
+108
-12
未找到文件。
Makefile
浏览文件 @
67ef08a8
...
...
@@ -40,6 +40,8 @@ RELEASE_ARGS = --disable-all --remove-assert --fpga-platform
DEBUG_ARGS
=
--enable-difftest
ifeq
($(RELEASE),1)
override
SIM_ARGS
+=
$(RELEASE_ARGS)
else
override
SIM_ARGS
+=
$(DEBUG_ARGS)
endif
TIMELOG
=
$(BUILD_DIR)
/time.log
...
...
@@ -52,9 +54,9 @@ help:
$(TOP_V)
:
$(SCALA_FILE)
mkdir
-p
$
(
@D
)
mill
-i
XiangShan.runMain
$(FPGATOP)
-td
$
(
@D
)
\
mill
-i
XiangShan.runMain
$(FPGATOP)
-td
$
(
@D
)
\
--config
$(CONFIG)
--full-stacktrace
--output-file
$
(
@F
)
\
--
repl-seq-mem
-c
:
$(FPGATOP)
:-o:
$
(
@D
)
/
$
(
@F
)
.conf
--infer-rw
\
--
infer-rw
--repl-seq-mem
-c
:
$(FPGATOP)
:-o:
$
(
@D
)
/
$
(
@F
)
.conf
\
--gen-mem-verilog
full
--num-cores
$(NUM_CORES)
\
$(RELEASE_ARGS)
sed
-i
-e
's/_\(aw\|ar\|w\|r\|b\)_\(\|bits_\)/_\1/g'
$@
...
...
@@ -74,11 +76,11 @@ $(SIM_TOP_V): $(SCALA_FILE) $(TEST_FILE)
mkdir
-p
$
(
@D
)
@
echo
"
\n
[mill] Generating Verilog files..."
>
$(TIMELOG)
@
date
-R
|
tee
-a
$(TIMELOG)
$(TIME_CMD)
mill
-i
XiangShan.test.runMain
$(SIMTOP)
-td
$
(
@D
)
\
$(TIME_CMD)
mill
-i
XiangShan.test.runMain
$(SIMTOP)
-td
$
(
@D
)
\
--config
$(CONFIG)
--full-stacktrace
--output-file
$
(
@F
)
\
--
repl-seq-mem
-c
:
$(SIMTOP)
:-o:
$
(
@D
)
/
$
(
@F
)
.conf
--infer-rw
\
--
infer-rw
--repl-seq-mem
-c
:
$(SIMTOP)
:-o:
$
(
@D
)
/
$
(
@F
)
.conf
\
--gen-mem-verilog
full
--num-cores
$(NUM_CORES)
\
$(
DEBUG_ARGS)
$(
SIM_ARGS)
$(SIM_ARGS)
@
git log
-n
1
>>
.__head__
@
git diff
>>
.__diff__
@
sed
-i
's/^/\/\// '
.__head__
...
...
difftest
@
9fc1180b
比较
fb00a5a7
...
9fc1180b
Subproject commit
fb00a5a7b020a1d66f854322c862c8cdaf2fb5a9
Subproject commit
9fc1180b77738dac273418a8177c6d9469ddc620
fudian
@
db5c2b43
比较
dff8392b
...
db5c2b43
Subproject commit d
ff8392b1f9eced37e8ee8eade69d0bf25542cce
Subproject commit d
b5c2b43c2f48e896d449ce825c4870dcf2fa314
ready-to-run
@
81f87ad0
比较
cb97f940
...
81f87ad0
Subproject commit
cb97f940276cbaf713856d1cfcf2b808d824ac22
Subproject commit
81f87ad06eabdadf7a598cda8a4b26b403947067
src/main/scala/top/Top.scala
浏览文件 @
67ef08a8
...
...
@@ -83,7 +83,7 @@ class XSTop()(implicit p: Parameters) extends BaseXSSoc() with HasSoCParameter
for
(
i
<-
0
until
NumCores
)
{
core_with_l2
(
i
).
clint_int_sink
:=
misc
.
clint
.
intnode
core_with_l2
(
i
).
plic_int_sink
:=
misc
.
plic
.
intnode
core_with_l2
(
i
).
plic_int_sink
:
*
=
misc
.
plic
.
intnode
core_with_l2
(
i
).
debug_int_sink
:=
misc
.
debugModule
.
debug
.
dmOuter
.
dmOuter
.
intnode
misc
.
plic
.
intnode
:=
core_with_l2
(
i
).
beu_int_source
misc
.
peripheral_ports
(
i
)
:=
core_with_l2
(
i
).
uncache
...
...
src/main/scala/utils/PipelineConnect.scala
浏览文件 @
67ef08a8
...
...
@@ -54,4 +54,4 @@ object PipelineConnect {
pipelineConnect
.
io
.
isFlush
:=
isFlush
right
<>
pipelineConnect
.
io
.
out
}
}
}
\ No newline at end of file
src/main/scala/utils/ResetGen.scala
浏览文件 @
67ef08a8
...
...
@@ -28,7 +28,7 @@ class ResetGen extends Module {
}
object
ResetGen
{
def
apply
(
resetChain
:
Seq
[
Seq
[
Module
]],
reset
:
Bool
,
sim
:
Boolean
)
:
Seq
[
Bool
]
=
{
def
apply
(
resetChain
:
Seq
[
Seq
[
M
ultiIOM
odule
]],
reset
:
Bool
,
sim
:
Boolean
)
:
Seq
[
Bool
]
=
{
val
resetReg
=
Wire
(
Vec
(
resetChain
.
length
+
1
,
Bool
()))
resetReg
.
foreach
(
_
:=
reset
)
for
((
resetLevel
,
i
)
<-
resetChain
.
zipWithIndex
)
{
...
...
src/main/scala/xiangshan/Bundle.scala
浏览文件 @
67ef08a8
...
...
@@ -307,6 +307,7 @@ class ExternalInterruptIO(implicit p: Parameters) extends XSBundle {
val
mtip
=
Input
(
Bool
())
val
msip
=
Input
(
Bool
())
val
meip
=
Input
(
Bool
())
val
seip
=
Input
(
Bool
())
val
debug
=
Input
(
Bool
())
}
...
...
@@ -330,7 +331,6 @@ class RobCommitInfo(implicit p: Parameters) extends XSBundle {
val
fpWen
=
Bool
()
val
wflags
=
Bool
()
val
commitType
=
CommitType
()
val
eliminatedMove
=
Bool
()
val
pdest
=
UInt
(
PhyRegIdxWidth
.
W
)
val
old_pdest
=
UInt
(
PhyRegIdxWidth
.
W
)
val
ftqIdx
=
new
FtqPtr
...
...
src/main/scala/xiangshan/Parameters.scala
浏览文件 @
67ef08a8
...
...
@@ -252,6 +252,7 @@ case class DebugOptions
(
FPGAPlatform
:
Boolean
=
false
,
EnableDifftest
:
Boolean
=
false
,
AlwaysBasicDiff
:
Boolean
=
true
,
EnableDebug
:
Boolean
=
false
,
EnablePerfDebug
:
Boolean
=
true
,
UseDRAMSim
:
Boolean
=
false
...
...
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
67ef08a8
...
...
@@ -58,7 +58,7 @@ abstract class XSCoreBase()(implicit p: config.Parameters) extends LazyModule
// interrupt sinks
val
clint_int_sink
=
IntSinkNode
(
IntSinkPortSimple
(
1
,
2
))
val
debug_int_sink
=
IntSinkNode
(
IntSinkPortSimple
(
1
,
1
))
val
plic_int_sink
=
IntSinkNode
(
IntSinkPortSimple
(
1
,
1
))
val
plic_int_sink
=
IntSinkNode
(
IntSinkPortSimple
(
2
,
1
))
// outer facing nodes
val
frontend
=
LazyModule
(
new
Frontend
())
val
ptw
=
LazyModule
(
new
PTWWrapper
())
...
...
@@ -278,6 +278,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
csrioIn
.
externalInterrupt
.
msip
:=
outer
.
clint_int_sink
.
in
.
head
.
_1
(
0
)
csrioIn
.
externalInterrupt
.
mtip
:=
outer
.
clint_int_sink
.
in
.
head
.
_1
(
1
)
csrioIn
.
externalInterrupt
.
meip
:=
outer
.
plic_int_sink
.
in
.
head
.
_1
(
0
)
csrioIn
.
externalInterrupt
.
seip
:=
outer
.
plic_int_sink
.
in
.
last
.
_1
(
0
)
csrioIn
.
externalInterrupt
.
debug
:=
outer
.
debug_int_sink
.
in
.
head
.
_1
(
0
)
csrioIn
.
distributedUpdate
<>
memBlock
.
io
.
csrUpdate
// TODO
...
...
@@ -296,7 +297,8 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
val
itlbRepeater1
=
PTWRepeater
(
frontend
.
io
.
ptw
,
fenceio
.
sfence
,
csrioIn
.
tlb
)
val
itlbRepeater2
=
PTWRepeater
(
itlbRepeater1
.
io
.
ptw
,
ptw
.
io
.
tlb
(
0
),
fenceio
.
sfence
,
csrioIn
.
tlb
)
val
dtlbRepeater
=
PTWFilter
(
memBlock
.
io
.
ptw
,
ptw
.
io
.
tlb
(
1
),
fenceio
.
sfence
,
csrioIn
.
tlb
,
l2tlbParams
.
filterSize
)
val
dtlbRepeater1
=
PTWFilter
(
memBlock
.
io
.
ptw
,
fenceio
.
sfence
,
csrioIn
.
tlb
,
l2tlbParams
.
filterSize
)
val
dtlbRepeater2
=
PTWRepeaterNB
(
passReady
=
false
,
dtlbRepeater1
.
io
.
ptw
,
ptw
.
io
.
tlb
(
1
),
fenceio
.
sfence
,
csrioIn
.
tlb
)
ptw
.
io
.
sfence
<>
fenceio
.
sfence
ptw
.
io
.
csr
.
tlb
<>
csrioIn
.
tlb
ptw
.
io
.
csr
.
distribute_csr
<>
csrioIn
.
customCtrl
.
distribute_csr
...
...
@@ -310,7 +312,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
// v v v v v
// PTW {MemBlock, dtlb} ExuBlocks CtrlBlock {Frontend, itlb}
val
resetChain
=
Seq
(
Seq
(
memBlock
,
dtlbRepeater
),
Seq
(
memBlock
,
dtlbRepeater
1
,
dtlbRepeater2
),
Seq
(
exuBlocks
.
head
),
// Note: arbiters don't actually have reset ports
exuBlocks
.
tail
++
Seq
(
outer
.
wbArbiter
.
module
),
...
...
src/main/scala/xiangshan/backend/Scheduler.scala
浏览文件 @
67ef08a8
...
...
@@ -448,13 +448,13 @@ class SchedulerImp(outer: Scheduler) extends LazyModuleImp(outer) with HasXSPara
}
}
if
(
env
.
EnableDifftest
&&
intRfConfig
.
_1
)
{
if
(
(
env
.
AlwaysBasicDiff
||
env
.
EnableDifftest
)
&&
intRfConfig
.
_1
)
{
val
difftest
=
Module
(
new
DifftestArchIntRegState
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
difftest
.
io
.
gpr
:=
intRfReadData
.
takeRight
(
32
)
}
if
(
env
.
EnableDifftest
&&
fpRfConfig
.
_1
)
{
if
(
(
env
.
AlwaysBasicDiff
||
env
.
EnableDifftest
)
&&
fpRfConfig
.
_1
)
{
val
difftest
=
Module
(
new
DifftestArchFpRegState
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
...
...
src/main/scala/xiangshan/backend/exu/WbArbiter.scala
浏览文件 @
67ef08a8
...
...
@@ -19,6 +19,7 @@ package xiangshan.backend.exu
import
chipsalliance.rocketchip.config.Parameters
import
chisel3._
import
chisel3.util._
import
difftest.
{
DifftestFpWriteback
,
DifftestIntWriteback
}
import
freechips.rocketchip.diplomacy.
{
LazyModule
,
LazyModuleImp
}
import
utils.
{
XSPerfAccumulate
,
XSPerfHistogram
}
import
xiangshan._
...
...
@@ -204,7 +205,7 @@ class WbArbiterWrapper(
val
numOutPorts
=
intArbiter
.
numOutPorts
+
fpArbiter
.
numOutPorts
lazy
val
module
=
new
LazyModuleImp
(
this
)
{
lazy
val
module
=
new
LazyModuleImp
(
this
)
with
HasXSParameter
{
val
io
=
IO
(
new
Bundle
()
{
val
in
=
Vec
(
numInPorts
,
Flipped
(
DecoupledIO
(
new
ExuOutput
)))
val
out
=
Vec
(
numOutPorts
,
ValidIO
(
new
ExuOutput
))
...
...
@@ -222,6 +223,14 @@ class WbArbiterWrapper(
wb
.
ready
:=
arb
.
ready
}
}
intArbiter
.
module
.
io
.
out
.
foreach
(
out
=>
{
val
difftest
=
Module
(
new
DifftestIntWriteback
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
difftest
.
io
.
valid
:=
out
.
valid
difftest
.
io
.
dest
:=
out
.
bits
.
uop
.
pdest
difftest
.
io
.
data
:=
out
.
bits
.
data
})
val
fpWriteback
=
io
.
in
.
zip
(
exuConfigs
).
filter
(
_
.
_2
.
writeFpRf
)
fpArbiter
.
module
.
io
.
in
.
zip
(
fpWriteback
).
foreach
{
case
(
arb
,
(
wb
,
cfg
))
=>
...
...
@@ -232,6 +241,14 @@ class WbArbiterWrapper(
wb
.
ready
:=
arb
.
ready
}
}
fpArbiter
.
module
.
io
.
out
.
foreach
(
out
=>
{
val
difftest
=
Module
(
new
DifftestFpWriteback
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
difftest
.
io
.
valid
:=
out
.
valid
difftest
.
io
.
dest
:=
out
.
bits
.
uop
.
pdest
difftest
.
io
.
data
:=
out
.
bits
.
data
})
io
.
out
<>
intArbiter
.
module
.
io
.
out
++
fpArbiter
.
module
.
io
.
out
}
...
...
src/main/scala/xiangshan/backend/fu/CSR.scala
浏览文件 @
67ef08a8
...
...
@@ -925,7 +925,7 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
mipWire
.
t
.
m
:=
csrio
.
externalInterrupt
.
mtip
mipWire
.
s
.
m
:=
csrio
.
externalInterrupt
.
msip
mipWire
.
e
.
m
:=
csrio
.
externalInterrupt
.
meip
mipWire
.
e
.
s
:=
csrio
.
externalInterrupt
.
m
eip
mipWire
.
e
.
s
:=
csrio
.
externalInterrupt
.
s
eip
// interrupts
val
intrNO
=
IntPriority
.
foldRight
(
0.
U
)((
i
:
Int
,
sum
:
UInt
)
=>
Mux
(
intrVec
(
i
),
i
.
U
,
sum
))
...
...
@@ -1079,7 +1079,8 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
val
difftestIntrNO
=
Mux
(
raiseIntr
,
causeNO
,
0.
U
)
if
(
env
.
EnableDifftest
)
{
// Always instantiate basic difftest modules.
if
(
env
.
AlwaysBasicDiff
||
env
.
EnableDifftest
)
{
val
difftest
=
Module
(
new
DifftestArchEvent
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
...
...
@@ -1088,7 +1089,8 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
difftest
.
io
.
exceptionPC
:=
RegNext
(
SignExt
(
csrio
.
exception
.
bits
.
uop
.
cf
.
pc
,
XLEN
))
}
if
(
env
.
EnableDifftest
)
{
// Always instantiate basic difftest modules.
if
(
env
.
AlwaysBasicDiff
||
env
.
EnableDifftest
)
{
val
difftest
=
Module
(
new
DifftestCSRState
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
...
...
src/main/scala/xiangshan/backend/fu/fpu/FDivSqrt.scala
浏览文件 @
67ef08a8
...
...
@@ -20,8 +20,7 @@ import chipsalliance.rocketchip.config.Parameters
import
chisel3._
import
chisel3.util._
import
freechips.rocketchip.tile.FType
import
fudian.FPUpConverter
import
hardfloat.
{
DivSqrtRecFNToRaw_small
,
DivSqrtRecFNToRaw_srt4
,
RoundAnyRawFNToRecFN
}
import
fudian.
{
FPUpConverter
,
FDIV
}
class
FDivSqrtDataModule
(
implicit
p
:
Parameters
)
extends
FPUDataModule
{
val
in_valid
,
out_ready
=
IO
(
Input
(
Bool
()))
...
...
@@ -32,101 +31,34 @@ class FDivSqrtDataModule(implicit p: Parameters) extends FPUDataModule {
val
in_fire
=
in_valid
&&
in_ready
val
out_fire
=
out_valid
&&
out_ready
val
s_idle
::
s_div
::
s_finish
::
Nil
=
Enum
(
3
)
val
state
=
RegInit
(
s_idle
)
val
divSqrt
=
Module
(
new
DivSqrtRecFNToRaw_srt4
(
FType
.
D
.
exp
,
FType
.
D
.
sig
))
val
divSqrtRawValid
=
divSqrt
.
io
.
rawOutValid_sqrt
||
divSqrt
.
io
.
rawOutValid_div
val
fpCtrl
=
io
.
in
.
fpCtrl
val
tag
=
fpCtrl
.
typeTagIn
val
single
=
RegEnable
(
tag
===
S
,
in_fire
)
val
rmReg
=
RegEnable
(
rm
,
in_fire
)
switch
(
state
){
is
(
s_idle
){
when
(
in_fire
&&
!
kill_w
){
state
:=
s_div
}
}
is
(
s_div
){
when
(
divSqrtRawValid
){
state
:=
s_finish
}
}
is
(
s_finish
){
when
(
out_fire
){
state
:=
s_idle
}
}
}
when
(
kill_r
){
state
:=
s_idle
}
val
in1_unboxed
=
FPU
.
unbox
(
io
.
in
.
src
(
0
),
tag
)
val
in2_unboxed
=
FPU
.
unbox
(
io
.
in
.
src
(
1
),
tag
)
def
up_convert_s_d
(
in
:
UInt
)
:
UInt
=
{
val
converter
=
Module
(
new
FPUpConverter
(
FPU
.
f32
.
expWidth
,
FPU
.
f32
.
precision
,
FPU
.
f64
.
expWidth
,
FPU
.
f64
.
precision
))
converter
.
io
.
in
:=
in
converter
.
io
.
rm
:=
DontCare
converter
.
io
.
result
}
val
src1
=
hardfloat
.
recFNFromFN
(
FType
.
D
.
exp
,
FType
.
D
.
sig
,
Mux
(
tag
===
FPU
.
S
,
up_convert_s_d
(
in1_unboxed
),
in1_unboxed
)
)
val
src2
=
hardfloat
.
recFNFromFN
(
FType
.
D
.
exp
,
FType
.
D
.
sig
,
Mux
(
tag
===
FPU
.
S
,
up_convert_s_d
(
in2_unboxed
),
in2_unboxed
)
)
divSqrt
.
io
.
inValid
:=
in_fire
&&
!
kill_w
divSqrt
.
io
.
sqrtOp
:=
fpCtrl
.
sqrt
divSqrt
.
io
.
kill
:=
kill_r
divSqrt
.
io
.
sigBits
:=
Mux
(
tag
===
S
,
FType
.
S
.
sig
.
U
,
FType
.
D
.
sig
.
U
)
divSqrt
.
io
.
a
:=
src1
divSqrt
.
io
.
b
:=
src2
divSqrt
.
io
.
roundingMode
:=
rm
val
round32
=
Module
(
new
RoundAnyRawFNToRecFN
(
FType
.
D
.
exp
,
FType
.
D
.
sig
+
2
,
FType
.
S
.
exp
,
FType
.
S
.
sig
,
0
))
val
round64
=
Module
(
new
RoundAnyRawFNToRecFN
(
FType
.
D
.
exp
,
FType
.
D
.
sig
+
2
,
FType
.
D
.
exp
,
FType
.
D
.
sig
,
0
))
for
(
rounder
<-
Seq
(
round32
,
round64
)){
rounder
.
io
.
invalidExc
:=
divSqrt
.
io
.
invalidExc
rounder
.
io
.
infiniteExc
:=
divSqrt
.
io
.
infiniteExc
rounder
.
io
.
in
:=
divSqrt
.
io
.
rawOut
rounder
.
io
.
roundingMode
:=
rmReg
rounder
.
io
.
detectTininess
:=
hardfloat
.
consts
.
tininess_afterRounding
val
src1
=
FPU
.
unbox
(
io
.
in
.
src
(
0
),
tag
)
val
src2
=
FPU
.
unbox
(
io
.
in
.
src
(
1
),
tag
)
val
typeSel
=
VecInit
(
FPU
.
ftypes
.
zipWithIndex
.
map
(
_
.
_2
.
U
===
tag
))
val
outSel
=
RegEnable
(
typeSel
,
VecInit
(
Seq
.
fill
(
typeSel
.
length
)(
true
.
B
)),
in_fire
)
// inelegant
val
divSqrt
=
FPU
.
ftypes
.
map
{
t
=>
val
fdiv
=
Module
(
new
FDIV
(
t
.
expWidth
,
t
.
precision
))
fdiv
.
io
.
a
:=
src1
fdiv
.
io
.
b
:=
src2
fdiv
.
io
.
rm
:=
rm
fdiv
.
io
.
specialIO
.
in_valid
:=
in_fire
&&
!
kill_w
fdiv
.
io
.
specialIO
.
out_ready
:=
out_ready
fdiv
.
io
.
specialIO
.
isSqrt
:=
fpCtrl
.
sqrt
fdiv
.
io
.
specialIO
.
kill
:=
kill_r
fdiv
}
val
data
=
Mux
(
single
,
FPU
.
box
(
Cat
(
0.
U
(
32.
W
),
hardfloat
.
fNFromRecFN
(
FType
.
S
.
exp
,
FType
.
S
.
sig
,
round32
.
io
.
out
)),
FPU
.
S
),
FPU
.
box
(
hardfloat
.
fNFromRecFN
(
FType
.
D
.
exp
,
FType
.
D
.
sig
,
round64
.
io
.
out
),
FPU
.
D
)
)
val
flags
=
Mux
(
single
,
round32
.
io
.
exceptionFlags
,
round64
.
io
.
exceptionFlags
)
assert
(!(
state
===
s_idle
&&
!
divSqrt
.
io
.
inReady
))
in_ready
:=
state
===
s_idle
out_valid
:=
state
===
s_finish
io
.
out
.
data
:=
RegNext
(
data
,
divSqrtRawValid
)
fflags
:=
RegNext
(
flags
,
divSqrtRawValid
)
in_ready
:=
Mux1H
(
outSel
,
divSqrt
.
map
(
_
.
io
.
specialIO
.
in_ready
))
out_valid
:=
Mux1H
(
outSel
,
divSqrt
.
map
(
_
.
io
.
specialIO
.
out_valid
))
io
.
out
.
data
:=
Mux1H
(
outSel
,
divSqrt
.
zip
(
FPU
.
ftypes
).
map
{
case
(
mod
,
t
)
=>
FPU
.
box
(
mod
.
io
.
result
,
t
)
})
fflags
:=
Mux1H
(
outSel
,
divSqrt
.
map
(
_
.
io
.
fflags
))
}
class
FDivSqrt
(
implicit
p
:
Parameters
)
extends
FPUSubModule
{
val
uopReg
=
RegEnable
(
io
.
in
.
bits
.
uop
,
io
.
in
.
fire
())
...
...
src/main/scala/xiangshan/backend/rename/Rename.scala
浏览文件 @
67ef08a8
...
...
@@ -270,7 +270,7 @@ class Rename(implicit p: Parameters) extends XSModule {
for
(
i
<-
0
until
CommitWidth
)
{
val
info
=
io
.
robCommits
.
info
(
i
)
XSDebug
(
io
.
robCommits
.
isWalk
&&
io
.
robCommits
.
valid
(
i
),
p
"[#$i walk info] pc:${Hexadecimal(info.pc)} "
+
p
"ldest:${info.ldest} rfWen:${info.rfWen} fpWen:${info.fpWen} "
+
p
"eliminatedMove:${info.eliminatedMove} "
+
p
"ldest:${info.ldest} rfWen:${info.rfWen} fpWen:${info.fpWen} "
+
p
"pdest:${info.pdest} old_pdest:${info.old_pdest}\n"
)
}
...
...
src/main/scala/xiangshan/backend/rob/Rob.scala
浏览文件 @
67ef08a8
...
...
@@ -277,8 +277,6 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
// data for redirect, exception, etc.
// val flagBkup = RegInit(VecInit(List.fill(RobSize)(false.B)))
val
flagBkup
=
Mem
(
RobSize
,
Bool
())
// record move elimination info for each instruction
val
eliminatedMove
=
Mem
(
RobSize
,
Bool
())
// data for debug
// Warn: debug_* prefix should not exist in generated verilog.
...
...
@@ -687,7 +685,6 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
// enqueue logic set 6 writebacked to false
for
(
i
<-
0
until
RenameWidth
)
{
when
(
canEnqueue
(
i
))
{
eliminatedMove
(
enqPtrVec
(
i
).
value
)
:=
io
.
enq
.
req
(
i
).
bits
.
eliminatedMove
writebacked
(
enqPtrVec
(
i
).
value
)
:=
io
.
enq
.
req
(
i
).
bits
.
eliminatedMove
&&
!
io
.
enq
.
req
(
i
).
bits
.
cf
.
exceptionVec
.
asUInt
.
orR
val
isStu
=
io
.
enq
.
req
(
i
).
bits
.
ctrl
.
fuType
===
FuType
.
stu
store_data_writebacked
(
enqPtrVec
(
i
).
value
)
:=
!
isStu
...
...
@@ -740,7 +737,6 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
wdata
.
fpWen
:=
req
.
ctrl
.
fpWen
wdata
.
wflags
:=
req
.
ctrl
.
fpu
.
wflags
wdata
.
commitType
:=
req
.
ctrl
.
commitType
wdata
.
eliminatedMove
:=
req
.
eliminatedMove
wdata
.
pdest
:=
req
.
pdest
wdata
.
old_pdest
:=
req
.
old_pdest
wdata
.
ftqIdx
:=
req
.
cf
.
ftqPtr
...
...
@@ -770,7 +766,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
def
load_wb_idxes
=
Seq
(
exuParameters
.
AluCnt
+
1
)
// second port for load
def
store_wb_idxes
=
io
.
exeWbResults
.
indices
.
takeRight
(
2
)
val
all_exception_possibilities
=
Seq
(
csr_wb_idx
,
atomic_wb_idx
)
++
load_wb_idxes
++
store_wb_idxes
all_exception_possibilities
.
zipWithIndex
.
map
{
case
(
p
,
i
)
=>
connect_exception
(
i
,
p
)
}
all_exception_possibilities
.
zipWithIndex
.
foreach
{
case
(
p
,
i
)
=>
connect_exception
(
i
,
p
)
}
def
connect_exception
(
index
:
Int
,
wb_index
:
Int
)
=
{
exceptionGen
.
io
.
wb
(
index
).
valid
:=
io
.
exeWbResults
(
wb_index
).
valid
// A temporary fix for float load writeback
...
...
@@ -911,21 +907,16 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
val
wdata
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
val
wpc
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
val
trapVec
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
for
(
i
<-
0
until
CommitWidth
)
{
val
idx
=
deqPtrVec
(
i
).
value
wdata
(
i
)
:=
debug_exuData
(
idx
)
wpc
(
i
)
:=
SignExt
(
commitDebugUop
(
i
).
cf
.
pc
,
XLEN
)
trapVec
(
i
)
:=
io
.
commits
.
valid
(
i
)
&&
(
state
===
s_idle
)
&&
commitDebugUop
(
i
).
ctrl
.
isXSTrap
}
val
retireCounterFix
=
Mux
(
io
.
exception
.
valid
,
1.
U
,
retireCounter
)
val
retirePCFix
=
SignExt
(
Mux
(
io
.
exception
.
valid
,
io
.
exception
.
bits
.
uop
.
cf
.
pc
,
debug_microOp
(
firstValidCommit
).
cf
.
pc
),
XLEN
)
val
retireInstFix
=
Mux
(
io
.
exception
.
valid
,
io
.
exception
.
bits
.
uop
.
cf
.
instr
,
debug_microOp
(
firstValidCommit
).
cf
.
instr
)
val
hitTrap
=
trapVec
.
reduce
(
_
||
_
)
val
trapCode
=
PriorityMux
(
wdata
.
zip
(
trapVec
).
map
(
x
=>
x
.
_2
->
x
.
_1
))
val
trapPC
=
SignExt
(
PriorityMux
(
wpc
.
zip
(
trapVec
).
map
(
x
=>
x
.
_2
->
x
.
_1
)),
XLEN
)
if
(
env
.
EnableDifftest
)
{
for
(
i
<-
0
until
CommitWidth
)
{
val
difftest
=
Module
(
new
DifftestInstrCommit
)
...
...
@@ -940,7 +931,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
difftest
.
io
.
valid
:=
RegNext
(
io
.
commits
.
valid
(
i
)
&&
!
io
.
commits
.
isWalk
)
difftest
.
io
.
pc
:=
RegNext
(
SignExt
(
uop
.
cf
.
pc
,
XLEN
))
difftest
.
io
.
instr
:=
RegNext
(
uop
.
cf
.
instr
)
difftest
.
io
.
special
:=
RegNext
(
CommitType
.
isFused
(
uop
.
ctrl
.
commitType
))
difftest
.
io
.
special
:=
RegNext
(
CommitType
.
isFused
(
io
.
commits
.
info
(
i
)
.
commitType
))
// when committing an eliminated move instruction,
// we must make sure that skip is properly set to false (output from EXU is random value)
difftest
.
io
.
skip
:=
RegNext
(
Mux
(
uop
.
eliminatedMove
,
false
.
B
,
exuOut
.
isMMIO
||
exuOut
.
isPerfCnt
))
...
...
@@ -948,9 +939,9 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
difftest
.
io
.
scFailed
:=
RegNext
(!
uop
.
diffTestDebugLrScValid
&&
uop
.
ctrl
.
fuType
===
FuType
.
mou
&&
(
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_d
||
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_w
))
difftest
.
io
.
wen
:=
RegNext
(
io
.
commits
.
valid
(
i
)
&&
uop
.
ctrl
.
rfWen
&&
uop
.
ctrl
.
ldest
=/=
0.
U
)
difftest
.
io
.
w
data
:=
RegNext
(
exuData
)
difftest
.
io
.
wdest
:=
RegNext
(
uop
.
ctrl
.
ldest
)
difftest
.
io
.
wen
:=
RegNext
(
io
.
commits
.
valid
(
i
)
&&
io
.
commits
.
info
(
i
).
rfWen
&&
io
.
commits
.
info
(
i
)
.
ldest
=/=
0.
U
)
difftest
.
io
.
w
pdest
:=
RegNext
(
io
.
commits
.
info
(
i
).
pdest
)
difftest
.
io
.
wdest
:=
RegNext
(
io
.
commits
.
info
(
i
)
ldest
)
// runahead commit hint
val
runahead_commit
=
Module
(
new
DifftestRunaheadCommitEvent
)
...
...
@@ -963,6 +954,44 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
runahead_commit
.
io
.
pc
:=
difftest
.
io
.
pc
}
}
else
if
(
env
.
AlwaysBasicDiff
)
{
// These are the structures used by difftest only and should be optimized after synthesis.
val
dt_eliminatedMove
=
Mem
(
RobSize
,
Bool
())
val
dt_isRVC
=
Mem
(
RobSize
,
Bool
())
val
dt_exuDebug
=
Reg
(
Vec
(
RobSize
,
new
DebugBundle
))
for
(
i
<-
0
until
RenameWidth
)
{
when
(
canEnqueue
(
i
))
{
dt_eliminatedMove
(
enqPtrVec
(
i
).
value
)
:=
io
.
enq
.
req
(
i
).
bits
.
eliminatedMove
dt_isRVC
(
enqPtrVec
(
i
).
value
)
:=
io
.
enq
.
req
(
i
).
bits
.
cf
.
pd
.
isRVC
}
}
for
(
i
<-
0
until
numWbPorts
)
{
when
(
io
.
exeWbResults
(
i
).
valid
)
{
val
wbIdx
=
io
.
exeWbResults
(
i
).
bits
.
uop
.
robIdx
.
value
dt_exuDebug
(
wbIdx
)
:=
io
.
exeWbResults
(
i
).
bits
.
debug
}
}
// Always instantiate basic difftest modules.
for
(
i
<-
0
until
CommitWidth
)
{
val
commitInfo
=
io
.
commits
.
info
(
i
)
val
ptr
=
deqPtrVec
(
i
).
value
val
exuOut
=
dt_exuDebug
(
ptr
)
val
eliminatedMove
=
dt_eliminatedMove
(
ptr
)
val
isRVC
=
dt_isRVC
(
ptr
)
val
difftest
=
Module
(
new
DifftestBasicInstrCommit
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
difftest
.
io
.
index
:=
i
.
U
difftest
.
io
.
valid
:=
RegNext
(
io
.
commits
.
valid
(
i
)
&&
!
io
.
commits
.
isWalk
)
difftest
.
io
.
special
:=
RegNext
(
CommitType
.
isFused
(
commitInfo
.
commitType
))
difftest
.
io
.
skip
:=
RegNext
(
Mux
(
eliminatedMove
,
false
.
B
,
exuOut
.
isMMIO
||
exuOut
.
isPerfCnt
))
difftest
.
io
.
isRVC
:=
RegNext
(
isRVC
)
difftest
.
io
.
wen
:=
RegNext
(
io
.
commits
.
valid
(
i
)
&&
commitInfo
.
rfWen
&&
commitInfo
.
ldest
=/=
0.
U
)
difftest
.
io
.
wpdest
:=
RegNext
(
commitInfo
.
pdest
)
difftest
.
io
.
wdest
:=
RegNext
(
commitInfo
.
ldest
)
}
}
if
(
env
.
EnableDifftest
)
{
for
(
i
<-
0
until
CommitWidth
)
{
...
...
@@ -981,7 +1010,18 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
}
}
// Always instantiate basic difftest modules.
if
(
env
.
EnableDifftest
)
{
val
dt_isXSTrap
=
Mem
(
RobSize
,
Bool
())
for
(
i
<-
0
until
RenameWidth
)
{
when
(
canEnqueue
(
i
))
{
dt_isXSTrap
(
enqPtrVec
(
i
).
value
)
:=
io
.
enq
.
req
(
i
).
bits
.
ctrl
.
isXSTrap
}
}
val
trapVec
=
io
.
commits
.
valid
.
zip
(
deqPtrVec
).
map
{
case
(
v
,
d
)
=>
state
===
s_idle
&&
v
&&
dt_isXSTrap
(
d
.
value
)
}
val
hitTrap
=
trapVec
.
reduce
(
_
||
_
)
val
trapCode
=
PriorityMux
(
wdata
.
zip
(
trapVec
).
map
(
x
=>
x
.
_2
->
x
.
_1
))
val
trapPC
=
SignExt
(
PriorityMux
(
wpc
.
zip
(
trapVec
).
map
(
x
=>
x
.
_2
->
x
.
_1
)),
XLEN
)
val
difftest
=
Module
(
new
DifftestTrapEvent
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
...
...
@@ -991,6 +1031,22 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
difftest
.
io
.
cycleCnt
:=
timer
difftest
.
io
.
instrCnt
:=
instrCnt
}
else
if
(
env
.
AlwaysBasicDiff
)
{
val
dt_isXSTrap
=
Mem
(
RobSize
,
Bool
())
for
(
i
<-
0
until
RenameWidth
)
{
when
(
canEnqueue
(
i
))
{
dt_isXSTrap
(
enqPtrVec
(
i
).
value
)
:=
io
.
enq
.
req
(
i
).
bits
.
ctrl
.
isXSTrap
}
}
val
trapVec
=
io
.
commits
.
valid
.
zip
(
deqPtrVec
).
map
{
case
(
v
,
d
)
=>
state
===
s_idle
&&
v
&&
dt_isXSTrap
(
d
.
value
)
}
val
hitTrap
=
trapVec
.
reduce
(
_
||
_
)
val
difftest
=
Module
(
new
DifftestBasicTrapEvent
)
difftest
.
io
.
clock
:=
clock
difftest
.
io
.
coreid
:=
hardId
.
U
difftest
.
io
.
valid
:=
hitTrap
difftest
.
io
.
cycleCnt
:=
timer
difftest
.
io
.
instrCnt
:=
instrCnt
}
val
perfinfo
=
IO
(
new
Bundle
(){
val
perfEvents
=
Output
(
new
PerfEventsBundle
(
18
))
...
...
src/main/scala/xiangshan/cache/mmu/PTW.scala
浏览文件 @
67ef08a8
...
...
@@ -98,6 +98,7 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
val
source
=
UInt
(
bSourceWidth
.
W
)
},
if
(
l2tlbParams
.
enablePrefetch
)
3
else
2
))
val
outArb
=
(
0
until
PtwWidth
).
map
(
i
=>
Module
(
new
Arbiter
(
new
PtwResp
,
3
)).
io
)
val
outArbCachePort
=
0
val
outArbFsmPort
=
1
val
outArbMqPort
=
2
...
...
@@ -130,7 +131,9 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
cache
.
io
.
req
.
bits
.
isFirst
:=
arb2
.
io
.
chosen
=/=
InArbMissQueuePort
.
U
cache
.
io
.
sfence
:=
sfence
cache
.
io
.
csr
:=
csr
cache
.
io
.
resp
.
ready
:=
Mux
(
cache
.
io
.
resp
.
bits
.
hit
,
true
.
B
,
missQueue
.
io
.
in
.
ready
||
(!
cache
.
io
.
resp
.
bits
.
toFsm
.
l2Hit
&&
fsm
.
io
.
req
.
ready
))
cache
.
io
.
resp
.
ready
:=
Mux
(
cache
.
io
.
resp
.
bits
.
hit
,
outReady
(
cache
.
io
.
resp
.
bits
.
req_info
.
source
,
outArbCachePort
),
missQueue
.
io
.
in
.
ready
||
(!
cache
.
io
.
resp
.
bits
.
toFsm
.
l2Hit
&&
fsm
.
io
.
req
.
ready
))
val
mq_in_arb
=
Module
(
new
Arbiter
(
new
L2TlbMQInBundle
,
2
))
mq_in_arb
.
io
.
in
(
0
).
valid
:=
cache
.
io
.
resp
.
valid
&&
!
cache
.
io
.
resp
.
bits
.
hit
&&
(
cache
.
io
.
resp
.
bits
.
toFsm
.
l2Hit
||
!
fsm
.
io
.
req
.
ready
)
...
...
@@ -150,8 +153,7 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
fsm
.
io
.
req
.
bits
.
ppn
:=
cache
.
io
.
resp
.
bits
.
toFsm
.
ppn
fsm
.
io
.
csr
:=
csr
fsm
.
io
.
sfence
:=
sfence
fsm
.
io
.
resp
.
ready
:=
MuxLookup
(
fsm
.
io
.
resp
.
bits
.
source
,
true
.
B
,
(
0
until
PtwWidth
).
map
(
i
=>
i
.
U
->
outArb
(
i
).
in
(
outArbFsmPort
).
ready
))
fsm
.
io
.
resp
.
ready
:=
outReady
(
fsm
.
io
.
resp
.
bits
.
source
,
outArbFsmPort
)
// mem req
def
blockBytes_align
(
addr
:
UInt
)
=
{
...
...
@@ -239,13 +241,12 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
pmp_check
(
1
).
req
<>
missQueue
.
io
.
pmp
.
req
missQueue
.
io
.
pmp
.
resp
<>
pmp_check
(
1
).
resp
mq_out
.
ready
:=
MuxLookup
(
missQueue
.
io
.
out
.
bits
.
req_info
.
source
,
true
.
B
,
(
0
until
PtwWidth
).
map
(
i
=>
i
.
U
->
outArb
(
i
).
in
(
outArbMqPort
).
ready
))
mq_out
.
ready
:=
outReady
(
mq_out
.
bits
.
req_info
.
source
,
outArbMqPort
)
for
(
i
<-
0
until
PtwWidth
)
{
outArb
(
i
).
in
(
0
).
valid
:=
cache
.
io
.
resp
.
valid
&&
cache
.
io
.
resp
.
bits
.
hit
&&
cache
.
io
.
resp
.
bits
.
req_info
.
source
===
i
.
U
outArb
(
i
).
in
(
0
).
bits
.
entry
:=
cache
.
io
.
resp
.
bits
.
toTlb
outArb
(
i
).
in
(
0
).
bits
.
pf
:=
false
.
B
outArb
(
i
).
in
(
0
).
bits
.
af
:=
false
.
B
outArb
(
i
).
in
(
outArbCachePort
).
valid
:=
cache
.
io
.
resp
.
valid
&&
cache
.
io
.
resp
.
bits
.
hit
&&
cache
.
io
.
resp
.
bits
.
req_info
.
source
===
i
.
U
outArb
(
i
).
in
(
outArbCachePort
).
bits
.
entry
:=
cache
.
io
.
resp
.
bits
.
toTlb
outArb
(
i
).
in
(
outArbCachePort
).
bits
.
pf
:=
false
.
B
outArb
(
i
).
in
(
outArbCachePort
).
bits
.
af
:=
false
.
B
outArb
(
i
).
in
(
outArbFsmPort
).
valid
:=
fsm
.
io
.
resp
.
valid
&&
fsm
.
io
.
resp
.
bits
.
source
===
i
.
U
outArb
(
i
).
in
(
outArbFsmPort
).
bits
:=
fsm
.
io
.
resp
.
bits
.
resp
outArb
(
i
).
in
(
outArbMqPort
).
valid
:=
mq_out
.
valid
&&
mq_out
.
bits
.
req_info
.
source
===
i
.
U
...
...
@@ -297,6 +298,11 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
ptw_resp
}
def
outReady
(
source
:
UInt
,
port
:
Int
)
:
Bool
=
{
MuxLookup
(
source
,
true
.
B
,
(
0
until
PtwWidth
).
map
(
i
=>
i
.
U
->
outArb
(
i
).
in
(
port
).
ready
))
}
// debug info
for
(
i
<-
0
until
PtwWidth
)
{
XSDebug
(
p
"[io.tlb(${i.U})] ${io.tlb(i)}\n"
)
...
...
src/main/scala/xiangshan/cache/mmu/PageTableCache.scala
浏览文件 @
67ef08a8
...
...
@@ -103,13 +103,18 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
val
rwHarzad
=
if
(
sramSinglePort
)
io
.
refill
.
valid
else
false
.
B
// handle hand signal and req_info
val
stage1
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
val
stage2
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
val
stage3
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
val
stage1
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
// enq stage & read page cache valid
val
stage2
=
Wire
(
Vec
(
2
,
Decoupled
(
new
PtwCacheReq
())))
// page cache resp & check hit & check ecc
val
stage3
=
Wire
(
Decoupled
(
new
PtwCacheReq
()))
// deq stage
/* stage1.valid && stage2(0).ready : stage1 (in) -> stage2
* stage2(1).valid && stage3.ready : stage2 -> stage3
* stage3.valid && io.resp.ready : stage3 (out) -> outside
*/
stage1
<>
io
.
req
PipelineConnect
(
stage1
,
stage2
,
stage3
.
ready
,
flush
,
rwHarzad
)
PipelineConnect
(
stage2
,
stage3
,
io
.
resp
.
ready
,
flush
)
stage3
.
ready
:=
io
.
resp
.
ready
PipelineConnect
(
stage1
,
stage2
(
0
),
stage2
(
1
).
ready
,
flush
,
rwHarzad
)
InsideStageConnect
(
stage2
(
0
),
stage2
(
1
))
PipelineConnect
(
stage2
(
1
),
stage3
,
io
.
resp
.
ready
,
flush
)
stage3
.
ready
:=
!
stage3
.
valid
||
io
.
resp
.
ready
// l1: level 0 non-leaf pte
val
l1
=
Reg
(
Vec
(
l2tlbParams
.
l1Size
,
new
PtwEntry
(
tagLen
=
PtwL1TagLen
)))
...
...
@@ -200,7 +205,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
XSDebug
(
stage1
.
fire
,
p
"[l1] l1(${i.U}) ${l1(i)} hit:${l1(i).hit(stage1.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
}
XSDebug
(
stage1
.
fire
,
p
"[l1] l1v:${Binary(l1v)} hitVecT:${Binary(VecInit(hitVecT).asUInt)}\n"
)
XSDebug
(
stage2
.
valid
,
p
"[l1] l1Hit:${hit} l1HitPPN:0x${Hexadecimal(hitPPN)} hitVec:${VecInit(hitVec).asUInt}\n"
)
XSDebug
(
stage2
(
0
)
.
valid
,
p
"[l1] l1Hit:${hit} l1HitPPN:0x${Hexadecimal(hitPPN)} hitVec:${VecInit(hitVec).asUInt}\n"
)
VecInit
(
hitVecT
).
suggestName
(
s
"l1_hitVecT"
)
VecInit
(
hitVec
).
suggestName
(
s
"l1_hitVec"
)
...
...
@@ -217,7 +222,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
l2
.
io
.
r
.
req
.
valid
:=
stage1
.
fire
l2
.
io
.
r
.
req
.
bits
.
apply
(
setIdx
=
ridx
)
val
ramDatas
=
l2
.
io
.
r
.
resp
.
data
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitWayEntry
=
ParallelPriorityMux
(
hitVec
zip
ramDatas
)
val
hitWayData
=
hitWayEntry
.
entries
val
hit
=
ParallelOR
(
hitVec
)
&&
cache_read_valid
&&
RegNext
(
l2
.
io
.
r
.
req
.
ready
,
init
=
false
.
B
)
...
...
@@ -231,16 +236,16 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
hitWayData
.
suggestName
(
s
"l2_hitWayData"
)
hitWay
.
suggestName
(
s
"l2_hitWay"
)
when
(
hit
)
{
ptwl2replace
.
access
(
genPtwL2SetIdx
(
stage2
.
bits
.
req_info
.
vpn
),
hitWay
)
}
when
(
hit
)
{
ptwl2replace
.
access
(
genPtwL2SetIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
),
hitWay
)
}
l2AccessPerf
.
zip
(
hitVec
).
map
{
case
(
l
,
h
)
=>
l
:=
h
&&
RegNext
(
stage1
.
fire
)
}
XSDebug
(
stage1
.
fire
,
p
"[l2] ridx:0x${Hexadecimal(ridx)}\n"
)
for
(
i
<-
0
until
l2tlbParams
.
l2nWays
)
{
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l2] ramDatas(${i.U}) ${ramDatas(i)} l2v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l2] ramDatas(${i.U}) ${ramDatas(i)} l2v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2
(0)
.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
}
XSDebug
(
stage2
.
valid
,
p
"[l2] l2Hit:${hit} l2HitPPN:0x${Hexadecimal(hitWayData.ppns(genPtwL2SectorIdx(stage2
.bits.req_info.vpn)))} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
XSDebug
(
stage2
(
0
).
valid
,
p
"[l2] l2Hit:${hit} l2HitPPN:0x${Hexadecimal(hitWayData.ppns(genPtwL2SectorIdx(stage2(0)
.bits.req_info.vpn)))} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
(
hit
,
hitWayData
.
ppns
(
genPtwL2SectorIdx
(
stage2
.
bits
.
req_info
.
vpn
)),
hitWayData
.
prefetch
,
eccError
)
(
hit
,
hitWayData
.
ppns
(
genPtwL2SectorIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
)),
hitWayData
.
prefetch
,
eccError
)
}
// l3
...
...
@@ -252,7 +257,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
l3
.
io
.
r
.
req
.
valid
:=
stage1
.
fire
l3
.
io
.
r
.
req
.
bits
.
apply
(
setIdx
=
ridx
)
val
ramDatas
=
l3
.
io
.
r
.
resp
.
data
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitVec
=
VecInit
(
ramDatas
.
zip
(
vidx
).
map
{
case
(
wayData
,
v
)
=>
wayData
.
entries
.
hit
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
,
io
.
csr
.
satp
.
asid
)
&&
v
})
val
hitWayEntry
=
ParallelPriorityMux
(
hitVec
zip
ramDatas
)
val
hitWayData
=
hitWayEntry
.
entries
val
hitWayEcc
=
hitWayEntry
.
ecc
...
...
@@ -260,14 +265,14 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
val
hitWay
=
ParallelPriorityMux
(
hitVec
zip
(
0
until
l2tlbParams
.
l3nWays
).
map
(
_
.
U
))
val
eccError
=
hitWayEntry
.
decode
()
when
(
hit
)
{
ptwl3replace
.
access
(
genPtwL3SetIdx
(
stage2
.
bits
.
req_info
.
vpn
),
hitWay
)
}
when
(
hit
)
{
ptwl3replace
.
access
(
genPtwL3SetIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
),
hitWay
)
}
l3AccessPerf
.
zip
(
hitVec
).
map
{
case
(
l
,
h
)
=>
l
:=
h
&&
RegNext
(
stage1
.
fire
)
}
XSDebug
(
stage1
.
fire
,
p
"[l3] ridx:0x${Hexadecimal(ridx)}\n"
)
for
(
i
<-
0
until
l2tlbParams
.
l3nWays
)
{
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l3] ramDatas(${i.U}) ${ramDatas(i)} l3v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
XSDebug
(
RegNext
(
stage1
.
fire
),
p
"[l3] ramDatas(${i.U}) ${ramDatas(i)} l3v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2
(0)
.bits.req_info.vpn, io.csr.satp.asid)}\n"
)
}
XSDebug
(
stage2
.
valid
,
p
"[l3] l3Hit:${hit} l3HitData:${hitWayData} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
XSDebug
(
stage2
(
0
)
.
valid
,
p
"[l3] l3Hit:${hit} l3HitData:${hitWayData} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n"
)
ridx
.
suggestName
(
s
"l3_ridx"
)
vidx
.
suggestName
(
s
"l3_vidx"
)
...
...
@@ -277,8 +282,8 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
(
hit
,
hitWayData
,
hitWayData
.
prefetch
,
eccError
)
}
val
l3HitPPN
=
l3HitData
.
ppns
(
genPtwL3SectorIdx
(
stage2
.
bits
.
req_info
.
vpn
))
val
l3HitPerm
=
l3HitData
.
perms
.
getOrElse
(
0.
U
.
asTypeOf
(
Vec
(
PtwL3SectorSize
,
new
PtePermBundle
)))(
genPtwL3SectorIdx
(
stage2
.
bits
.
req_info
.
vpn
))
val
l3HitPPN
=
l3HitData
.
ppns
(
genPtwL3SectorIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
))
val
l3HitPerm
=
l3HitData
.
perms
.
getOrElse
(
0.
U
.
asTypeOf
(
Vec
(
PtwL3SectorSize
,
new
PtePermBundle
)))(
genPtwL3SectorIdx
(
stage2
(
0
)
.
bits
.
req_info
.
vpn
))
// super page
val
spreplace
=
ReplacementPolicy
.
fromString
(
l2tlbParams
.
spReplacer
,
l2tlbParams
.
spSize
)
...
...
@@ -294,7 +299,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
for
(
i
<-
0
until
l2tlbParams
.
spSize
)
{
XSDebug
(
stage1
.
fire
,
p
"[sp] sp(${i.U}) ${sp(i)} hit:${sp(i).hit(stage1.bits.req_info.vpn, io.csr.satp.asid)} spv:${spv(i)}\n"
)
}
XSDebug
(
stage2
.
valid
,
p
"[sp] spHit:${hit} spHitData:${hitData} hitVec:${Binary(VecInit(hitVec).asUInt)}\n"
)
XSDebug
(
stage2
(
0
)
.
valid
,
p
"[sp] spHit:${hit} spHitData:${hitData} hitVec:${Binary(VecInit(hitVec).asUInt)}\n"
)
VecInit
(
hitVecT
).
suggestName
(
s
"sp_hitVecT"
)
VecInit
(
hitVec
).
suggestName
(
s
"sp_hitVec"
)
...
...
@@ -313,7 +318,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
// stage3, add stage 3 for ecc check...
val
s3_res
=
Reg
(
new
PageCacheRespBundle
)
when
(
stage2
.
fire
())
{
when
(
stage2
(
1
)
.
fire
())
{
s3_res
:=
s2_res_reg
}
...
...
@@ -551,6 +556,12 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
}
}
def
InsideStageConnect
[
T
<:
Data
](
in
:
DecoupledIO
[
T
],
out
:
DecoupledIO
[
T
],
block
:
Bool
=
false
.
B
)
:
Unit
=
{
in
.
ready
:=
!
in
.
valid
||
out
.
ready
out
.
valid
:=
in
.
valid
out
.
bits
:=
in
.
bits
}
// Perf Count
val
resp_l3
=
s3_res
.
l3
.
hit
val
resp_sp
=
s3_res
.
sp
.
hit
...
...
src/main/scala/xiangshan/cache/mmu/PageTableWalker.scala
浏览文件 @
67ef08a8
...
...
@@ -117,21 +117,21 @@ class PtwFsm()(implicit p: Parameters) extends XSModule with HasPtwConst {
}
is
(
s_check_pte
)
{
when
(
io
.
resp
.
valid
)
{
when
(
io
.
resp
.
valid
)
{
// find pte already or accessFault (mentioned below)
when
(
io
.
resp
.
fire
())
{
state
:=
s_idle
}
finish
:=
true
.
B
}.
otherwise
{
when
(
io
.
pmp
.
resp
.
ld
)
{
// do nothing
}
.
elsewhen
(
io
.
mq
.
valid
)
{
when
(
io
.
mq
.
fire
())
{
state
:=
s_idle
}
finish
:=
true
.
B
}.
otherwise
{
//
when level is 1.U, finish
assert
(
level
=
/=
2
.
U
)
}.
elsewhen
(
io
.
mq
.
valid
)
{
// the next level is pte, go to miss queue
when
(
io
.
mq
.
fire
()
)
{
state
:=
s_idle
}
finish
:=
true
.
B
}
otherwise
{
// go to next level, access the memory, need pmp check first
when
(
io
.
pmp
.
resp
.
ld
)
{
// pmp check failed, raise access-fault
// do nothing, RegNext the pmp check result and do it later (mentioned above)
}.
otherwise
{
//
go to next level.
assert
(
level
=
==
0
.
U
)
level
:=
levelNext
state
:=
s_mem_req
}
...
...
src/main/scala/xiangshan/cache/mmu/Repeater.scala
浏览文件 @
67ef08a8
...
...
@@ -29,6 +29,19 @@ class PTWReapterIO(Width: Int)(implicit p: Parameters) extends MMUIOBaseBundle {
val
tlb
=
Flipped
(
new
TlbPtwIO
(
Width
))
val
ptw
=
new
TlbPtwIO
def
apply
(
tlb
:
TlbPtwIO
,
ptw
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
ptw
<>
ptw
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
def
apply
(
tlb
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
override
def
cloneType
:
this.
type
=
(
new
PTWReapterIO
(
Width
)).
asInstanceOf
[
this.
type
]
}
...
...
@@ -71,10 +84,66 @@ class PTWRepeater(Width: Int = 1)(implicit p: Parameters) extends XSModule with
/* dtlb
*
*/
class
PTWRepeaterNB
(
Width
:
Int
=
1
,
passReady
:
Boolean
=
false
)(
implicit
p
:
Parameters
)
extends
XSModule
with
HasPtwConst
{
val
io
=
IO
(
new
PTWReapterIO
(
Width
))
val
req_in
=
if
(
Width
==
1
)
{
io
.
tlb
.
req
(
0
)
}
else
{
val
arb
=
Module
(
new
RRArbiter
(
io
.
tlb
.
req
(
0
).
bits
.
cloneType
,
Width
))
arb
.
io
.
in
<>
io
.
tlb
.
req
arb
.
io
.
out
}
val
(
tlb
,
ptw
,
flush
)
=
(
io
.
tlb
,
io
.
ptw
,
RegNext
(
io
.
sfence
.
valid
||
io
.
csr
.
satp
.
changed
))
/* sent: tlb -> repeater -> ptw
* recv: ptw -> repeater -> tlb
* different from PTWRepeater
*/
// tlb -> repeater -> ptw
val
req
=
RegEnable
(
req_in
.
bits
,
req_in
.
fire
())
val
sent
=
BoolStopWatch
(
req_in
.
fire
(),
ptw
.
req
(
0
).
fire
()
||
flush
)
req_in
.
ready
:=
!
sent
||
{
if
(
passReady
)
ptw
.
req
(
0
).
ready
else
false
.
B
}
ptw
.
req
(
0
).
valid
:=
sent
ptw
.
req
(
0
).
bits
:=
req
// ptw -> repeater -> tlb
val
resp
=
RegEnable
(
ptw
.
resp
.
bits
,
ptw
.
resp
.
fire
())
val
recv
=
BoolStopWatch
(
ptw
.
resp
.
fire
(),
tlb
.
resp
.
fire
()
||
flush
)
ptw
.
resp
.
ready
:=
!
recv
||
{
if
(
passReady
)
tlb
.
resp
.
ready
else
false
.
B
}
tlb
.
resp
.
valid
:=
recv
tlb
.
resp
.
bits
:=
resp
XSPerfAccumulate
(
"req"
,
req_in
.
fire
())
XSPerfAccumulate
(
"resp"
,
tlb
.
resp
.
fire
())
if
(!
passReady
)
{
XSPerfAccumulate
(
"req_blank"
,
req_in
.
valid
&&
sent
&&
ptw
.
req
(
0
).
ready
)
XSPerfAccumulate
(
"resp_blank"
,
ptw
.
resp
.
valid
&&
recv
&&
tlb
.
resp
.
ready
)
XSPerfAccumulate
(
"req_blank_ignore_ready"
,
req_in
.
valid
&&
sent
)
XSPerfAccumulate
(
"resp_blank_ignore_ready"
,
ptw
.
resp
.
valid
&&
recv
)
}
XSDebug
(
req_in
.
valid
||
io
.
tlb
.
resp
.
valid
,
p
"tlb: ${tlb}\n"
)
XSDebug
(
io
.
ptw
.
req
(
0
).
valid
||
io
.
ptw
.
resp
.
valid
,
p
"ptw: ${ptw}\n"
)
}
class
PTWFilterIO
(
Width
:
Int
)(
implicit
p
:
Parameters
)
extends
MMUIOBaseBundle
{
val
tlb
=
Flipped
(
new
BTlbPtwIO
(
Width
))
val
ptw
=
new
TlbPtwIO
()
def
apply
(
tlb
:
BTlbPtwIO
,
ptw
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
ptw
<>
ptw
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
def
apply
(
tlb
:
BTlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)
:
Unit
=
{
this
.
tlb
<>
tlb
this
.
sfence
<>
sfence
this
.
csr
<>
csr
}
override
def
cloneType
:
this.
type
=
(
new
PTWFilterIO
(
Width
)).
asInstanceOf
[
this.
type
]
}
...
...
@@ -233,10 +302,7 @@ object PTWRepeater {
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeater
(
width
))
repeater
.
io
.
tlb
<>
tlb
repeater
.
io
.
sfence
<>
sfence
repeater
.
io
.
csr
<>
csr
repeater
.
io
.
apply
(
tlb
,
sfence
,
csr
)
repeater
}
...
...
@@ -248,11 +314,32 @@ object PTWRepeater {
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeater
(
width
))
repeater
.
io
.
tlb
<>
tlb
repeater
.
io
.
ptw
<>
ptw
repeater
.
io
.
sfence
<>
sfence
repeater
.
io
.
csr
<>
csr
repeater
.
io
.
apply
(
tlb
,
ptw
,
sfence
,
csr
)
repeater
}
}
object
PTWRepeaterNB
{
def
apply
(
passReady
:
Boolean
,
tlb
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeaterNB
(
width
,
passReady
))
repeater
.
io
.
apply
(
tlb
,
sfence
,
csr
)
repeater
}
def
apply
(
passReady
:
Boolean
,
tlb
:
TlbPtwIO
,
ptw
:
TlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
repeater
=
Module
(
new
PTWRepeaterNB
(
width
,
passReady
))
repeater
.
io
.
apply
(
tlb
,
ptw
,
sfence
,
csr
)
repeater
}
}
...
...
@@ -267,11 +354,20 @@ object PTWFilter {
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
filter
=
Module
(
new
PTWFilter
(
width
,
size
))
filter
.
io
.
tlb
<>
tlb
filter
.
io
.
ptw
<>
ptw
filter
.
io
.
sfence
<>
sfence
filter
.
io
.
csr
<>
csr
filter
.
io
.
apply
(
tlb
,
ptw
,
sfence
,
csr
)
filter
}
def
apply
(
tlb
:
BTlbPtwIO
,
sfence
:
SfenceBundle
,
csr
:
TlbCsrBundle
,
size
:
Int
)(
implicit
p
:
Parameters
)
=
{
val
width
=
tlb
.
req
.
size
val
filter
=
Module
(
new
PTWFilter
(
width
,
size
))
filter
.
io
.
apply
(
tlb
,
sfence
,
csr
)
filter
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录