Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
35668667
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,发现更多精彩内容 >>
提交
35668667
编写于
10月 22, 2020
作者:
L
Lingrui98
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
RAS: wrap mems with Module
上级
cfb9e474
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
148 addition
and
103 deletion
+148
-103
src/main/scala/xiangshan/frontend/RAS.scala
src/main/scala/xiangshan/frontend/RAS.scala
+148
-103
未找到文件。
src/main/scala/xiangshan/frontend/RAS.scala
浏览文件 @
35668667
...
...
@@ -30,12 +30,95 @@ class RAS extends BasePredictor
val
branchInfo
=
Output
(
new
RASBranchInfo
)
}
def
rasEntry
()
=
new
Bundle
{
class
RASEntry
()
extends
XS
Bundle
{
val
retAddr
=
UInt
(
VAddrBits
.
W
)
val
ctr
=
UInt
(
8.
W
)
// layer of nested call functions
}
def
rasEntry
()
=
new
RASEntry
object
RASEntry
{
def
apply
(
retAddr
:
UInt
,
ctr
:
UInt
)
:
RASEntry
=
{
val
e
=
Wire
(
rasEntry
())
e
.
retAddr
:=
retAddr
e
.
ctr
:=
ctr
e
}
}
override
val
io
=
IO
(
new
RASIO
)
class
RASStack
(
val
rasSize
:
Int
)
extends
XSModule
{
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
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_out_mem
=
Output
(
Vec
(
rasSize
,
rasEntry
()))
val
copy_out_sp
=
Output
(
UInt
(
log2Up
(
rasSize
).
W
))
})
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
(
0.
U
(
log2Up
(
rasSize
).
W
))
val
stack
=
Module
(
new
Stack
(
rasSize
)).
io
stack
.
rIdx
:=
sp
-
1.
U
val
top_entry
=
stack
.
rdata
val
top_addr
=
top_entry
.
retAddr
val
top_ctr
=
top_entry
.
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
))
stack
.
wdata
:=
Mux
(
io
.
pop_valid
&&
top_ctr
=/=
1.
U
,
RASEntry
(
top_addr
,
top_ctr
-
1.
U
),
Mux
(
alloc_new
,
RASEntry
(
io
.
new_addr
,
1.
U
),
RASEntry
(
top_addr
,
top_ctr
+
1.
U
)))
when
(
io
.
push_valid
&&
alloc_new
)
{
sp
:=
sp
+
1.
U
}
when
(
io
.
pop_valid
&&
top_ctr
===
1.
U
)
{
sp
:=
Mux
(
sp
===
0.
U
,
0.
U
,
sp
-
1.
U
)
}
io
.
copy_out_mem
:=
stack
.
copy_out
io
.
copy_out_sp
:=
sp
stack
.
copyen
:=
io
.
copy_valid
stack
.
copy_in
:=
io
.
copy_in_mem
when
(
io
.
copy_valid
)
{
sp
:=
io
.
copy_in_sp
}
io
.
top_addr
:=
top_addr
io
.
is_empty
:=
sp
===
0.
U
io
.
is_full
:=
sp
===
(
RasSize
-
1
).
U
}
// 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))
...
...
@@ -46,120 +129,82 @@ class RAS extends BasePredictor
// 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_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_ras
=
Module
(
new
RASStack
(
RasSize
)).
io
val
spec_is_empty
=
spec_sp
===
0.
U
val
spec_is_full
=
spec_sp
===
(
RasSize
-
1
).
U
val
spec_push
=
WireInit
(
false
.
B
)
val
spec_pop
=
WireInit
(
false
.
B
)
val
spec_new_addr
=
WireInit
(
io
.
pc
.
bits
+
(
io
.
callIdx
.
bits
<<
1.
U
)
+
Mux
(
io
.
isRVC
,
2.
U
,
4.
U
))
spec_ras
.
push_valid
:=
spec_push
spec_ras
.
pop_valid
:=
spec_pop
spec_ras
.
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_addr
val
spec_ras_top_entry
=
spec_ras
(
spec_sp
-
1.
U
)
val
spec_ras_top_addr
=
spec_ras_top_entry
.
retAddr
val
spec_ras_top_ctr
=
spec_ras_top_entry
.
ctr
//no need to pass the ras branchInfo
io
.
branchInfo
.
rasSp
:=
DontCare
io
.
branchInfo
.
rasTopCtr
:=
DontCare
io
.
branchInfo
.
rasToqAddr
:=
DontCare
spec_push
:=
!
spec_is_full
&&
io
.
callIdx
.
valid
&&
io
.
pc
.
valid
spec_pop
:=
!
spec_is_empty
&&
io
.
is_ret
&&
io
.
pc
.
valid
io
.
out
.
valid
:=
!
spec_is_empty
&&
io
.
is_ret
val
commit_ras
=
Module
(
new
RASStack
(
RasSize
)).
io
// update spec RAS
// speculative update RAS
val
spec_push
=
!
spec_is_full
&&
io
.
callIdx
.
valid
&&
io
.
pc
.
valid
val
spec_pop
=
!
spec_is_empty
&&
io
.
is_ret
&&
io
.
pc
.
valid
val
spec_new_addr
=
io
.
pc
.
bits
+
(
io
.
callIdx
.
bits
<<
1.
U
)
+
Mux
(
io
.
isRVC
,
2.
U
,
4.
U
)
val
spec_ras_write
=
WireInit
(
0.
U
.
asTypeOf
(
rasEntry
()))
val
sepc_alloc_new
=
spec_new_addr
=/=
spec_ras_top_addr
when
(
spec_push
)
{
//push
spec_ras_write
.
ctr
:=
1.
U
spec_ras_write
.
retAddr
:=
spec_new_addr
when
(
sepc_alloc_new
){
spec_sp
:=
spec_sp
+
1.
U
spec_ras
(
spec_sp
)
:=
spec_ras_write
}.
otherwise
{
spec_ras_top_ctr
:=
spec_ras_top_ctr
+
1.
U
}
}
when
(
spec_pop
)
{
//pop
when
(
spec_ras_top_ctr
===
1.
U
)
{
spec_sp
:=
Mux
(
spec_sp
===
0.
U
,
0.
U
,
spec_sp
-
1.
U
)
}.
otherwise
{
spec_ras_top_ctr
:=
spec_ras_top_ctr
-
1.
U
}
}
io
.
out
.
bits
.
target
:=
spec_ras_top_addr
val
commit_push
=
WireInit
(
false
.
B
)
val
commit_pop
=
WireInit
(
false
.
B
)
val
commit_new_addr
=
WireInit
(
io
.
recover
.
bits
.
pc
+
4.
U
)
//TODO: consider RVC
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
commit_push
:=
!
commit_is_full
&&
io
.
recover
.
valid
&&
io
.
recover
.
bits
.
pd
.
isCall
commit_pop
:=
!
commit_is_empty
&&
io
.
recover
.
valid
&&
io
.
recover
.
bits
.
pd
.
isRet
io
.
out
.
valid
:=
!
spec_is_empty
&&
io
.
is_ret
io
.
out
.
bits
.
target
:=
spec_top_addr
// TODO: back-up stack for ras
// use checkpoint to recover RAS
val
commit_is_empty
=
commit_sp
===
0.
U
val
commit_is_full
=
commit_sp
===
(
RasSize
-
1
).
U
val
commit_ras_top_entry
=
commit_ras
(
commit_sp
-
1.
U
)
val
commit_ras_top_addr
=
commit_ras_top_entry
.
retAddr
val
commit_ras_top_ctr
=
commit_ras_top_entry
.
ctr
//update commit ras
val
commit_push
=
!
commit_is_full
&&
io
.
recover
.
valid
&&
io
.
recover
.
bits
.
pd
.
isCall
val
commit_pop
=
!
commit_is_empty
&&
io
.
recover
.
valid
&&
io
.
recover
.
bits
.
pd
.
isRet
val
commit_new_addr
=
io
.
recover
.
bits
.
pc
+
4.
U
//TODO: consider RVC
val
commit_ras_write
=
WireInit
(
0.
U
.
asTypeOf
(
rasEntry
()))
val
commit_alloc_new
=
commit_new_addr
=/=
commit_ras_top_addr
when
(
commit_push
)
{
//push
commit_ras_write
.
ctr
:=
1.
U
commit_ras_write
.
retAddr
:=
commit_new_addr
when
(
commit_alloc_new
){
commit_sp
:=
commit_sp
+
1.
U
commit_ras
(
commit_sp
)
:=
commit_ras_write
}.
otherwise
{
commit_ras_top_ctr
:=
commit_ras_top_ctr
+
1.
U
}
}
when
(
commit_pop
)
{
//pop
when
(
commit_ras_top_ctr
===
1.
U
)
{
commit_sp
:=
Mux
(
commit_sp
===
0.
U
,
0.
U
,
commit_sp
-
1.
U
)
}.
otherwise
{
commit_ras_top_ctr
:=
commit_ras_top_ctr
-
1.
U
}
}
val
copy_valid
=
io
.
recover
.
valid
&&
io
.
recover
.
bits
.
isMisPred
val
copy_next
=
RegNext
(
copy_valid
)
when
(
copy_next
)
{
for
(
i
<-
0
until
RasSize
)
{
spec_ras
(
i
)
:=
commit_ras
(
i
)
spec_sp
:=
commit_sp
}
}
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
commit_ras
.
copy_valid
:=
DontCare
commit_ras
.
copy_in_mem
:=
DontCare
commit_ras
.
copy_in_sp
:=
DontCare
if
(
BPUDebug
&&
debug
)
{
XSDebug
(
"----------------RAS(spec)----------------\n"
)
XSDebug
(
" index addr ctr \n"
)
for
(
i
<-
0
until
RasSize
){
XSDebug
(
" (%d) 0x%x %d"
,
i
.
U
,
spec_ras
(
i
).
retAddr
,
spec_ras
(
i
).
ctr
)
when
(
i
.
U
===
spec_sp
){
XSDebug
(
false
,
true
.
B
,
" <----sp"
)}
XSDebug
(
false
,
true
.
B
,
"\n"
)
}
XSDebug
(
"----------------RAS(commit)----------------\n"
)
XSDebug
(
" index addr ctr \n"
)
for
(
i
<-
0
until
RasSize
){
XSDebug
(
" (%d) 0x%x %d"
,
i
.
U
,
commit_ras
(
i
).
retAddr
,
commit_ras
(
i
).
ctr
)
when
(
i
.
U
===
commit_sp
){
XSDebug
(
false
,
true
.
B
,
" <----sp"
)}
XSDebug
(
false
,
true
.
B
,
"\n"
)
}
//no need to pass the ras branchInfo
io
.
branchInfo
.
rasSp
:=
DontCare
io
.
branchInfo
.
rasTopCtr
:=
DontCare
io
.
branchInfo
.
rasToqAddr
:=
DontCare
XSDebug
(
spec_push
,
"(spec_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n"
,
spec_ras_write
.
retAddr
,
spec_ras_write
.
ctr
,
sepc_alloc_new
,
spec_sp
.
asUInt
)
XSDebug
(
spec_pop
,
"(spec_ras)pop outValid:%d outAddr: 0x%x \n"
,
io
.
out
.
valid
,
io
.
out
.
bits
.
target
)
XSDebug
(
commit_push
,
"(commit_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n"
,
commit_ras_write
.
retAddr
,
commit_ras_write
.
ctr
,
sepc_alloc_new
,
commit_sp
.
asUInt
)
XSDebug
(
commit_pop
,
"(commit_ras)pop outValid:%d outAddr: 0x%x \n"
,
io
.
out
.
valid
,
io
.
out
.
bits
.
target
)
XSDebug
(
"copyValid:%d copyNext:%d \n"
,
copy_valid
,
copy_next
)
if
(
BPUDebug
&&
debug
)
{
// XSDebug("----------------RAS(spec)----------------\n")
// XSDebug(" index addr ctr \n")
// for(i <- 0 until RasSize){
// XSDebug(" (%d) 0x%x %d",i.U,spec_ras(i).retAddr,spec_ras(i).ctr)
// when(i.U === spec_sp){XSDebug(false,true.B," <----sp")}
// XSDebug(false,true.B,"\n")
// }
// XSDebug("----------------RAS(commit)----------------\n")
// XSDebug(" index addr ctr \n")
// for(i <- 0 until RasSize){
// XSDebug(" (%d) 0x%x %d",i.U,commit_ras(i).retAddr,commit_ras(i).ctr)
// when(i.U === commit_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_ras_write.retAddr,spec_ras_write.ctr,sepc_alloc_new,spec_sp.asUInt)
// XSDebug(spec_pop, "(spec_ras)pop outValid:%d outAddr: 0x%x \n",io.out.valid,io.out.bits.target)
// XSDebug(commit_push, "(commit_ras)push inAddr: 0x%x inCtr: %d | allocNewEntry:%d | sp:%d \n",commit_ras_write.retAddr,commit_ras_write.ctr,sepc_alloc_new,commit_sp.asUInt)
// XSDebug(commit_pop, "(commit_ras)pop outValid:%d outAddr: 0x%x \n",io.out.valid,io.out.bits.target)
// XSDebug("copyValid:%d copyNext:%d \n",copy_valid,copy_next)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录