Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
3c16548d
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 搜索 >>
提交
3c16548d
编写于
12月 07, 2021
作者:
L
Lingrui98
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
tage, ittage: use single port srams with bank-interleaving technology to reduce write conflict
上级
82dc6ff8
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
163 addition
and
120 deletion
+163
-120
src/main/scala/utils/DataModuleTemplate.scala
src/main/scala/utils/DataModuleTemplate.scala
+6
-1
src/main/scala/utils/SRAMTemplate.scala
src/main/scala/utils/SRAMTemplate.scala
+2
-2
src/main/scala/xiangshan/frontend/ITTAGE.scala
src/main/scala/xiangshan/frontend/ITTAGE.scala
+69
-50
src/main/scala/xiangshan/frontend/Tage.scala
src/main/scala/xiangshan/frontend/Tage.scala
+86
-67
未找到文件。
src/main/scala/utils/DataModuleTemplate.scala
浏览文件 @
3c16548d
...
...
@@ -86,13 +86,15 @@ class DataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWr
class
SyncDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
DataModuleTemplate
(
gen
,
numEntries
,
numRead
,
numWrite
,
true
)
class
AsyncDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
DataModuleTemplate
(
gen
,
numEntries
,
numRead
,
numWrite
,
false
)
class
Folded1WDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
isSync
:
Boolean
,
width
:
Int
)
extends
Module
{
class
Folded1WDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
isSync
:
Boolean
,
width
:
Int
,
hasResetEn
:
Boolean
=
true
)
extends
Module
{
val
io
=
IO
(
new
Bundle
{
val
raddr
=
Vec
(
numRead
,
Input
(
UInt
(
log2Up
(
numEntries
).
W
)))
val
rdata
=
Vec
(
numRead
,
Output
(
gen
))
val
wen
=
Input
(
Bool
())
val
waddr
=
Input
(
UInt
(
log2Up
(
numEntries
).
W
))
val
wdata
=
Input
(
gen
)
val
resetEn
=
if
(
hasResetEn
)
Some
(
Input
(
Bool
()))
else
None
})
require
(
width
>
0
&&
isPow2
(
width
))
...
...
@@ -103,6 +105,9 @@ class Folded1WDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: In
val
data
=
Mem
(
nRows
,
Vec
(
width
,
gen
))
val
doing_reset
=
RegInit
(
true
.
B
)
if
(
hasResetEn
)
{
io
.
resetEn
.
map
(
en
=>
when
(
en
)
{
doing_reset
:=
true
.
B
})
}
val
resetRow
=
RegInit
(
0.
U
(
log2Ceil
(
nRows
).
W
))
resetRow
:=
resetRow
+
doing_reset
when
(
resetRow
===
(
nRows
-
1
).
U
)
{
doing_reset
:=
false
.
B
}
...
...
src/main/scala/utils/SRAMTemplate.scala
浏览文件 @
3c16548d
...
...
@@ -168,7 +168,7 @@ class FoldedSRAMTemplate[T <: Data](gen: T, set: Int, width: Int = 4,
io
.
w
.
req
.
ready
:=
array
.
io
.
w
.
req
.
ready
val
raddr
=
io
.
r
.
req
.
bits
.
setIdx
>>
log2Ceil
(
width
)
val
ridx
=
RegNext
(
i
o
.
r
.
req
.
bits
.
setIdx
(
log2Ceil
(
width
)-
1
,
0
))
val
ridx
=
RegNext
(
i
f
(
width
!=
1
)
io
.
r
.
req
.
bits
.
setIdx
(
log2Ceil
(
width
)-
1
,
0
)
else
0.
U
(
1.
W
))
val
ren
=
io
.
r
.
req
.
valid
array
.
io
.
r
.
req
.
valid
:=
ren
...
...
@@ -178,7 +178,7 @@ class FoldedSRAMTemplate[T <: Data](gen: T, set: Int, width: Int = 4,
val
wen
=
io
.
w
.
req
.
valid
val
wdata
=
VecInit
(
Seq
.
fill
(
width
)(
io
.
w
.
req
.
bits
.
data
(
0
)))
val
waddr
=
io
.
w
.
req
.
bits
.
setIdx
>>
log2Ceil
(
width
)
val
wmask
=
UIntToOH
(
i
o
.
w
.
req
.
bits
.
setIdx
(
log2Ceil
(
width
)-
1
,
0
))
val
wmask
=
UIntToOH
(
i
f
(
width
!=
1
)
io
.
w
.
req
.
bits
.
setIdx
(
log2Ceil
(
width
)-
1
,
0
)
else
1.
U
(
1.
W
))
array
.
io
.
w
.
apply
(
wen
,
wdata
,
waddr
,
wmask
)
}
...
...
src/main/scala/xiangshan/frontend/ITTAGE.scala
浏览文件 @
3c16548d
...
...
@@ -36,7 +36,7 @@ trait ITTageParams extends HasXSParameter with HasBPUParameter {
val
ITTageNTables
=
ITTageTableInfos
.
size
// Number of tage tables
val
UBitPeriod
=
2048
val
ITTageCtrBits
=
2
val
uFoldedWidth
=
8
val
uFoldedWidth
=
16
val
TickWidth
=
8
def
ctr_null
(
ctr
:
UInt
,
ctrBits
:
Int
=
ITTageCtrBits
)
=
{
ctr
===
0.
U
...
...
@@ -149,11 +149,23 @@ class ITTageTable
)(
implicit
p
:
Parameters
)
extends
ITTageModule
with
HasFoldedHistory
{
val
io
=
IO
(
new
Bundle
()
{
val
req
=
Input
(
Valid
(
new
ITTageReq
))
val
req
=
Flipped
(
DecoupledIO
(
new
ITTageReq
))
val
resp
=
Output
(
Valid
(
new
ITTageResp
))
val
update
=
Input
(
new
ITTageUpdate
)
})
val
SRAM_SIZE
=
128
val
nBanks
=
2
val
bankSize
=
nRows
/
nBanks
val
bankFoldWidth
=
if
(
bankSize
>=
SRAM_SIZE
)
bankSize
/
SRAM_SIZE
else
1
if
(
bankSize
<
SRAM_SIZE
)
{
println
(
f
"warning: ittage table $tableIdx has small sram depth of $bankSize"
)
}
val
bankIdxWidth
=
log2Ceil
(
nBanks
)
def
get_bank_mask
(
idx
:
UInt
)
=
VecInit
((
0
until
nBanks
).
map
(
idx
(
bankIdxWidth
-
1
,
0
)
===
_
.
U
))
def
get_bank_idx
(
idx
:
UInt
)
=
idx
>>
bankIdxWidth
// override val debug = true
// bypass entries for tage update
val
wrBypassEntries
=
4
...
...
@@ -186,12 +198,14 @@ class ITTageTable
def
inc_ctr
(
ctr
:
UInt
,
taken
:
Bool
)
:
UInt
=
satUpdate
(
ctr
,
ITTageCtrBits
,
taken
)
class
ITTageEntry
()
extends
ITTageBundle
{
val
valid
=
Bool
()
//
val valid = Bool()
val
tag
=
UInt
(
tagLen
.
W
)
val
ctr
=
UInt
(
ITTageCtrBits
.
W
)
val
target
=
UInt
(
VAddrBits
.
W
)
}
val
validArray
=
RegInit
(
0.
U
(
nRows
.
W
))
// Why need add instOffsetBits?
val
ittageEntrySz
=
1
+
tagLen
+
ITTageCtrBits
+
VAddrBits
...
...
@@ -204,60 +218,58 @@ class ITTageTable
// val (s0_idx, s0_tag) = compute_tag_and_hash(s0_unhashed_idx, io.req.bits.hist, io.req.bits.phist)
val
(
s0_idx
,
s0_tag
)
=
compute_tag_and_hash
(
s0_unhashed_idx
,
io
.
req
.
bits
.
folded_hist
)
val
(
s1_idx
,
s1_tag
)
=
(
RegEnable
(
s0_idx
,
io
.
req
.
valid
),
RegEnable
(
s0_tag
,
io
.
req
.
valid
))
val
us
=
Module
(
new
SyncDataModuleTemplate
(
Bool
(),
nRows
,
1
,
1
))
val
table
=
Module
(
new
SRAMTemplate
(
new
ITTageEntry
,
set
=
nRows
,
way
=
1
,
shouldReset
=
true
,
holdRead
=
true
,
singlePort
=
false
))
table
.
io
.
r
.
req
.
valid
:=
io
.
req
.
valid
table
.
io
.
r
.
req
.
bits
.
setIdx
:=
s0_idx
val
(
s1_idx
,
s1_tag
)
=
(
RegEnable
(
s0_idx
,
io
.
req
.
fire
),
RegEnable
(
s0_tag
,
io
.
req
.
fire
))
val
s0_bank_req_1h
=
get_bank_mask
(
s0_idx
)
val
s1_bank_req_1h
=
RegEnable
(
s0_bank_req_1h
,
io
.
req
.
fire
)
val
us
=
Module
(
new
Folded1WDataModuleTemplate
(
Bool
(),
nRows
,
1
,
isSync
=
true
,
width
=
uFoldedWidth
))
// val table = Module(new SRAMTemplate(new ITTageEntry, set=nRows, way=1, shouldReset=true, holdRead=true, singlePort=false))
val
table_banks
=
Seq
.
fill
(
nBanks
)(
Module
(
new
FoldedSRAMTemplate
(
new
ITTageEntry
,
set
=
nRows
/
nBanks
,
width
=
bankFoldWidth
,
shouldReset
=
false
,
holdRead
=
true
,
singlePort
=
true
)))
for
(
b
<-
0
until
nBanks
)
{
table_banks
(
b
).
io
.
r
.
req
.
valid
:=
io
.
req
.
fire
&&
s0_bank_req_1h
(
b
)
table_banks
(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
get_bank_idx
(
s0_idx
)
}
us
.
io
.
raddr
(
0
)
:=
s0_idx
val
s1_table_r
=
table
.
io
.
r
.
resp
.
data
(
0
)
val
table_banks_r
=
table_banks
.
map
(
_
.
io
.
r
.
resp
.
data
(
0
)
)
val
s1_req_rhit
=
s1_table_r
.
valid
&&
s1_table_r
.
tag
===
s1_tag
val
resp_selected
=
Mux1H
(
s1_bank_req_1h
,
table_banks_r
)
val
s1_req_rhit
=
validArray
(
s1_idx
)
&&
resp_selected
.
tag
===
s1_tag
io
.
resp
.
valid
:=
(
if
(
tagLen
!=
0
)
s1_req_rhit
else
true
.
B
)
// && s1_mask(b)
io
.
resp
.
bits
.
ctr
:=
s1_table_r
.
ctr
io
.
resp
.
bits
.
ctr
:=
resp_selected
.
ctr
io
.
resp
.
bits
.
u
:=
us
.
io
.
rdata
(
0
)
io
.
resp
.
bits
.
target
:=
s1_table_r
.
target
// TODO: reset all us at once?
val
doing_reset_u
=
RegInit
(
true
.
B
)
val
resetRow
=
RegInit
(
0.
U
(
log2Ceil
(
nRows
).
W
))
resetRow
:=
resetRow
+
doing_reset_u
when
(
io
.
update
.
reset_u
)
{
doing_reset_u
:=
true
.
B
}.
elsewhen
(
resetRow
===
(
nRows
-
1
).
U
)
{
doing_reset_u
:=
false
.
B
}
io
.
resp
.
bits
.
target
:=
resp_selected
.
target
// Use fetchpc to compute hash
// val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist)
val
(
update_idx
,
update_tag
)
=
compute_tag_and_hash
(
getUnhashedIdx
(
io
.
update
.
pc
),
io
.
update
.
folded_hist
)
val
update_req_bank_1h
=
get_bank_mask
(
update_idx
)
val
update_idx_in_bank
=
get_bank_idx
(
update_idx
)
val
update_target
=
io
.
update
.
target
val
update_wdata
=
Wire
(
new
ITTageEntry
)
for
(
b
<-
0
until
nBanks
)
{
table_banks
(
b
).
io
.
w
.
apply
(
valid
=
io
.
update
.
valid
&&
update_req_bank_1h
(
b
),
data
=
update_wdata
,
setIdx
=
update_idx_in_bank
,
waymask
=
true
.
B
)
}
table
.
io
.
w
.
apply
(
valid
=
io
.
update
.
valid
,
data
=
update_wdata
,
setIdx
=
update_idx
,
waymask
=
io
.
update
.
valid
)
val
update_u
=
io
.
update
.
u
val
u_wen
=
io
.
update
.
uValid
||
doing_reset_u
val
u_waddr
=
Mux
(
doing_reset_u
,
resetRow
,
update_idx
)
val
u_wdata
=
Mux
(
doing_reset_u
,
false
.
B
,
update_u
)
val
bank_conflict
=
(
0
until
nBanks
).
map
(
b
=>
table_banks
(
b
).
io
.
w
.
req
.
valid
&&
s0_bank_req_1h
(
b
)).
reduce
(
_
||
_
)
io
.
req
.
ready
:=
!
bank_conflict
XSPerfAccumulate
(
f
"ittage_table_bank_conflict"
,
bank_conflict
)
us
.
io
.
wen
(
0
)
:=
u_wen
us
.
io
.
waddr
(
0
)
:=
u_waddr
us
.
io
.
wdata
(
0
)
:=
u_wdata
us
.
io
.
wen
:=
io
.
update
.
uValid
us
.
io
.
waddr
:=
update_idx
us
.
io
.
wdata
:=
io
.
update
.
u
val
wrbypass
=
Module
(
new
WrBypass
(
UInt
(
ITTageCtrBits
.
W
),
wrBypassEntries
,
log2Ceil
(
nRows
),
tagWidth
=
tagLen
))
...
...
@@ -268,21 +280,30 @@ class ITTageTable
val
old_ctr
=
Mux
(
wrbypass
.
io
.
hit
,
wrbypass
.
io
.
hit_data
(
0
).
bits
,
io
.
update
.
oldCtr
)
update_wdata
.
ctr
:=
Mux
(
io
.
update
.
alloc
,
2.
U
,
inc_ctr
(
old_ctr
,
io
.
update
.
correct
))
update_wdata
.
valid
:=
true
.
B
update_wdata
.
tag
:=
update_tag
// only when ctr is null
update_wdata
.
target
:=
Mux
(
ctr_null
(
old_ctr
),
update_target
,
io
.
update
.
old_target
)
val
newValidArray
=
VecInit
(
validArray
.
asBools
)
when
(
io
.
update
.
valid
)
{
newValidArray
(
update_idx
)
:=
true
.
B
validArray
:=
newValidArray
.
asUInt
}
// reset all us in 32 cycles
us
.
io
.
resetEn
.
map
(
_
:=
io
.
update
.
reset_u
)
XSPerfAccumulate
(
"ittage_table_updates"
,
io
.
update
.
valid
)
XSPerfAccumulate
(
"ittage_table_hits"
,
io
.
resp
.
valid
)
if
(
BPUDebug
&&
debug
)
{
val
u
=
io
.
update
val
idx
=
s0_idx
val
tag
=
s0_tag
XSDebug
(
io
.
req
.
valid
,
XSDebug
(
io
.
req
.
fire
,
p
"ITTageTableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, "
+
p
"idx=$idx, tag=$tag\n"
)
XSDebug
(
RegNext
(
io
.
req
.
valid
)
&&
s1_req_rhit
,
XSDebug
(
RegNext
(
io
.
req
.
fire
)
&&
s1_req_rhit
,
p
"ITTageTableResp: idx=$s1_idx, hit:${s1_req_rhit}, "
+
p
"ctr:${io.resp.bits.ctr}, u:${io.resp.bits.u}, tar:${Hexadecimal(io.resp.bits.target)}\n"
)
XSDebug
(
io
.
update
.
valid
,
...
...
@@ -293,7 +314,7 @@ class ITTageTable
p
"update ITTAGE Table: writing tag:${update_tag}, "
+
p
"ctr: ${update_wdata.ctr}, target:${Hexadecimal(update_wdata.target)}"
+
p
" in idx $update_idx\n"
)
XSDebug
(
RegNext
(
io
.
req
.
valid
)
&&
!
s1_req_rhit
,
"TageTableResp: no hits!\n"
)
XSDebug
(
RegNext
(
io
.
req
.
fire
)
&&
!
s1_req_rhit
,
"TageTableResp: no hits!\n"
)
// ------------------------------Debug-------------------------------------
...
...
@@ -342,11 +363,6 @@ class ITTage(implicit p: Parameters) extends BaseITTage {
case
((
nRows
,
histLen
,
tagLen
),
i
)
=>
// val t = if(EnableBPD) Module(new TageTable(nRows, histLen, tagLen, UBitPeriod)) else Module(new FakeTageTable)
val
t
=
Module
(
new
ITTageTable
(
nRows
,
histLen
,
tagLen
,
UBitPeriod
,
i
))
// t.io.req.valid := io.pc.valid
// t.io.req.bits.pc := io.pc.bits
// t.io.req.bits.hist := io.hist
// t.io.req.bits.mask := io.inMask
t
.
io
.
req
.
valid
:=
io
.
s0_fire
t
.
io
.
req
.
bits
.
pc
:=
s0_pc
t
.
io
.
req
.
bits
.
folded_hist
:=
io
.
in
.
bits
.
folded_hist
...
...
@@ -620,6 +636,9 @@ class ITTage(implicit p: Parameters) extends BaseITTage {
tables
(
i
).
io
.
update
.
folded_hist
:=
RegNext
(
updateFhist
)
}
// all should be ready for req
io
.
s1_ready
:=
tables
.
map
(
_
.
io
.
req
.
ready
).
reduce
(
_
&&
_
)
XSPerfAccumulate
(
f
"ittage_write_blocks_read"
,
!
io
.
s1_ready
)
// Debug and perf info
def
pred_perf
(
name
:
String
,
cond
:
Bool
)
=
XSPerfAccumulate
(
s
"${name}_at_pred"
,
cond
&&
io
.
s2_fire
)
...
...
src/main/scala/xiangshan/frontend/Tage.scala
浏览文件 @
3c16548d
...
...
@@ -36,9 +36,11 @@ trait TageParams extends HasBPUConst with HasXSParameter {
val
BankTageNTables
=
BankTageTableInfos
.
map
(
_
.
size
)
// Number of tage tables
val
UBitPeriod
=
256
val
TageCtrBits
=
3
val
uFoldedWidth
=
8
val
uFoldedWidth
=
32
val
TickWidth
=
8
val
TotalBits
=
BankTageTableInfos
.
map
{
info
=>
info
.
map
{
case
(
s
,
h
,
t
)
=>
{
...
...
@@ -46,6 +48,7 @@ trait TageParams extends HasBPUConst with HasXSParameter {
}
}.
reduce
(
_
+
_
)
}.
reduce
(
_
+
_
)
}
trait
HasFoldedHistory
{
...
...
@@ -214,37 +217,29 @@ class TageTable
)(
implicit
p
:
Parameters
)
extends
TageModule
with
HasFoldedHistory
{
val
io
=
IO
(
new
Bundle
()
{
val
req
=
Input
(
Valid
(
new
TageReq
))
val
req
=
Flipped
(
DecoupledIO
(
new
TageReq
))
val
resp
=
Output
(
Valid
(
new
TageResp
))
val
update
=
Input
(
new
TageUpdate
)
})
val
SRAM_SIZE
=
128
// physical size
require
(
nRows
%
SRAM_SIZE
==
0
)
val
nBanks
=
4
val
bankSize
=
nRows
/
nBanks
val
bankFoldWidth
=
if
(
bankSize
>=
SRAM_SIZE
)
bankSize
/
SRAM_SIZE
else
1
if
(
bankSize
<
SRAM_SIZE
)
{
println
(
f
"warning: tage table $tableIdx has small sram depth of $bankSize"
)
}
val
bankIdxWidth
=
log2Ceil
(
nBanks
)
def
get_bank_mask
(
idx
:
UInt
)
=
VecInit
((
0
until
nBanks
).
map
(
idx
(
bankIdxWidth
-
1
,
0
)
===
_
.
U
))
def
get_bank_idx
(
idx
:
UInt
)
=
idx
>>
bankIdxWidth
// bypass entries for tage update
val
wrBypassEntries
=
8
val
phistLen
=
if
(
PathHistoryLength
>
histLen
)
histLen
else
PathHistoryLength
// def compute_tag_and_hash(unhashed_idx: UInt, hist: UInt, phist: UInt) = {
// def F(phist: UInt, len: Int) = {
// val lenMask = Fill(len, 1.U(1.W))
// val rowMask = Fill(log2Ceil(nRows), 1.U(1.W))
// val masked = phist & lenMask
// val a1 = masked & rowMask
// val a2 = masked >> log2Ceil(nRows)
// val a3 = ((a2 << tableIdx) & rowMask) + (a2 >> (log2Ceil(nRows) - tableIdx))
// val a4 = a1 ^ a3
// val res = ((a3 << tableIdx) & rowMask) + (a3 >> (log2Ceil(nRows) - tableIdx))
// res
// }
// val idx_history = compute_folded_ghist(hist, log2Ceil(nRows))
// val idx_phist = F(phist, (if (PathHistoryLength > histLen) histLen else PathHistoryLength))
// // val idx = (unhashed_idx ^ (unhashed_idx >> (log2Ceil(nRows)-tableIdx+1)) ^ idx_history ^ idx_phist)(log2Ceil(nRows) - 1, 0)
// val idx = (unhashed_idx ^ idx_history)(log2Ceil(nRows) - 1, 0)
// val tag_history = compute_folded_ghist(hist, tagLen)
// val alt_tag_history = compute_folded_ghist(hist, tagLen-1)
// // Use another part of pc to make tags
// val tag = ((unhashed_idx >> log2Ceil(nRows)) ^ tag_history ^ (alt_tag_history << 1)) (tagLen - 1, 0)
// (idx, tag)
// }
val
idxFhInfo
=
(
histLen
,
min
(
log2Ceil
(
nRows
),
histLen
))
val
tagFhInfo
=
(
histLen
,
min
(
histLen
,
tagLen
))
...
...
@@ -265,14 +260,13 @@ class TageTable
def
inc_ctr
(
ctr
:
UInt
,
taken
:
Bool
)
:
UInt
=
satUpdate
(
ctr
,
TageCtrBits
,
taken
)
class
TageEntry
()
extends
TageBundle
{
val
valid
=
Bool
()
//
val valid = Bool()
val
tag
=
UInt
(
tagLen
.
W
)
val
ctr
=
UInt
(
TageCtrBits
.
W
)
}
// Why need add instOffsetBits?
// val tageEntrySz = instOffsetBits + tagLen + TageCtrBits
val
tageEntrySz
=
1
+
tagLen
+
TageCtrBits
val
validArray
=
RegInit
(
0.
U
(
nRows
.
W
))
// pc is start address of basic block, most 2 branch inst in block
// def getUnhashedIdx(pc: UInt) = pc >> (instOffsetBits+log2Ceil(TageBanks))
...
...
@@ -281,42 +275,41 @@ class TageTable
// val s1_pc = io.req.bits.pc
val
req_unhashed_idx
=
getUnhashedIdx
(
io
.
req
.
bits
.
pc
)
val
us
=
Module
(
new
SyncDataModuleTemplate
(
Bool
(),
nRows
,
1
,
1
))
val
us
=
Module
(
new
Folded1WDataModuleTemplate
(
Bool
(),
nRows
,
1
,
isSync
=
true
,
width
=
uFoldedWidth
))
val
table
=
Module
(
new
SRAMTemplate
(
new
TageEntry
,
set
=
nRows
,
way
=
1
,
shouldReset
=
true
,
holdRead
=
true
,
singlePort
=
false
))
val
table_banks
=
Seq
.
fill
(
nBanks
)(
Module
(
new
FoldedSRAMTemplate
(
new
TageEntry
,
set
=
nRows
/
nBanks
,
width
=
bankFoldWidth
,
shouldReset
=
false
,
holdRead
=
true
,
singlePort
=
true
)))
// val table = Module(new SRAMTemplate(new TageEntry, set=nRows, way=1, shouldReset=false, holdRead=true, singlePort=false))
val
(
s0_idx
,
s0_tag
)
=
compute_tag_and_hash
(
req_unhashed_idx
,
io
.
req
.
bits
.
folded_hist
)
val
s0_bank_req_1h
=
get_bank_mask
(
s0_idx
)
table
.
io
.
r
.
req
.
valid
:=
io
.
req
.
valid
table
.
io
.
r
.
req
.
bits
.
setIdx
:=
s0_idx
for
(
b
<-
0
until
nBanks
)
{
table_banks
(
b
).
io
.
r
.
req
.
valid
:=
io
.
req
.
fire
&&
s0_bank_req_1h
(
b
)
table_banks
(
b
).
io
.
r
.
req
.
bits
.
setIdx
:=
get_bank_idx
(
s0_idx
)
}
us
.
io
.
raddr
(
0
)
:=
s0_idx
// us.io.raddr(1) := DontCare
// us.io.raddr(2) := DontCare
val
s1_idx
=
RegEnable
(
s0_idx
,
io
.
req
.
valid
)
val
s1_tag
=
RegEnable
(
s0_tag
,
io
.
req
.
valid
)
val
s1_idx
=
RegEnable
(
s0_idx
,
io
.
req
.
fire
)
val
s1_tag
=
RegEnable
(
s0_tag
,
io
.
req
.
fire
)
val
s1_bank_req_1h
=
RegEnable
(
s0_bank_req_1h
,
io
.
req
.
fire
)
val
table
_r
=
table
.
io
.
r
.
resp
.
data
(
0
)
// s1
val
table
s_r
=
table_banks
.
map
(
_
.
io
.
r
.
resp
.
data
(
0
)
)
// s1
val
req_rhit
=
table_r
.
valid
&&
table_r
.
tag
===
s1_tag
val
resp_selected
=
Mux1H
(
s1_bank_req_1h
,
tables_r
)
val
req_rhit
=
validArray
(
s1_idx
)
&&
resp_selected
.
tag
===
s1_tag
io
.
resp
.
valid
:=
req_rhit
io
.
resp
.
bits
.
ctr
:=
table_r
.
ctr
io
.
resp
.
bits
.
ctr
:=
resp_selected
.
ctr
io
.
resp
.
bits
.
u
:=
us
.
io
.
rdata
(
0
)
// TODO: reset all us at once?
val
doing_reset_u
=
RegInit
(
true
.
B
)
val
resetRow
=
RegInit
(
0.
U
(
log2Ceil
(
nRows
).
W
))
resetRow
:=
resetRow
+
doing_reset_u
when
(
io
.
update
.
reset_u
)
{
doing_reset_u
:=
true
.
B
}.
elsewhen
(
resetRow
===
(
nRows
-
1
).
U
)
{
doing_reset_u
:=
false
.
B
}
// reset all us in 32 cycles
us
.
io
.
resetEn
.
map
(
_
:=
io
.
update
.
reset_u
)
// Use fetchpc to compute hash
...
...
@@ -324,40 +317,59 @@ class TageTable
// val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist)
val
(
update_idx
,
update_tag
)
=
compute_tag_and_hash
(
getUnhashedIdx
(
io
.
update
.
pc
),
io
.
update
.
folded_hist
)
val
update_req_bank_1h
=
get_bank_mask
(
update_idx
)
val
update_idx_in_bank
=
get_bank_idx
(
update_idx
)
table
.
io
.
w
.
apply
(
valid
=
io
.
update
.
mask
,
data
=
update_wdata
,
setIdx
=
update_idx
,
waymask
=
true
.
B
)
val
not_silent_update
=
Wire
(
Bool
())
for
(
b
<-
0
until
nBanks
)
{
table_banks
(
b
).
io
.
w
.
apply
(
valid
=
io
.
update
.
mask
&&
update_req_bank_1h
(
b
)
&&
not_silent_update
,
data
=
update_wdata
,
setIdx
=
update_idx_in_bank
,
waymask
=
true
.
B
)
}
val
bank_conflict
=
(
0
until
nBanks
).
map
(
b
=>
table_banks
(
b
).
io
.
w
.
req
.
valid
&&
s0_bank_req_1h
(
b
)).
reduce
(
_
||
_
)
io
.
req
.
ready
:=
!
bank_conflict
XSPerfAccumulate
(
f
"tage_table_bank_conflict"
,
bank_conflict
)
val
update_u
=
io
.
update
.
u
val
u_wen
=
io
.
update
.
uMask
||
doing_reset_u
val
u_waddr
=
Mux
(
doing_reset_u
,
resetRow
,
update_idx
)
val
u_wdata
=
Mux
(
doing_reset_u
,
false
.
B
,
update_u
)
val
newValidArray
=
VecInit
(
validArray
.
asBools
)
when
(
io
.
update
.
mask
)
{
newValidArray
(
update_idx
)
:=
true
.
B
validArray
:=
newValidArray
.
asUInt
}
us
.
io
.
wen
(
0
)
:=
u_wen
us
.
io
.
waddr
(
0
)
:=
u_waddr
us
.
io
.
wdata
(
0
)
:=
u_wdata
us
.
io
.
wen
:=
io
.
update
.
uMask
us
.
io
.
waddr
:=
update_idx
us
.
io
.
wdata
:=
io
.
update
.
u
val
wrbypass
=
Module
(
new
WrBypass
(
UInt
(
TageCtrBits
.
W
),
wrBypassEntries
,
log2Ceil
(
nRows
),
tagWidth
=
tagLen
))
wrbypass
.
io
.
wen
:=
io
.
update
.
mask
wrbypass
.
io
.
wen
:=
io
.
update
.
mask
&&
not_silent_update
wrbypass
.
io
.
write_data
.
map
(
_
:=
update_wdata
.
ctr
)
val
bypass_ctr
=
wrbypass
.
io
.
hit_data
(
0
).
bits
update_wdata
.
ctr
:=
Mux
(
io
.
update
.
alloc
,
Mux
(
io
.
update
.
taken
,
4.
U
,
3.
U
),
Mux
(
wrbypass
.
io
.
hit
,
inc_ctr
(
wrbypass
.
io
.
hit_data
(
0
).
bits
,
io
.
update
.
taken
),
inc_ctr
(
bypass_ctr
,
io
.
update
.
taken
),
inc_ctr
(
io
.
update
.
oldCtr
,
io
.
update
.
taken
)
)
)
update_wdata
.
valid
:=
true
.
B
update_wdata
.
tag
:=
update_tag
// remove silent updates
def
silentUpdate
(
ctr
:
UInt
,
taken
:
Bool
)
=
{
ctr
.
andR
&&
taken
||
!
ctr
.
orR
&&
!
taken
}
not_silent_update
:=
Mux
(
wrbypass
.
io
.
hit
,
!
silentUpdate
(
bypass_ctr
,
io
.
update
.
taken
),
!
silentUpdate
(
io
.
update
.
oldCtr
,
io
.
update
.
taken
))
||
io
.
update
.
alloc
wrbypass
.
io
.
write_idx
:=
update_idx
wrbypass
.
io
.
write_tag
.
map
(
_
:=
update_tag
)
...
...
@@ -367,16 +379,18 @@ class TageTable
XSPerfAccumulate
(
f
"tage_table_wrbypass_hit"
,
io
.
update
.
mask
&&
wrbypass
.
io
.
hit
)
XSPerfAccumulate
(
f
"tage_table_wrbypass_enq"
,
io
.
update
.
mask
&&
!
wrbypass
.
io
.
hit
)
XSPerfAccumulate
(
f
"tage_table_real_updates"
,
io
.
update
.
mask
&&
not_silent_update
)
XSPerfAccumulate
(
f
"tage_table_silent_updates_eliminated"
,
io
.
update
.
mask
&&
!
not_silent_update
)
XSPerfAccumulate
(
"tage_table_hits"
,
PopCount
(
io
.
resp
.
valid
))
val
u
=
io
.
update
val
b
=
PriorityEncoder
(
u
.
mask
)
val
ub
=
PriorityEncoder
(
u
.
uMask
)
XSDebug
(
io
.
req
.
valid
,
XSDebug
(
io
.
req
.
fire
,
p
"tableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, "
+
p
"idx=$s0_idx, tag=$s0_tag\n"
)
XSDebug
(
RegNext
(
io
.
req
.
valid
)
&&
req_rhit
,
XSDebug
(
RegNext
(
io
.
req
.
fire
)
&&
req_rhit
,
p
"TageTableResp: idx=$s1_idx, hit:$req_rhit, "
+
p
"ctr:${io.resp.bits.ctr}, u:${io.resp.bits.u}\n"
)
XSDebug
(
io
.
update
.
mask
,
...
...
@@ -385,7 +399,7 @@ class TageTable
XSDebug
(
io
.
update
.
mask
,
p
"update Table: writing tag:$update_tag, "
+
p
"ctr: ${update_wdata.ctr} in idx ${update_idx}\n"
)
XSDebug
(
RegNext
(
io
.
req
.
valid
)
&&
!
req_rhit
,
"TageTableResp: not hit!\n"
)
XSDebug
(
RegNext
(
io
.
req
.
fire
)
&&
!
req_rhit
,
"TageTableResp: not hit!\n"
)
// ------------------------------Debug-------------------------------------
val
valids
=
Reg
(
Vec
(
nRows
,
Bool
()))
...
...
@@ -655,6 +669,7 @@ class Tage(implicit p: Parameters) extends BaseTage {
}
XSPerfAccumulate
(
s
"tage_bank_${w}_reset_u"
,
updateResetU
(
w
))
XSPerfAccumulate
(
s
"tage_bank_${w}_mispred"
,
updateValid
&&
updateMisPred
)
}
...
...
@@ -684,6 +699,10 @@ class Tage(implicit p: Parameters) extends BaseTage {
bt
.
io
.
update
.
valid
:=
RegNext
(
baseupdate
.
reduce
(
_
||
_
))
bt
.
io
.
update_cnt
:=
RegNext
(
updatebcnt
)
// all should be ready for req
io
.
s1_ready
:=
bank_tables
.
flatMap
(
_
.
map
(
_
.
io
.
req
.
ready
)).
reduce
(
_
&&
_
)
XSPerfAccumulate
(
f
"tage_write_blocks_read"
,
!
io
.
s1_ready
)
def
pred_perf
(
name
:
String
,
cnt
:
UInt
)
=
XSPerfAccumulate
(
s
"${name}_at_pred"
,
cnt
)
def
commit_perf
(
name
:
String
,
cnt
:
UInt
)
=
XSPerfAccumulate
(
s
"${name}_at_commit"
,
cnt
)
def
tage_perf
(
name
:
String
,
pred_cnt
:
UInt
,
commit_cnt
:
UInt
)
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录