Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
2aa3b6d8
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,发现更多精彩内容 >>
提交
2aa3b6d8
编写于
7月 09, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branches 'origin' and 'origin/issueQueue-fixSrcType' into improve-dp2
上级
5fcd1d16
e14a0fbb
09b6ad0b
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
376 addition
and
143 deletion
+376
-143
src/main/scala/xiangshan/Bundle.scala
src/main/scala/xiangshan/Bundle.scala
+10
-1
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+1
-0
src/main/scala/xiangshan/backend/Backend.scala
src/main/scala/xiangshan/backend/Backend.scala
+10
-1
src/main/scala/xiangshan/backend/brq/Brq.scala
src/main/scala/xiangshan/backend/brq/Brq.scala
+109
-46
src/main/scala/xiangshan/backend/decode/DecodeHelper.scala
src/main/scala/xiangshan/backend/decode/DecodeHelper.scala
+2
-2
src/main/scala/xiangshan/backend/decode/Decoder.scala
src/main/scala/xiangshan/backend/decode/Decoder.scala
+4
-3
src/main/scala/xiangshan/backend/decode/XSTrap.scala
src/main/scala/xiangshan/backend/decode/XSTrap.scala
+20
-0
src/main/scala/xiangshan/backend/exu/Alu.scala
src/main/scala/xiangshan/backend/exu/Alu.scala
+1
-44
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
+34
-26
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+37
-6
src/main/scala/xiangshan/frontend/Frontend.scala
src/main/scala/xiangshan/frontend/Frontend.scala
+5
-2
src/main/scala/xiangshan/utils/PriorityMuxDefault.scala
src/main/scala/xiangshan/utils/PriorityMuxDefault.scala
+20
-0
src/test/csrc/emu.h
src/test/csrc/emu.h
+3
-1
src/test/csrc/monitor.cpp
src/test/csrc/monitor.cpp
+2
-0
src/test/scala/top/XSSim.scala
src/test/scala/top/XSSim.scala
+6
-6
src/test/scala/xiangshan/backend/brq/BrqTest.scala
src/test/scala/xiangshan/backend/brq/BrqTest.scala
+107
-0
src/test/scala/xiangshan/testutils/TestCaseGenerator.scala
src/test/scala/xiangshan/testutils/TestCaseGenerator.scala
+5
-5
未找到文件。
src/main/scala/xiangshan/Bundle.scala
浏览文件 @
2aa3b6d8
...
...
@@ -62,6 +62,15 @@ class Redirect extends XSBundle {
val
freelistAllocPtr
=
new
FreeListPtr
}
class
RedirectInfo
extends
XSBundle
{
val
valid
=
Bool
()
// a valid commit form brq/roq
val
misPred
=
Bool
()
// a branch miss prediction ?
val
redirect
=
new
Redirect
def
flush
()
:
Bool
=
valid
&&
(
redirect
.
isException
||
misPred
)
}
class
Dp1ToDp2IO
extends
XSBundle
{
val
intDqToDp2
=
Vec
(
IntDqDeqWidth
,
DecoupledIO
(
new
MicroOp
))
val
fpDqToDp2
=
Vec
(
FpDqDeqWidth
,
DecoupledIO
(
new
MicroOp
))
...
...
@@ -104,6 +113,6 @@ class FrontendToBackendIO extends XSBundle {
// to backend end
val
cfVec
=
Vec
(
DecodeWidth
,
DecoupledIO
(
new
CtrlFlow
))
// from backend
val
redirect
=
Flipped
(
ValidIO
(
new
Redirect
)
)
val
redirect
Info
=
Input
(
new
RedirectInfo
)
val
commits
=
Vec
(
CommitWidth
,
Flipped
(
ValidIO
(
new
RoqCommit
)))
// update branch pred
}
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
2aa3b6d8
...
...
@@ -31,6 +31,7 @@ trait HasXSParameter {
val
RenameWidth
=
6
val
CommitWidth
=
6
val
BrqSize
=
16
val
IssQueSize
=
8
val
BrTagWidth
=
log2Up
(
BrqSize
)
val
NRPhyRegs
=
128
val
PhyRegIdxWidth
=
log2Up
(
NRPhyRegs
)
...
...
src/main/scala/xiangshan/backend/Backend.scala
浏览文件 @
2aa3b6d8
...
...
@@ -46,7 +46,16 @@ class Backend(implicit val p: XSConfig) extends XSModule
numWirtePorts
=
NRWritePorts
,
hasZero
=
false
))
// backend redirect, flush pipeline
val
redirect
=
Mux
(
roq
.
io
.
redirect
.
valid
,
roq
.
io
.
redirect
,
brq
.
io
.
redirect
)
val
redirectInfo
=
Wire
(
new
RedirectInfo
)
// exception or misprediction
redirectInfo
.
valid
:=
roq
.
io
.
redirect
.
valid
||
brq
.
io
.
out
.
valid
redirectInfo
.
misPred
:=
!
roq
.
io
.
redirect
.
valid
&&
brq
.
io
.
redirect
.
valid
redirectInfo
.
redirect
:=
redirect
.
bits
val
issueQueues
=
exeUnits
.
zipWithIndex
.
map
({
case
(
eu
,
i
)
=>
def
needBypass
(
x
:
Exu
)
:
Boolean
=
eu
.
enableBypass
val
bypassCnt
=
exeUnits
.
count
(
needBypass
)
//if(eu.fuTypeInt == FuType.alu.litValue()) exuConfig.AluCnt else 0
...
...
@@ -86,7 +95,7 @@ class Backend(implicit val p: XSConfig) extends XSModule
lsuExeUnits
.
foreach
(
_
.
io
.
dmem
<>
io
.
dmem
)
lsuExeUnits
.
foreach
(
_
.
io
.
scommit
<>
roq
.
io
.
scommit
)
io
.
frontend
.
redirect
<>
redirect
io
.
frontend
.
redirect
Info
<>
redirectInfo
io
.
frontend
.
commits
<>
roq
.
io
.
commits
decode
.
io
.
in
<>
io
.
frontend
.
cfVec
...
...
src/main/scala/xiangshan/backend/brq/Brq.scala
浏览文件 @
2aa3b6d8
...
...
@@ -3,7 +3,7 @@ package xiangshan.backend.brq
import
chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.utils.
XSInfo
import
xiangshan.utils.
_
class
BrqPtr
extends
XSBundle
{
...
...
@@ -22,25 +22,17 @@ class BrqPtr extends XSBundle {
(
this
.
value
===
that
.
value
)
&&
(
this
.
flag
===
that
.
flag
)
}
// this.age <
=
that.age
final
def
<
=
(
that
:
BrqPtr
)
:
Bool
=
{
// this.age < that.age
final
def
<
(
that
:
BrqPtr
)
:
Bool
=
{
Mux
(
this
.
flag
===
that
.
flag
,
this
.
value
>
that
.
value
,
this
.
value
<
that
.
value
)
}
def
needBrFlush
(
redirectTag
:
BrqPtr
)
:
Bool
=
this
<
=
redirectTag
def
needBrFlush
(
redirectTag
:
BrqPtr
)
:
Bool
=
this
<
redirectTag
def
needFlush
(
redirect
:
Valid
[
Redirect
])
:
Bool
=
{
val
redirectTag
=
redirect
.
bits
.
brTag
// assert(!(
// redirect.valid &&
// !redirect.bits.isException &&
// (flag=/=redirectTag.flag) &&
// (this.value===redirectTag.value)
// )
// )
redirect
.
valid
&&
(
redirect
.
bits
.
isException
||
needBrFlush
(
redirect
.
bits
.
brTag
))
}
...
...
@@ -57,30 +49,45 @@ object BrqPtr {
}
}
class
BrqIO
extends
XSBundle
{
// interrupt/exception happen, flush Brq
val
roqRedirect
=
Input
(
Valid
(
new
Redirect
))
// receive branch/jump calculated target
val
exuRedirect
=
Vec
(
exuConfig
.
AluCnt
+
exuConfig
.
BruCnt
,
Flipped
(
ValidIO
(
new
ExuOutput
)))
// from decode, branch insts enq
val
enqReqs
=
Vec
(
DecodeWidth
,
Flipped
(
DecoupledIO
(
new
CfCtrl
)))
// to decode
val
brTags
=
Output
(
Vec
(
DecodeWidth
,
new
BrqPtr
))
// to roq
val
out
=
ValidIO
(
new
ExuOutput
)
// misprediction, flush pipeline
val
redirect
=
Output
(
Valid
(
new
Redirect
))
}
class
Brq
extends
XSModule
{
val
io
=
IO
(
new
Bundle
()
{
// interrupt/exception happen, flush Brq
val
roqRedirect
=
Input
(
Valid
(
new
Redirect
))
// receive branch/jump calculated target
val
exuRedirect
=
Vec
(
exuConfig
.
AluCnt
+
exuConfig
.
BruCnt
,
Flipped
(
ValidIO
(
new
ExuOutput
)))
// from decode, branch insts enq
val
enqReqs
=
Vec
(
DecodeWidth
,
Flipped
(
DecoupledIO
(
new
CfCtrl
)))
// to decode
val
brTags
=
Output
(
Vec
(
DecodeWidth
,
new
BrqPtr
))
// to roq
val
out
=
ValidIO
(
new
ExuOutput
)
// misprediction, flush pipeline
val
redirect
=
Output
(
Valid
(
new
Redirect
))
})
val
io
=
IO
(
new
BrqIO
)
def
redirctWindowSize
:
Int
=
BrqSize
/
2
require
(
redirctWindowSize
<=
BrqSize
&&
redirctWindowSize
>
0
)
class
BrqEntry
extends
Bundle
{
val
ptrFlag
=
Bool
()
val
npc
=
UInt
(
VAddrBits
.
W
)
val
misPred
=
Bool
()
val
exuOut
=
new
ExuOutput
}
val
s_idle
::
s_wb
::
s_commited
::
Nil
=
List
.
tabulate
(
3
)(
i
=>
(
1
<<
i
).
U
(
3.
W
).
asTypeOf
(
new
StateQueueEntry
))
class
StateQueueEntry
extends
Bundle
{
val
isCommit
=
Bool
()
val
isWb
=
Bool
()
val
isIdle
=
Bool
()
}
val
brQueue
=
Reg
(
Vec
(
BrqSize
,
new
BrqEntry
))
val
wbFlags
=
RegInit
(
VecInit
(
Seq
.
fill
(
BrqSize
)(
false
.
B
)))
val
stateQueue
=
RegInit
(
VecInit
(
Seq
.
fill
(
BrqSize
)(
s_idle
)))
val
headPtr
,
tailPtr
=
RegInit
(
BrqPtr
(
false
.
B
,
0.
U
))
...
...
@@ -90,18 +97,57 @@ class Brq extends XSModule {
// dequeue
val
headIdx
=
headPtr
.
value
val
deqValid
=
wbFlags
(
headIdx
)
val
deqEntry
=
brQueue
(
headIdx
)
var
commitIdx
=
WireInit
(
headIdx
)
val
headPtrNext
=
WireInit
(
headPtr
+
deqValid
)
when
(
deqValid
){
wbFlags
(
headIdx
)
:=
false
.
B
def
needCheckNext
(
idx
:
UInt
)
:
Bool
=
{
(
stateQueue
(
idx
).
isWb
&&
!
brQueue
(
idx
).
misPred
)
||
stateQueue
(
idx
).
isCommit
}
var
checkNext
=
WireInit
(
needCheckNext
(
headIdx
))
for
(
i
<-
1
until
redirctWindowSize
){
val
idx
=
commitIdx
+
i
.
U
val
commitThis
=
checkNext
&&
stateQueue
(
idx
).
isWb
&&
brQueue
(
idx
).
misPred
commitIdx
=
Mux
(
commitThis
,
idx
,
commitIdx
)
checkNext
=
checkNext
&&
needCheckNext
(
idx
)
}
val
commitIsHead
=
commitIdx
===
headIdx
val
deqValid
=
!
stateQueue
(
headIdx
).
isIdle
&&
commitIsHead
val
commitValid
=
stateQueue
(
commitIdx
).
isWb
val
commitEntry
=
brQueue
(
commitIdx
)
XSDebug
(
p
"headIdx:$headIdx commitIdx:$commitIdx\n"
)
XSDebug
(
p
"headPtr:$headPtr tailPtr:$tailPtr\n"
)
XSDebug
(
""
)
stateQueue
.
map
(
s
=>{
XSDebug
(
false
,
s
.
isIdle
,
"-"
)
XSDebug
(
false
,
s
.
isWb
,
"w"
)
XSDebug
(
false
,
s
.
isCommit
,
"c"
)
})
XSDebug
(
false
,
true
.
B
,
"\n"
)
val
headPtrNext
=
WireInit
(
headPtr
+
deqValid
)
stateQueue
(
commitIdx
):=
Mux
(
deqValid
,
s_idle
,
Mux
(
commitValid
,
s_commited
,
stateQueue
(
commitIdx
)
)
)
headPtr
:=
headPtrNext
io
.
redirect
.
valid
:=
deqValid
&&
(
deqEntry
.
npc
=/=
deqEntry
.
exuOut
.
redirect
.
target
)
io
.
redirect
.
bits
:=
deqEntry
.
exuOut
.
redirect
io
.
out
.
valid
:=
deqValid
io
.
out
.
bits
:=
deqEntry
.
exuOut
io
.
redirect
.
valid
:=
commitValid
&&
commitEntry
.
misPred
io
.
redirect
.
bits
:=
commitEntry
.
exuOut
.
redirect
io
.
out
.
valid
:=
commitValid
io
.
out
.
bits
:=
commitEntry
.
exuOut
XSInfo
(
io
.
out
.
valid
,
p
"commit branch to roq, mispred:${io.redirect.valid} pc=${Hexadecimal(io.out.bits.uop.cf.pc)}\n"
)
// branch insts enq
var
full
=
WireInit
(
isFull
(
headPtrNext
,
tailPtr
))
...
...
@@ -110,7 +156,10 @@ class Brq extends XSModule {
enq
.
ready
:=
!
full
brTag
:=
tailPtrNext
// TODO: check rvc and use predict npc
when
(
enq
.
fire
()){
brQueue
(
tailPtrNext
.
value
).
npc
:=
enq
.
bits
.
cf
.
pc
+
4.
U
}
when
(
enq
.
fire
()){
brQueue
(
tailPtrNext
.
value
).
npc
:=
enq
.
bits
.
cf
.
pc
+
4.
U
brQueue
(
tailPtrNext
.
value
).
ptrFlag
:=
tailPtrNext
.
flag
}
tailPtrNext
=
tailPtrNext
+
enq
.
fire
()
full
=
isFull
(
tailPtrNext
,
headPtrNext
)
}
...
...
@@ -119,17 +168,31 @@ class Brq extends XSModule {
// exu write back
for
(
exuWb
<-
io
.
exuRedirect
){
when
(
exuWb
.
valid
){
wbFlags
(
exuWb
.
bits
.
uop
.
brTag
.
value
)
:=
true
.
B
brQueue
(
exuWb
.
bits
.
uop
.
brTag
.
value
).
exuOut
:=
exuWb
.
bits
val
wbIdx
=
exuWb
.
bits
.
redirect
.
brTag
.
value
XSInfo
(
p
"exu write back: brTag:${exuWb.bits.redirect.brTag}"
+
p
" pc=${Hexadecimal(exuWb.bits.uop.cf.pc)}\n"
)
stateQueue
(
wbIdx
)
:=
s_wb
brQueue
(
wbIdx
).
exuOut
:=
exuWb
.
bits
brQueue
(
wbIdx
).
misPred
:=
brQueue
(
wbIdx
).
npc
=/=
exuWb
.
bits
.
redirect
.
target
}
}
// when redirect, reset all regs
when
(
io
.
roqRedirect
.
valid
||
io
.
redirect
.
valid
){
wbFlags
.
foreach
(
_
:=
false
.
B
)
val
resetPtr
=
io
.
redirect
.
bits
.
brTag
+
true
.
B
headPtr
:=
resetPtr
tailPtr
:=
resetPtr
when
(
io
.
roqRedirect
.
valid
){
// exception
stateQueue
.
foreach
(
_
:=
s_idle
)
headPtr
:=
BrqPtr
(
false
.
B
,
0.
U
)
tailPtr
:=
BrqPtr
(
false
.
B
,
0.
U
)
}.
elsewhen
(
io
.
redirect
.
valid
){
// misprediction
stateQueue
.
zipWithIndex
.
foreach
({
case
(
s
,
i
)
=>
val
ptr
=
BrqPtr
(
brQueue
(
i
).
ptrFlag
,
i
.
U
)
when
(
ptr
.
needBrFlush
(
io
.
redirect
.
bits
.
brTag
)){
s
:=
s_idle
}
})
tailPtr
:=
io
.
redirect
.
bits
.
brTag
+
true
.
B
}
...
...
@@ -141,7 +204,7 @@ class Brq extends XSModule {
val
debug_normal_mode
=
!(
debug_roq_redirect
||
debug_brq_redirect
)
for
(
i
<-
0
until
DecodeWidth
){
XS
Info
(
XS
Debug
(
debug_normal_mode
,
p
"enq v:${io.enqReqs(i).valid} rdy:${io.enqReqs(i).ready} pc:${Hexadecimal(io.enqReqs(i).bits.cf.pc)}"
+
p
" brTag:${io.brTags(i)}\n"
...
...
src/main/scala/xiangshan/backend/decode/DecodeHelper.scala
浏览文件 @
2aa3b6d8
...
...
@@ -2,8 +2,8 @@ package xiangshan.backend.decode
import
chisel3._
import
chisel3.util._
import
noop.
{
ALUOpType
,
NOOPTrap
}
import
xiangshan.
{
FuType
,
HasXSParameter
}
import
xiangshan.backend._
import
xiangshan.backend.decode.isa._
trait
HasInstrType
{
...
...
@@ -36,7 +36,7 @@ object FuOpType {
object
Instructions
extends
HasInstrType
with
HasXSParameter
{
def
NOP
=
0x00000013
.
U
val
DecodeDefault
=
List
(
InstrN
,
FuType
.
alu
,
ALUOpType
.
sll
)
def
DecodeTable
=
RVIInstr
.
table
++
NOOP
Trap
.
table
++
def
DecodeTable
=
RVIInstr
.
table
++
XS
Trap
.
table
++
(
if
(
HasMExtension
)
RVMInstr
.
table
else
Nil
)
// ++
// (if (HasCExtension) RVCInstr.table else Nil) ++
// (if (HasFPU) RVFInstr.table ++ RVDInstr.table else Nil) ++
...
...
src/main/scala/xiangshan/backend/decode/Decoder.scala
浏览文件 @
2aa3b6d8
...
...
@@ -3,7 +3,6 @@ package xiangshan.backend.decode
import
chisel3._
import
chisel3.util._
import
chisel3.util.experimental.BoringUtils
import
noop.NOOPTrap
import
xiangshan._
import
utils.
{
LookupTree
,
SignExt
,
ZeroExt
}
import
xiangshan.backend._
...
...
@@ -141,7 +140,6 @@ class Decoder extends XSModule with HasInstrType {
val
BlockList
=
Seq
(
)
io
.
out
.
ctrl
.
isXSTrap
:=
(
instr
(
31
,
0
)
===
NOOPTrap
.
TRAP
)
io
.
out
.
ctrl
.
noSpecExec
:=
NoSpecList
.
map
(
j
=>
io
.
out
.
ctrl
.
fuType
===
j
).
foldRight
(
false
.
B
)((
sum
,
i
)
=>
sum
|
i
)
io
.
out
.
ctrl
.
isBlocked
:=
DontCare
// (
...
...
@@ -169,7 +167,10 @@ class Decoder extends XSModule with HasInstrType {
io
.
out
.
cf
.
exceptionVec
(
instrPageFault
)
:=
io
.
in
.
exceptionVec
(
instrPageFault
)
io
.
out
.
cf
.
exceptionVec
(
instrAccessFault
)
:=
io
.
in
.
pc
(
VAddrBits
-
1
,
PAddrBits
).
orR
&&
!
vmEnable
io
.
out
.
ctrl
.
isXSTrap
:=
(
instr
===
NOOPTrap
.
TRAP
)
io
.
out
.
ctrl
.
isXSTrap
:=
(
instr
===
XSTrap
.
TRAP
)
when
(
io
.
out
.
ctrl
.
isXSTrap
){
io
.
out
.
ctrl
.
lsrc1
:=
10.
U
// a0
}
// io.isWFI := (instr === Priviledged.WFI) && io.in.valid
}
src/main/scala/xiangshan/backend/decode/XSTrap.scala
0 → 100644
浏览文件 @
2aa3b6d8
package
xiangshan.backend.decode
import
chisel3._
import
chisel3.util._
import
xiangshan.FuType
import
xiangshan.backend.ALUOpType
object
XSTrap
extends
HasInstrType
{
def
StateGoodTrap
=
0.
U
def
StateBadTrap
=
1.
U
def
StateInvOpcode
=
2.
U
def
StateRunning
=
3.
U
/*
calculate as ADDI => addi zero, a0, 0
replace rs '?????' with '01010'(a0) in decode stage
*/
def
TRAP
=
BitPat
(
"b000000000000_?????_000_00000_1101011"
)
val
table
=
Array
(
TRAP
->
List
(
InstrI
,
FuType
.
alu
,
ALUOpType
.
add
))
}
src/main/scala/xiangshan/backend/exu/Alu.scala
浏览文件 @
2aa3b6d8
...
...
@@ -5,50 +5,7 @@ import chisel3.util._
import
xiangshan._
import
xiangshan.FuType._
import
xiangshan.utils._
import
xiangshan.backend.regfile.RfWritePort
object
ALUOpType
{
def
add
=
"b000000"
.
U
def
sll
=
"b000001"
.
U
def
slt
=
"b000010"
.
U
def
sltu
=
"b000011"
.
U
def
xor
=
"b000100"
.
U
def
srl
=
"b000101"
.
U
def
or
=
"b000110"
.
U
def
and
=
"b000111"
.
U
def
sub
=
"b001000"
.
U
def
sra
=
"b001101"
.
U
def
addw
=
"b100000"
.
U
def
subw
=
"b101000"
.
U
def
sllw
=
"b100001"
.
U
def
srlw
=
"b100101"
.
U
def
sraw
=
"b101101"
.
U
def
isWordOp
(
func
:
UInt
)
=
func
(
5
)
// TODO: move jal/jalr/call/ret from ALU to BRU&CSR
def
jal
=
"b011000"
.
U
def
jalr
=
"b011010"
.
U
// def cjalr= "b111010".U // pc + 2 instead of 4
def
beq
=
"b010000"
.
U
def
bne
=
"b010001"
.
U
def
blt
=
"b010100"
.
U
def
bge
=
"b010101"
.
U
def
bltu
=
"b010110"
.
U
def
bgeu
=
"b010111"
.
U
// for RAS
def
call
=
"b011100"
.
U
def
ret
=
"b011110"
.
U
// def pcPlus2(func: UInt) = func(5)//[important]
def
isBranch
(
func
:
UInt
)
=
func
(
4
,
3
)===
2.
U
def
isBru
(
func
:
UInt
)
=
func
(
4
)
def
isJump
(
func
:
UInt
)
=
func
(
4
,
3
)===
3.
U
//isBru(func) && !isBranch(func)
def
getBranchType
(
func
:
UInt
)
=
func
(
2
,
1
)
def
isBranchInvert
(
func
:
UInt
)
=
func
(
0
)
}
import
xiangshan.backend._
class
Alu
extends
Exu
(
alu
.
litValue
(),
hasRedirect
=
true
)
{
override
def
toString
:
String
=
"Alu"
...
...
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
浏览文件 @
2aa3b6d8
...
...
@@ -6,8 +6,8 @@ import xiangshan._
import
xiangshan.backend.rename.FreeListPtr
import
xiangshan.utils._
trait
IQConst
{
val
iqSize
=
8
trait
IQConst
extends
HasXSParameter
{
val
iqSize
=
IssQueSize
val
iqIdxWidth
=
log2Up
(
iqSize
)
}
...
...
@@ -43,6 +43,9 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
// use bypass uops to speculative wake-up
val
bypassUops
=
if
(
useBypass
)
Vec
(
bypassCnt
,
Flipped
(
ValidIO
(
new
MicroOp
)))
else
null
val
bypassData
=
if
(
useBypass
)
Vec
(
bypassCnt
,
Flipped
(
ValidIO
(
new
ExuOutput
)))
else
null
// to Dispatch
val
numExist
=
Output
(
UInt
((
iqIdxWidth
+
1
).
W
))
})
val
srcAllNum
=
3
...
...
@@ -92,7 +95,9 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
val
popOne
=
Wire
(
Bool
())
io
.
enqCtrl
.
ready
:=
!
full
||
popOne
val
enqSelIq
=
Wire
(
UInt
(
iqIdxWidth
.
W
))
val
enqSrcRdy
=
List
(
Mux
(
SrcType
.
isPcImm
(
io
.
enqCtrl
.
bits
.
src1State
),
true
.
B
,
io
.
enqCtrl
.
bits
.
src1State
===
SrcState
.
rdy
),
Mux
(
SrcType
.
isPcImm
(
io
.
enqCtrl
.
bits
.
src2State
),
true
.
B
,
io
.
enqCtrl
.
bits
.
src2State
===
SrcState
.
rdy
),
Mux
(
SrcType
.
isPcImm
(
io
.
enqCtrl
.
bits
.
src3State
),
true
.
B
,
io
.
enqCtrl
.
bits
.
src3State
===
SrcState
.
rdy
))
val
enqSrcRdy
=
List
(
Mux
(
SrcType
.
isPcImm
(
io
.
enqCtrl
.
bits
.
ctrl
.
src1Type
),
true
.
B
,
io
.
enqCtrl
.
bits
.
src1State
===
SrcState
.
rdy
),
Mux
(
SrcType
.
isPcImm
(
io
.
enqCtrl
.
bits
.
ctrl
.
src2Type
),
true
.
B
,
io
.
enqCtrl
.
bits
.
src2State
===
SrcState
.
rdy
),
Mux
(
SrcType
.
isPcImm
(
io
.
enqCtrl
.
bits
.
ctrl
.
src3Type
),
true
.
B
,
io
.
enqCtrl
.
bits
.
src3State
===
SrcState
.
rdy
))
// state enq
when
(
enqFire
)
{
...
...
@@ -184,7 +189,7 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
// redirect issQue
val
redHitVec
=
List
.
tabulate
(
iqSize
)(
i
=>
issQue
(
i
).
uop
.
brTag
.
needFlush
(
io
.
redirect
))
for
(
i
<-
0
until
iqSize
)
{
for
(
i
<-
validQue
.
indices
)
{
when
(
redHitVec
(
i
)
&&
validQue
(
i
))
{
validQue
(
i
)
:=
false
.
B
}
...
...
@@ -229,19 +234,22 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
idQue
(
tail
)
)
// Note: direct by IQue's idx, different from deqSel
io
.
numExist
:=
tailAll
assert
(
tailAll
<
9.
U
)
//-----------------------------------------
// Wakeup and Bypass
//-----------------------------------------
if
(
wakeupCnt
>
0
)
{
val
cdbValid
=
List
.
tabulate
(
wakeupCnt
)(
i
=>
io
.
wakeUpPorts
(
i
)
.
valid
)
val
cdbData
=
List
.
tabulate
(
wakeupCnt
)(
i
=>
io
.
wakeUpPorts
(
i
)
.
bits
.
data
)
val
cdbPdest
=
List
.
tabulate
(
wakeupCnt
)(
i
=>
io
.
wakeUpPorts
(
i
)
.
bits
.
uop
.
pdest
)
val
cdbrfWen
=
List
.
tabulate
(
wakeupCnt
)(
i
=>
io
.
wakeUpPorts
(
i
)
.
bits
.
uop
.
ctrl
.
rfWen
)
val
cdbfpWen
=
List
.
tabulate
(
wakeupCnt
)(
i
=>
io
.
wakeUpPorts
(
i
)
.
bits
.
uop
.
ctrl
.
fpWen
)
val
cdbValid
=
io
.
wakeUpPorts
.
map
(
_
.
valid
)
val
cdbData
=
io
.
wakeUpPorts
.
map
(
_
.
bits
.
data
)
val
cdbPdest
=
io
.
wakeUpPorts
.
map
(
_
.
bits
.
uop
.
pdest
)
val
cdbrfWen
=
io
.
wakeUpPorts
.
map
(
_
.
bits
.
uop
.
ctrl
.
rfWen
)
val
cdbfpWen
=
io
.
wakeUpPorts
.
map
(
_
.
bits
.
uop
.
ctrl
.
fpWen
)
for
(
i
<-
0
until
iqSize
)
{
for
(
i
<-
idQue
.
indices
)
{
// Should be IssQue.indices but Mem() does not support
for
(
j
<-
0
until
srcListenNum
)
{
val
hitVec
=
List
.
tabulate
(
wakeupCnt
)
(
k
=>
psrc
(
i
)(
j
)
===
cdbPdest
(
k
)
&&
cdbValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
cdbrfWen
(
k
)
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
cdbfpWen
(
k
)))
val
hitVec
=
cdbValid
.
indices
.
map
(
k
=>
psrc
(
i
)(
j
)
===
cdbPdest
(
k
)
&&
cdbValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
cdbrfWen
(
k
)
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
cdbfpWen
(
k
)))
val
hit
=
ParallelOR
(
hitVec
).
asBool
val
data
=
ParallelMux
(
hitVec
zip
cdbData
)
when
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
)
{
...
...
@@ -249,36 +257,36 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
srcRdyVec
(
i
)(
j
)
:=
true
.
B
}
// XSDebug(validQue(i) && !srcRdyVec(i)(j) && hit, "WakeUp: Sel:%d Src:(%d|%d) Rdy:%d Hit:%d HitVec:%b Data:%x\n", i.U, j.U, psrc(i)(j), srcRdyVec(i)(j), hit, VecInit(hitVec).asUInt, data)
for
(
k
<-
0
until
wakeupCnt
)
{
for
(
k
<-
cdbValid
.
indices
)
{
XSDebug
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
&&
hitVec
(
k
),
"WakeUpHit: IQIdx:%d Src%d:%d Ports:%d Data:%x Pc:%x RoqIdx:%x\n"
,
i
.
U
,
j
.
U
,
psrc
(
i
)(
j
),
k
.
U
,
cdbData
(
k
),
io
.
wakeUpPorts
(
k
).
bits
.
uop
.
cf
.
pc
,
io
.
wakeUpPorts
(
k
).
bits
.
uop
.
roqIdx
)
}
}
}
}
if
(
useBypass
)
{
val
bpPdest
=
List
.
tabulate
(
bypassCnt
)(
i
=>
io
.
bypassUops
(
i
)
.
bits
.
pdest
)
val
bpValid
=
List
.
tabulate
(
bypassCnt
)(
i
=>
io
.
bypassUops
(
i
)
.
valid
)
val
bpData
=
List
.
tabulate
(
bypassCnt
)(
i
=>
io
.
bypassData
(
i
)
.
bits
.
data
)
val
bprfWen
=
List
.
tabulate
(
bypassCnt
)(
i
=>
io
.
bypassUops
(
i
)
.
bits
.
ctrl
.
rfWen
)
val
bpfpWen
=
List
.
tabulate
(
bypassCnt
)(
i
=>
io
.
bypassUops
(
i
)
.
bits
.
ctrl
.
fpWen
)
val
bpPdest
=
io
.
bypassUops
.
map
(
_
.
bits
.
pdest
)
val
bpValid
=
io
.
bypassUops
.
map
(
_
.
valid
)
val
bpData
=
io
.
bypassData
.
map
(
_
.
bits
.
data
)
val
bprfWen
=
io
.
bypassUops
.
map
(
_
.
bits
.
ctrl
.
rfWen
)
val
bpfpWen
=
io
.
bypassUops
.
map
(
_
.
bits
.
ctrl
.
fpWen
)
for
(
i
<-
0
until
iqSize
)
{
for
(
i
<-
idQue
.
indices
)
{
// Should be IssQue.indices but Mem() does not support
for
(
j
<-
0
until
srcListenNum
)
{
val
hitVec
=
List
.
tabulate
(
bypassCnt
)
(
k
=>
psrc
(
i
)(
j
)
===
bpPdest
(
k
)
&&
bpValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
bprfWen
(
k
)
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
bpfpWen
(
k
)))
val
hitVec
=
bpValid
.
indices
.
map
(
k
=>
psrc
(
i
)(
j
)
===
bpPdest
(
k
)
&&
bpValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
bprfWen
(
k
)
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
bpfpWen
(
k
)))
val
hitVecNext
=
hitVec
.
map
(
RegNext
(
_
))
val
hit
=
ParallelOR
(
hitVec
).
asBool
when
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
)
{
srcRdyVec
(
i
)(
j
)
:=
true
.
B
// FIXME: if uncomment the up comment, will cause combiantional loop, but it is Mem type??
srcRdyVec
(
i
)(
j
)
:=
true
.
B
}
when
(
RegNext
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
))
{
srcDataWire
(
i
)(
j
)
:=
PriorityMux
(
hitVecNext
zip
bpData
)
}
// XSDebug(validQue(i) && !srcRdyVec(i)(j) && hit, "BypassCtrl: Sel:%d Src:(%d|%d) Rdy:%d Hit:%d HitVec:%b\n", i.U, j.U, psrc(i)(j), srcRdyVec(i)(j), hit, VecInit(hitVec).asUInt)
for
(
k
<-
0
until
bypassCnt
)
{
for
(
k
<-
bpValid
.
indices
)
{
XSDebug
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
&&
hitVec
(
k
),
"BypassCtrlHit: IQIdx:%d Src%d:%d Ports:%d Pc:%x RoqIdx:%x\n"
,
i
.
U
,
j
.
U
,
psrc
(
i
)(
j
),
k
.
U
,
io
.
bypassUops
(
k
).
bits
.
cf
.
pc
,
io
.
bypassUops
(
k
).
bits
.
roqIdx
)
}
// XSDebug(RegNext(validQue(i) && !srcRdyVec(i)(j) && hit), "BypassData: Sel:%d Src:(%d|%d) HitVecNext:%b Data:%x (for last cycle's Ctrl)\n", i.U, j.U, psrc(i)(j), VecInit(hitVecNext).asUInt, ParallelMux(hitVecNext zip bpData))
for
(
k
<-
0
until
bypassCnt
)
{
for
(
k
<-
bpValid
.
indices
)
{
XSDebug
(
RegNext
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
&&
hitVec
(
k
)),
"BypassDataHit: IQIdx:%d Src%d:%d Ports:%d Data:%x Pc:%x RoqIdx:%x\n"
,
i
.
U
,
j
.
U
,
psrc
(
i
)(
j
),
k
.
U
,
bpData
(
k
),
io
.
bypassUops
(
k
).
bits
.
cf
.
pc
,
io
.
bypassUops
(
k
).
bits
.
roqIdx
)
}
}
...
...
@@ -289,7 +297,7 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
val
enqPsrc
=
List
(
enqCtrl
.
bits
.
psrc1
,
enqCtrl
.
bits
.
psrc2
,
enqCtrl
.
bits
.
psrc3
)
val
enqSrcType
=
List
(
enqCtrl
.
bits
.
ctrl
.
src1Type
,
enqCtrl
.
bits
.
ctrl
.
src2Type
,
enqCtrl
.
bits
.
ctrl
.
src3Type
)
for
(
i
<-
0
until
srcListenNum
)
{
val
hitVec
=
List
.
tabulate
(
bypassCnt
)
(
j
=>
enqPsrc
(
i
)===
bpPdest
(
j
)
&&
bpValid
(
j
)
&&
(
enqSrcType
(
i
)===
SrcType
.
reg
&&
bprfWen
(
j
)
||
enqSrcType
(
i
)===
SrcType
.
fp
&&
bpfpWen
(
j
)))
val
hitVec
=
bpValid
.
indices
.
map
(
j
=>
enqPsrc
(
i
)===
bpPdest
(
j
)
&&
bpValid
(
j
)
&&
(
enqSrcType
(
i
)===
SrcType
.
reg
&&
bprfWen
(
j
)
||
enqSrcType
(
i
)===
SrcType
.
fp
&&
bpfpWen
(
j
)))
val
hitVecNext
=
hitVec
.
map
(
RegNext
(
_
))
val
hit
=
ParallelOR
(
hitVec
).
asBool
when
(
enqFire
&&
hit
&&
!
enqSrcRdy
(
i
))
{
...
...
@@ -299,17 +307,17 @@ class IssueQueue(val fuTypeInt: BigInt, val wakeupCnt: Int, val bypassCnt: Int =
srcDataWire
(
enqSelIqNext
)(
i
)
:=
ParallelMux
(
hitVecNext
zip
bpData
)
}
// XSDebug(enqFire && hit, "EnqBypassCtrl: enqSelIq:%d Src:(%d|%d) Hit:%d HitVec:%b \n", enqSelIq, i.U, enqPsrc(i), hit, VecInit(hitVec).asUInt)
for
(
k
<-
0
until
bypassCnt
)
{
for
(
k
<-
bpValid
.
indices
)
{
XSDebug
(
enqFire
&&
hit
&&
!
enqSrcRdy
(
i
)
&&
hitVec
(
k
),
"EnqBypassCtrlHit: enqSelIq:%d Src%d:%d Ports:%d Pc:%x RoqIdx:%x\n"
,
enqSelIq
,
i
.
U
,
enqPsrc
(
i
),
k
.
U
,
io
.
bypassUops
(
k
).
bits
.
cf
.
pc
,
io
.
bypassUops
(
k
).
bits
.
roqIdx
)
}
// XSDebug(RegNext(enqFire && hit), "EnqBypassData: enqSelIqNext:%d Src:(%d|%d) HitVecNext:%b Data:%x (for last cycle's Ctrl)\n", enqSelIqNext, i.U, enqPsrc(i), VecInit(hitVecNext).asUInt, ParallelMux(hitVecNext zip bpData))
for
(
k
<-
0
until
bypassCnt
)
{
for
(
k
<-
bpValid
.
indices
)
{
XSDebug
(
RegNext
(
enqFire
&&
hit
&&
!
enqSrcRdy
(
i
)
&&
hitVec
(
k
)),
"EnqBypassDataHit: enqSelIq:%d Src%d:%d Ports:%d Data:%x Pc:%x RoqIdx:%x\n"
,
enqSelIq
,
i
.
U
,
enqPsrc
(
i
),
k
.
U
,
bpData
(
k
),
io
.
bypassUops
(
k
).
bits
.
cf
.
pc
,
io
.
bypassUops
(
k
).
bits
.
roqIdx
)
}
}
// send out bypass
assert
(
fixedDelay
==
1
)
// only support fixedDelay is 1 now
require
(
fixedDelay
==
1
)
// only support fixedDelay is 1 now
val
sel
=
io
.
selectedUop
sel
.
valid
:=
toIssFire
sel
.
bits
:=
DontCare
...
...
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
2aa3b6d8
...
...
@@ -5,6 +5,7 @@ import chisel3.util._
import
xiangshan._
import
xiangshan.utils._
import
chisel3.util.experimental.BoringUtils
import
xiangshan.backend.decode.XSTrap
// A "just-enough" Roq
class
Roq
(
implicit
val
p
:
XSConfig
)
extends
XSModule
{
...
...
@@ -216,14 +217,23 @@ class Roq(implicit val p: XSConfig) extends XSModule {
val
wdata
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
val
wdst
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
32.
W
)))
val
wpc
=
Wire
(
Vec
(
CommitWidth
,
UInt
(
VAddrBits
.
W
)))
val
trapVec
=
Wire
(
Vec
(
CommitWidth
,
Bool
()))
for
(
i
<-
0
until
CommitWidth
){
// io.commits(i).valid
skip
(
i
)
:=
exuDebug
(
ringBufferTail
+
i
.
U
).
isMMIO
&&
io
.
commits
(
i
).
valid
wen
(
i
)
:=
io
.
commits
(
i
).
valid
&&
microOp
(
ringBufferTail
+
i
.
U
).
ctrl
.
rfWen
&&
microOp
(
ringBufferTail
+
i
.
U
).
ctrl
.
ldest
=/=
0.
U
wdata
(
i
)
:=
exuData
(
ringBufferTail
+
i
.
U
)
wdst
(
i
)
:=
microOp
(
ringBufferTail
+
i
.
U
).
ctrl
.
ldest
wpc
(
i
)
:=
microOp
(
ringBufferTail
+
i
.
U
).
cf
.
pc
// io.commits(i).valid
val
idx
=
ringBufferTail
+
i
.
U
val
uop
=
microOp
(
idx
)
skip
(
i
)
:=
exuDebug
(
idx
).
isMMIO
&&
io
.
commits
(
i
).
valid
wen
(
i
)
:=
io
.
commits
(
i
).
valid
&&
uop
.
ctrl
.
rfWen
&&
uop
.
ctrl
.
ldest
=/=
0.
U
wdata
(
i
)
:=
exuData
(
idx
)
wdst
(
i
)
:=
uop
.
ctrl
.
ldest
wpc
(
i
)
:=
uop
.
cf
.
pc
trapVec
(
i
)
:=
io
.
commits
(
i
).
valid
&&
(
state
===
s_idle
)
&&
uop
.
ctrl
.
isXSTrap
}
val
instrCnt
=
RegInit
(
0.
U
(
64.
W
))
instrCnt
:=
instrCnt
+
retireCounter
val
hitTrap
=
trapVec
.
reduce
(
_
||
_
)
val
trapCode
=
PriorityMux
(
wdata
.
zip
(
trapVec
).
map
(
x
=>
x
.
_2
->
x
.
_1
))
val
trapPC
=
PriorityMux
(
wpc
.
zip
(
trapVec
).
map
(
x
=>
x
.
_2
->
x
.
_1
))
if
(!
p
.
FPGAPlatform
){
BoringUtils
.
addSource
(
RegNext
(
retireCounter
),
"difftestCommit"
)
...
...
@@ -247,5 +257,26 @@ class Roq(implicit val p: XSConfig) extends XSModule {
BoringUtils
.
addSource
(
emptyCsr
,
"difftestSepc"
)
BoringUtils
.
addSource
(
emptyCsr
,
"difftestMcause"
)
BoringUtils
.
addSource
(
emptyCsr
,
"difftestScause"
)
class
Monitor
extends
BlackBox
{
val
io
=
IO
(
new
Bundle
{
val
clk
=
Input
(
Clock
())
val
reset
=
Input
(
Reset
())
val
isNoopTrap
=
Input
(
Bool
())
val
trapCode
=
Input
(
UInt
(
32.
W
))
val
trapPC
=
Input
(
UInt
(
64.
W
))
val
cycleCnt
=
Input
(
UInt
(
64.
W
))
val
instrCnt
=
Input
(
UInt
(
64.
W
))
})
}
val
debugMonitor
=
Module
(
new
Monitor
)
debugMonitor
.
io
.
clk
:=
this
.
clock
debugMonitor
.
io
.
reset
:=
this
.
reset
debugMonitor
.
io
.
isNoopTrap
:=
hitTrap
debugMonitor
.
io
.
trapCode
:=
trapCode
debugMonitor
.
io
.
trapPC
:=
trapPC
debugMonitor
.
io
.
cycleCnt
:=
GTimer
()
debugMonitor
.
io
.
instrCnt
:=
instrCnt
}
}
src/main/scala/xiangshan/frontend/Frontend.scala
浏览文件 @
2aa3b6d8
...
...
@@ -14,10 +14,13 @@ class Frontend extends XSModule {
val
fakeIFU
=
Module
(
new
FakeIFU
)
val
ibuffer
=
Module
(
new
Ibuffer
)
fakeIFU
.
io
.
redirect
:=
io
.
backend
.
redirect
val
needFlush
=
io
.
backend
.
redirectInfo
.
flush
()
fakeIFU
.
io
.
redirect
.
valid
:=
needFlush
fakeIFU
.
io
.
redirect
.
bits
:=
io
.
backend
.
redirectInfo
.
redirect
ibuffer
.
io
.
in
<>
fakeIFU
.
io
.
fetchPacket
ibuffer
.
io
.
flush
:=
io
.
backend
.
redirect
.
valid
ibuffer
.
io
.
flush
:=
needFlush
io
.
backend
.
cfVec
<>
ibuffer
.
io
.
out
...
...
src/main/scala/xiangshan/utils/PriorityMuxDefault.scala
0 → 100644
浏览文件 @
2aa3b6d8
package
xiangshan.utils
import
chisel3._
object
PriorityMuxDefault
{
def
apply
[
T
<:
Data
](
in
:
Seq
[(
Bool
,
T
)],
default
:
T
)
:
T
=
{
in
.
size
match
{
case
1
=>
Mux
(
in
.
head
.
_1
,
in
.
head
.
_2
,
default
)
case
_
=>
Mux
(
in
.
head
.
_1
,
in
.
head
.
_2
,
PriorityMuxDefault
(
in
.
tail
,
default
))
}
}
}
object
PriorityEncoderDefault
{
def
apply
(
in
:
Seq
[
Bool
],
default
:
UInt
)
:
UInt
=
{
PriorityMuxDefault
(
in
.
zipWithIndex
.
map
(
x
=>
x
.
_1
->
x
.
_2
.
U
),
default
)
}
}
\ No newline at end of file
src/test/csrc/emu.h
浏览文件 @
2aa3b6d8
...
...
@@ -149,10 +149,12 @@ class Emulator {
tfp
->
open
(
"vlt_dump.vcd"
);
// Open the dump file
#endif
while
(
!
is_finish
()
&&
n
>
0
)
{
while
(
n
>
0
)
{
single_cycle
();
n
--
;
if
(
is_finish
())
return
;
if
(
lastcommit
-
n
>
stuck_limit
&&
hascommit
)
{
eprintf
(
"No instruction commits for %d cycles, maybe get stuck
\n
"
"(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)
\n
"
,
...
...
src/test/csrc/monitor.cpp
浏览文件 @
2aa3b6d8
...
...
@@ -39,6 +39,8 @@ int display_trapinfo(uint64_t max_cycles) {
case
STATE_RUNNING
:
eprintf
(
ANSI_COLOR_RED
"Timeout after %"
PRIx64
" cycles
\n
"
ANSI_COLOR_RESET
,
max_cycles
);
break
;
default:
eprintf
(
ANSI_COLOR_RED
"Unknown trap code: %d
\n
"
,
g_trapCode
);
}
double
ipc
=
(
double
)
g_instrCnt
/
g_cycleCnt
;
...
...
src/test/scala/top/XSSim.scala
浏览文件 @
2aa3b6d8
...
...
@@ -9,16 +9,16 @@ import chisel3.stage.ChiselGeneratorAnnotation
import
device.AXI4RAM
import
xiangshan._
class
DiffTestIO
extends
Bundle
{
val
r
=
Output
(
Vec
(
64
,
UInt
(
64
.
W
)))
class
DiffTestIO
extends
XS
Bundle
{
val
r
=
Output
(
Vec
(
64
,
UInt
(
XLEN
.
W
)))
val
commit
=
Output
(
UInt
(
32.
W
))
val
thisPC
=
Output
(
UInt
(
64
.
W
))
val
thisPC
=
Output
(
UInt
(
VAddrBits
.
W
))
val
thisINST
=
Output
(
UInt
(
32.
W
))
val
skip
=
Output
(
UInt
(
32.
W
))
val
wen
=
Output
(
UInt
(
32.
W
))
val
wdata
=
Output
(
Vec
(
6
,
UInt
(
64
.
W
)))
// set difftest width to 6
val
wdst
=
Output
(
Vec
(
6
,
UInt
(
32.
W
)))
// set difftest width to 6
val
wpc
=
Output
(
Vec
(
6
,
UInt
(
39
.
W
)))
// set difftest width to 6
val
wdata
=
Output
(
Vec
(
CommitWidth
,
UInt
(
XLEN
.
W
)))
// set difftest width to 6
val
wdst
=
Output
(
Vec
(
CommitWidth
,
UInt
(
32.
W
)))
// set difftest width to 6
val
wpc
=
Output
(
Vec
(
CommitWidth
,
UInt
(
VAddrBits
.
W
)))
// set difftest width to 6
val
isRVC
=
Output
(
Bool
())
val
intrNO
=
Output
(
UInt
(
64.
W
))
...
...
src/test/scala/xiangshan/backend/brq/BrqTest.scala
0 → 100644
浏览文件 @
2aa3b6d8
package
xiangshan.backend.brq
import
org.scalatest._
import
chiseltest._
import
chisel3._
import
chisel3.experimental.BundleLiterals._
import
chisel3.util._
import
chiseltest.experimental.TestOptionBuilder._
import
chiseltest.internal.VerilatorBackendAnnotation
import
xiangshan._
import
xiangshan.testutils._
import
xiangshan.testutils.TestCaseGenerator._
import
scala.util.Random
class
BrqTest
extends
FlatSpec
with
ChiselScalatestTester
with
Matchers
with
ParallelTestExecution
with
HasPartialDecoupledDriver
{
it
should
""
in
{
test
(
new
Brq
{
AddSinks
()
}).
withAnnotations
(
Seq
(
VerilatorBackendAnnotation
))
{
c
=>
def
genEnqReq
(
x
:
=>
DecoupledIO
[
CfCtrl
],
pc
:
Long
)
=
{
chiselTypeOf
(
x
.
bits
).
Lit
(
_
.
cf
.
pc
->
pc
.
U
)
}
def
genExuWb
(
exuRedirect
:
=>
Valid
[
ExuOutput
],
tagIdx
:
Int
,
tagFlag
:
Boolean
,
target
:
Long
)
=
{
chiselTypeOf
(
exuRedirect
.
bits
).
Lit
(
_
.
redirect
.
brTag
.
value
->
tagIdx
.
U
,
_
.
redirect
.
brTag
.
flag
->
tagFlag
.
B
,
_
.
redirect
.
target
->
target
.
U
)
}
c
.
io
.
enqReqs
.
head
.
initSource
().
setSourceClock
(
c
.
clock
)
var
brqPtrSeq
=
Seq
[(
BigInt
,
Boolean
)]()
for
(
i
<-
0
until
10
)
{
val
enqPort
=
c
.
io
.
enqReqs
.
head
enqPort
.
enqueuePartial
(
genEnqReq
(
enqPort
,
i
*
0x1000
))
}
var
enqTags
=
List
.
tabulate
(
10
)(
i
=>
i
)
val
misPred
=
Random
.
nextInt
(
10
)
println
(
s
"enqTags:$enqTags misPredTag:$misPred"
)
enqTags
=
enqTags
.
take
(
misPred
+
1
)
var
deqTags
=
List
[
Int
]()
def
checkDeq
=
{
if
(
c
.
io
.
out
.
valid
.
peek
().
litToBoolean
)
{
deqTags
=
deqTags
:+
c
.
io
.
redirect
.
bits
.
brTag
.
value
.
peek
().
litValue
().
toInt
println
(
s
"====deq tags:$deqTags===="
)
}
}
println
(
"====Start random write back===="
)
val
wbPort
=
c
.
io
.
exuRedirect
.
head
//-----------------write back-----------------//
while
(
enqTags
.
nonEmpty
)
{
val
idx
=
Random
.
nextInt
(
enqTags
.
size
)
val
tag
=
enqTags
(
idx
)
println
(
s
"====write tag:$tag back to Brq===="
)
enqTags
=
enqTags
.
filter
(
x
=>
x
!=
tag
)
wbPort
.
valid
.
poke
(
true
.
B
)
wbPort
.
bits
.
pokePartial
(
genExuWb
(
wbPort
,
tag
,
tagFlag
=
false
,
if
(
tag
==
misPred
)
0xffff
else
tag
*
0x1000
+
4
)
)
checkDeq
c
.
clock
.
step
(
1
)
wbPort
.
valid
.
poke
(
false
.
B
)
for
(
i
<-
0
until
Random
.
nextInt
(
3
))
{
checkDeq
c
.
clock
.
step
(
1
)
}
}
while
(
deqTags
.
size
!=
misPred
+
1
)
{
checkDeq
c
.
clock
.
step
(
1
)
}
c
.
clock
.
step
(
10
)
val
left
=
deqTags
.
takeWhile
(
x
=>
x
!=
misPred
)
val
right
=
deqTags
.
dropWhile
(
x
=>
x
!=
misPred
).
drop
(
1
)
println
(
s
"deq before mispred: $left"
)
println
(
s
"deq after mispred: $right"
)
def
isValidDeqSeq
(
in
:
Seq
[
Int
])
:
Boolean
=
{
for
(
i
<-
1
until
in
.
size
){
if
(
in
(
i
)
==
in
(
i
-
1
))
return
false
}
true
}
assert
(
isValidDeqSeq
(
left
)
&&
isValidDeqSeq
(
right
))
}
}
}
src/test/scala/xiangshan/testutils/TestCaseGenerator.scala
浏览文件 @
2aa3b6d8
...
...
@@ -6,7 +6,7 @@ import chisel3.experimental.BundleLiterals._
import
chiseltest._
import
noop.MDUOpType
import
xiangshan._
import
xiangshan.backend.
exu.
{
ALUOpType
,
LSUOpType
}
import
xiangshan.backend.
_
object
TestCaseGenerator
{
...
...
@@ -61,15 +61,15 @@ object TestCaseGenerator {
}
def
genLsuLd
(
x
:
=>
ExuInput
,
base
:
Long
,
offset
:
Long
)
=
genLsuInput
(
L
S
UOpType
.
ld
)(
x
,
base
,
offset
,
0
)
genLsuInput
(
L
D
UOpType
.
ld
)(
x
,
base
,
offset
,
0
)
def
genLsuLw
(
x
:
=>
ExuInput
,
base
:
Long
,
offset
:
Long
)
=
genLsuInput
(
L
S
UOpType
.
lw
)(
x
,
base
,
offset
,
0
)
genLsuInput
(
L
D
UOpType
.
lw
)(
x
,
base
,
offset
,
0
)
def
genLsuSd
(
x
:
=>
ExuInput
,
base
:
Long
,
offset
:
Long
,
stData
:
Long
)
=
genLsuInput
(
LS
UOpType
.
sd
)(
x
,
base
,
offset
,
stData
)
genLsuInput
(
ST
UOpType
.
sd
)(
x
,
base
,
offset
,
stData
)
def
genLsuSw
(
x
:
=>
ExuInput
,
base
:
Long
,
offset
:
Long
,
stData
:
Long
)
=
genLsuInput
(
LS
UOpType
.
sw
)(
x
,
base
,
offset
,
stData
)
genLsuInput
(
ST
UOpType
.
sw
)(
x
,
base
,
offset
,
stData
)
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录