Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
583a68ce
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 搜索 >>
未验证
提交
583a68ce
编写于
6月 26, 2020
作者:
张
张发旺
提交者:
GitHub
6月 26, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into ibuf
上级
2151df3f
4e2453fb
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
338 addition
and
236 deletion
+338
-236
Makefile
Makefile
+4
-1
debug/Makefile
debug/Makefile
+6
-1
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+0
-1
src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala
src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala
+1
-1
src/main/scala/xiangshan/backend/decode/DecodeStage.scala
src/main/scala/xiangshan/backend/decode/DecodeStage.scala
+5
-5
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
+6
-2
src/main/scala/xiangshan/backend/dispatch/Dispatch2.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch2.scala
+7
-6
src/main/scala/xiangshan/backend/exu/Exu.scala
src/main/scala/xiangshan/backend/exu/Exu.scala
+14
-1
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
+33
-33
src/main/scala/xiangshan/backend/rename/BusyTable.scala
src/main/scala/xiangshan/backend/rename/BusyTable.scala
+7
-1
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+26
-7
src/main/scala/xiangshan/frontend/Ibuffer.scala
src/main/scala/xiangshan/frontend/Ibuffer.scala
+164
-160
src/main/scala/xiangshan/utils/LogUtils.scala
src/main/scala/xiangshan/utils/LogUtils.scala
+14
-9
src/test/csrc/common.h
src/test/csrc/common.h
+12
-0
src/test/csrc/emu.h
src/test/csrc/emu.h
+6
-3
src/test/csrc/log.cpp
src/test/csrc/log.cpp
+22
-0
src/test/csrc/main.cpp
src/test/csrc/main.cpp
+6
-3
src/test/scala/top/XSSim.scala
src/test/scala/top/XSSim.scala
+5
-2
未找到文件。
Makefile
浏览文件 @
583a68ce
...
...
@@ -86,11 +86,14 @@ $(EMU): $(EMU_MK) $(EMU_DEPS) $(EMU_HEADERS) $(REF_SO)
SEED
=
-s
$(
shell
seq
1 10000 |
shuf
|
head
-n
1
)
# log will only be printed when (B<=GTimer<=E) && (L < loglevel)
# use 'emu -h' to see more details
B
?=
0
E
?=
-1
L
?=
ALL
emu
:
$(EMU)
@
$(EMU)
-i
$(IMAGE)
$(SEED)
-b
$(B)
-e
$(E)
@
$(EMU)
-i
$(IMAGE)
$(SEED)
-b
$(B)
-e
$(E)
-l
$(L)
cache
:
$(MAKE)
emu
IMAGE
=
Makefile
...
...
debug/Makefile
浏览文件 @
583a68ce
...
...
@@ -2,12 +2,17 @@ ARCH = ARCH=riscv64-noop
NANOS_HOME
?=
$(AM_HOME)
/../nanos-lite
SINGLETEST
=
ALL
=
min3
B
?=
0
E
?=
-1
L
?=
ALL
EMU_ARGS
=
B
=
$(B)
E
=
$(E)
L
=
$(L)
# ------------------------------------------------------------------
# bulid CPU and run dummy test
# ------------------------------------------------------------------
cpu
:
$(MAKE)
-C
$(AM_HOME)
/tests/cputest
$(ARCH)
ALL
=
dummy run
$(MAKE)
-C
$(AM_HOME)
/tests/cputest
$(ARCH)
ALL
=
dummy
$(EMU_ARGS)
run
# ------------------------------------------------------------------
# run different test sets
...
...
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
583a68ce
...
...
@@ -11,7 +11,6 @@ import xiangshan.frontend.Frontend
import
xiangshan.utils._
trait
HasXSParameter
{
val
LogLevel
=
XSLogLevel
.
ALL
val
XLEN
=
64
val
HasMExtension
=
true
val
HasCExtension
=
true
...
...
src/main/scala/xiangshan/backend/decode/DecodeBuffer.scala
浏览文件 @
583a68ce
...
...
@@ -5,7 +5,7 @@ import chisel3.util._
import
xiangshan._
import
xiangshan.utils._
class
DecodeBuffer
extends
XSModule
with
NeedImpl
{
class
DecodeBuffer
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
val
redirect
=
Flipped
(
ValidIO
(
new
Redirect
))
val
in
=
Vec
(
DecodeWidth
,
Flipped
(
DecoupledIO
(
new
CfCtrl
)))
...
...
src/main/scala/xiangshan/backend/decode/DecodeStage.scala
浏览文件 @
583a68ce
...
...
@@ -36,16 +36,16 @@ class DecodeStage extends XSModule {
decoderToBrq
(
i
)
:=
decoders
(
i
).
io
.
out
// CfCtrl without bfTag and brMask
// send CfCtrl without brTags and brMasks to brq
io
.
toBrq
(
i
).
valid
:=
io
.
in
(
i
).
valid
&&
io
.
out
(
i
).
ready
&&
decoders
(
i
).
io
.
out
.
cf
.
isBr
XSDebug
(
io
.
toBrq
(
i
).
valid
&&
io
.
toBrq
(
i
).
ready
,
p
"Branch instr detected. Sending it to BRQ."
)
XSDebug
(
io
.
toBrq
(
i
).
valid
&&
!
io
.
toBrq
(
i
).
ready
,
p
"Branch instr detected. BRQ full...waiting"
)
XSDebug
(
io
.
in
(
i
).
valid
&&
!
io
.
out
(
i
).
ready
,
p
"DecBuf full...waiting"
)
XSDebug
(
io
.
toBrq
(
i
).
valid
&&
io
.
toBrq
(
i
).
ready
,
p
"Branch instr detected. Sending it to BRQ.
\n
"
)
XSDebug
(
io
.
toBrq
(
i
).
valid
&&
!
io
.
toBrq
(
i
).
ready
,
p
"Branch instr detected. BRQ full...waiting
\n
"
)
XSDebug
(
io
.
in
(
i
).
valid
&&
!
io
.
out
(
i
).
ready
,
p
"DecBuf full...waiting
\n
"
)
decoderToBrq
(
i
).
brMask
:=
DontCare
decoderToBrq
(
i
).
brTag
:=
DontCare
io
.
toBrq
(
i
).
bits
:=
decoderToBrq
(
i
)
// if brq returns ready, then assert valid and send CfCtrl with bfTag and brMask to DecBuffer
io
.
out
(
i
).
valid
:=
io
.
toBrq
(
i
).
ready
&&
io
.
in
(
i
).
valid
XSDebug
(
io
.
out
(
i
).
valid
&&
decoders
(
i
).
io
.
out
.
cf
.
isBr
&&
io
.
out
(
i
).
ready
,
p
"Sending branch instr to DecBuf"
)
XSDebug
(
io
.
out
(
i
).
valid
&&
!
decoders
(
i
).
io
.
out
.
cf
.
isBr
&&
io
.
out
(
i
).
ready
,
p
"Sending non-branch instr to DecBuf"
)
XSDebug
(
io
.
out
(
i
).
valid
&&
decoders
(
i
).
io
.
out
.
cf
.
isBr
&&
io
.
out
(
i
).
ready
,
p
"Sending branch instr to DecBuf
\n
"
)
XSDebug
(
io
.
out
(
i
).
valid
&&
!
decoders
(
i
).
io
.
out
.
cf
.
isBr
&&
io
.
out
(
i
).
ready
,
p
"Sending non-branch instr to DecBuf
\n
"
)
decoderToDecBuffer
(
i
)
:=
decoders
(
i
).
io
.
out
decoderToDecBuffer
(
i
).
brTag
:=
io
.
brTags
(
i
)
decoderToDecBuffer
(
i
).
brMask
:=
io
.
brMasks
(
i
)
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
浏览文件 @
583a68ce
...
...
@@ -3,7 +3,7 @@ package xiangshan.backend.dispatch
import
chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.utils.
{
XSDebug
,
XSInfo
}
import
xiangshan.utils.
{
XSDebug
,
XSInfo
,
XSWarn
}
case
class
DP1Config
(
...
...
@@ -72,7 +72,6 @@ class Dispatch1 extends XSModule{
for
(
i
<-
0
until
RenameWidth
)
{
uop_nroq
(
i
)
:=
io
.
fromRename
(
i
).
bits
uop_nroq
(
i
).
roqIdx
:=
Mux
(
io
.
toRoq
(
i
).
ready
,
io
.
roqIdxs
(
i
),
roqIndexReg
(
i
))
XSDebug
(
io
.
toRoq
(
i
).
fire
(),
"instruction 0x%x receives nroq %d\n"
,
io
.
fromRename
(
i
).
bits
.
cf
.
pc
,
io
.
roqIdxs
(
i
))
}
// uop can enqueue when rename.valid and roq.valid
...
...
@@ -93,6 +92,11 @@ class Dispatch1 extends XSModule{
for
(
i
<-
0
until
RenameWidth
)
{
io
.
toRoq
(
i
).
bits
<>
io
.
fromRename
(
i
).
bits
io
.
toRoq
(
i
).
valid
:=
io
.
fromRename
(
i
).
valid
&&
!
roqIndexRegValid
(
i
)
XSDebug
(
io
.
toRoq
(
i
).
fire
(),
"instruction 0x%x receives nroq %d\n"
,
io
.
fromRename
(
i
).
bits
.
cf
.
pc
,
io
.
roqIdxs
(
i
))
if
(
i
>
0
)
{
XSWarn
(
io
.
toRoq
(
i
).
fire
()
&&
!
io
.
toRoq
(
i
-
1
).
ready
&&
io
.
toRoq
(
i
-
1
).
valid
,
"roq handshake not continuous %d"
,
i
.
U
)
}
io
.
fromRename
(
i
).
ready
:=
all_recv
XSDebug
(
io
.
fromRename
(
i
).
valid
,
"instruction 0x%x of type %b is in %d-th slot\n"
,
io
.
fromRename
(
i
).
bits
.
cf
.
pc
,
io
.
fromRename
(
i
).
bits
.
ctrl
.
fuType
,
i
.
U
)
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch2.scala
浏览文件 @
583a68ce
...
...
@@ -6,7 +6,7 @@ import xiangshan._
import
xiangshan.backend.regfile.RfReadPort
import
xiangshan.utils.
{
XSDebug
,
XSInfo
}
class
Dispatch2
extends
XSModule
with
NeedImpl
{
class
Dispatch2
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
// from dispatch queues
val
fromIntDq
=
Flipped
(
Vec
(
IntDqDeqWidth
,
DecoupledIO
(
new
MicroOp
)))
...
...
@@ -116,8 +116,8 @@ class Dispatch2 extends XSModule with NeedImpl {
enq
.
bits
.
src2State
:=
io
.
intPregRdy
(
11
)
}
XSInfo
(
enq
.
fire
(),
"instruction 0x%x with type %b enters reservation station %d from %d\n"
,
enq
.
bits
.
cf
.
pc
,
enq
.
bits
.
ctrl
.
fuType
,
i
.
U
,
instIdxes
(
i
))
XSInfo
(
enq
.
fire
(),
"instruction 0x%x with type %b
srcState(%d %d %d)
enters reservation station %d from %d\n"
,
enq
.
bits
.
cf
.
pc
,
enq
.
bits
.
ctrl
.
fuType
,
enq
.
bits
.
src1State
,
enq
.
bits
.
src2State
,
enq
.
bits
.
src3State
,
i
.
U
,
instIdxes
(
i
))
}
// responds to dispatch queue
...
...
@@ -221,9 +221,10 @@ class Dispatch2 extends XSModule with NeedImpl {
io
.
enqIQData
(
i
).
bits
.
src3
:=
Mux
(
index_reg
(
i
)(
2
),
0.
U
,
src3
)
XSDebug
(
io
.
enqIQData
(
i
).
valid
,
"instruction 0x%x reads operands from (%d, %d, %x), (%d, %d, %x), (%d, %d, %x)\n"
,
io
.
enqIQData
(
i
).
bits
.
uop
.
cf
.
pc
,
src1Type
(
i
),
src1Index
(
i
),
src1
,
src2Type
(
i
),
src2Index
(
i
),
src2
,
src3Type
(
i
),
src3Index
(
i
),
src3
)
"instruction 0x%x reads operands from (%d, %d, %d, %x), (%d, %d, %d, %x), (%d, %d, %d, %x)\n"
,
io
.
enqIQData
(
i
).
bits
.
uop
.
cf
.
pc
,
src1Type
(
i
),
src1Index
(
i
),
io
.
enqIQData
(
i
).
bits
.
uop
.
psrc1
,
src1
,
src2Type
(
i
),
src2Index
(
i
),
io
.
enqIQData
(
i
).
bits
.
uop
.
psrc2
,
src2
,
src3Type
(
i
),
src3Index
(
i
),
io
.
enqIQData
(
i
).
bits
.
uop
.
psrc3
,
src3
)
}
}
src/main/scala/xiangshan/backend/exu/Exu.scala
浏览文件 @
583a68ce
...
...
@@ -108,11 +108,24 @@ trait HasExeUnits{
exeUnits
.
foreach
(
_
.
io
.
dmem
:=
DontCare
)
}
class
WriteBackArbMtoN
(
m
:
Int
,
n
:
Int
)
extends
XSModule
with
NeedImpl
{
class
WriteBackArbMtoN
(
m
:
Int
,
n
:
Int
)
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
val
in
=
Vec
(
m
,
Flipped
(
DecoupledIO
(
new
ExuOutput
)))
val
out
=
Vec
(
n
,
ValidIO
(
new
ExuOutput
))
})
// TODO: arbiter logic
for
(
i
<-
0
until
m
)
{
io
.
in
(
i
).
ready
:=
false
.
B
}
io
.
out
<>
DontCare
for
(
i
<-
0
until
4
)
{
io
.
out
(
i
).
valid
:=
io
.
in
(
i
+
1
).
valid
io
.
out
(
i
).
bits
:=
io
.
in
(
i
+
1
).
bits
io
.
in
(
i
+
1
).
ready
:=
true
.
B
}
}
...
...
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
浏览文件 @
583a68ce
...
...
@@ -8,9 +8,6 @@ import xiangshan.utils._
trait
IQConst
{
val
iqSize
=
8
val
iqIdxWidth
=
log2Up
(
iqSize
)
val
layer1Size
=
iqSize
val
layer2Size
=
iqSize
/
2
val
debug
=
false
}
sealed
abstract
class
IQBundle
extends
XSBundle
with
IQConst
...
...
@@ -109,14 +106,14 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
//Tag Queue
val
ctrlFlow
=
Mem
(
iqSize
,
new
CtrlFlow
)
val
ctrlSig
=
Mem
(
iqSize
,
new
CtrlSignals
)
val
brMask
=
Reg
Init
(
VecInit
(
Seq
.
fill
(
iqSize
)(
0.
U
(
BrqSize
.
W
)
)))
val
brTag
=
RegInit
(
VecInit
(
Seq
.
fill
(
iqSize
)(
0.
U
(
BrTagWidth
.
W
)
)))
val
brMask
=
Reg
(
Vec
(
iqSize
,
UInt
(
BrqSize
.
W
)))
val
brTag
=
Reg
(
Vec
(
iqSize
,
UInt
(
BrTagWidth
.
W
)))
val
validReg
=
RegInit
(
VecInit
(
Seq
.
fill
(
iqSize
)(
false
.
B
)))
val
validWillFalse
=
WireInit
(
VecInit
(
Seq
.
fill
(
iqSize
)(
false
.
B
)))
val
valid
=
validReg
.
asUInt
&
~
validWillFalse
.
asUInt
val
src1Rdy
=
Reg
Init
(
VecInit
(
Seq
.
fill
(
iqSize
)(
false
.
B
)))
val
src2Rdy
=
Reg
Init
(
VecInit
(
Seq
.
fill
(
iqSize
)(
false
.
B
)))
val
src3Rdy
=
Reg
Init
(
VecInit
(
Seq
.
fill
(
iqSize
)(
false
.
B
)))
val
src1Rdy
=
Reg
(
Vec
(
iqSize
,
Bool
(
)))
val
src2Rdy
=
Reg
(
Vec
(
iqSize
,
Bool
(
)))
val
src3Rdy
=
Reg
(
Vec
(
iqSize
,
Bool
(
)))
val
prfSrc1
=
Reg
(
Vec
(
iqSize
,
UInt
(
PhyRegIdxWidth
.
W
)))
val
prfSrc2
=
Reg
(
Vec
(
iqSize
,
UInt
(
PhyRegIdxWidth
.
W
)))
val
prfSrc3
=
Reg
(
Vec
(
iqSize
,
UInt
(
PhyRegIdxWidth
.
W
)))
...
...
@@ -143,7 +140,9 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
srcEnqRdy
(
0
)
:=
Mux
(
io
.
enqCtrl
.
bits
.
ctrl
.
src1Type
=/=
SrcType
.
reg
,
true
.
B
,
io
.
enqCtrl
.
bits
.
src1State
===
SrcState
.
rdy
)
srcEnqRdy
(
1
)
:=
Mux
(
io
.
enqCtrl
.
bits
.
ctrl
.
src2Type
=/=
SrcType
.
reg
,
true
.
B
,
io
.
enqCtrl
.
bits
.
src2State
===
SrcState
.
rdy
)
srcEnqRdy
(
2
)
:=
Mux
(
io
.
enqCtrl
.
bits
.
ctrl
.
src3Type
=/=
SrcType
.
reg
,
true
.
B
,
io
.
enqCtrl
.
bits
.
src3State
===
SrcState
.
rdy
)
//TODO:
if
(
fuTypeInt
!=
FuType
.
fmac
.
litValue
()){
srcEnqRdy
(
2
)
:=
true
.
B
}
else
{
srcEnqRdy
(
2
)
:=
Mux
(
io
.
enqCtrl
.
bits
.
ctrl
.
src3Type
=/=
SrcType
.
reg
,
true
.
B
,
io
.
enqCtrl
.
bits
.
src3State
===
SrcState
.
rdy
)}
when
(
io
.
enqCtrl
.
fire
())
{
ctrlFlow
(
enqueueSelect
)
:=
io
.
enqCtrl
.
bits
.
cf
...
...
@@ -161,10 +160,10 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
oldPDest
(
enqueueSelect
)
:=
io
.
enqCtrl
.
bits
.
old_pdest
freelistAllocPtr
(
enqueueSelect
)
:=
io
.
enqCtrl
.
bits
.
freelistAllocPtr
roqIdx
(
enqueueSelect
)
:=
io
.
enqCtrl
.
bits
.
roqIdx
if
(
debug
)
{
XSDebug
(
"[IQ enq]: enqSelect:%d | s1Rd:%d s2Rd:%d s3Rd:%d\n"
,
enqueueSelect
.
asUInt
,
XSDebug
(
"[IQ enq]: enqSelect:%d | s1Rd:%d s2Rd:%d s3Rd:%d\n"
,
enqueueSelect
.
asUInt
,
(
io
.
enqCtrl
.
bits
.
src1State
===
SrcState
.
rdy
),
(
io
.
enqCtrl
.
bits
.
src2State
===
SrcState
.
rdy
),
(
io
.
enqCtrl
.
bits
.
src3State
===
SrcState
.
rdy
))
}
(
io
.
enqCtrl
.
bits
.
src3State
===
SrcState
.
rdy
))
}
...
...
@@ -184,19 +183,24 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
when
(
src2Rdy
(
enqSelNext
)){
src2Data
(
enqSelNext
)
:=
io
.
enqData
.
bits
.
src2
}
when
(
src3Rdy
(
enqSelNext
)){
src3Data
(
enqSelNext
)
:=
io
.
enqData
.
bits
.
src3
}
}
if
(
debug
)
{
XSDebug
(
"[Reg info-ENQ] enqSelNext:%d | enqFireNext:%d \n"
,
enqSelNext
,
enqFireNext
)
XSDebug
(
"[IQ content] valid vr vf| pc insruction | src1rdy src1 | src2Rdy src2 pdest \n"
)
for
(
i
<-
0
to
(
iqSize
-
1
)){
val
ins
=
ctrlFlow
(
i
).
instr
val
pc
=
ctrlFlow
(
i
).
pc
when
(
valid
(
i
)){
XSDebug
(
"[IQ content][%d] %d%d%d |%x %x| %x %x | %x %x | %d valid|\n"
,
i
.
asUInt
,
valid
(
i
),
validReg
(
i
),
validWillFalse
(
i
),
pc
,
ins
,
src1Rdy
(
i
),
src1Data
(
i
),
src2Rdy
(
i
),
src2Data
(
i
),
prfDest
(
i
))}
.
elsewhen
(
validReg
(
i
)
&&
validWillFalse
(
i
)){
XSDebug
(
"[IQ content][%d] %d%d%d |%x %x| %x %x | %x %x | %d valid will be False|\n"
,
i
.
asUInt
,
valid
(
i
),
validReg
(
i
),
validWillFalse
(
i
),
pc
,
ins
,
src1Rdy
(
i
),
src1Data
(
i
),
src2Rdy
(
i
),
src2Data
(
i
),
prfDest
(
i
))}
.
otherwise
{
XSDebug
(
"[IQ content][%d] %d%d%d |%x %x| %x %x | %x %x | %d\n"
,
i
.
asUInt
,
valid
(
i
),
validReg
(
i
),
validWillFalse
(
i
),
pc
,
ins
,
src1Rdy
(
i
),
src1Data
(
i
),
src2Rdy
(
i
),
src2Data
(
i
),
prfDest
(
i
))}
}
XSDebug
(
"[Reg info-ENQ] enqSelNext:%d | enqFireNext:%d \n"
,
enqSelNext
,
enqFireNext
)
XSDebug
(
"[IQ content] valid vr vf| pc insruction | src1rdy src1 | src2Rdy src2 | src3Rdy src3 | pdest \n"
)
for
(
i
<-
0
to
(
iqSize
-
1
))
{
val
ins
=
ctrlFlow
(
i
).
instr
val
pc
=
ctrlFlow
(
i
).
pc
XSDebug
(
valid
(
i
),
"[IQ content][%d] %d%d%d |%x %x| %x %x | %x %x | %x %x | %d valid|\n"
,
i
.
asUInt
,
valid
(
i
),
validReg
(
i
),
validWillFalse
(
i
),
pc
,
ins
,
src1Rdy
(
i
),
src1Data
(
i
),
src2Rdy
(
i
),
src2Data
(
i
),
src3Rdy
(
i
),
src3Data
(
i
),
prfDest
(
i
))
XSDebug
(
validReg
(
i
)
&&
validWillFalse
(
i
),
"[IQ content][%d] %d%d%d |%x %x| %x %x | %x %x | %x %x | %d valid will be False|\n"
,
i
.
asUInt
,
valid
(
i
),
validReg
(
i
),
validWillFalse
(
i
),
pc
,
ins
,
src1Rdy
(
i
),
src1Data
(
i
),
src2Rdy
(
i
),
src2Data
(
i
),
src3Rdy
(
i
),
src3Data
(
i
),
prfDest
(
i
))
XSDebug
(
"[IQ content][%d] %d%d%d |%x %x| %x %x | %x %x | %x %x | %d\n"
,
i
.
asUInt
,
valid
(
i
),
validReg
(
i
),
validWillFalse
(
i
),
pc
,
ins
,
src1Rdy
(
i
),
src1Data
(
i
),
src2Rdy
(
i
),
src2Data
(
i
),
src3Rdy
(
i
),
src3Data
(
i
),
prfDest
(
i
))
}
// From Common Data Bus(wakeUpPort)
// chisel claims that firrtl will optimize Mux1H to and/or tree
...
...
@@ -286,9 +290,7 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
Wire
(
new
CmpInputBundle
).
apply
(
instRdy
(
i
),
roqIdx
(
i
),
i
.
U
)
}
val
selResult
=
ParallelSel
(
selVec
)
if
(
debug
)
{
XSDebug
(
"[Sel Result] ResReady:%d || ResultId:%d\n"
,
selResult
.
instRdy
,
selResult
.
iqIdx
.
asUInt
)
}
XSDebug
(
"[Sel Result] ResReady:%d || ResultId:%d\n"
,
selResult
.
instRdy
,
selResult
.
iqIdx
.
asUInt
)
//---------------------------------------------------------
// Redirect Logic
//---------------------------------------------------------
...
...
@@ -340,14 +342,12 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
io
.
deq
.
bits
.
src1
:=
src1Data
(
dequeueSelect
)
io
.
deq
.
bits
.
src2
:=
src2Data
(
dequeueSelect
)
io
.
deq
.
bits
.
src3
:=
src3Data
(
dequeueSelect
)
if
(
debug
)
{
XSDebug
(
"[Reg Info-Sel] selInstRdy:%d || selIdx:%d\n"
,
selInstRdy
,
selInstIdx
.
asUInt
)
XSDebug
(
IQreadyGo
,
"[IQ dequeue] **dequeue fire:%d** roqIdx:%d dequeueSel:%d | src1Rd:%d src1:%d | src2Rd:%d src2:%d\n"
,
io
.
deq
.
fire
(),
io
.
deq
.
bits
.
uop
.
roqIdx
,
dequeueSelect
.
asUInt
,
(
io
.
deq
.
bits
.
uop
.
src1State
===
SrcState
.
rdy
),
io
.
deq
.
bits
.
uop
.
psrc1
,
(
io
.
deq
.
bits
.
uop
.
src2State
===
SrcState
.
rdy
),
io
.
deq
.
bits
.
uop
.
psrc2
)
}
XSDebug
(
"[Reg Info-Sel] selInstRdy:%d || selIdx:%d\n"
,
selInstRdy
,
selInstIdx
.
asUInt
)
XSDebug
(
IQreadyGo
,
"[IQ dequeue] **dequeue fire:%d** roqIdx:%d dequeueSel:%d | src1Rd:%d src1:%d | src2Rd:%d src2:%d\n"
,
io
.
deq
.
fire
(),
io
.
deq
.
bits
.
uop
.
roqIdx
,
dequeueSelect
.
asUInt
,
(
io
.
deq
.
bits
.
uop
.
src1State
===
SrcState
.
rdy
),
io
.
deq
.
bits
.
uop
.
psrc1
,
(
io
.
deq
.
bits
.
uop
.
src2State
===
SrcState
.
rdy
),
io
.
deq
.
bits
.
uop
.
psrc2
)
//update the index register of instruction that can be issue, unless function unit not allow in
//then the issue will be stopped to wait the function unit
...
...
src/main/scala/xiangshan/backend/rename/BusyTable.scala
浏览文件 @
583a68ce
...
...
@@ -3,7 +3,7 @@ package xiangshan.backend.rename
import
chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.utils.
ParallelOR
import
xiangshan.utils.
{
ParallelOR
,
XSDebug
}
class
BusyTable
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
...
...
@@ -27,15 +27,21 @@ class BusyTable extends XSModule {
when
(
alloc
.
valid
){
table
(
alloc
.
bits
)
:=
true
.
B
}
XSDebug
(
alloc
.
valid
,
"Allocate %d\n"
,
alloc
.
bits
)
}
for
((
wb
,
i
)
<-
io
.
wbPregs
.
zipWithIndex
){
when
(
wb
.
valid
){
table
(
wb
.
bits
)
:=
false
.
B
}
XSDebug
(
wb
.
valid
,
"writeback %d\n"
,
wb
.
bits
)
}
when
(
io
.
flush
){
table
.
foreach
(
_
:=
false
.
B
)
}
for
(
i
<-
0
until
NRPhyRegs
)
{
XSDebug
(
table
(
i
),
"%d is busy\n"
,
i
.
U
)
}
}
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
583a68ce
...
...
@@ -99,6 +99,14 @@ class Roq(implicit val p: XSConfig) extends XSModule {
val
retireCounter
=
Mux
(
state
===
s_idle
,
PopCount
(
validCommit
),
0.
U
)
// TODO: commit store
XSInfo
(
retireCounter
>
0.
U
,
"retired %d insts\n"
,
retireCounter
)
XSInfo
(
""
)
XSInfo
(){
printf
(
"retired pcs are: "
)
for
(
i
<-
0
until
CommitWidth
){
when
(
io
.
commits
(
i
).
valid
){
printf
(
"%d:0x%x "
,
ringBufferTail
+
i
.
U
,
microOp
(
ringBufferTail
+
i
.
U
).
cf
.
pc
)
}
}
printf
(
"\n"
)
}
val
walkFinished
=
(
0
until
CommitWidth
).
map
(
i
=>
(
ringBufferWalk
+
i
.
U
)
===
ringBufferWalkTarget
).
reduce
(
_
||
_
)
...
...
@@ -133,19 +141,30 @@ class Roq(implicit val p: XSConfig) extends XSModule {
}
printf
(
"\n"
)
}
XSDebug
(){
for
(
i
<-
0
until
RoqSize
){
if
(
i
%
4
==
0
)
XSDebug
(
""
)
printf
(
"%x "
,
microOp
(
i
).
cf
.
pc
)
when
(!
valid
(
i
)){
printf
(
"- "
)}
when
(
valid
(
i
)
&&
writebacked
(
i
)){
printf
(
"w "
)}
when
(
valid
(
i
)
&&
!
writebacked
(
i
)){
printf
(
"v "
)}
if
(
i
%
4
==
3
)
printf
(
"\n"
)
}
}
//difftest signals
val
firstValidCommit
=
ringBufferTail
+
PriorityMux
(
validCommit
,
VecInit
(
List
.
tabulate
(
CommitWidth
)(
_
.
U
)))
val
emptyCsr
=
WireInit
(
0.
U
(
64.
W
))
if
(!
p
.
FPGAPlatform
){
BoringUtils
.
addS
ink
(
RegNext
(
retireCounter
),
"difftestCommit"
)
BoringUtils
.
addS
ink
(
RegNext
(
microOp
(
firstValidCommit
).
cf
.
pc
),
"difftestThisPC"
)
//first valid PC
BoringUtils
.
addS
ink
(
RegNext
(
microOp
(
firstValidCommit
).
cf
.
instr
),
"difftestThisINST"
)
//first valid inst
BoringUtils
.
addS
ink
(
archRF
,
"difftestRegs"
)
//arch RegFile
BoringUtils
.
addS
ink
(
RegNext
(
false
.
B
),
"difftestSkip"
)
//SKIP
BoringUtils
.
addS
ink
(
RegNext
(
false
.
B
),
"difftestIsRVC"
)
//FIXIT
BoringUtils
.
addS
ink
(
RegNext
(
0.
U
),
"difftestIntrNO"
)
BoringUtils
.
addS
ource
(
RegNext
(
retireCounter
),
"difftestCommit"
)
BoringUtils
.
addS
ource
(
RegNext
(
microOp
(
firstValidCommit
).
cf
.
pc
),
"difftestThisPC"
)
//first valid PC
BoringUtils
.
addS
ource
(
RegNext
(
microOp
(
firstValidCommit
).
cf
.
instr
),
"difftestThisINST"
)
//first valid inst
BoringUtils
.
addS
ource
(
archRF
,
"difftestRegs"
)
//arch RegFile
BoringUtils
.
addS
ource
(
RegNext
(
false
.
B
),
"difftestSkip"
)
//SKIP
BoringUtils
.
addS
ource
(
RegNext
(
false
.
B
),
"difftestIsRVC"
)
//FIXIT
BoringUtils
.
addS
ource
(
RegNext
(
0.
U
),
"difftestIntrNO"
)
//TODO: skip insts that commited in the same cycle ahead of exception
//csr debug signals
...
...
src/main/scala/xiangshan/frontend/Ibuffer.scala
浏览文件 @
583a68ce
package
xiangshan.frontend
import
chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.utils._
class
Ibuffer
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
val
flush
=
Input
(
Bool
())
val
in
=
Flipped
(
DecoupledIO
(
new
FetchPacket
))
val
out
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
})
when
(
io
.
in
.
valid
)
{
XSDebug
(
"cache data\n"
)
for
(
i
<-
0
until
FetchWidth
)
{
XSDebug
(
"%b\n"
,
io
.
in
.
bits
.
instrs
(
i
))
}
}
// ignore
for
(
i
<-
0
until
DecodeWidth
)
{
io
.
out
(
i
).
bits
.
exceptionVec
:=
DontCare
io
.
out
(
i
).
bits
.
intrVec
:=
DontCare
io
.
out
(
i
).
bits
.
isBr
:=
DontCare
}
//mask initial
// val mask = Wire(Vec(FetchWidth*2, false.B))
// (0 until 16).map(i => mask(i.U) := (io.in.bits.pc(4,1) <= i.U))
// ibuf define
val
ibuf
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
0.
U
(
16.
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
)))
val
head_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
val
tail_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
// true: Last operation is enqueue
// false: Last operation is deq_ueue
val
last_enq
=
RegInit
(
false
.
B
)
val
full
=
head_ptr
===
tail_ptr
&&
last_enq
val
empty
=
head_ptr
===
tail_ptr
&&
!
last_enq
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(_||_)
XSWarn
(
empty
,
"Ibuffer is empty\n"
)
XSWarn
(
full
,
"Ibuffer is full\n"
)
io
.
in
.
ready
:=
enqValid
// enque
when
(
enqValid
)
{
XSInfo
(
"Enque start\n"
)
var
enq_idx
=
0.
U
(
log2Up
(
FetchWidth
*
2
+
1
).
W
)
for
(
i
<-
0
until
FetchWidth
*
2
)
{
when
(
io
.
in
.
bits
.
mask
(
i
))
{
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_pc
(
tail_ptr
+
enq_idx
)
:=
io
.
in
.
bits
.
pc
+
enq_idx
<<
1
ibuf_valid
(
tail_ptr
+
enq_idx
)
:=
true
.
B
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
)
}
tail_ptr
:=
tail_ptr
+
enq_idx
last_enq
:=
true
.
B
XSInfo
(
"Enque finished, tail_ptr=%d\n"
,
tail_ptr
+
enq_idx
)
}
// deque
when
(
deqValid
)
{
XSInfo
(
"Deque start\n"
)
var
deq_idx
=
0.
U
(
log2Up
(
DecodeWidth
*
2
+
1
).
W
)
for
(
i
<-
0
until
DecodeWidth
)
{
when
(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
))
{
when
(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
{
// is RVC
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
)
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
}.
elsewhen
(
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
))
{
// isn't RVC
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
)
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
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
true
.
B
ibuf_valid
(
head_ptr
+
deq_idx
)
:=
false
.
B
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
)
:=
false
.
B
}.
otherwise
{
// half inst keep in buffer
io
.
out
(
i
).
bits
.
instr
:=
0.
U
(
32.
W
)
XSWarn
(
"This is half inst\n"
)
io
.
out
(
i
).
bits
.
pc
:=
0.
U
(
VAddrBits
.
W
)
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
false
.
B
}
}.
otherwise
{
XSWarn
(
"This output is not ready, or buffer is empty\n"
)
io
.
out
(
i
).
bits
.
instr
:=
0.
U
io
.
out
(
i
).
bits
.
pc
:=
0.
U
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
false
.
B
}
// When can't deque, deq_idx+0
// when RVC deque, deq_idx+1
// when not RVC deque, deq_idx+2
// when only have half inst, keep it in buffer
//deq_idx = 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)) +
// (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))
deq_idx
=
deq_idx
+
PriorityMux
(
Seq
(
!(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
))
->
0.
U
,
(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
->
1.
U
,
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
)
->
2.
U
))
}
head_ptr
:=
head_ptr
+
deq_idx
XSInfo
(
"Deque finished\n"
)
XSInfo
(
"head_prt=%d, tail_ptr=%d\n"
,
head_ptr
+
deq_idx
,
tail_ptr
)
last_enq
:=
false
.
B
}.
otherwise
{
for
(
i
<-
0
until
DecodeWidth
)
{
io
.
out
(
i
).
bits
.
instr
:=
0.
U
io
.
out
(
i
).
bits
.
pc
:=
0.
U
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
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
}
}
package
xiangshan.frontend
import
chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.utils._
class
Ibuffer
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
val
flush
=
Input
(
Bool
())
val
in
=
Flipped
(
DecoupledIO
(
new
FetchPacket
))
val
out
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
})
when
(
io
.
in
.
valid
)
{
XSDebug
(
"cache data\n"
)
for
(
i
<-
0
until
FetchWidth
)
{
XSDebug
(
"%b\n"
,
io
.
in
.
bits
.
instrs
(
i
))
}
}
// ignore
for
(
i
<-
0
until
DecodeWidth
)
{
io
.
out
(
i
).
bits
.
exceptionVec
:=
DontCare
io
.
out
(
i
).
bits
.
intrVec
:=
DontCare
io
.
out
(
i
).
bits
.
isBr
:=
DontCare
}
//mask initial
// val mask = Wire(Vec(FetchWidth*2, false.B))
// (0 until 16).map(i => mask(i.U) := (io.in.bits.pc(4,1) <= i.U))
// ibuf define
val
ibuf
=
RegInit
(
VecInit
(
Seq
.
fill
(
IBufSize
*
2
)(
0.
U
(
16.
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
)))
val
head_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
val
tail_ptr
=
RegInit
(
0.
U
(
log2Up
(
IBufSize
*
2
).
W
))
// true: Last operation is enqueue
// false: Last operation is deq_ueue
val
last_enq
=
RegInit
(
false
.
B
)
val
full
=
head_ptr
===
tail_ptr
&&
last_enq
val
empty
=
head_ptr
===
tail_ptr
&&
!
last_enq
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(_||_)
XSWarn
(
empty
,
"Ibuffer is empty\n"
)
XSWarn
(
full
,
"Ibuffer is full\n"
)
io
.
in
.
ready
:=
enqValid
// enque
when
(
enqValid
)
{
XSInfo
(
"Enque start\n"
)
var
enq_idx
=
0.
U
(
log2Up
(
FetchWidth
*
2
+
1
).
W
)
for
(
i
<-
0
until
FetchWidth
*
2
)
{
when
(
io
.
in
.
bits
.
mask
(
i
))
{
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_pc
(
tail_ptr
+
enq_idx
)
:=
io
.
in
.
bits
.
pc
+
enq_idx
<<
1
ibuf_valid
(
tail_ptr
+
enq_idx
)
:=
true
.
B
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
)
}
tail_ptr
:=
tail_ptr
+
enq_idx
last_enq
:=
true
.
B
XSInfo
(
"Enque finished, tail_ptr=%d\n"
,
tail_ptr
+
enq_idx
)
}
// deque
when
(
deqValid
)
{
XSInfo
(
"Deque start\n"
)
var
deq_idx
=
0.
U
(
log2Up
(
DecodeWidth
*
2
+
1
).
W
)
for
(
i
<-
0
until
DecodeWidth
)
{
when
(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
))
{
when
(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
{
// is RVC
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
)
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
}.
elsewhen
(
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
))
{
// isn't RVC
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
)
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
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
true
.
B
ibuf_valid
(
head_ptr
+
deq_idx
)
:=
false
.
B
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
)
:=
false
.
B
}.
otherwise
{
// half inst keep in buffer
io
.
out
(
i
).
bits
.
instr
:=
0.
U
(
32.
W
)
XSWarn
(
"This is half inst\n"
)
io
.
out
(
i
).
bits
.
pc
:=
0.
U
(
VAddrBits
.
W
)
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
false
.
B
}
}.
otherwise
{
XSWarn
(
"This output is not ready, or buffer is empty\n"
)
io
.
out
(
i
).
bits
.
instr
:=
0.
U
io
.
out
(
i
).
bits
.
pc
:=
0.
U
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
io
.
out
(
i
).
valid
:=
false
.
B
}
// When can't deque, deq_idx+0
// when RVC deque, deq_idx+1
// when not RVC deque, deq_idx+2
// when only have half inst, keep it in buffer
//deq_idx = 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)) +
// (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))
deq_idx
=
deq_idx
+
PriorityMux
(
Seq
(
!(
io
.
out
(
i
).
ready
&&
ibuf_valid
(
head_ptr
+
deq_idx
))
->
0.
U
,
(
ibuf
(
head_ptr
+
deq_idx
)(
1
,
0
)
=/=
"b11"
.
U
)
->
1.
U
,
ibuf_valid
(
head_ptr
+
deq_idx
+
1.
U
)
->
2.
U
))
}
head_ptr
:=
head_ptr
+
deq_idx
XSInfo
(
"Deque finished\n"
)
XSInfo
(
"head_prt=%d, tail_ptr=%d\n"
,
head_ptr
+
deq_idx
,
tail_ptr
)
last_enq
:=
false
.
B
}.
otherwise
{
for
(
i
<-
0
until
DecodeWidth
)
{
io
.
out
(
i
).
bits
.
instr
:=
0.
U
io
.
out
(
i
).
bits
.
pc
:=
0.
U
io
.
out
(
i
).
bits
.
isRVC
:=
false
.
B
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
src/main/scala/xiangshan/utils/LogUtils.scala
浏览文件 @
583a68ce
...
...
@@ -8,7 +8,7 @@ import xiangshan.utils.XSLogLevel.XSLogLevel
object
XSLogLevel
extends
Enumeration
{
type
XSLogLevel
=
Value
val
ALL
=
Value
(
"ALL "
)
val
ALL
=
Value
(
0
,
"ALL "
)
val
DEBUG
=
Value
(
"DEBUG"
)
val
INFO
=
Value
(
"INFO "
)
val
WARN
=
Value
(
"WARN "
)
...
...
@@ -16,9 +16,9 @@ object XSLogLevel extends Enumeration {
val
OFF
=
Value
(
"OFF "
)
}
object
XSLog
extends
HasXSParameter
{
object
XSLog
{
def
displayLog
()
:
Bool
=
{
def
displayLog
:
Bool
=
{
val
disp_begin
,
disp_end
=
WireInit
(
0.
U
(
64.
W
))
BoringUtils
.
addSink
(
disp_begin
,
"DISPALY_LOG_START"
)
BoringUtils
.
addSink
(
disp_end
,
"DISPLAY_LOG_END"
)
...
...
@@ -26,14 +26,19 @@ object XSLog extends HasXSParameter {
(
GTimer
()
>=
disp_begin
)
&&
(
GTimer
()
<=
disp_end
)
}
def
xsLogLevel
:
UInt
=
{
val
log_level
=
WireInit
(
0.
U
(
64.
W
))
BoringUtils
.
addSink
(
log_level
,
"DISPLAY_LOG_LEVEL"
)
assert
(
log_level
<
XSLogLevel
.
maxId
.
U
)
log_level
}
def
apply
(
debugLevel
:
XSLogLevel
)
(
cond
:
Bool
,
pable
:
Printable
)
(
implicit
m
:
Module
)
:
Any
=
{
if
(
debugLevel
>=
LogLevel
)
{
when
(
cond
&&
displayLog
())
{
val
commonInfo
=
p
"[$debugLevel][time=${GTimer()}] ${m.name}: "
printf
(
commonInfo
+
pable
)
}
val
commonInfo
=
p
"[$debugLevel][time=${GTimer()}] ${m.name}: "
when
(
debugLevel
.
id
.
U
>=
xsLogLevel
&&
cond
&&
displayLog
)
{
printf
(
commonInfo
+
pable
)
}
}
}
...
...
@@ -49,7 +54,7 @@ sealed abstract class LogHelper(val logLevel: XSLogLevel) extends HasXSParameter
// Do not use that unless you have valid reasons
def
apply
(
cond
:
Bool
=
true
.
B
)(
body
:
=>
Unit
)
:
Any
=
if
(
logLevel
>=
LogLevel
)
{
when
(
cond
&&
XSLog
.
displayLog
())
{
body
}
}
when
(
logLevel
.
id
.
U
>=
XSLog
.
xsLogLevel
&&
cond
&&
XSLog
.
displayLog
)
{
body
}
}
object
XSDebug
extends
LogHelper
(
XSLogLevel
.
DEBUG
)
...
...
src/test/csrc/common.h
浏览文件 @
583a68ce
...
...
@@ -42,6 +42,18 @@ void init_device(void);
bool
is_finished
(
void
);
int
get_exit_code
(
void
);
// log
enum
{
LOG_ALL
=
0
,
LOG_DEBUG
,
LOG_INFO
,
LOG_WARN
,
LOG_ERROR
,
LOG_OFF
};
uint64_t
getLogLevel
(
const
char
*
str
);
void
app_error
(
const
char
*
fmt
,
...);
int
monitor
(
void
);
...
...
src/test/csrc/emu.h
浏览文件 @
583a68ce
...
...
@@ -25,7 +25,7 @@ class Emulator {
// emu control variable
uint32_t
seed
;
uint64_t
max_cycles
,
cycles
;
uint64_t
log_begin
,
log_end
;
uint64_t
log_begin
,
log_end
,
log_level
;
std
::
vector
<
const
char
*>
parse_args
(
int
argc
,
const
char
*
argv
[]);
...
...
@@ -57,7 +57,7 @@ class Emulator {
image
(
nullptr
),
dut_ptr
(
new
std
::
remove_reference
<
decltype
(
*
dut_ptr
)
>::
type
),
seed
(
0
),
max_cycles
(
-
1
),
cycles
(
0
),
log_begin
(
0
),
log_end
(
-
1
)
log_begin
(
0
),
log_end
(
-
1
)
,
log_level
(
LOG_ALL
)
{
// init emu
auto
args
=
parse_args
(
argc
,
argv
);
...
...
@@ -67,9 +67,10 @@ class Emulator {
srand48
(
seed
);
Verilated
::
randReset
(
2
);
// set log time range
// set log time range
and log level
dut_ptr
->
io_logCtrl_log_begin
=
log_begin
;
dut_ptr
->
io_logCtrl_log_end
=
log_end
;
dut_ptr
->
io_logCtrl_log_level
=
log_level
;
// init ram
extern
void
init_ram
(
const
char
*
img
);
...
...
@@ -141,6 +142,8 @@ class Emulator {
set_abort
();
}
printf
(
"xsstatus pc=%lx commit=%d
\n
"
,
dut_ptr
->
io_difftest_thisPC
,
dut_ptr
->
io_difftest_commit
);
//FIXIT: delete me when dummy test is passed
if
(
!
hascommit
&&
dut_ptr
->
io_difftest_thisPC
==
0x80000000u
)
{
hascommit
=
1
;
extern
void
init_difftest
(
uint64_t
*
reg
);
...
...
src/test/csrc/log.cpp
0 → 100644
浏览文件 @
583a68ce
#include <cstdio>
#include <cstring>
#include "common.h"
uint64_t
getLogLevel
(
const
char
*
str
)
{
if
(
!
strcmp
(
"ALL"
,
str
)){
return
LOG_ALL
;
}
else
if
(
!
strcmp
(
"DEBUG"
,
str
)){
return
LOG_DEBUG
;
}
else
if
(
!
strcmp
(
"INFO"
,
str
)){
return
LOG_INFO
;
}
else
if
(
!
strcmp
(
"WARN"
,
str
)){
return
LOG_WARN
;
}
else
if
(
!
strcmp
(
"ERROR"
,
str
)){
return
LOG_ERROR
;
}
else
if
(
!
strcmp
(
"OFF"
,
str
)){
return
LOG_OFF
;
}
else
{
printf
(
"Unknown verbosity level!
\n
"
);
exit
(
-
1
);
}
}
src/test/csrc/main.cpp
浏览文件 @
583a68ce
...
...
@@ -20,8 +20,9 @@ const struct option Emulator::long_options[] = {
{
"seed"
,
1
,
NULL
,
's'
},
{
"max-cycles"
,
1
,
NULL
,
'C'
},
{
"image"
,
1
,
NULL
,
'i'
},
{
"log-begin"
,
1
,
NULL
,
'b'
},
{
"log-end"
,
1
,
NULL
,
'e'
},
{
"log-begin"
,
1
,
NULL
,
'b'
},
{
"log-end"
,
1
,
NULL
,
'e'
},
{
"verbose"
,
1
,
NULL
,
'v'
},
{
"help"
,
0
,
NULL
,
'h'
},
{
0
,
0
,
NULL
,
0
}
};
...
...
@@ -34,6 +35,7 @@ void Emulator::print_help(const char *file) {
printf
(
" -i, --image=FILE run with this image file
\n
"
);
printf
(
" -b, --log-begin=NUM display log from NUM th cycle
\n
"
);
printf
(
" -e, --log-end=NUM stop display log at NUM th cycle
\n
"
);
printf
(
" -v, --verbose=STR verbosity level, can be one of [ALL, DEBUG, INFO, WARN, ERROR]
\n
"
);
printf
(
" -h, --help print program help info
\n
"
);
printf
(
"
\n
"
);
}
...
...
@@ -41,7 +43,7 @@ void Emulator::print_help(const char *file) {
std
::
vector
<
const
char
*>
Emulator
::
parse_args
(
int
argc
,
const
char
*
argv
[])
{
std
::
vector
<
const
char
*>
args
=
{
argv
[
0
]
};
int
o
;
while
(
(
o
=
getopt_long
(
argc
,
const_cast
<
char
*
const
*>
(
argv
),
"-s:C:hi:m:b:e:"
,
long_options
,
NULL
))
!=
-
1
)
{
while
(
(
o
=
getopt_long
(
argc
,
const_cast
<
char
*
const
*>
(
argv
),
"-s:C:hi:m:b:e:
l:
"
,
long_options
,
NULL
))
!=
-
1
)
{
switch
(
o
)
{
case
's'
:
if
(
std
::
string
(
optarg
)
!=
"NO_SEED"
)
{
...
...
@@ -56,6 +58,7 @@ std::vector<const char *> Emulator::parse_args(int argc, const char *argv[]) {
break
;
case
'b'
:
log_begin
=
atoll
(
optarg
);
break
;
case
'e'
:
log_end
=
atoll
(
optarg
);
break
;
case
'v'
:
log_level
=
getLogLevel
(
optarg
);
break
;
default:
print_help
(
argv
[
0
]);
exit
(
0
);
...
...
src/test/scala/top/XSSim.scala
浏览文件 @
583a68ce
...
...
@@ -28,7 +28,8 @@ class DiffTestIO extends Bundle {
}
class
LogCtrlIO
extends
Bundle
{
val
log_begin
,
log_end
=
Input
(
UInt
(
32.
W
))
val
log_begin
,
log_end
=
Input
(
UInt
(
64.
W
))
val
log_level
=
Input
(
UInt
(
64.
W
))
// a cpp uint
}
class
XSSimTop
extends
Module
{
...
...
@@ -72,12 +73,14 @@ class XSSimTop extends Module {
BoringUtils
.
addSink
(
difftest
.
scause
,
"difftestScause"
)
io
.
difftest
:=
difftest
val
log_begin
,
log_end
=
Wire
(
UInt
(
32
.
W
))
val
log_begin
,
log_end
,
log_level
=
Wire
(
UInt
(
64
.
W
))
log_begin
:=
io
.
logCtrl
.
log_begin
log_end
:=
io
.
logCtrl
.
log_end
log_level
:=
io
.
logCtrl
.
log_level
BoringUtils
.
addSource
(
log_begin
,
"DISPALY_LOG_START"
)
BoringUtils
.
addSource
(
log_end
,
"DISPLAY_LOG_END"
)
BoringUtils
.
addSource
(
log_level
,
"DISPLAY_LOG_LEVEL"
)
}
object
TestMain
extends
App
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录