Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
32c36961
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
12 个月 前同步成功
通知
1183
Star
3914
Fork
526
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
XiangShan
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
32c36961
编写于
1月 27, 2021
作者:
L
Lingrui98
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ras: fix bugs and remove commit stack
上级
33c5e073
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
109 addition
and
178 deletion
+109
-178
src/main/scala/xiangshan/frontend/RAS.scala
src/main/scala/xiangshan/frontend/RAS.scala
+109
-178
未找到文件。
src/main/scala/xiangshan/frontend/RAS.scala
浏览文件 @
32c36961
...
...
@@ -6,6 +6,7 @@ import xiangshan._
import
xiangshan.backend.ALUOpType
import
utils._
import
chisel3.experimental.chiselName
import
scala.tools.nsc.doc.base.comment.Bold
class
RASEntry
()
extends
XSBundle
{
val
retAddr
=
UInt
(
VAddrBits
.
W
)
...
...
@@ -57,126 +58,108 @@ class RAS extends BasePredictor
val
io
=
IO
(
new
Bundle
{
val
push_valid
=
Input
(
Bool
())
val
pop_valid
=
Input
(
Bool
())
val
new_addr
=
Input
(
UInt
(
VAddrBits
.
W
))
val
top_addr
=
Output
(
UInt
(
VAddrBits
.
W
))
val
spec_new_addr
=
Input
(
UInt
(
VAddrBits
.
W
))
val
recover_sp
=
Input
(
UInt
(
log2Up
(
rasSize
).
W
))
val
recover_top
=
Input
(
rasEntry
())
val
recover_valid
=
Input
(
Bool
())
val
recover_push
=
Input
(
Bool
())
val
recover_pop
=
Input
(
Bool
())
val
recover_new_addr
=
Input
(
UInt
(
VAddrBits
.
W
))
val
sp
=
Output
(
UInt
(
log2Up
(
rasSize
).
W
))
val
top
=
Output
(
rasEntry
())
val
is_empty
=
Output
(
Bool
())
val
is_full
=
Output
(
Bool
())
val
copy_valid
=
Input
(
Bool
())
val
copy_in_mem
=
Input
(
Vec
(
rasSize
,
rasEntry
()))
val
copy_in_sp
=
Input
(
UInt
(
log2Up
(
rasSize
).
W
))
val
copy_in_top
=
Input
(
rasEntry
())
val
copy_out_mem
=
Output
(
Vec
(
rasSize
,
rasEntry
()))
val
copy_out_sp
=
Output
(
UInt
(
log2Up
(
rasSize
).
W
))
val
copy_out_top
=
Output
(
rasEntry
())
})
val
debugIO
=
IO
(
new
Bundle
{
val
write
_entry
=
Output
(
rasEntry
())
val
push
_entry
=
Output
(
rasEntry
())
val
alloc_new
=
Output
(
Bool
())
val
sp
=
Output
(
UInt
(
log2Up
(
rasSize
).
W
))
val
topRegister
=
Output
(
rasEntry
())
val
out_mem
=
Output
(
Vec
(
RasSize
,
rasEntry
()))
})
@chiselName
class
Stack
(
val
size
:
Int
)
extends
XSModule
{
val
io
=
IO
(
new
Bundle
{
val
rIdx
=
Input
(
UInt
(
log2Up
(
size
).
W
))
val
rdata
=
Output
(
rasEntry
())
val
wen
=
Input
(
Bool
())
val
wIdx
=
Input
(
UInt
(
log2Up
(
size
).
W
))
val
wdata
=
Input
(
rasEntry
())
val
copyen
=
Input
(
Bool
())
val
copy_in
=
Input
(
Vec
(
size
,
rasEntry
()))
val
copy_out
=
Output
(
Vec
(
size
,
rasEntry
()))
})
val
mem
=
Reg
(
Vec
(
size
,
rasEntry
()))
when
(
io
.
wen
)
{
mem
(
io
.
wIdx
)
:=
io
.
wdata
}
io
.
rdata
:=
mem
(
io
.
rIdx
)
(
0
until
size
).
foreach
{
i
=>
io
.
copy_out
(
i
)
:=
mem
(
i
)
}
when
(
io
.
copyen
)
{
(
0
until
size
).
foreach
{
i
=>
mem
(
i
)
:=
io
.
copy_in
(
i
)
}
}
}
val
sp
=
RegInit
(
RasSize
.
U
((
log2Up
(
rasSize
)
+
1
).
W
))
val
topRegister
=
RegInit
(
0.
U
.
asTypeOf
(
new
RASEntry
))
val
stack
=
Module
(
new
Stack
(
rasSize
)).
io
stack
.
rIdx
:=
sp
-
1.
U
val
top_addr
=
topRegister
.
retAddr
val
top_ctr
=
topRegister
.
ctr
val
alloc_new
=
io
.
new_addr
=/=
top_addr
// stack.wen := io.push_valid || io.pop_valid && top_ctr =/= 1.U
// stack.wIdx := Mux(io.pop_valid && top_ctr =/= 1.U, sp - 1.U, Mux(alloc_new, sp, sp - 1.U))
// val write_addr = Mux(io.pop_valid && top_ctr =/= 1.U, top_addr, io.new_addr)
// val write_ctr = Mux(io.pop_valid && top_ctr =/= 1.U, top_ctr - 1.U, Mux(alloc_new, 1.U, top_ctr + 1.U))
val
stack
=
Mem
(
RasSize
,
new
RASEntry
)
val
sp
=
RegInit
(
1.
U
((
log2Up
(
rasSize
)
+
1
).
W
))
val
top
=
RegInit
(
0.
U
.
asTypeOf
(
new
RASEntry
))
val
topPtr
=
RegInit
(
0.
U
((
log2Up
(
rasSize
)
+
1
).
W
))
def
full
(
sp
:
UInt
=
sp
)
=
sp
===
0.
U
def
empty
(
sp
:
UInt
=
sp
)
=
sp
===
(
RasSize
-
1
).
U
val
is_empty
=
empty
()
val
is_full
=
full
()
val
alloc_new
=
io
.
spec_new_addr
=/=
top
.
retAddr
val
recover_alloc_new
=
io
.
recover_new_addr
=/=
io
.
recover_top
.
retAddr
def
update
(
recover
:
Bool
)(
do_push
:
Bool
,
do_pop
:
Bool
,
do_alloc_new
:
Bool
,
do_sp
:
UInt
,
do_top_ptr
:
UInt
,
do_new_addr
:
UInt
,
do_top
:
RASEntry
)
=
{
when
(
do_push
)
{
when
(
do_alloc_new
)
{
sp
:=
Mux
(
full
(
do_sp
),
do_sp
,
do_sp
+
1.
U
)
topPtr
:=
Mux
(
full
(
do_sp
),
do_sp
-
1.
U
,
do_sp
)
top
.
retAddr
:=
do_new_addr
top
.
ctr
:=
1.
U
stack
.
write
(
do_sp
,
RASEntry
(
do_new_addr
,
1.
U
))
}.
otherwise
{
when
(
recover
)
{
sp
:=
do_sp
topPtr
:=
do_top_ptr
top
.
retAddr
:=
do_top
.
retAddr
}
top
.
ctr
:=
do_top
.
ctr
+
1.
U
stack
.
write
(
do_top_ptr
,
RASEntry
(
do_new_addr
,
do_top
.
ctr
+
1.
U
))
}
}.
elsewhen
(
do_pop
)
{
when
(
do_top
.
ctr
===
1.
U
)
{
sp
:=
Mux
(
empty
(
do_sp
),
do_sp
,
do_sp
-
1.
U
)
topPtr
:=
Mux
(
empty
(
do_sp
),
do_sp
-
1.
U
,
do_sp
-
2.
U
)
top
:=
stack
.
read
(
do_top_ptr
)
}.
otherwise
{
when
(
recover
)
{
sp
:=
do_sp
topPtr
:=
do_top_ptr
top
.
retAddr
:=
do_top
.
retAddr
}
top
.
ctr
:=
do_top
.
ctr
-
1.
U
stack
.
write
(
do_top_ptr
,
RASEntry
(
do_top
.
retAddr
,
do_top
.
ctr
-
1.
U
))
}
}.
otherwise
{
when
(
recover
)
{
sp
:=
do_sp
topPtr
:=
do_top_ptr
top
:=
do_top
stack
.
write
(
do_top_ptr
,
do_top
)
}
}
}
stack
.
wen
:=
io
.
push_valid
&&
!
io
.
is_empty
stack
.
wIdx
:=
sp
val
write_addr
=
topRegister
.
retAddr
val
write_ctr
=
topRegister
.
ctr
update
(
io
.
recover_valid
)(
Mux
(
io
.
recover_valid
,
io
.
recover_push
,
io
.
push_valid
),
Mux
(
io
.
recover_valid
,
io
.
recover_pop
,
io
.
pop_valid
),
Mux
(
io
.
recover_valid
,
recover_alloc_new
,
alloc_new
),
Mux
(
io
.
recover_valid
,
io
.
recover_sp
,
sp
),
Mux
(
io
.
recover_valid
,
io
.
recover_sp
-
1.
U
,
topPtr
),
Mux
(
io
.
recover_valid
,
io
.
recover_new_addr
,
io
.
spec_new_addr
),
Mux
(
io
.
recover_valid
,
io
.
recover_top
,
top
))
io
.
sp
:=
sp
io
.
top
:=
top
io
.
is_empty
:=
is_empty
io
.
is_full
:=
is_full
val
write_entry
=
RASEntry
(
write_addr
,
write_ctr
)
stack
.
wdata
:=
write_entry
debugIO
.
write_entry
:=
write_entry
debugIO
.
push_entry
:=
RASEntry
(
io
.
spec_new_addr
,
Mux
(
alloc_new
,
1.
U
,
top
.
ctr
+
1.
U
))
debugIO
.
alloc_new
:=
alloc_new
debugIO
.
sp
:=
sp
debugIO
.
topRegister
:=
topRegister
val
is_empty
=
sp
===
RasSize
.
U
val
is_full
=
sp
===
(
RasSize
-
1
).
U
when
(
io
.
push_valid
&&
alloc_new
)
{
sp
:=
Mux
(
is_full
,
sp
,
Mux
(
is_empty
,
0.
U
,
sp
+
1.
U
))
top_addr
:=
io
.
new_addr
top_ctr
:=
1.
U
}
.
elsewhen
(
io
.
push_valid
)
{
top_ctr
:=
top_ctr
+
1.
U
}
when
(
io
.
pop_valid
&&
top_ctr
===
1.
U
)
{
sp
:=
Mux
(
is_empty
,
sp
,
Mux
(
sp
===
0.
U
,
RasSize
.
U
,
sp
-
1.
U
))
top_addr
:=
stack
.
rdata
.
retAddr
top_ctr
:=
stack
.
rdata
.
ctr
}
.
elsewhen
(
io
.
pop_valid
)
{
top_ctr
:=
top_ctr
-
1.
U
}
io
.
copy_out_mem
:=
stack
.
copy_out
io
.
copy_out_sp
:=
sp
io
.
copy_out_top
:=
topRegister
if
(
EnableCommit
){
stack
.
copyen
:=
io
.
copy_valid
stack
.
copy_in
:=
io
.
copy_in_mem
}
else
{
stack
.
copyen
:=
false
.
B
stack
.
copy_in
:=
DontCare
}
when
(
io
.
copy_valid
)
{
sp
:=
io
.
copy_in_sp
topRegister
:=
io
.
copy_in_top
debugIO
.
topRegister
:=
top
for
(
i
<-
0
until
RasSize
)
{
debugIO
.
out_mem
(
i
)
:=
stack
.
read
(
i
.
U
)
}
io
.
top_addr
:=
top_addr
io
.
is_empty
:=
is_empty
io
.
is_full
:=
is_full
}
// val ras_0 = Reg(Vec(RasSize, rasEntry())) //RegInit(0.U)asTypeOf(Vec(RasSize,rasEntry)) cause comb loop
// val ras_1 = Reg(Vec(RasSize, rasEntry()))
// val sp_0 = RegInit(0.U(log2Up(RasSize).W))
// val sp_1 = RegInit(0.U(log2Up(RasSize).W))
// val choose_bit = RegInit(false.B) //start with 0
// val spec_ras = Mux(choose_bit, ras_1, ras_0)
// val spec_sp = Mux(choose_bit,sp_1,sp_0)
// val commit_ras = Mux(choose_bit, ras_0, ras_1)
// val commit_sp = Mux(choose_bit,sp_0,sp_1)
// val spec_ras = Reg(Vec(RasSize, rasEntry()))
// val spec_sp = RegInit(0.U(log2Up(RasSize).W))
// val commit_ras = Reg(Vec(RasSize, rasEntry()))
// val commit_sp = RegInit(0.U(log2Up(RasSize).W))
val
spec
=
Module
(
new
RASStack
(
RasSize
))
val
spec_ras
=
spec
.
io
...
...
@@ -188,85 +171,31 @@ class RAS extends BasePredictor
val
spec_new_addr
=
packetAligned
(
io
.
pc
.
bits
)
+
(
io
.
callIdx
.
bits
<<
instOffsetBits
.
U
)
+
Mux
(
(
io
.
isRVC
|
call_is_last_half
)
&&
HasCExtension
.
B
,
2.
U
,
4.
U
)
spec_ras
.
push_valid
:=
spec_push
spec_ras
.
pop_valid
:=
spec_pop
spec_ras
.
new_addr
:=
spec_new_addr
spec_ras
.
spec_
new_addr
:=
spec_new_addr
val
spec_is_empty
=
spec_ras
.
is_empty
val
spec_is_full
=
spec_ras
.
is_full
val
spec_top_addr
=
spec_ras
.
top
_a
ddr
val
spec_top_addr
=
spec_ras
.
top
.
retA
ddr
spec_push
:=
!
spec_is_full
&&
io
.
callIdx
.
valid
&&
io
.
pc
.
valid
spec_pop
:=
!
spec_is_empty
&&
io
.
is_ret
&&
io
.
pc
.
valid
val
copy_valid
=
io
.
redirect
.
valid
val
copy_next
=
RegNext
(
copy_valid
)
// val copy_bits = RegNext(io.recover.bpuMeta)
if
(
EnableCommit
){
val
commit_cfi
=
io
.
redirect
.
bits
.
cfiUpdate
val
commit
=
Module
(
new
RASStack
(
RasSize
))
val
commit_ras
=
commit
.
io
val
recover_cfi
=
io
.
redirect
.
bits
.
cfiUpdate
val
commit_push
=
WireInit
(
false
.
B
)
val
commit_pop
=
WireInit
(
false
.
B
)
val
commit_new_addr
=
Mux
(
commit_cfi
.
pd
.
isRVC
&&
HasCExtension
.
B
,
commit_cfi
.
pc
+
2.
U
,
commit_cfi
.
pc
+
4.
U
)
commit_ras
.
push_valid
:=
commit_push
commit_ras
.
pop_valid
:=
commit_pop
commit_ras
.
new_addr
:=
commit_new_addr
val
commit_is_empty
=
commit_ras
.
is_empty
val
commit_is_full
=
commit_ras
.
is_full
val
commit_top_addr
=
commit_ras
.
top_addr
val
retMissPred
=
copy_valid
&&
io
.
redirect
.
bits
.
level
===
0.
U
&&
recover_cfi
.
pd
.
isRet
val
callMissPred
=
copy_valid
&&
io
.
redirect
.
bits
.
level
===
0.
U
&&
recover_cfi
.
pd
.
isCall
// when we mispredict a call, we must redo a push operation
// similarly, when we mispredict a return, we should redo a pop
spec_ras
.
recover_valid
:=
copy_valid
spec_ras
.
recover_push
:=
callMissPred
spec_ras
.
recover_pop
:=
retMissPred
val
update_valid
=
io
.
update
.
valid
val
update
=
io
.
update
.
bits
val
update_call_valid
=
update_valid
&&
update
.
cfiIsCall
&&
update
.
cfiIndex
.
valid
&&
update
.
valids
(
update
.
cfiIndex
.
bits
)
val
update_ret_valid
=
update_valid
&&
update
.
cfiIsRet
&&
update
.
cfiIndex
.
valid
&&
update
.
valids
(
update
.
cfiIndex
.
bits
)
commit_push
:=
!
commit_is_full
&&
update_call_valid
commit_pop
:=
!
commit_is_empty
&&
update_ret_valid
spec_ras
.
recover_sp
:=
recover_cfi
.
rasSp
spec_ras
.
recover_top
:=
recover_cfi
.
rasEntry
spec_ras
.
recover_new_addr
:=
recover_cfi
.
pc
+
Mux
(
recover_cfi
.
pd
.
isRVC
,
2.
U
,
4.
U
)
commit_ras
.
copy_valid
:=
false
.
B
commit_ras
.
copy_in_mem
:=
DontCare
commit_ras
.
copy_in_sp
:=
DontCare
commit_ras
.
copy_in_top
:=
DontCare
spec_ras
.
copy_valid
:=
copy_next
spec_ras
.
copy_in_mem
:=
commit_ras
.
copy_out_mem
spec_ras
.
copy_in_sp
:=
commit_ras
.
copy_out_sp
spec_ras
.
copy_in_top
:=
commit_ras
.
copy_out_top
//no need to pass the ras branchInfo
io
.
meta
.
rasSp
:=
DontCare
io
.
meta
.
rasTop
:=
DontCare
if
(
BPUDebug
&&
debug
)
{
val
commit_debug
=
commit
.
debugIO
XSDebug
(
"----------------RAS(commit)----------------\n"
)
XSDebug
(
" TopRegister: 0x%x %d \n"
,
commit_debug
.
topRegister
.
retAddr
,
commit_debug
.
topRegister
.
ctr
)
XSDebug
(
" index addr ctr \n"
)
for
(
i
<-
0
until
RasSize
){
XSDebug
(
" (%d) 0x%x %d"
,
i
.
U
,
commit_ras
.
copy_out_mem
(
i
).
retAddr
,
commit_ras
.
copy_out_mem
(
i
).
ctr
)
when
(
i
.
U
===
commit_ras
.
copy_out_sp
){
XSDebug
(
false
,
true
.
B
,
" <----sp"
)}
XSDebug
(
false
,
true
.
B
,
"\n"
)
}
XSDebug
(
commit_push
,
"(commit_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d | TopReg.addr %x ctr:%d\n"
,
commit_new_addr
,
commit_debug
.
write_entry
.
ctr
,
commit_debug
.
alloc_new
,
commit_debug
.
sp
.
asUInt
,
commit_debug
.
topRegister
.
retAddr
,
commit_debug
.
topRegister
.
ctr
)
XSDebug
(
commit_pop
,
"(commit_ras)pop outValid:%d outAddr: 0x%x \n"
,
io
.
out
.
valid
,
io
.
out
.
bits
.
target
)
}
}
else
{
val
retMissPred
=
copy_valid
&&
io
.
redirect
.
bits
.
level
===
0.
U
&&
io
.
redirect
.
bits
.
cfiUpdate
.
pd
.
isRet
val
recoverSp
=
io
.
redirect
.
bits
.
cfiUpdate
.
rasSp
val
recoverTopAddr
=
io
.
redirect
.
bits
.
cfiUpdate
.
rasEntry
.
retAddr
val
recoverTopCtr
=
io
.
redirect
.
bits
.
cfiUpdate
.
rasEntry
.
ctr
spec_ras
.
copy_valid
:=
copy_valid
spec_ras
.
copy_in_mem
:=
DontCare
spec_ras
.
copy_in_sp
:=
Mux
(
retMissPred
&&
recoverTopCtr
===
1.
U
,
recoverSp
-
1.
U
,
recoverSp
)
spec_ras
.
copy_in_top
.
retAddr
:=
recoverTopAddr
spec_ras
.
copy_in_top
.
ctr
:=
Mux
(!
retMissPred
,
recoverTopCtr
,
Mux
(
recoverTopCtr
===
1.
U
,
recoverTopCtr
,
recoverTopCtr
-
1.
U
))
io
.
meta
.
rasSp
:=
spec_ras
.
copy_out_sp
io
.
meta
.
rasTop
:=
spec
.
debugIO
.
topRegister
}
io
.
meta
.
rasSp
:=
spec_ras
.
sp
io
.
meta
.
rasTop
:=
spec_ras
.
top
io
.
out
.
valid
:=
!
spec_is_empty
io
.
out
.
bits
.
target
:=
spec_top_addr
...
...
@@ -275,18 +204,20 @@ class RAS extends BasePredictor
if
(
BPUDebug
&&
debug
)
{
val
spec_debug
=
spec
.
debugIO
XSDebug
(
"----------------RAS
(spec)
----------------\n"
)
XSDebug
(
"----------------RAS----------------\n"
)
XSDebug
(
" TopRegister: 0x%x %d \n"
,
spec_debug
.
topRegister
.
retAddr
,
spec_debug
.
topRegister
.
ctr
)
XSDebug
(
" index addr ctr \n"
)
for
(
i
<-
0
until
RasSize
){
XSDebug
(
" (%d) 0x%x %d"
,
i
.
U
,
spec_
ras
.
copy_out_mem
(
i
).
retAddr
,
spec_ras
.
copy_
out_mem
(
i
).
ctr
)
when
(
i
.
U
===
spec_
ras
.
copy_out_
sp
){
XSDebug
(
false
,
true
.
B
,
" <----sp"
)}
XSDebug
(
" (%d) 0x%x %d"
,
i
.
U
,
spec_
debug
.
out_mem
(
i
).
retAddr
,
spec_debug
.
out_mem
(
i
).
ctr
)
when
(
i
.
U
===
spec_
debug
.
sp
){
XSDebug
(
false
,
true
.
B
,
" <----sp"
)}
XSDebug
(
false
,
true
.
B
,
"\n"
)
}
XSDebug
(
spec_push
,
"(spec_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n"
,
spec_new_addr
,
spec_debug
.
write_entry
.
ctr
,
spec_debug
.
alloc_new
,
spec_debug
.
sp
.
asUInt
)
XSDebug
(
spec_push
,
"(spec_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n"
,
spec_new_addr
,
spec_debug
.
push_entry
.
ctr
,
spec_debug
.
alloc_new
,
spec_debug
.
sp
.
asUInt
)
XSDebug
(
spec_pop
,
"(spec_ras)pop outValid:%d outAddr: 0x%x \n"
,
io
.
out
.
valid
,
io
.
out
.
bits
.
target
)
XSDebug
(
"copyValid:%d copyNext:%d recover(SP:%d retAddr:%x ctr:%d) \n"
,
copy_valid
,
copy_next
,
io
.
redirect
.
bits
.
cfiUpdate
.
rasSp
,
io
.
redirect
.
bits
.
cfiUpdate
.
rasEntry
.
retAddr
,
io
.
redirect
.
bits
.
cfiUpdate
.
rasEntry
.
ctr
)
val
redirectUpdate
=
io
.
redirect
.
bits
.
cfiUpdate
XSDebug
(
"copyValid:%d recover(SP:%d retAddr:%x ctr:%d) \n"
,
copy_valid
,
redirectUpdate
.
rasSp
,
redirectUpdate
.
rasEntry
.
retAddr
,
redirectUpdate
.
rasEntry
.
ctr
)
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录