Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
f04ed0d5
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,发现更多精彩内容 >>
未验证
提交
f04ed0d5
编写于
6月 27, 2020
作者:
L
ljw
提交者:
GitHub
6月 27, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Revert "Ibuf"
上级
16e27c9a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
155 addition
and
166 deletion
+155
-166
src/main/scala/xiangshan/Bundle.scala
src/main/scala/xiangshan/Bundle.scala
+1
-1
src/main/scala/xiangshan/frontend/FakeIFU.scala
src/main/scala/xiangshan/frontend/FakeIFU.scala
+1
-1
src/main/scala/xiangshan/frontend/Ibuffer.scala
src/main/scala/xiangshan/frontend/Ibuffer.scala
+153
-164
未找到文件。
src/main/scala/xiangshan/Bundle.scala
浏览文件 @
f04ed0d5
...
@@ -8,7 +8,7 @@ import xiangshan.backend.rename.FreeListPtr
...
@@ -8,7 +8,7 @@ import xiangshan.backend.rename.FreeListPtr
// Fetch FetchWidth x 32-bit insts from Icache
// Fetch FetchWidth x 32-bit insts from Icache
class
FetchPacket
extends
XSBundle
{
class
FetchPacket
extends
XSBundle
{
val
instrs
=
Vec
(
FetchWidth
,
UInt
(
32.
W
))
val
instrs
=
Vec
(
FetchWidth
,
UInt
(
32.
W
))
val
mask
=
UInt
(
(
FetchWidth
*
2
)
.
W
)
val
mask
=
UInt
(
FetchWidth
.
W
)
val
pc
=
UInt
(
VAddrBits
.
W
)
// the pc of first inst in the fetch group
val
pc
=
UInt
(
VAddrBits
.
W
)
// the pc of first inst in the fetch group
}
}
...
...
src/main/scala/xiangshan/frontend/FakeIFU.scala
浏览文件 @
f04ed0d5
...
@@ -69,7 +69,7 @@ class FakeIFU extends XSModule with HasIFUConst {
...
@@ -69,7 +69,7 @@ class FakeIFU extends XSModule with HasIFUConst {
fakeCache
.
io
.
addr
:=
pc
fakeCache
.
io
.
addr
:=
pc
io
.
fetchPacket
.
valid
:=
!
io
.
redirect
.
valid
io
.
fetchPacket
.
valid
:=
!
io
.
redirect
.
valid
io
.
fetchPacket
.
bits
.
mask
:=
Fill
(
FetchWidth
*
2
,
1.
U
(
1.
W
))
<<
pc
(
log2Up
(
FetchWidth
*
2
),
1
)
io
.
fetchPacket
.
bits
.
mask
:=
Fill
(
FetchWidth
,
1.
U
(
1.
W
))
<<
pc
(
2
+
log2Up
(
FetchWidth
)-
1
,
2
)
io
.
fetchPacket
.
bits
.
pc
:=
pc
io
.
fetchPacket
.
bits
.
pc
:=
pc
io
.
fetchPacket
.
bits
.
instrs
:=
fakeCache
.
io
.
rdata
io
.
fetchPacket
.
bits
.
instrs
:=
fakeCache
.
io
.
rdata
...
...
src/main/scala/xiangshan/frontend/Ibuffer.scala
浏览文件 @
f04ed0d5
package
xiangshan.frontend
package
xiangshan.frontend
import
chisel3._
import
chisel3._
import
chisel3.util._
import
chisel3.util._
import
xiangshan._
import
xiangshan._
import
xiangshan.utils._
import
xiangshan.utils._
class
Ibuffer
extends
XSModule
{
class
Ibuffer
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
val
io
=
IO
(
new
Bundle
()
{
val
flush
=
Input
(
Bool
())
val
flush
=
Input
(
Bool
())
val
in
=
Flipped
(
DecoupledIO
(
new
FetchPacket
))
val
in
=
Flipped
(
DecoupledIO
(
new
FetchPacket
))
val
out
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
val
out
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
})
})
when
(
io
.
in
.
valid
)
{
when
(
io
.
in
.
valid
)
{
XSDebug
(
"cache data\n"
)
XSDebug
(
"cache data\n"
)
for
(
i
<-
0
until
FetchWidth
)
{
for
(
i
<-
0
until
FetchWidth
)
{
XSDebug
(
"%b\n"
,
io
.
in
.
bits
.
instrs
(
i
))
XSDebug
(
"%b\n"
,
io
.
in
.
bits
.
instrs
(
i
))
}
}
}
}
// ignore
// ignore
for
(
i
<-
0
until
DecodeWidth
)
{
for
(
i
<-
0
until
DecodeWidth
)
{
io
.
out
(
i
).
bits
.
exceptionVec
:=
DontCare
io
.
out
(
i
).
bits
.
exceptionVec
:=
DontCare
io
.
out
(
i
).
bits
.
intrVec
:=
DontCare
io
.
out
(
i
).
bits
.
intrVec
:=
DontCare
io
.
out
(
i
).
bits
.
isBr
:=
DontCare
io
.
out
(
i
).
bits
.
isBr
:=
DontCare
}
}
//mask initial
// ibuf define
// val mask = Wire(Vec(FetchWidth*2, false.B))
val
ibuf
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
0.
U
(
16.
W
))))
// (0 until 16).map(i => mask(i.U) := (io.in.bits.pc(4,1) <= i.U))
val
ibuf_pc
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
0.
U
(
VAddrBits
.
W
))))
val
ibuf_valid
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
false
.
B
)))
// ibuf define
val
head_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
val
ibuf
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
0.
U
(
16.
W
))))
val
tail_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
val
ibuf_pc
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
0.
U
(
VAddrBits
.
W
))))
val
ibuf_valid
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
false
.
B
)))
// true: Last operation is enqueue
val
head_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
// false: Last operation is deq_ueue
val
tail_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
val
last_enq
=
RegInit
(
false
.
B
)
val
full
=
head_ptr
===
tail_ptr
&&
last_enq
// true: Last operation is enqueue
val
empty
=
head_ptr
===
tail_ptr
&&
!
last_enq
// false: Last operation is deq_ueue
val
enqValid
=
!
io
.
flush
&&
io
.
in
.
valid
&&
!
full
&&
!
ibuf_valid
(
tail_ptr
+
(
FetchWidth
*
2
).
U
)
val
last_enq
=
RegInit
(
false
.
B
)
val
deqValid
=
!
io
.
flush
&&
!
empty
//&& io.out.map(_.ready).reduce(_||_)
val
full
=
head_ptr
===
tail_ptr
&&
last_enq
val
empty
=
head_ptr
===
tail_ptr
&&
!
last_enq
io
.
in
.
ready
:=
enqValid
val
enqValid
=
!
io
.
flush
&&
io
.
in
.
valid
&&
!
full
&&
!
ibuf_valid
(
tail_ptr
+
(
FetchWidth
*
2
).
U
)
val
deqValid
=
!
io
.
flush
&&
!
empty
//&& io.out.map(_.ready).reduce(_||_)
// enque
when
(
enqValid
)
{
XSWarn
(
empty
,
"Ibuffer is empty\n"
)
XSInfo
(
"Enque start\n"
)
XSWarn
(
full
,
"Ibuffer is full\n"
)
io
.
in
.
ready
:=
enqValid
var
enq_idx
=
0.
U
(
log2Up
(
FetchWidth
*
2
+
1
).
W
)
for
(
i
<-
0
until
FetchWidth
)
{
// enque
when
(
io
.
in
.
bits
.
mask
(
i
))
{
when
(
enqValid
)
{
ibuf
(
tail_ptr
+
enq_idx
)
:=
io
.
in
.
bits
.
instrs
(
i
)(
15
,
0
)
XSInfo
(
"Enque start\n"
)
ibuf_pc
(
tail_ptr
+
enq_idx
)
:=
io
.
in
.
bits
.
pc
+
enq_idx
+
enq_idx
ibuf_valid
(
tail_ptr
+
enq_idx
)
:=
true
.
B
var
enq_idx
=
0.
U
(
log2Up
(
FetchWidth
*
2
+
1
).
W
)
for
(
i
<-
0
until
FetchWidth
*
2
)
{
ibuf
(
tail_ptr
+
enq_idx
+
1.
U
)
:=
io
.
in
.
bits
.
instrs
(
i
)(
31
,
16
)
when
(
io
.
in
.
bits
.
mask
(
i
))
{
ibuf_pc
(
tail_ptr
+
enq_idx
+
1.
U
)
:=
io
.
in
.
bits
.
pc
+
enq_idx
+
enq_idx
+
2.
U
ibuf
(
tail_ptr
+
enq_idx
)
:=
Mux
(
i
.
U
(
0
),
io
.
in
.
bits
.
instrs
(
i
>>
1
)(
31
,
16
),
io
.
in
.
bits
.
instrs
(
i
>>
1
)(
15
,
0
))
ibuf_valid
(
tail_ptr
+
enq_idx
+
1.
U
)
:=
true
.
B
ibuf_pc
(
tail_ptr
+
enq_idx
)
:=
io
.
in
.
bits
.
pc
+
enq_idx
<<
1
ibuf_valid
(
tail_ptr
+
enq_idx
)
:=
true
.
B
XSDebug
(
"Enque: %b\n"
,
io
.
in
.
bits
.
instrs
(
i
)(
15
,
0
))
XSDebug
(
"Enque: %b\n"
,
io
.
in
.
bits
.
instrs
(
i
)(
31
,
16
))
XSDebug
(
"Enque: %b\n"
,
Mux
(
i
.
U
(
0
),
io
.
in
.
bits
.
instrs
(
i
>>
1
)(
31
,
16
),
io
.
in
.
bits
.
instrs
(
i
>>
1
)(
15
,
0
)))
}
}
enq_idx
=
enq_idx
+
io
.
in
.
bits
.
mask
(
i
)
+
io
.
in
.
bits
.
mask
(
i
)
enq_idx
=
enq_idx
+
io
.
in
.
bits
.
mask
(
i
)
}
}
tail_ptr
:=
tail_ptr
+
enq_idx
tail_ptr
:=
tail_ptr
+
enq_idx
last_enq
:=
true
.
B
last_enq
:=
true
.
B
XSInfo
(
"Enque finished, tail_ptr=%d\n"
,
tail_ptr
+
enq_idx
)
XSInfo
(
"Enque finished, tail_ptr=%d\n"
,
tail_ptr
+
enq_idx
)
}
}
// deque
// deque
when
(
deqValid
)
{
when
(
deqValid
)
{
XSInfo
(
"Deque start\n"
)
XSInfo
(
"Deque start\n"
)
var
deq_idx
=
0.
U
(
log2Up
(
DecodeWidth
*
2
+
1
).
W
)
var
deq_idx
=
0.
U
(
log2Up
(
DecodeWidth
*
2
+
1
).
W
)
for
(
i
<-
0
until
DecodeWidth
)
{
for
(
i
<-
0
until
DecodeWidth
)
{
when
(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
))
{
when
(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
))
{
when
(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
{
when
(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
{
// is RVC
// is RVC
io
.
out
(
i
).
bits
.
instr
:=
Cat
(
0.
U
(
16.
W
),
ibuf
(
head_ptr
+
deq_idx
))
io
.
out
(
i
).
bits
.
instr
:=
Cat
(
0.
U
(
16.
W
),
ibuf
(
head_ptr
+
deq_idx
))
io
.
out
(
i
).
bits
.
pc
:=
ibuf_pc
(
head_ptr
+
deq_idx
)
io
.
out
(
i
).
bits
.
pc
:=
ibuf_pc
(
head_ptr
+
deq_idx
)
XSDebug
(
"%b[RVC] PC=%d\n"
,
Cat
(
0.
U
(
16.
W
),
ibuf
(
head_ptr
+
deq_idx
)),
ibuf_pc
(
head_ptr
+
deq_idx
))
XSDebug
(
"%b[RVC] PC=%d\n"
,
Cat
(
0.
U
(
16.
W
),
ibuf
(
head_ptr
+
deq_idx
)),
ibuf_pc
(
head_ptr
+
deq_idx
))
io
.
out
(
i
).
bits
.
isRVC
:=
true
.
B
io
.
out
(
i
).
valid
:=
true
.
B
ibuf_valid
(
head_ptr
+
deq_idx
)
:=
false
.
B
io
.
out
(
i
).
bits
.
isRVC
:=
true
.
B
}.
elsewhen
(
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
))
{
io
.
out
(
i
).
valid
:=
true
.
B
// isn't RVC
ibuf_valid
(
head_ptr
+
deq_idx
)
:=
false
.
B
io
.
out
(
i
).
bits
.
instr
:=
Cat
(
ibuf
(
head_ptr
+
deq_idx
+
1.
U
),
ibuf
(
head_ptr
+
deq_idx
))
}.
elsewhen
(
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
))
{
io
.
out
(
i
).
bits
.
pc
:=
ibuf_pc
(
head_ptr
+
deq_idx
)
// isn't RVC
XSDebug
(
"%b[NORVC] PC=%d\n"
,
Cat
(
ibuf
(
head_ptr
+
deq_idx
+
1.
U
),
ibuf
(
head_ptr
+
deq_idx
)),
ibuf_pc
(
head_ptr
+
deq_idx
))
io
.
out
(
i
).
bits
.
instr
:=
Cat
(
ibuf
(
head_ptr
+
deq_idx
+
1.
U
),
ibuf
(
head_ptr
+
deq_idx
))
io
.
out
(
i
).
bits
.
pc
:=
ibuf_pc
(
head_ptr
+
deq_idx
)
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
true
.
B
XSDebug
(
"%b[NORVC] PC=%d\n"
,
Cat
(
ibuf
(
head_ptr
+
deq_idx
+
1.
U
),
ibuf
(
head_ptr
+
deq_idx
)),
ibuf_pc
(
head_ptr
+
deq_idx
))
ibuf_valid
(
head_ptr
+
deq_idx
)
:=
false
.
B
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
)
:=
false
.
B
}.
otherwise
{
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
// half inst keep in buffer
io
.
out
(
i
).
valid
:=
true
.
B
io
.
out
(
i
).
bits
.
instr
:=
0.
U
(
32.
W
)
ibuf_valid
(
head_ptr
+
deq_idx
)
:=
false
.
B
XSWarn
(
"This is half inst\n"
)
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
)
:=
false
.
B
}.
otherwise
{
io
.
out
(
i
).
bits
.
pc
:=
0.
U
(
VAddrBits
.
W
)
// half inst keep in buffer
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
io
.
out
(
i
).
bits
.
instr
:=
0.
U
(
32.
W
)
io
.
out
(
i
).
valid
:=
false
.
B
XSWarn
(
"This is half inst\n"
)
}
}.
otherwise
{
io
.
out
(
i
).
bits
.
pc
:=
0.
U
(
VAddrBits
.
W
)
XSWarn
(
"This output is not ready, or buffer is empty\n"
)
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
false
.
B
io
.
out
(
i
).
bits
.
instr
:=
0.
U
}
io
.
out
(
i
).
bits
.
pc
:=
0.
U
}.
otherwise
{
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
XSWarn
(
"This output is not ready, or buffer is empty\n"
)
io
.
out
(
i
).
valid
:=
false
.
B
}
io
.
out
(
i
).
bits
.
instr
:=
0.
U
io
.
out
(
i
).
bits
.
pc
:=
0.
U
// When can't deque, deq_idx+0
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
// when RVC deque, deq_idx+1
io
.
out
(
i
).
valid
:=
false
.
B
// when not RVC deque, deq_idx+2
}
// when only have half inst, keep it in buffer
deq_idx
=
deq_idx
+
// When can't deque, deq_idx+0
(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
)
&&
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
+
// when RVC deque, deq_idx+1
(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
)
&&
!(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
&&
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
))
+
// when not RVC deque, deq_idx+2
(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
)
&&
!(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
&&
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
))
// when only have half inst, keep it in buffer
}
//deq_idx = deq_idx +
head_ptr
:=
head_ptr
+
deq_idx
// (io.out(i).ready && ibuf_valid(head_ptr + deq_idx) && ibuf(head_ptr + deq_idx)(1,0) =/= "b11".U) +
// (io.out(i).ready && ibuf_valid(head_ptr + deq_idx) && !(ibuf(head_ptr + deq_idx)(1,0) =/= "b11".U) && ibuf_valid(head_ptr + deq_idx + 1.U)) +
XSInfo
(
"Deque finished\n"
)
// (io.out(i).ready && ibuf_valid(head_ptr + deq_idx) && !(ibuf(head_ptr + deq_idx)(1,0) =/= "b11".U) && ibuf_valid(head_ptr + deq_idx + 1.U))
XSInfo
(
"head_prt=%d, tail_ptr=%d\n"
,
head_ptr
+
deq_idx
,
tail_ptr
)
last_enq
:=
false
.
B
deq_idx
=
deq_idx
+
PriorityMux
(
Seq
(
}.
otherwise
{
!(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
))
->
0.
U
,
for
(
i
<-
0
until
DecodeWidth
)
{
(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
->
1.
U
,
io
.
out
(
i
).
bits
.
instr
:=
0.
U
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
)
->
2.
U
io
.
out
(
i
).
bits
.
pc
:=
0.
U
))
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
}
io
.
out
(
i
).
valid
:=
false
.
B
head_ptr
:=
head_ptr
+
deq_idx
}
}
XSInfo
(
"Deque finished\n"
)
XSInfo
(
"head_prt=%d, tail_ptr=%d\n"
,
head_ptr
+
deq_idx
,
tail_ptr
)
// flush
last_enq
:=
false
.
B
when
(
io
.
flush
)
{
}.
otherwise
{
XSInfo
(
"Flush signal received, clear buffer\n"
)
for
(
i
<-
0
until
DecodeWidth
)
{
for
(
i
<-
0
until
IBufSize
)
{
io
.
out
(
i
).
bits
.
instr
:=
0.
U
ibuf_valid
(
i
)
:=
false
.
B
io
.
out
(
i
).
bits
.
pc
:=
0.
U
head_ptr
:=
0.
U
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
tail_ptr
:=
0.
U
io
.
out
(
i
).
valid
:=
false
.
B
}
}
}
for
(
i
<-
0
until
DecodeWidth
)
{
io
.
out
(
i
).
valid
:=
false
.
B
// flush
}
when
(
io
.
flush
)
{
}
XSInfo
(
"Flush signal received, clear buffer\n"
)
for
(
i
<-
0
until
IBufSize
)
{
ibuf_valid
(
i
)
:=
false
.
B
head_ptr
:=
0.
U
tail_ptr
:=
0.
U
}
for
(
i
<-
0
until
DecodeWidth
)
{
io
.
out
(
i
).
valid
:=
false
.
B
}
}
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录