Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
ed91f056
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
ed91f056
编写于
12月 10, 2020
作者:
Fa_wang
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master' into debian-gogogo
上级
7b9c6243
4c63baf4
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
276 addition
and
112 deletion
+276
-112
src/main/scala/device/AXI4RAM.scala
src/main/scala/device/AXI4RAM.scala
+4
-3
src/main/scala/device/AXI4SlaveModule.scala
src/main/scala/device/AXI4SlaveModule.scala
+2
-2
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+1
-1
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
...scala/xiangshan/backend/issue/ReservationStationNew.scala
+10
-9
src/main/scala/xiangshan/cache/dtlb.scala
src/main/scala/xiangshan/cache/dtlb.scala
+71
-4
src/main/scala/xiangshan/cache/ptw.scala
src/main/scala/xiangshan/cache/ptw.scala
+164
-73
src/test/csrc/ram.cpp
src/test/csrc/ram.cpp
+15
-15
src/test/scala/cache/L2CacheTest.scala
src/test/scala/cache/L2CacheTest.scala
+8
-4
src/test/scala/top/XSSim.scala
src/test/scala/top/XSSim.scala
+1
-1
未找到文件。
src/main/scala/device/AXI4RAM.scala
浏览文件 @
ed91f056
...
...
@@ -37,10 +37,11 @@ class AXI4RAM
val
split
=
beatBytes
/
8
val
bankByte
=
memByte
/
split
val
offsetBits
=
log2Up
(
memByte
)
val
offsetMask
=
(
1
<<
offsetBits
)
-
1
require
(
address
.
length
>=
1
)
val
baseAddress
=
address
(
0
).
base
def
index
(
addr
:
UInt
)
=
((
addr
&
offsetMask
.
U
)
>>
log2Ceil
(
beatBytes
)).
asUInt
()
def
index
(
addr
:
UInt
)
=
((
addr
-
baseAddress
.
U
)(
offsetBits
-
1
,
0
)
>>
log2Ceil
(
beatBytes
)).
asUInt
()
def
inRange
(
idx
:
UInt
)
=
idx
<
(
memByte
/
beatBytes
).
U
...
...
@@ -53,7 +54,7 @@ class AXI4RAM
val
mems
=
(
0
until
split
).
map
{
_
=>
Module
(
new
RAMHelper
(
bankByte
))}
mems
.
zipWithIndex
map
{
case
(
mem
,
i
)
=>
mem
.
io
.
clk
:=
clock
mem
.
io
.
en
:=
!
reset
.
asBool
()
mem
.
io
.
en
:=
!
reset
.
asBool
()
&&
(
state
===
s_rdata
)
mem
.
io
.
rIdx
:=
(
rIdx
<<
log2Up
(
split
))
+
i
.
U
mem
.
io
.
wIdx
:=
(
wIdx
<<
log2Up
(
split
))
+
i
.
U
mem
.
io
.
wdata
:=
in
.
w
.
bits
.
data
((
i
+
1
)
*
64
-
1
,
i
*
64
)
...
...
src/main/scala/device/AXI4SlaveModule.scala
浏览文件 @
ed91f056
...
...
@@ -75,9 +75,9 @@ class AXI4SlaveModuleImp[T<:Data](outer: AXI4SlaveModule[T])
assert
(
in
.
ar
.
bits
.
burst
===
AXI4Parameters
.
BURST_INCR
,
"only support busrt ince!"
)
}
private
val
s_idle
::
s_rdata
::
s_wdata
::
s_wresp
::
Nil
=
Enum
(
4
)
val
s_idle
::
s_rdata
::
s_wdata
::
s_wresp
::
Nil
=
Enum
(
4
)
private
val
state
=
RegInit
(
s_idle
)
val
state
=
RegInit
(
s_idle
)
switch
(
state
){
is
(
s_idle
){
...
...
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
ed91f056
...
...
@@ -52,7 +52,7 @@ case class XSCoreParameters
RenameWidth
:
Int
=
6
,
CommitWidth
:
Int
=
6
,
BrqSize
:
Int
=
32
,
IssQueSize
:
Int
=
8
,
IssQueSize
:
Int
=
12
,
NRPhyRegs
:
Int
=
160
,
NRIntReadPorts
:
Int
=
14
,
NRIntWritePorts
:
Int
=
8
,
...
...
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
浏览文件 @
ed91f056
...
...
@@ -61,7 +61,7 @@ class ReservationStationCtrl
feedback
:
Boolean
,
fixedDelay
:
Int
,
replayDelay
:
Int
=
10
)
extends
XSModule
{
)
extends
XSModule
with
HasCircularQueuePtrHelper
{
val
iqSize
=
IssQueSize
val
iqIdxWidth
=
log2Up
(
iqSize
)
...
...
@@ -95,7 +95,8 @@ class ReservationStationCtrl
val
cntQueue
=
Reg
(
Vec
(
iqSize
,
UInt
(
log2Up
(
replayDelay
).
W
)))
// rs queue part:
val
tailPtr
=
RegInit
(
0.
U
((
iqIdxWidth
+
1
).
W
))
// val tailPtr = RegInit(0.U((iqIdxWidth+1).W))
val
tailPtr
=
RegInit
(
0.
U
.
asTypeOf
(
new
CircularQueuePtr
(
iqSize
)))
val
idxQueue
=
RegInit
(
VecInit
((
0
until
iqSize
).
map
(
_
.
U
(
iqIdxWidth
.
W
))))
val
readyQueue
=
VecInit
(
srcQueue
.
zip
(
validQueue
).
map
{
case
(
a
,
b
)
=>
Cat
(
a
).
andR
&
b
})
...
...
@@ -133,7 +134,7 @@ class ReservationStationCtrl
Mux
(
notBlock
,
!
selectedIdxRegOH
(
i
),
true
.
B
)
)))
val
(
firstBubble
,
findBubble
)
=
PriorityEncoderWithFlag
(
bubMask
)
haveBubble
:=
findBubble
&&
(
firstBubble
<
tailPtr
)
haveBubble
:=
findBubble
&&
(
firstBubble
<
tailPtr
.
asUInt
)
val
bubValid
=
haveBubble
val
bubReg
=
RegNext
(
bubValid
)
val
bubIdxReg
=
RegNext
(
firstBubble
-
moveMask
(
firstBubble
))
...
...
@@ -204,7 +205,7 @@ class ReservationStationCtrl
// enq
val
tailAfterRealDeq
=
tailPtr
-
(
issFire
&&
!
needFeedback
||
bubReg
)
val
isFull
=
tailAfterRealDeq
.
head
(
1
).
asBool
()
// tailPtr===qsize.U
val
isFull
=
tailAfterRealDeq
.
flag
// tailPtr===qsize.U
tailPtr
:=
tailAfterRealDeq
+
io
.
enqCtrl
.
fire
()
io
.
enqCtrl
.
ready
:=
!
isFull
&&
!
io
.
redirect
.
valid
// TODO: check this redirect && need more optimization
...
...
@@ -213,7 +214,7 @@ class ReservationStationCtrl
val
srcTypeSeq
=
Seq
(
enqUop
.
ctrl
.
src1Type
,
enqUop
.
ctrl
.
src2Type
,
enqUop
.
ctrl
.
src3Type
)
val
srcStateSeq
=
Seq
(
enqUop
.
src1State
,
enqUop
.
src2State
,
enqUop
.
src3State
)
val
enqIdx_ctrl
=
tailAfterRealDeq
.
tail
(
1
)
val
enqIdx_ctrl
=
tailAfterRealDeq
.
value
val
enqBpVec
=
io
.
data
.
srcUpdate
(
IssQueSize
)
def
stateCheck
(
src
:
UInt
,
srcType
:
UInt
)
:
Bool
=
{
...
...
@@ -245,19 +246,19 @@ class ReservationStationCtrl
}
// other to Data
io
.
data
.
enqPtr
:=
idxQueue
(
Mux
(
tailPtr
.
head
(
1
).
asBool
,
deqIdx
,
tailPtr
.
tail
(
1
)
))
io
.
data
.
enqPtr
:=
idxQueue
(
Mux
(
tailPtr
.
flag
,
deqIdx
,
tailPtr
.
value
))
io
.
data
.
deqPtr
.
valid
:=
selValid
io
.
data
.
deqPtr
.
bits
:=
idxQueue
(
selectedIdxWire
)
io
.
data
.
enqCtrl
.
valid
:=
io
.
enqCtrl
.
fire
io
.
data
.
enqCtrl
.
bits
:=
io
.
enqCtrl
.
bits
// other io
io
.
numExist
:=
tailPtr
io
.
numExist
:=
Mux
(
tailPtr
.
flag
,
(
iqSize
-
1
).
U
,
tailPtr
.
value
)
// NOTE: numExist is iqIdxWidth.W, maybe a bug
// assert
assert
(
RegNext
(
tailPtr
<=
iqSize
.
U
))
assert
(
RegNext
(
Mux
(
tailPtr
.
flag
,
tailPtr
.
value
===
0.
U
,
true
.
B
)
))
val
print
=
!(
tailPtr
===
0.
U
)
||
io
.
enqCtrl
.
valid
val
print
=
!(
tailPtr
.
asUInt
===
0.
U
)
||
io
.
enqCtrl
.
valid
XSDebug
(
print
||
true
.
B
,
p
"In(${io.enqCtrl.valid} ${io.enqCtrl.ready}) Out(${issValid} ${io.data.fuReady})\n"
)
XSDebug
(
print
,
p
"tailPtr:${tailPtr} tailPtrAdq:${tailAfterRealDeq} isFull:${isFull} "
+
p
"needFeed:${needFeedback} vQue:${Binary(VecInit(validQueue).asUInt)} rQue:${Binary(readyQueue.asUInt)}\n"
)
...
...
src/main/scala/xiangshan/cache/dtlb.scala
浏览文件 @
ed91f056
...
...
@@ -56,7 +56,7 @@ class PermBundle(val hasV: Boolean = true) extends TlbBundle {
if
(
hasV
)
{
val
v
=
Bool
()
}
override
def
toPrintable
:
Printable
=
{
p
"d:${d} a:${a} g:${g} u:${u} x:${x} w:${w} r:${r}"
// +
p
"d:${d} a:${a} g:${g} u:${u} x:${x} w:${w} r:${r}"
// +
//(if(hasV) (p"v:${v}") else p"")
}
}
...
...
@@ -114,6 +114,73 @@ class TlbEntry extends TlbBundle {
}
}
class
TlbEntires
(
num
:
Int
,
tagLen
:
Int
)
extends
TlbBundle
{
require
(
log2Up
(
num
)==
log2Down
(
num
))
/* vpn can be divide into three part */
// vpn: tagPart + addrPart
val
cutLen
=
log2Up
(
num
)
val
tag
=
UInt
(
tagLen
.
W
)
// NOTE: high part of vpn
val
level
=
UInt
(
log2Up
(
Level
).
W
)
val
ppns
=
Vec
(
num
,
UInt
(
ppnLen
.
W
))
val
perms
=
Vec
(
num
,
new
PermBundle
(
hasV
=
false
))
val
vs
=
Vec
(
num
,
Bool
())
def
tagClip
(
vpn
:
UInt
,
level
:
UInt
)
=
{
// full vpn => tagLen
Mux
(
level
===
0.
U
,
Cat
(
vpn
(
vpnLen
-
1
,
vpnnLen
*
2
+
cutLen
),
0.
U
(
vpnnLen
*
2
+
cutLen
)),
Mux
(
level
===
1.
U
,
Cat
(
vpn
(
vpnLen
-
1
,
vpnnLen
*
1
+
cutLen
),
0.
U
(
vpnnLen
*
1
+
cutLen
)),
Cat
(
vpn
(
vpnLen
-
1
,
vpnnLen
*
0
+
cutLen
),
0.
U
(
vpnnLen
*
0
+
cutLen
))))(
tagLen
-
1
,
0
)
}
// NOTE: get insize idx
def
idxClip
(
vpn
:
UInt
,
level
:
UInt
)
=
{
Mux
(
level
===
0.
U
,
vpn
(
vpnnLen
*
2
+
cutLen
-
1
,
vpnnLen
*
2
),
Mux
(
level
===
1.
U
,
vpn
(
vpnnLen
*
1
+
cutLen
-
1
,
vpnnLen
*
1
),
vpn
(
vpnnLen
*
0
+
cutLen
-
1
,
vpnnLen
*
0
)))
}
def
hit
(
vpn
:
UInt
)
=
{
(
tag
===
tagClip
(
vpn
,
level
))
&&
vs
(
idxClip
(
vpn
,
level
))
}
def
genEntries
(
data
:
UInt
,
level
:
UInt
,
vpn
:
UInt
)
:
TlbEntires
=
{
require
((
data
.
getWidth
/
XLEN
)
==
num
,
"input data length must be multiple of pte length"
)
assert
(
level
=/=
3.
U
,
"level should not be 3"
)
val
ts
=
Wire
(
new
TlbEntires
(
num
,
tagLen
))
ts
.
tag
:=
tagClip
(
vpn
,
level
)
ts
.
level
:=
level
for
(
i
<-
0
until
num
)
{
val
pte
=
data
((
i
+
1
)*
XLEN
-
1
,
i
*
XLEN
).
asTypeOf
(
new
PteBundle
)
ts
.
ppns
(
i
)
:=
pte
.
ppn
ts
.
perms
(
i
):=
pte
.
perm
// this.perms has no v
ts
.
vs
(
i
)
:=
!
pte
.
isPf
(
level
)
&&
pte
.
isLeaf
()
// legal and leaf, store to l2Tlb
}
ts
}
def
get
(
vpn
:
UInt
)
:
TlbEntry
=
{
val
t
=
Wire
(
new
TlbEntry
())
val
idx
=
idxClip
(
vpn
,
level
)
t
.
vpn
:=
vpn
// Note: Use input vpn, not vpn in TlbL2
t
.
ppn
:=
ppns
(
idx
)
t
.
level
:=
level
t
.
perm
:=
perms
(
idx
)
t
}
override
def
cloneType
:
this.
type
=
(
new
TlbEntires
(
num
,
tagLen
)).
asInstanceOf
[
this.
type
]
override
def
toPrintable
:
Printable
=
{
require
(
num
==
4
,
"if num is not 4, please comment this toPrintable"
)
// NOTE: if num is not 4, please comment this toPrintable
p
"tag:${Hexadecimal(tag)} level:${level} ppn(0):${Hexadecimal(ppns(0))} ppn(1):${Hexadecimal(ppns(1))}"
+
p
"ppn(2):${Hexadecimal(ppns(2))} ppn(3):${Hexadecimal(ppns(3))} "
+
p
"perms(0):${perms(0)} perms(1):${perms(1)} perms(2):${perms(2)} perms(3):${perms(3)} vs:${Binary(vs.asUInt)}"
}
}
object
TlbCmd
{
def
read
=
"b00"
.
U
def
write
=
"b01"
.
U
...
...
@@ -388,7 +455,7 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
// assert(req(i).bits.vaddr===resp(i).bits.paddr, "vaddr:0x%x paddr:0x%x hitVec:%x ", req(i).bits.vaddr, resp(i).bits.paddr, VecInit(hitVec(i)).asUInt)
// } // FIXME: remove me when tlb may be ok
// }
// assert((v&pf)===0.U, "v and pf can't be true at same time: v:0x%x pf:0x%x", v, pf)
}
...
...
@@ -403,12 +470,12 @@ object TLB {
shouldBlock
:
Boolean
)
=
{
require
(
in
.
length
==
width
)
val
tlb
=
Module
(
new
TLB
(
width
,
isDtlb
))
tlb
.
io
.
sfence
<>
sfence
tlb
.
io
.
csr
<>
csr
if
(!
shouldBlock
)
{
// dtlb
for
(
i
<-
0
until
width
)
{
tlb
.
io
.
requestor
(
i
)
<>
in
(
i
)
...
...
src/main/scala/xiangshan/cache/ptw.scala
浏览文件 @
ed91f056
...
...
@@ -11,6 +11,23 @@ import freechips.rocketchip.tilelink.{TLClientNode, TLMasterParameters, TLMaster
trait
HasPtwConst
extends
HasTlbConst
with
MemoryOpConstants
{
val
PtwWidth
=
2
val
MemBandWidth
=
256
// TODO: change to IO bandwidth param
val
TlbL2LineSize
=
MemBandWidth
/
XLEN
val
TlbL2LineNum
=
TlbL2EntrySize
/
TlbL2LineSize
val
PtwL2LineSize
=
MemBandWidth
/
XLEN
val
PtwL2LineNum
=
PtwL2EntrySize
/
PtwL2LineSize
val
PtwL1TagLen
=
PAddrBits
-
log2Up
(
XLEN
/
8
)
val
PtwL2TagLen
=
PAddrBits
-
log2Up
(
XLEN
/
8
)
-
log2Up
(
PtwL2EntrySize
)
val
TlbL2TagLen
=
vpnLen
-
log2Up
(
TlbL2EntrySize
)
def
genPtwL2Idx
(
addr
:
UInt
)
=
{
/* tagLen :: outSizeIdxLen :: insideIdxLen*/
addr
(
log2Up
(
PtwL2EntrySize
)-
1
+
log2Up
(
XLEN
/
8
),
log2Up
(
PtwL2LineSize
)+
log2Up
(
XLEN
/
8
))
}
def
genTlbL2Idx
(
vpn
:
UInt
)
=
{
vpn
(
log2Up
(
TlbL2LineNum
)-
1
+
log2Up
(
TlbL2LineSize
),
0
+
log2Up
(
TlbL2LineSize
))
}
def
MakeAddr
(
ppn
:
UInt
,
off
:
UInt
)
=
{
require
(
off
.
getWidth
==
9
)
...
...
@@ -41,12 +58,19 @@ class PteBundle extends PtwBundle{
val
v
=
Bool
()
}
def
isPf
()
=
{
!
perm
.
v
||
(!
perm
.
r
&&
perm
.
w
)
def
unaligned
(
level
:
UInt
)
=
{
assert
(
level
=/=
3.
U
)
isLeaf
()
&&
!(
level
===
2.
U
||
level
===
1.
U
&&
ppn
(
vpnnLen
-
1
,
0
)
===
0.
U
||
level
===
0.
U
&&
ppn
(
vpnnLen
*
2
-
1
,
0
)
===
0.
U
)
}
def
isPf
(
level
:
UInt
)
=
{
!
perm
.
v
||
(!
perm
.
r
&&
perm
.
w
)
||
unaligned
(
level
)
}
def
isLeaf
()
=
{
!
isPf
()
&&
(
perm
.
r
||
perm
.
x
)
perm
.
r
||
perm
.
x
||
perm
.
w
}
override
def
toPrintable
:
Printable
=
{
...
...
@@ -57,9 +81,7 @@ class PteBundle extends PtwBundle{
class
PtwEntry
(
tagLen
:
Int
)
extends
PtwBundle
{
val
tag
=
UInt
(
tagLen
.
W
)
val
ppn
=
UInt
(
ppnLen
.
W
)
val
perm
=
new
PermBundle
// TODO: add superpage
def
hit
(
addr
:
UInt
)
=
{
require
(
addr
.
getWidth
>=
PAddrBits
)
tag
===
addr
(
PAddrBits
-
1
,
PAddrBits
-
tagLen
)
...
...
@@ -68,21 +90,69 @@ class PtwEntry(tagLen: Int) extends PtwBundle {
def
refill
(
addr
:
UInt
,
pte
:
UInt
)
{
tag
:=
addr
(
PAddrBits
-
1
,
PAddrBits
-
tagLen
)
ppn
:=
pte
.
asTypeOf
(
pteBundle
).
ppn
perm
:=
pte
.
asTypeOf
(
pteBundle
).
perm
}
def
genPtwEntry
(
addr
:
UInt
,
pte
:
UInt
)
=
{
val
e
=
Wire
(
new
PtwEntry
(
tagLen
))
e
.
tag
:=
addr
(
PAddrBits
-
1
,
PAddrBits
-
tagLen
)
e
.
ppn
:=
pte
.
asTypeOf
(
pteBundle
).
ppn
e
.
perm
:=
pte
.
asTypeOf
(
pteBundle
).
perm
e
}
override
def
cloneType
:
this.
type
=
(
new
PtwEntry
(
tagLen
)).
asInstanceOf
[
this.
type
]
override
def
toPrintable
:
Printable
=
{
p
"tag:0x${Hexadecimal(tag)} ppn:0x${Hexadecimal(ppn)} perm:${perm}"
// p"tag:0x${Hexadecimal(tag)} ppn:0x${Hexadecimal(ppn)} perm:${perm}"
p
"tag:0x${Hexadecimal(tag)} ppn:0x${Hexadecimal(ppn)}"
}
}
class
PtwEntries
(
num
:
Int
,
tagLen
:
Int
)
extends
PtwBundle
{
require
(
log2Up
(
num
)==
log2Down
(
num
))
val
tag
=
UInt
(
tagLen
.
W
)
val
ppns
=
Vec
(
num
,
UInt
(
ppnLen
.
W
))
val
vs
=
Vec
(
num
,
Bool
())
def
tagClip
(
addr
:
UInt
)
=
{
require
(
addr
.
getWidth
==
PAddrBits
)
addr
(
PAddrBits
-
1
,
PAddrBits
-
tagLen
)
}
def
hit
(
idx
:
UInt
,
addr
:
UInt
)
=
{
require
(
idx
.
getWidth
==
log2Up
(
num
),
s
"PtwEntries.hit: error idx width idxWidth:${idx.getWidth} num:${num}"
)
(
tag
===
tagClip
(
addr
))
&&
vs
(
idx
)
}
def
genEntries
(
addr
:
UInt
,
data
:
UInt
,
level
:
UInt
)
:
PtwEntries
=
{
require
((
data
.
getWidth
/
XLEN
)
==
num
,
"input data length must be multiple of pte length"
)
val
ps
=
Wire
(
new
PtwEntries
(
num
,
tagLen
))
ps
.
tag
:=
tagClip
(
addr
)
for
(
i
<-
0
until
num
)
{
val
pte
=
data
((
i
+
1
)*
XLEN
-
1
,
i
*
XLEN
).
asTypeOf
(
new
PteBundle
)
ps
.
ppns
(
i
)
:=
pte
.
ppn
ps
.
vs
(
i
)
:=
!
pte
.
isPf
(
level
)
&&
!
pte
.
isLeaf
()
}
ps
}
def
get
(
idx
:
UInt
)
=
{
require
(
idx
.
getWidth
==
log2Up
(
num
),
s
"PtwEntries.get: error idx width idxWidth:${idx.getWidth} num:${num}"
)
(
vs
(
idx
),
ppns
(
idx
))
}
override
def
cloneType
:
this.
type
=
(
new
PtwEntries
(
num
,
tagLen
)).
asInstanceOf
[
this.
type
]
override
def
toPrintable
:
Printable
=
{
require
(
num
==
4
,
"if num is not 4, please comment this toPrintable"
)
// NOTE: if num is not 4, please comment this toPrintable
p
"tag:${Hexadecimal(tag)} ppn(0):${Hexadecimal(ppns(0))} ppn(1):${Hexadecimal(ppns(1))}"
+
p
"ppn(2):${Hexadecimal(ppns(2))} ppn(3):${Hexadecimal(ppns(3))} vs:${Binary(vs.asUInt)}"
}
}
...
...
@@ -153,7 +223,6 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
val
req
=
RegEnable
(
arb
.
io
.
out
.
bits
,
arb
.
io
.
out
.
fire
())
val
resp
=
VecInit
(
io
.
tlb
.
map
(
_
.
resp
))
val
valid
=
ValidHold
(
arb
.
io
.
out
.
fire
(),
resp
(
arbChosen
).
fire
())
val
validOneCycle
=
OneCycleValid
(
arb
.
io
.
out
.
fire
())
arb
.
io
.
out
.
ready
:=
!
valid
// || resp(arbChosen).fire()
...
...
@@ -166,27 +235,21 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
// two level: l2-tlb-cache && pde/pte-cache
// l2-tlb-cache is ram-larger-edition tlb
// pde/pte-cache is cache of page-table, speeding up ptw
// may seperate valid bits to speed up sfence's flush
// Reg/Mem/SyncReadMem is not sure now
val
tagLen1
=
PAddrBits
-
log2Up
(
XLEN
/
8
)
val
tagLen2
=
PAddrBits
-
log2Up
(
XLEN
/
8
)
-
log2Up
(
PtwL2EntrySize
)
// val tlbl2 = SyncReadMem(TlbL2EntrySize, new TlbEntry)
val
tlbl2
=
Module
(
new
SRAMTemplate
(
new
TlbEntry
,
set
=
TlbL2EntrySize
))
val
tlbv
=
RegInit
(
0.
U
(
TlbL2EntrySize
.
W
))
// valid
val
tlbg
=
RegInit
(
0.
U
(
TlbL2EntrySize
.
W
))
// global
val
ptwl1
=
Reg
(
Vec
(
PtwL1EntrySize
,
new
PtwEntry
(
tagLen
=
tagLen1
)))
val
tlbl2
=
Module
(
new
SRAMTemplate
(
new
TlbEntires
(
num
=
TlbL2LineSize
,
tagLen
=
TlbL2TagLen
),
set
=
TlbL2LineNum
))
// (total 256, one line is 4 => 64 lines)
val
tlbv
=
RegInit
(
0.
U
(
TlbL2LineNum
.
W
))
// valid
val
tlbg
=
Reg
(
UInt
(
TlbL2LineNum
.
W
))
// global
val
ptwl1
=
Reg
(
Vec
(
PtwL1EntrySize
,
new
PtwEntry
(
tagLen
=
PtwL1TagLen
)))
val
l1v
=
RegInit
(
0.
U
(
PtwL1EntrySize
.
W
))
// valid
val
l1g
=
VecInit
((
ptwl1
.
map
(
_
.
perm
.
g
))).
asUInt
// val ptwl2 = SyncReadMem(PtwL2EntrySize, new PtwEntry(tagLen = tagLen2)) // NOTE: the Mem could be only single port(r&w)
val
ptwl2
=
Module
(
new
SRAMTemplate
(
new
PtwEntry
(
tagLen
=
tagLen2
),
set
=
PtwL2EntrySize
))
val
l2v
=
RegInit
(
0.
U
(
PtwL2EntrySize
.
W
))
// valid
val
l2g
=
RegInit
(
0.
U
(
PtwL2EntrySize
.
W
))
// global
val
l1g
=
Reg
(
UInt
(
PtwL1EntrySize
.
W
))
val
ptwl2
=
Module
(
new
SRAMTemplate
(
new
PtwEntries
(
num
=
PtwL2LineSize
,
tagLen
=
PtwL2TagLen
),
set
=
PtwL2LineNum
))
// (total 256, one line is 4 => 64 lines)
val
l2v
=
RegInit
(
0.
U
(
PtwL2LineNum
.
W
))
// valid
val
l2g
=
Reg
(
UInt
(
PtwL2LineNum
.
W
))
// global
// mem alias
// val memRdata = mem.d.bits.data
val
memRdata
=
Wire
(
UInt
(
XLEN
.
W
))
val
memPte
=
memRdata
.
asTypeOf
(
new
PteBundle
)
val
memRdata
=
mem
.
d
.
bits
.
data
val
memSelData
=
Wire
(
UInt
(
XLEN
.
W
))
val
memPte
=
memSelData
.
asTypeOf
(
new
PteBundle
)
val
memPtes
=(
0
until
TlbL2LineSize
).
map
(
i
=>
memRdata
((
i
+
1
)*
XLEN
-
1
,
i
*
XLEN
).
asTypeOf
(
new
PteBundle
))
val
memValid
=
mem
.
d
.
valid
val
memRespReady
=
mem
.
d
.
ready
val
memRespFire
=
mem
.
d
.
fire
()
...
...
@@ -205,26 +268,27 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
* tlbl2
*/
val
(
tlbHit
,
tlbHitData
)
=
{
// tlbl2 is by addr
// TODO: optimize tlbl2'l2 tag len
assert
(
tlbl2
.
io
.
r
.
req
.
ready
)
val
ridx
=
genTlbL2Idx
(
req
.
vpn
)
val
vidx
=
RegEnable
(
tlbv
(
ridx
),
validOneCycle
)
tlbl2
.
io
.
r
.
req
.
valid
:=
validOneCycle
tlbl2
.
io
.
r
.
req
.
bits
.
apply
(
setIdx
=
r
eq
.
vpn
(
log2Up
(
TlbL2EntrySize
-
1
),
0
)
)
tlbl2
.
io
.
r
.
req
.
bits
.
apply
(
setIdx
=
r
idx
)
val
ramData
=
tlbl2
.
io
.
r
.
resp
.
data
(
0
)
// val ramData = tlbl2.r(req.vpn(log2Up(TlbL2EntrySize)-1, 0), validOneCycle)
val
vidx
=
RegEnable
(
tlbv
(
req
.
vpn
(
log2Up
(
TlbL2EntrySize
)-
1
,
0
)),
validOneCycle
)
(
ramData
.
hit
(
req
.
vpn
)
&&
vidx
,
ramData
)
// TODO: optimize tag
// TODO: add exception and refill
XSDebug
(
tlbl2
.
io
.
r
.
req
.
valid
,
p
"tlbl2 Read rIdx:${Hexadecimal(ridx)}\n"
)
XSDebug
(
RegNext
(
tlbl2
.
io
.
r
.
req
.
valid
),
p
"tlbl2 RamData:${ramData}\n"
)
XSDebug
(
RegNext
(
tlbl2
.
io
.
r
.
req
.
valid
),
p
"tlbl2 v:${vidx} hit:${ramData.hit(req.vpn)} tlbPte:${ramData.get(req.vpn)}\n"
)
(
ramData
.
hit
(
req
.
vpn
)
&&
vidx
,
ramData
.
get
(
req
.
vpn
))
}
/*
* ptwl1
*/
val
l1addr
=
MakeAddr
(
satp
.
ppn
,
getVpnn
(
req
.
vpn
,
2
))
val
(
l1Hit
,
l1HitData
)
=
{
// TODO: add excp
// 16 terms may casue long latency, so divide it into 2 stage, like l2tlb
val
(
l1Hit
,
l1HitData
)
=
{
val
hitVecT
=
ptwl1
.
zipWithIndex
.
map
{
case
(
a
,
b
)
=>
a
.
hit
(
l1addr
)
&&
l1v
(
b
)
}
val
hitVec
=
hitVecT
.
map
(
RegEnable
(
_
,
validOneCycle
))
// TODO: could have useless init value
val
hitVec
=
hitVecT
.
map
(
RegEnable
(
_
,
validOneCycle
))
val
hitData
=
ParallelMux
(
hitVec
zip
ptwl1
)
val
hit
=
ParallelOR
(
hitVec
).
asBool
(
hit
,
hitData
)
...
...
@@ -236,17 +300,21 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
val
l1MemBack
=
memRespFire
&&
state
===
state_wait_resp
&&
level
===
0.
U
val
l1Res
=
Mux
(
l1Hit
,
l1HitData
.
ppn
,
RegEnable
(
memPte
.
ppn
,
l1MemBack
))
val
l2addr
=
MakeAddr
(
l1Res
,
getVpnn
(
req
.
vpn
,
1
))
val
(
l2Hit
,
l2HitData
)
=
{
// TODO: add excp
val
readRam
=
(
l1Hit
&&
level
===
0.
U
&&
state
===
state_req
)
||
(
memRespFire
&&
state
===
state_wait_resp
&&
level
===
0.
U
)
val
ridx
=
l2addr
(
log2Up
(
PtwL2EntrySize
)-
1
+
log2Up
(
XLEN
/
8
),
log2Up
(
XLEN
/
8
))
val
(
l2Hit
,
l2HitPPN
)
=
{
val
readRam
=
(!
tlbHit
&&
l1Hit
&&
level
===
0.
U
&&
state
===
state_req
)
||
(
memRespFire
&&
state
===
state_wait_resp
&&
level
===
0.
U
)
val
ridx
=
genPtwL2Idx
(
l2addr
)
val
idx
=
RegEnable
(
l2addr
(
log2Up
(
PtwL2LineSize
)+
log2Up
(
XLEN
/
8
)-
1
,
log2Up
(
XLEN
/
8
)),
readRam
)
val
vidx
=
RegEnable
(
l2v
(
ridx
),
readRam
)
assert
(
ptwl2
.
io
.
r
.
req
.
ready
)
ptwl2
.
io
.
r
.
req
.
valid
:=
readRam
ptwl2
.
io
.
r
.
req
.
bits
.
apply
(
setIdx
=
ridx
)
val
ramData
=
ptwl2
.
io
.
r
.
resp
.
data
(
0
)
// val ramData = ptwl2.read(ridx, readRam)
val
vidx
=
RegEnable
(
l2v
(
ridx
),
readRam
)
(
ramData
.
hit
(
l2addr
)
&&
vidx
,
ramData
)
// TODO: optimize tag
XSDebug
(
ptwl2
.
io
.
r
.
req
.
valid
,
p
"ptwl2 rIdx:${Hexadecimal(ridx)}\n"
)
XSDebug
(
RegNext
(
ptwl2
.
io
.
r
.
req
.
valid
),
p
"ptwl2 RamData:${ramData}\n"
)
XSDebug
(
RegNext
(
ptwl2
.
io
.
r
.
req
.
valid
),
p
"ptwl2 v:${vidx} hit:${ramData.hit(idx, l2addr)}\n"
)
(
ramData
.
hit
(
idx
,
l2addr
)
&&
vidx
,
ramData
.
get
(
idx
).
_2
)
// TODO: optimize tag
}
/* ptwl3
...
...
@@ -255,7 +323,7 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
* if l2-tlb does not hit, ptwl3 would not hit (mostly)
*/
val
l2MemBack
=
memRespFire
&&
state
===
state_wait_resp
&&
level
===
1.
U
val
l2Res
=
Mux
(
l2Hit
,
l2Hit
Data
.
ppn
,
RegEnable
(
memPte
.
ppn
,
l2MemBack
))
val
l2Res
=
Mux
(
l2Hit
,
l2Hit
PPN
,
RegEnable
(
memPte
.
ppn
,
l2MemBack
))
val
l3addr
=
MakeAddr
(
l2Res
,
getVpnn
(
req
.
vpn
,
0
))
/*
...
...
@@ -280,7 +348,7 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
state
:=
state_wait_ready
}
}
.
elsewhen
(
l1Hit
&&
level
===
0.
U
||
l2Hit
&&
level
===
1.
U
)
{
level
:=
levelNext
// TODO: consider superpage
level
:=
levelNext
}
.
elsewhen
(
memReqReady
&&
!
sfenceLatch
)
{
state
:=
state_wait_resp
}
...
...
@@ -288,13 +356,13 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
is
(
state_wait_resp
)
{
when
(
memRespFire
)
{
when
(
memPte
.
isLeaf
()
||
memPte
.
isPf
())
{
when
(
memPte
.
isLeaf
()
||
memPte
.
isPf
(
level
))
{
when
(
resp
(
arbChosen
).
ready
)
{
state
:=
state_idle
}.
otherwise
{
state
:=
state_wait_ready
latch
.
entry
:=
new
TlbEntry
().
genTlbEntry
(
memRdata
,
level
,
req
.
vpn
)
latch
.
pf
:=
memPte
.
isPf
()
latch
.
pf
:=
memPte
.
isPf
(
level
)
}
}.
otherwise
{
level
:=
levelNext
...
...
@@ -331,24 +399,27 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
lgSize
=
log2Up
(
l1BusDataWidth
/
8
).
U
).
_2
mem
.
a
.
bits
:=
pteRead
mem
.
a
.
valid
:=
state
===
state_req
&&
mem
.
a
.
valid
:=
state
===
state_req
&&
((
level
===
0.
U
&&
!
tlbHit
&&
!
l1Hit
)
||
(
level
===
1.
U
&&
!
l2Hit
)
||
(
level
===
2.
U
))
&&
!
sfenceLatch
&&
!
sfence
.
valid
mem
.
d
.
ready
:=
state
===
state_wait_resp
||
sfenceLatch
val
memAddrLatch
=
RegEnable
(
memAddr
,
mem
.
a
.
valid
)
mem
Rdata
:=
(
mem
.
d
.
bits
.
data
>>
(
memAddrLatch
(
log2Up
(
l1BusDataWidth
/
8
)
-
1
,
log2Up
(
XLEN
/
8
))
<<
log2Up
(
XLEN
)))(
XLEN
-
1
,
0
)
mem
SelData
:=
memRdata
.
asTypeOf
(
Vec
(
MemBandWidth
/
XLEN
,
UInt
(
XLEN
.
W
)))(
memAddrLatch
(
log2Up
(
l1BusDataWidth
/
8
)
-
1
,
log2Up
(
XLEN
/
8
))
)
/*
* resp
*/
val
ptwFinish
=
(
state
===
state_req
&&
tlbHit
&&
level
===
0.
U
)
||
((
memPte
.
isLeaf
()
||
memPte
.
isPf
()
||
(!
memPte
.
isLeaf
()
&&
level
===
2.
U
))
&&
memRespFire
&&
!
sfenceLatch
)
||
state
===
state_wait_ready
val
ptwFinish
=
(
state
===
state_req
&&
tlbHit
&&
level
===
0.
U
)
||
((
memPte
.
isLeaf
()
||
memPte
.
isPf
(
level
)
||
(!
memPte
.
isLeaf
()
&&
level
===
2.
U
))
&&
memRespFire
&&
!
sfenceLatch
)
||
state
===
state_wait_ready
for
(
i
<-
0
until
PtwWidth
)
{
resp
(
i
).
valid
:=
valid
&&
arbChosen
===
i
.
U
&&
ptwFinish
// TODO: add resp valid logic
resp
(
i
).
bits
.
entry
:=
Mux
(
tlbHit
,
tlbHitData
,
Mux
(
state
===
state_wait_ready
,
latch
.
entry
,
new
TlbEntry
().
genTlbEntry
(
mem
Rd
ata
,
Mux
(
level
===
3.
U
,
2.
U
,
level
),
req
.
vpn
)))
resp
(
i
).
bits
.
pf
:=
Mux
(
level
===
3.
U
||
notFound
,
true
.
B
,
Mux
(
tlbHit
,
false
.
B
,
Mux
(
state
===
state_wait_ready
,
latch
.
pf
,
memPte
.
isPf
())))
Mux
(
state
===
state_wait_ready
,
latch
.
entry
,
new
TlbEntry
().
genTlbEntry
(
mem
SelD
ata
,
Mux
(
level
===
3.
U
,
2.
U
,
level
),
req
.
vpn
)))
resp
(
i
).
bits
.
pf
:=
Mux
(
level
===
3.
U
||
notFound
,
true
.
B
,
Mux
(
tlbHit
,
false
.
B
,
Mux
(
state
===
state_wait_ready
,
latch
.
pf
,
memPte
.
isPf
(
level
))))
// TODO: the pf must not be correct, check it
}
...
...
@@ -360,32 +431,45 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
ptwl2
.
io
.
w
.
req
.
valid
:=
false
.
B
tlbl2
.
io
.
w
.
req
.
valid
:=
false
.
B
assert
(!
memRespFire
||
(
state
===
state_wait_resp
||
sfenceLatch
))
when
(
memRespFire
&&
!
memPte
.
isPf
()
&&
!
sfenceLatch
)
{
when
(
memRespFire
&&
!
memPte
.
isPf
(
level
)
&&
!
sfenceLatch
)
{
when
(
level
===
0.
U
&&
!
memPte
.
isLeaf
)
{
val
refillIdx
=
LFSR64
()(
log2Up
(
PtwL1EntrySize
)-
1
,
0
)
// TODO: may be LRU
ptwl1
(
refillIdx
).
refill
(
l1addr
,
mem
Rd
ata
)
ptwl1
(
refillIdx
).
refill
(
l1addr
,
mem
SelD
ata
)
l1v
:=
l1v
|
UIntToOH
(
refillIdx
)
l1g
:=
(
l1g
&
~
UIntToOH
(
refillIdx
))
|
Mux
(
memPte
.
perm
.
g
,
UIntToOH
(
refillIdx
),
0.
U
)
}
when
(
level
===
1.
U
&&
!
memPte
.
isLeaf
)
{
val
l2addrStore
=
RegEnable
(
l2addr
,
memReqFire
&&
state
===
state_req
&&
level
===
1.
U
)
val
refillIdx
=
getVpnn
(
req
.
vpn
,
1
)(
log2Up
(
PtwL2EntrySize
)-
1
,
0
)
val
refillIdx
=
genPtwL2Idx
(
l2addrStore
)
//getVpnn(req.vpn, 1)(log2Up(PtwL2EntrySize)-1, 0)
//TODO: check why the old refillIdx is right
assert
(
ptwl2
.
io
.
w
.
req
.
ready
)
// ptwl2.io.w.req.valid := true.B
ptwl2
.
io
.
w
.
apply
(
valid
=
true
.
B
,
setIdx
=
refillIdx
,
data
=
new
PtwEntry
(
tagLen2
).
genPtwEntry
(
l2addrStore
,
memRdata
),
waymask
=
-
1.
S
.
asUInt
)
// ptwl2.write(refillIdx, new PtwEntry(tagLen2).genPtwEntry(l2addrStore, memRdata))
val
ps
=
new
PtwEntries
(
PtwL2LineSize
,
PtwL2TagLen
).
genEntries
(
l2addrStore
,
memRdata
,
level
)
ptwl2
.
io
.
w
.
apply
(
valid
=
true
.
B
,
setIdx
=
refillIdx
,
data
=
ps
,
waymask
=
-
1.
S
.
asUInt
)
l2v
:=
l2v
|
UIntToOH
(
refillIdx
)
l2g
:=
l2g
|
Mux
(
memPte
.
perm
.
g
,
UIntToOH
(
refillIdx
),
0.
U
)
l2g
:=
(
l2g
&
~
UIntToOH
(
refillIdx
))
|
Mux
(
Cat
(
memPtes
.
map
(
_
.
perm
.
g
)).
andR
,
UIntToOH
(
refillIdx
),
0.
U
)
XSDebug
(
p
"ptwl2 RefillIdx:${Hexadecimal(refillIdx)} ps:${ps}\n"
)
}
when
(
memPte
.
isLeaf
())
{
val
refillIdx
=
getVpnn
(
req
.
vpn
,
0
)(
log2Up
(
TlbL2EntrySize
)-
1
,
0
)
val
refillIdx
=
genTlbL2Idx
(
req
.
vpn
)
//getVpnn(req.vpn, 0)(log2Up(TlbL2EntrySize)-1, 0)
//TODO: check why the old refillIdx is right
assert
(
tlbl2
.
io
.
w
.
req
.
ready
)
// tlbl2.io.w.req.valid := true.B
tlbl2
.
io
.
w
.
apply
(
valid
=
true
.
B
,
setIdx
=
refillIdx
,
data
=
new
TlbEntry
().
genTlbEntry
(
memRdata
,
level
,
req
.
vpn
),
waymask
=
-
1.
S
.
asUInt
)
// tlbl2.write(refillIdx, new TlbEntry().genTlbEntry(memRdata, level, req.vpn))
val
ts
=
new
TlbEntires
(
num
=
TlbL2LineSize
,
tagLen
=
TlbL2TagLen
).
genEntries
(
memRdata
,
level
,
req
.
vpn
)
tlbl2
.
io
.
w
.
apply
(
valid
=
true
.
B
,
setIdx
=
refillIdx
,
data
=
ts
,
waymask
=
-
1.
S
.
asUInt
)
tlbv
:=
tlbv
|
UIntToOH
(
refillIdx
)
tlbg
:=
tlbg
|
Mux
(
memPte
.
perm
.
g
,
UIntToOH
(
refillIdx
),
0.
U
)
tlbg
:=
(
tlbg
&
~
UIntToOH
(
refillIdx
))
|
Mux
(
Cat
(
memPtes
.
map
(
_
.
perm
.
g
)).
andR
,
UIntToOH
(
refillIdx
),
0.
U
)
XSDebug
(
p
"tlbl2 refillIdx:${Hexadecimal(refillIdx)} ts:${ts}\n"
)
}
}
...
...
@@ -447,18 +531,25 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
XSDebug
(
false
,
validOneCycle
,
p
"(v:${validOneCycle} r:${arb.io.out.ready}) vpn:0x${Hexadecimal(req.vpn)}\n"
)
XSDebug
(
resp
(
arbChosen
).
fire
(),
"**Ptw Resp to "
)
PrintFlag
(
resp
(
arbChosen
).
fire
(),
arbChosen
===
0.
U
,
"DTLB**:\n"
,
"ITLB**\n"
)
XSDebug
(
resp
(
arbChosen
).
fire
(),
p
"(v:${resp(arbChosen).valid} r:${resp(arbChosen).ready}) entry:${resp(arbChosen).bits.entry} pf:${resp(arbChosen).bits.pf}\n"
)
XSDebug
(
resp
(
arbChosen
).
fire
(),
p
"(v:${resp(arbChosen).valid} r:${resp(arbChosen).ready})"
+
p
" entry:${resp(arbChosen).bits.entry} pf:${resp(arbChosen).bits.pf}\n"
)
XSDebug
(
sfence
.
valid
,
p
"Sfence: sfence instr here ${sfence.bits}\n"
)
XSDebug
(
valid
,
p
"CSR: ${csr}\n"
)
XSDebug
(
valid
,
p
"vpn2:0x${Hexadecimal(getVpnn(req.vpn, 2))} vpn1:0x${Hexadecimal(getVpnn(req.vpn, 1))} vpn0:0x${Hexadecimal(getVpnn(req.vpn, 0))}\n"
)
XSDebug
(
valid
,
p
"state:${state} level:${level} tlbHit:${tlbHit} l1addr:0x${Hexadecimal(l1addr)} l1Hit:${l1Hit} l2addr:0x${Hexadecimal(l2addr)} l2Hit:${l2Hit} l3addr:0x${Hexadecimal(l3addr)} memReq(v:${mem.a.valid} r:${mem.a.ready})\n"
)
XSDebug
(
valid
,
p
"vpn2:0x${Hexadecimal(getVpnn(req.vpn, 2))} vpn1:0x${Hexadecimal(getVpnn(req.vpn, 1))}"
+
p
" vpn0:0x${Hexadecimal(getVpnn(req.vpn, 0))}\n"
)
XSDebug
(
valid
,
p
"state:${state} level:${level} tlbHit:${tlbHit} l1addr:0x${Hexadecimal(l1addr)} l1Hit:${l1Hit}"
+
p
" l2addr:0x${Hexadecimal(l2addr)} l2Hit:${l2Hit} l3addr:0x${Hexadecimal(l3addr)} memReq(v:${mem.a.valid} r:${mem.a.ready})\n"
)
XSDebug
(
memReqFire
,
p
"mem req fire addr:0x${Hexadecimal(memAddr)}\n"
)
XSDebug
(
memRespFire
,
p
"mem resp fire rdata:0x${Hexadecimal(mem.d.bits.data)} Pte:${memPte}\n"
)
XSDebug
(
memRespFire
,
p
"mem resp fire: \n"
)
for
(
i
<-
0
until
(
MemBandWidth
/
XLEN
))
{
XSDebug
(
memRespFire
,
p
" ${i.U}: ${memPtes(i)} isPf:${memPtes(i).isPf(level)} isLeaf:${memPtes(i).isLeaf}\n"
)
}
XSDebug
(
sfenceLatch
,
p
"ptw has a flushed req waiting for resp... state:${state} mem.a(${mem.a.valid} ${mem.a.ready}) d($memValid} ${memRespReady})\n"
)
XSDebug
(
sfenceLatch
,
p
"ptw has a flushed req waiting for resp... "
+
p
"state:${state} mem.a(${mem.a.valid} ${mem.a.ready}) d($memValid} ${memRespReady})\n"
)
// TODO: add ptw perf cnt
}
src/test/csrc/ram.cpp
浏览文件 @
ed91f056
...
...
@@ -4,7 +4,7 @@
#include "common.h"
#include "ram.h"
#define RAMSIZE (
256
* 1024 * 1024UL)
#define RAMSIZE (
64 * 1024
* 1024 * 1024UL)
#ifdef WITH_DRAMSIM3
#include "cosimulation.h"
...
...
@@ -24,12 +24,12 @@ void addpageSv39() {
//addr range: 0x0000000080000000 - 0x0000000088000000 for 128MB from 2GB - 2GB128MB
//the first layer: one entry for 1GB. (512GB in total by 512 entries). need the 2th entries
//the second layer: one entry for 2MB. (1GB in total by 512 entries). need the 0th-63rd entries
//the third layer: one entry for 4KB (2MB in total by 512 entries). need 64 with each one all
//the third layer: one entry for 4KB (2MB in total by 512 entries). need 64 with each one all
#define TOPSIZE (128 * 1024 * 1024)
#define PAGESIZE (4 * 1024) // 4KB = 2^12B
#define ENTRYNUM (PAGESIZE / 8) //512 2^9
#define PTEVOLUME (PAGESIZE * ENTRYNUM) // 2MB
#define PTENUM (
RAM
SIZE / PTEVOLUME) // 128MB / 2MB = 64
#define PTENUM (
TOP
SIZE / PTEVOLUME) // 128MB / 2MB = 64
#define PDDENUM 1
#define PDENUM 1
#define PDDEADDR (0x88000000 - (PAGESIZE * (PTENUM + 2))) //0x88000000 - 0x1000*66
...
...
@@ -43,7 +43,7 @@ void addpageSv39() {
uint64_t
pdde
[
ENTRYNUM
];
uint64_t
pde
[
ENTRYNUM
];
uint64_t
pte
[
PTENUM
][
ENTRYNUM
];
// special addr for mmio 0x40000000 - 0x4fffffff
uint64_t
pdemmio
[
ENTRYNUM
];
uint64_t
ptemmio
[
PTEMMIONUM
][
ENTRYNUM
];
...
...
@@ -71,13 +71,13 @@ void addpageSv39() {
for
(
int
i
=
0
;
i
<
PTEMMIONUM
;
i
++
)
{
pdemmio
[
i
]
=
(((
PDDEADDR
-
PAGESIZE
*
(
PTEMMIONUM
+
PDEMMIONUM
-
i
))
&
0xfffff000
)
>>
2
)
|
0x1
;
}
for
(
int
outidx
=
0
;
outidx
<
PTEMMIONUM
;
outidx
++
)
{
for
(
int
inidx
=
0
;
inidx
<
ENTRYNUM
;
inidx
++
)
{
ptemmio
[
outidx
][
inidx
]
=
(((
0x40000000
+
outidx
*
PTEVOLUME
+
inidx
*
PAGESIZE
)
&
0xfffff000
)
>>
2
)
|
0xf
;
}
}
//0x800000000 - 0x87ffffff
pdde
[
2
]
=
((
PDEADDR
&
0xfffff000
)
>>
2
)
|
0x1
;
//pdde[2] = ((0x80000000&0xc0000000) >> 2) | 0xf;
...
...
@@ -93,13 +93,13 @@ void addpageSv39() {
}
}
memcpy
((
char
*
)
ram
+
(
RAM
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
+
PTEMMIONUM
+
PDEDEVNUM
+
PTEDEVNUM
)),
ptedev
,
PAGESIZE
*
PTEDEVNUM
);
memcpy
((
char
*
)
ram
+
(
RAM
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
+
PTEMMIONUM
+
PDEDEVNUM
)),
pdedev
,
PAGESIZE
*
PDEDEVNUM
);
memcpy
((
char
*
)
ram
+
(
RAM
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
+
PTEMMIONUM
)),
ptemmio
,
PAGESIZE
*
PTEMMIONUM
);
memcpy
((
char
*
)
ram
+
(
RAM
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
)),
pdemmio
,
PAGESIZE
*
PDEMMIONUM
);
memcpy
((
char
*
)
ram
+
(
RAM
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
)),
pdde
,
PAGESIZE
*
PDDENUM
);
memcpy
((
char
*
)
ram
+
(
RAM
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDENUM
)),
pde
,
PAGESIZE
*
PDENUM
);
memcpy
((
char
*
)
ram
+
(
RAM
SIZE
-
PAGESIZE
*
PTENUM
),
pte
,
PAGESIZE
*
PTENUM
);
memcpy
((
char
*
)
ram
+
(
TOP
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
+
PTEMMIONUM
+
PDEDEVNUM
+
PTEDEVNUM
)),
ptedev
,
PAGESIZE
*
PTEDEVNUM
);
memcpy
((
char
*
)
ram
+
(
TOP
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
+
PTEMMIONUM
+
PDEDEVNUM
)),
pdedev
,
PAGESIZE
*
PDEDEVNUM
);
memcpy
((
char
*
)
ram
+
(
TOP
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
+
PTEMMIONUM
)),
ptemmio
,
PAGESIZE
*
PTEMMIONUM
);
memcpy
((
char
*
)
ram
+
(
TOP
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
+
PDEMMIONUM
)),
pdemmio
,
PAGESIZE
*
PDEMMIONUM
);
memcpy
((
char
*
)
ram
+
(
TOP
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDDENUM
+
PDENUM
)),
pdde
,
PAGESIZE
*
PDDENUM
);
memcpy
((
char
*
)
ram
+
(
TOP
SIZE
-
PAGESIZE
*
(
PTENUM
+
PDENUM
)),
pde
,
PAGESIZE
*
PDENUM
);
memcpy
((
char
*
)
ram
+
(
TOP
SIZE
-
PAGESIZE
*
PTENUM
),
pte
,
PAGESIZE
*
PTENUM
);
}
#endif
...
...
@@ -187,7 +187,7 @@ void init_ram(const char *img) {
ret
=
fread
(
ram
,
img_size
,
1
,
fp
);
assert
(
ret
==
1
);
fclose
(
fp
);
fclose
(
fp
);
}
#ifdef TLB_UNITTEST
...
...
src/test/scala/cache/L2CacheTest.scala
浏览文件 @
ed91f056
...
...
@@ -4,8 +4,7 @@ import chipsalliance.rocketchip.config.{Field, Parameters}
import
chisel3._
import
chisel3.util._
import
chiseltest.experimental.TestOptionBuilder._
import
chiseltest.internal.VerilatorBackendAnnotation
import
chiseltest.internal.LineCoverageAnnotation
import
chiseltest.internal.
{
VerilatorBackendAnnotation
,
LineCoverageAnnotation
,
ToggleCoverageAnnotation
,
UserCoverageAnnotation
,
StructuralCoverageAnnotation
}
import
chiseltest._
import
chisel3.experimental.BundleLiterals._
import
firrtl.stage.RunFirrtlTransformAnnotation
...
...
@@ -58,7 +57,7 @@ case object L3CacheTestKey extends Field[L3CacheTestParams]
class
L2TestTopIO
extends
Bundle
{
val
in
=
Flipped
(
DecoupledIO
(
new
Bundle
()
{
val
wdata
=
Input
(
UInt
(
64.
W
))
val
waddr
=
Input
(
UInt
(
2
0.
W
))
val
waddr
=
Input
(
UInt
(
4
0.
W
))
val
hartId
=
Input
(
UInt
(
1.
W
))
}))
val
out
=
DecoupledIO
(
new
Bundle
()
{
...
...
@@ -260,6 +259,9 @@ class L2CacheTest extends AnyFlatSpec with ChiselScalatestTester with Matchers{
val
annos
=
Seq
(
VerilatorBackendAnnotation
,
LineCoverageAnnotation
,
ToggleCoverageAnnotation
,
UserCoverageAnnotation
,
StructuralCoverageAnnotation
,
RunFirrtlTransformAnnotation
(
new
PrintModuleName
)
)
...
...
@@ -281,7 +283,9 @@ class L2CacheTest extends AnyFlatSpec with ChiselScalatestTester with Matchers{
c
.
clock
.
step
(
100
)
for
(
i
<-
0
until
100000
){
val
addr
=
Random
.
nextInt
(
0xfffff
)
&
0xffe00
// align to block size
// DRAM AddressSet is above 0x80000000L
// also, note that, + has higher priority than & !!!
val
addr
=
(
Random
.
nextInt
(
0x7fffffff
).
toLong
&
0xfffffe00
L
)
+
0x80000000
L
// align to block size
val
data
=
Random
.
nextLong
()
&
0x7fffffffffffffff
L
c
.
io
.
in
.
enqueue
(
chiselTypeOf
(
c
.
io
.
in
.
bits
).
Lit
(
_
.
waddr
->
addr
.
U
,
...
...
src/test/scala/top/XSSim.scala
浏览文件 @
ed91f056
...
...
@@ -85,7 +85,7 @@ class XSSimSoC(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
else
LazyModule
(
new
AXI4RAM
(
dramRange
,
memByte
=
128
*
1024
*
1024
,
memByte
=
64L
*
1024
*
1024
*
1024
,
useBlackBox
=
true
,
beatBytes
=
L3BusWidth
/
8
)).
node
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录