Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
c3ece97f
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,发现更多精彩内容 >>
未验证
提交
c3ece97f
编写于
12月 17, 2020
作者:
S
Steve Gou
提交者:
GitHub
12月 17, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #329 from RISCVERS/ifu-timing
Ifu timing
上级
a733b931
e79b9380
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
68 addition
and
38 deletion
+68
-38
src/main/scala/utils/ParallelMux.scala
src/main/scala/utils/ParallelMux.scala
+25
-2
src/main/scala/utils/PriorityMuxGen.scala
src/main/scala/utils/PriorityMuxGen.scala
+19
-0
src/main/scala/xiangshan/Bundle.scala
src/main/scala/xiangshan/Bundle.scala
+9
-9
src/main/scala/xiangshan/frontend/IFU.scala
src/main/scala/xiangshan/frontend/IFU.scala
+15
-27
未找到文件。
src/main/scala/utils/ParallelMux.scala
浏览文件 @
c3ece97f
...
...
@@ -4,7 +4,7 @@ import chisel3._
import
chisel3.util._
object
ParallelOperation
{
def
apply
[
T
<:
Data
](
xs
:
Seq
[
T
],
func
:
(
T
,
T
)
=>
T
)
:
T
=
{
def
apply
[
T
](
xs
:
Seq
[
T
],
func
:
(
T
,
T
)
=>
T
)
:
T
=
{
require
(
xs
.
nonEmpty
)
xs
match
{
case
Seq
(
a
)
=>
a
...
...
@@ -21,12 +21,22 @@ object ParallelOR {
}
}
object
ParallelORR
{
def
apply
(
in
:
Seq
[
Bool
])
:
Bool
=
ParallelOR
(
in
)
def
apply
(
in
:
Bits
)
:
Bool
=
apply
(
in
.
asBools
)
}
object
ParallelAND
{
def
apply
[
T
<:
Data
](
xs
:
Seq
[
T
])
:
T
=
{
ParallelOperation
(
xs
,
(
a
:
T
,
b
:
T
)
=>
(
a
.
asUInt
()
&
b
.
asUInt
()).
asTypeOf
(
xs
.
head
))
}
}
object
ParallelANDR
{
def
apply
(
in
:
Seq
[
Bool
])
:
Bool
=
ParallelAND
(
in
)
def
apply
(
in
:
Bits
)
:
Bool
=
apply
(
in
.
asBools
)
}
object
ParallelMux
{
def
apply
[
T
<:
Data
](
in
:
Seq
[(
Bool
,
T
)])
:
T
=
{
val
xs
=
in
map
{
case
(
cond
,
x
)
=>
(
Fill
(
x
.
getWidth
,
cond
)
&
x
.
asUInt
()).
asTypeOf
(
in
.
head
.
_2
)
}
...
...
@@ -50,4 +60,17 @@ object ParallelMin {
def
apply
[
T
<:
Data
](
xs
:
Seq
[
T
])
:
T
=
{
ParallelOperation
(
xs
,
(
a
:
T
,
b
:
T
)
=>
Mux
(
a
.
asUInt
()
<
b
.
asUInt
(),
a
,
b
).
asTypeOf
(
xs
.
head
))
}
}
\ No newline at end of file
}
object
ParallelPriorityMux
{
def
apply
[
T
<:
Data
](
in
:
Seq
[(
Bool
,
T
)])
:
T
=
{
ParallelOperation
(
in
,
(
a
:
(
Bool
,
T
),
b
:
(
Bool
,
T
))
=>
(
a
.
_1
||
b
.
_1
,
Mux
(
a
.
_1
,
a
.
_2
,
b
.
_2
))).
_2
}
def
apply
[
T
<:
Data
](
sel
:
Bits
,
in
:
Seq
[
T
])
:
T
=
apply
((
0
until
in
.
size
).
map
(
sel
(
_
)),
in
)
def
apply
[
T
<:
Data
](
sel
:
Seq
[
Bool
],
in
:
Seq
[
T
])
:
T
=
apply
(
sel
zip
in
)
}
object
ParallelPriorityEncoder
{
def
apply
(
in
:
Seq
[
Bool
])
:
UInt
=
ParallelPriorityMux
(
in
,
(
0
until
in
.
size
).
map
(
_
.
asUInt
))
def
apply
(
in
:
Bits
)
:
UInt
=
apply
(
in
.
asBools
)
}
src/main/scala/utils/PriorityMuxGen.scala
0 → 100644
浏览文件 @
c3ece97f
package
utils
import
chisel3._
import
chisel3.util._
// this could be used to handle the situation
// in which we have mux sources at multiple
// locations, and this is same to multiple
// when clauses as below, but collect them
// and put them into a ParallelPrioriyMux
// when (sel1) { x := in1 }
// when (sel2) { x := in2 }
class
PriorityMuxGenerator
[
T
<:
Data
]
{
var
src
:
List
[(
Bool
,
T
)]
=
List
()
def
register
(
sel
:
Bool
,
in
:
T
)
=
src
=
(
sel
,
in
)
::
src
def
register
(
in
:
Seq
[(
Bool
,
T
)])
=
src
=
in
.
toList
:::
src
def
register
(
sel
:
Seq
[
Bool
],
in
:
Seq
[
T
])
=
src
=
(
sel
zip
in
).
toList
:::
src
def
apply
()
:
T
=
ParallelPriorityMux
(
src
)
}
\ No newline at end of file
src/main/scala/xiangshan/Bundle.scala
浏览文件 @
c3ece97f
...
...
@@ -90,7 +90,7 @@ class BranchPrediction extends XSBundle with HasIFUConst {
def
lastHalfRVIClearMask
=
~
lastHalfRVIMask
// is taken from half RVI
def
lastHalfRVITaken
=
(
takens
&
lastHalfRVIMask
).
orR
def
lastHalfRVITaken
=
ParallelORR
(
takens
&
lastHalfRVIMask
)
def
lastHalfRVIIdx
=
Mux
(
firstBankHasHalfRVI
,
(
bankWidth
-
1
).
U
,
(
PredictWidth
-
1
).
U
)
// should not be used if not lastHalfRVITaken
...
...
@@ -102,18 +102,18 @@ class BranchPrediction extends XSBundle with HasIFUConst {
def
brNotTakens
=
~
realTakens
&
realBrMask
def
sawNotTakenBr
=
VecInit
((
0
until
PredictWidth
).
map
(
i
=>
(
if
(
i
==
0
)
false
.
B
else
brNotTakens
(
i
-
1
,
0
).
orR
)))
(
if
(
i
==
0
)
false
.
B
else
ParallelORR
(
brNotTakens
(
i
-
1
,
0
))
)))
// def hasNotTakenBrs = (brNotTakens & LowerMaskFromLowest(realTakens)).orR
def
unmaskedJmpIdx
=
PriorityEncoder
(
takens
)
def
saveHalfRVI
=
(
firstBankHasHalfRVI
&&
(
unmaskedJmpIdx
===
(
bankWidth
-
1
).
U
||
!(
takens
.
orR
)))
||
def
unmaskedJmpIdx
=
P
arallelP
riorityEncoder
(
takens
)
def
saveHalfRVI
=
(
firstBankHasHalfRVI
&&
(
unmaskedJmpIdx
===
(
bankWidth
-
1
).
U
||
!(
ParallelORR
(
takens
)
)))
||
(
lastBankHasHalfRVI
&&
unmaskedJmpIdx
===
(
PredictWidth
-
1
).
U
)
// could get PredictWidth-1 when only the first bank is valid
def
jmpIdx
=
PriorityEncoder
(
realTakens
)
def
jmpIdx
=
P
arallelP
riorityEncoder
(
realTakens
)
// only used when taken
def
target
=
targets
(
jmpIdx
)
def
taken
=
realTakens
.
orR
def
takenOnBr
=
taken
&&
realBrMask
(
jmpIdx
)
def
hasNotTakenBrs
=
Mux
(
taken
,
sawNotTakenBr
(
jmpIdx
),
brNotTakens
.
orR
)
def
target
=
ParallelPriorityMux
(
realTakens
,
targets
)
def
taken
=
ParallelORR
(
realTakens
)
def
takenOnBr
=
taken
&&
ParallelPriorityMux
(
realTakens
,
realBrMask
.
asBools
)
def
hasNotTakenBrs
=
Mux
(
taken
,
ParallelPriorityMux
(
realTakens
,
sawNotTakenBr
),
ParallelORR
(
brNotTakens
)
)
}
class
BranchInfo
extends
XSBundle
with
HasBPUParameter
{
...
...
src/main/scala/xiangshan/frontend/IFU.scala
浏览文件 @
c3ece97f
...
...
@@ -140,23 +140,15 @@ class IFU extends XSModule with HasIFUConst
.
elsewhen
(
if2_flush
)
{
if2_valid
:=
false
.
B
}
.
elsewhen
(
if2_fire
)
{
if2_valid
:=
false
.
B
}
when
(
RegNext
(
reset
.
asBool
)
&&
!
reset
.
asBool
)
{
if1_npc
:=
resetVector
.
U
(
VAddrBits
.
W
)
}.
elsewhen
(
if2_fire
)
{
if1_npc
:=
if2_snpc
}.
otherwise
{
if1_npc
:=
RegNext
(
if1_npc
)
}
val
npcGen
=
new
PriorityMuxGenerator
[
UInt
]
npcGen
.
register
(
true
.
B
,
RegNext
(
if1_npc
))
npcGen
.
register
(
if2_fire
,
if2_snpc
)
val
if2_bp
=
bpu
.
io
.
out
(
0
)
// val if2_GHInfo = wrapGHInfo(if2_bp, if2_predHist)
// if taken, bp_redirect should be true
// when taken on half RVI, we suppress this redirect signal
if2_redirect
:=
if2_fire
&&
if2_bp
.
taken
when
(
if2_redirect
)
{
if1_npc
:=
if2_bp
.
target
}
npcGen
.
register
(
if2_redirect
,
if2_bp
.
target
)
if2_predicted_gh
:=
if2_gh
.
update
(
if2_bp
.
hasNotTakenBrs
,
if2_bp
.
takenOnBr
)
...
...
@@ -166,7 +158,6 @@ class IFU extends XSModule with HasIFUConst
val
if3_fire
=
if3_valid
&&
if4_ready
&&
(
inLoop
||
io
.
icacheResp
.
valid
)
&&
!
if3_flush
val
if3_pc
=
RegEnable
(
if2_pc
,
if2_fire
)
val
if3_predHist
=
RegEnable
(
if2_predHist
,
enable
=
if2_fire
)
// val if3_nextValidPC = Mux(if2_valid)
if3_ready
:=
if3_fire
||
!
if3_valid
||
if3_flush
when
(
if3_flush
)
{
if3_valid
:=
false
.
B
}
.
elsewhen
(
if2_fire
)
{
if3_valid
:=
true
.
B
}
...
...
@@ -181,7 +172,7 @@ class IFU extends XSModule with HasIFUConst
val
hasPrevHalfInstrReq
=
prevHalfInstrReq
.
valid
val
if3_prevHalfInstr
=
RegInit
(
0.
U
.
asTypeOf
(
new
PrevHalfInstr
))
// val if4_prevHalfInstr = Wire(new PrevHalfInstr)
// 32-bit instr crosses 2 pages, and the higher 16-bit triggers page fault
val
crossPageIPF
=
WireInit
(
false
.
B
)
...
...
@@ -238,10 +229,11 @@ class IFU extends XSModule with HasIFUConst
// }.elsewhen (if3_ghInfoNotIdenticalRedirect) {
// if3_target := Mux(if3_bp.taken, if3_bp.target, snpc(if3_pc))
// }
npcGen
.
register
(
if3_redirect
,
if3_target
)
when
(
if3_redirect
)
{
if1_npc
:=
if3_target
}
//
when (if3_redirect) {
//
if1_npc := if3_target
//
}
//********************** IF4 ****************************//
val
if4_pd
=
RegEnable
(
pd
.
io
.
out
,
if3_fire
)
...
...
@@ -350,9 +342,7 @@ class IFU extends XSModule with HasIFUConst
// }.elsewhen (if4_ghInfoNotIdenticalRedirect) {
// if4_target := Mux(if4_bp.taken, if4_bp.target, if4_snpc)
// }
when
(
if4_redirect
)
{
if1_npc
:=
if4_target
}
npcGen
.
register
(
if4_redirect
,
if4_target
)
when
(
if4_fire
)
{
final_gh
:=
if4_predicted_gh
...
...
@@ -378,13 +368,11 @@ class IFU extends XSModule with HasIFUConst
flush_final_gh
:=
true
.
B
}
when
(
loopBufPar
.
LBredirect
.
valid
)
{
if1_npc
:=
loopBufPar
.
LBredirect
.
bits
}
npcGen
.
register
(
loopBufPar
.
LBredirect
.
valid
,
loopBufPar
.
LBredirect
.
bits
)
npcGen
.
register
(
io
.
redirect
.
valid
,
io
.
redirect
.
bits
)
npcGen
.
register
(
RegNext
(
reset
.
asBool
)
&&
!
reset
.
asBool
,
resetVector
.
U
(
VAddrBits
.
W
))
when
(
io
.
redirect
.
valid
)
{
if1_npc
:=
io
.
redirect
.
bits
}
if1_npc
:=
npcGen
()
when
(
inLoop
)
{
io
.
icacheReq
.
valid
:=
if4_flush
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录