Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
0393f8ed
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,发现更多精彩内容 >>
提交
0393f8ed
编写于
1月 16, 2021
作者:
B
BigWhiteDog
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into L1DTest
上级
ea9d9c86
9471478b
变更
34
展开全部
隐藏空白更改
内联
并排
Showing
34 changed file
with
853 addition
and
524 deletion
+853
-524
.github/workflows/emu.yml
.github/workflows/emu.yml
+18
-4
build.sc
build.sc
+2
-2
src/main/scala/utils/DataModuleTemplate.scala
src/main/scala/utils/DataModuleTemplate.scala
+5
-33
src/main/scala/xiangshan/Bundle.scala
src/main/scala/xiangshan/Bundle.scala
+4
-2
src/main/scala/xiangshan/XSCore.scala
src/main/scala/xiangshan/XSCore.scala
+1
-0
src/main/scala/xiangshan/backend/CtrlBlock.scala
src/main/scala/xiangshan/backend/CtrlBlock.scala
+6
-3
src/main/scala/xiangshan/backend/FloatBlock.scala
src/main/scala/xiangshan/backend/FloatBlock.scala
+3
-2
src/main/scala/xiangshan/backend/IntegerBlock.scala
src/main/scala/xiangshan/backend/IntegerBlock.scala
+9
-4
src/main/scala/xiangshan/backend/brq/Brq.scala
src/main/scala/xiangshan/backend/brq/Brq.scala
+62
-25
src/main/scala/xiangshan/backend/decode/DecodeUnit.scala
src/main/scala/xiangshan/backend/decode/DecodeUnit.scala
+109
-29
src/main/scala/xiangshan/backend/dispatch/Dispatch2Int.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch2Int.scala
+27
-24
src/main/scala/xiangshan/backend/dispatch/IndexMapping.scala
src/main/scala/xiangshan/backend/dispatch/IndexMapping.scala
+3
-3
src/main/scala/xiangshan/backend/exu/Exu.scala
src/main/scala/xiangshan/backend/exu/Exu.scala
+1
-0
src/main/scala/xiangshan/backend/exu/JumpExeUnit.scala
src/main/scala/xiangshan/backend/exu/JumpExeUnit.scala
+5
-0
src/main/scala/xiangshan/backend/exu/Wb.scala
src/main/scala/xiangshan/backend/exu/Wb.scala
+34
-17
src/main/scala/xiangshan/backend/fu/Alu.scala
src/main/scala/xiangshan/backend/fu/Alu.scala
+20
-10
src/main/scala/xiangshan/backend/fu/CSR.scala
src/main/scala/xiangshan/backend/fu/CSR.scala
+163
-274
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
+3
-3
src/main/scala/xiangshan/backend/fu/Jump.scala
src/main/scala/xiangshan/backend/fu/Jump.scala
+12
-5
src/main/scala/xiangshan/backend/fu/util/CSRConst.scala
src/main/scala/xiangshan/backend/fu/util/CSRConst.scala
+188
-0
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
...scala/xiangshan/backend/issue/ReservationStationNew.scala
+34
-4
src/main/scala/xiangshan/backend/package.scala
src/main/scala/xiangshan/backend/package.scala
+4
-2
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+13
-10
src/main/scala/xiangshan/cache/dcacheWrapper.scala
src/main/scala/xiangshan/cache/dcacheWrapper.scala
+1
-1
src/main/scala/xiangshan/cache/dtlb.scala
src/main/scala/xiangshan/cache/dtlb.scala
+1
-1
src/main/scala/xiangshan/cache/missQueue.scala
src/main/scala/xiangshan/cache/missQueue.scala
+1
-1
src/main/scala/xiangshan/cache/wbu.scala
src/main/scala/xiangshan/cache/wbu.scala
+2
-2
src/main/scala/xiangshan/frontend/LoopPredictor.scala
src/main/scala/xiangshan/frontend/LoopPredictor.scala
+4
-2
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
+1
-0
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
+1
-0
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
+3
-1
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
+3
-1
src/main/scala/xiangshan/mem/sbuffer/NewSbuffer.scala
src/main/scala/xiangshan/mem/sbuffer/NewSbuffer.scala
+27
-14
src/test/scala/xiangshan/memend/SbufferTest.scala
src/test/scala/xiangshan/memend/SbufferTest.scala
+83
-45
未找到文件。
.github/workflows/emu.yml
浏览文件 @
0393f8ed
...
...
@@ -3,20 +3,34 @@ name: EMU Test
on
:
push
:
branches
:
[
master
,
update-ci
]
branches
:
[
master
]
pull_request
:
branches
:
[
master
]
jobs
:
build-emu
:
generate-verilog
:
runs-on
:
self-hosted
name
:
Make EMU
name
:
Generate Verilog
steps
:
-
uses
:
actions/checkout@v2
with
:
submodules
:
'
recursive'
-
name
:
Check Wiring
run
:
bash .github/workflows/check-usage.sh "BoringUtils" $GITHUB_WORKSPACE
-
name
:
set env
run
:
|
echo "NEMU_HOME=/home/ci-runner/xsenv/NEMU" >> $GITHUB_ENV
echo "NOOP_HOME=$GITHUB_WORKSPACE" >> $GITHUB_ENV
-
name
:
generate verilog file
run
:
make verilog SIM_ARGS=--dual-core
build-emu
:
runs-on
:
self-hosted
name
:
Make EMU
steps
:
-
uses
:
actions/checkout@v2
with
:
submodules
:
'
recursive'
-
name
:
Set env
run
:
|
echo "NEMU_HOME=/home/ci-runner/xsenv/NEMU" >> $GITHUB_ENV
...
...
@@ -25,7 +39,7 @@ jobs:
echo "AM_HOME=/home/ci-runner/xsenv/nexus-am" >> $GITHUB_ENV
-
name
:
Build EMU
run
:
make ./build/emu SIM_ARGS=--disable-all NEMU_HOME=$NEMU_HOME NOOP_HOME=$NOOP_HOME -j
6
0
make ./build/emu SIM_ARGS=--disable-all NEMU_HOME=$NEMU_HOME NOOP_HOME=$NOOP_HOME -j
22
0
-
name
:
Run cputest
run
:
|
CPU_TEST_DIR=$AM_HOME/tests/cputest
...
...
build.sc
浏览文件 @
0393f8ed
...
...
@@ -29,7 +29,7 @@ trait CommonModule extends ScalaModule {
}
val
chisel
=
Agg
(
ivy
"edu.berkeley.cs::chisel3:3.4.
0
"
ivy
"edu.berkeley.cs::chisel3:3.4.
1
"
)
object
`api-config-chipsalliance`
extends
CommonModule
{
...
...
@@ -103,4 +103,4 @@ object XiangShan extends CommonModule with SbtModule {
}
}
}
\ No newline at end of file
}
src/main/scala/utils/DataModuleTemplate.scala
浏览文件 @
0393f8ed
...
...
@@ -3,7 +3,7 @@ package utils
import
chisel3._
import
chisel3.util._
class
AsyncDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
Module
{
class
DataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
,
isSync
:
Boolean
)
extends
Module
{
val
io
=
IO
(
new
Bundle
{
val
raddr
=
Vec
(
numRead
,
Input
(
UInt
(
log2Up
(
numEntries
).
W
)))
val
rdata
=
Vec
(
numRead
,
Output
(
gen
))
...
...
@@ -15,8 +15,9 @@ class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int,
val
data
=
Mem
(
numEntries
,
gen
)
// read ports
val
raddr
=
if
(
isSync
)
(
RegNext
(
io
.
raddr
))
else
io
.
raddr
for
(
i
<-
0
until
numRead
)
{
io
.
rdata
(
i
)
:=
data
(
io
.
raddr
(
i
))
io
.
rdata
(
i
)
:=
data
(
raddr
(
i
))
}
// below is the write ports (with priorities)
...
...
@@ -34,34 +35,5 @@ class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int,
}
}
class
SyncDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
Module
{
val
io
=
IO
(
new
Bundle
{
val
raddr
=
Vec
(
numRead
,
Input
(
UInt
(
log2Up
(
numEntries
).
W
)))
val
rdata
=
Vec
(
numRead
,
Output
(
gen
))
val
wen
=
Vec
(
numWrite
,
Input
(
Bool
()))
val
waddr
=
Vec
(
numWrite
,
Input
(
UInt
(
log2Up
(
numEntries
).
W
)))
val
wdata
=
Vec
(
numWrite
,
Input
(
gen
))
})
val
data
=
Mem
(
numEntries
,
gen
)
// read ports
val
raddr_reg
=
RegNext
(
io
.
raddr
)
for
(
i
<-
0
until
numRead
)
{
io
.
rdata
(
i
)
:=
data
(
raddr_reg
(
i
))
}
// below is the write ports (with priorities)
for
(
i
<-
0
until
numWrite
)
{
when
(
io
.
wen
(
i
))
{
data
(
io
.
waddr
(
i
))
:=
io
.
wdata
(
i
)
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for
(
i
<-
0
until
numWrite
)
{
for
(
j
<-
i
+
1
until
numWrite
)
{
assert
(!(
io
.
wen
(
i
)
&&
io
.
wen
(
j
)
&&
io
.
waddr
(
i
)
===
io
.
waddr
(
j
)))
}
}
}
class
SyncDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
DataModuleTemplate
(
gen
,
numEntries
,
numRead
,
numWrite
,
true
)
class
AsyncDataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
)
extends
DataModuleTemplate
(
gen
,
numEntries
,
numRead
,
numWrite
,
false
)
src/main/scala/xiangshan/Bundle.scala
浏览文件 @
0393f8ed
...
...
@@ -6,7 +6,7 @@ import xiangshan.backend.SelImm
import
xiangshan.backend.brq.BrqPtr
import
xiangshan.backend.rename.FreeListPtr
import
xiangshan.backend.roq.RoqPtr
import
xiangshan.backend.decode.
XDecode
import
xiangshan.backend.decode.
{
ImmUnion
,
XDecode
}
import
xiangshan.mem.
{
LqPtr
,
SqPtr
}
import
xiangshan.frontend.PreDecodeInfo
import
xiangshan.frontend.HasBPUParameter
...
...
@@ -14,6 +14,7 @@ import xiangshan.frontend.HasTageParameter
import
xiangshan.frontend.HasIFUConst
import
xiangshan.frontend.GlobalHistory
import
utils._
import
scala.math.max
import
Chisel.experimental.chiselName
...
...
@@ -219,7 +220,7 @@ class CtrlSignals extends XSBundle {
val
flushPipe
=
Bool
()
// This inst will flush all the pipe when commit, like exception but can commit
val
isRVF
=
Bool
()
val
selImm
=
SelImm
()
val
imm
=
UInt
(
XLEN
.
W
)
val
imm
=
UInt
(
ImmUnion
.
maxLen
.
W
)
val
commitType
=
CommitType
()
val
fpu
=
new
FPUCtrlSignals
...
...
@@ -283,6 +284,7 @@ class ReplayPregReq extends XSBundle {
class
DebugBundle
extends
XSBundle
{
val
isMMIO
=
Bool
()
val
isPerfCnt
=
Bool
()
}
class
ExuInput
extends
XSBundle
{
...
...
src/main/scala/xiangshan/XSCore.scala
浏览文件 @
0393f8ed
...
...
@@ -425,6 +425,7 @@ class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer)
integerBlock
.
io
.
csrio
.
memExceptionVAddr
<>
memBlock
.
io
.
lsqio
.
exceptionAddr
.
vaddr
integerBlock
.
io
.
csrio
.
externalInterrupt
<>
io
.
externalInterrupt
integerBlock
.
io
.
csrio
.
tlb
<>
memBlock
.
io
.
tlbCsr
integerBlock
.
io
.
csrio
.
perfinfo
<>
ctrlBlock
.
io
.
roqio
.
toCSR
.
perfinfo
integerBlock
.
io
.
fenceio
.
sfence
<>
memBlock
.
io
.
sfence
integerBlock
.
io
.
fenceio
.
sbuffer
<>
memBlock
.
io
.
fenceToSbuffer
...
...
src/main/scala/xiangshan/backend/CtrlBlock.scala
浏览文件 @
0393f8ed
...
...
@@ -5,18 +5,19 @@ import chisel3.util._
import
utils._
import
xiangshan._
import
xiangshan.backend.decode.DecodeStage
import
xiangshan.backend.rename.
{
Rename
,
BusyTabl
e
}
import
xiangshan.backend.brq.
Brq
import
xiangshan.backend.rename.
{
BusyTable
,
Renam
e
}
import
xiangshan.backend.brq.
{
Brq
,
BrqPcRead
}
import
xiangshan.backend.dispatch.Dispatch
import
xiangshan.backend.exu._
import
xiangshan.backend.exu.Exu.exuConfigs
import
xiangshan.backend.regfile.RfReadPort
import
xiangshan.backend.roq.
{
Roq
,
Roq
Ptr
,
RoqCSRIO
}
import
xiangshan.backend.roq.
{
Roq
,
Roq
CSRIO
,
RoqPtr
}
import
xiangshan.mem.LsqEnqIO
class
CtrlToIntBlockIO
extends
XSBundle
{
val
enqIqCtrl
=
Vec
(
exuParameters
.
IntExuCnt
,
DecoupledIO
(
new
MicroOp
))
val
readRf
=
Vec
(
NRIntReadPorts
,
Flipped
(
new
RfReadPort
(
XLEN
)))
val
jumpPc
=
Output
(
UInt
(
VAddrBits
.
W
))
// int block only uses port 0~7
val
readPortIndex
=
Vec
(
exuParameters
.
IntExuCnt
,
Output
(
UInt
(
log2Ceil
(
8
/
2
).
W
)))
// TODO parameterize 8 here
val
redirect
=
ValidIO
(
new
Redirect
)
...
...
@@ -87,6 +88,8 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
brq
.
io
.
redirect
.
bits
<>
redirect
brq
.
io
.
bcommit
<>
roq
.
io
.
bcommit
brq
.
io
.
exuRedirectWb
<>
io
.
fromIntBlock
.
exuRedirect
brq
.
io
.
pcReadReq
.
brqIdx
:=
dispatch
.
io
.
enqIQCtrl
(
0
).
bits
.
brTag
// jump
io
.
toIntBlock
.
jumpPc
:=
brq
.
io
.
pcReadReq
.
pc
// pipeline between decode and dispatch
val
lastCycleRedirect
=
RegNext
(
redirectValid
)
...
...
src/main/scala/xiangshan/backend/FloatBlock.scala
浏览文件 @
0393f8ed
...
...
@@ -156,8 +156,9 @@ class FloatBlock
(
0
until
exuParameters
.
StuCnt
).
foreach
(
i
=>
io
.
toMemBlock
.
readFpRf
(
i
).
data
:=
fpRf
.
io
.
readPorts
(
i
+
12
).
data
)
// write fp rf arbiter
val
fpWbArbiter
=
Module
(
new
Wb
(
(
exeUnits
.
map
(
_
.
config
)
++
fastWakeUpIn
++
slowWakeUpIn
).
map
(
_
.
wbFpPriority
),
NRFpWritePorts
(
exeUnits
.
map
(
_
.
config
)
++
fastWakeUpIn
++
slowWakeUpIn
),
NRFpWritePorts
,
isFp
=
true
))
fpWbArbiter
.
io
.
in
<>
exeUnits
.
map
(
_
.
io
.
toFp
)
++
io
.
wakeUpIn
.
fast
++
io
.
wakeUpIn
.
slow
...
...
src/main/scala/xiangshan/backend/IntegerBlock.scala
浏览文件 @
0393f8ed
...
...
@@ -82,6 +82,9 @@ class IntegerBlock
val
memExceptionVAddr
=
Input
(
UInt
(
VAddrBits
.
W
))
// from lsq
val
externalInterrupt
=
new
ExternalInterruptIO
// from outside
val
tlb
=
Output
(
new
TlbCsrBundle
)
// from tlb
val
perfinfo
=
new
Bundle
{
val
retiredInstr
=
Input
(
UInt
(
3.
W
))
}
}
val
fenceio
=
new
Bundle
{
val
sfence
=
Output
(
new
SfenceBundle
)
// to front,mem
...
...
@@ -99,11 +102,11 @@ class IntegerBlock
len
=
XLEN
))
val
aluExeUnits
=
Array
.
tabulate
(
exuParameters
.
AluCnt
)(
_
=>
Module
(
new
AluExeUnit
))
val
jmpExeUnit
=
Module
(
new
JumpExeUnit
)
val
mduExeUnits
=
Array
.
tabulate
(
exuParameters
.
MduCnt
)(
_
=>
Module
(
new
MulDivExeUnit
))
val
aluExeUnits
=
Array
.
tabulate
(
exuParameters
.
AluCnt
)(
_
=>
Module
(
new
AluExeUnit
))
val
exeUnits
=
jmpExeUnit
+:
(
aluExeUnits
++
md
uExeUnits
)
val
exeUnits
=
jmpExeUnit
+:
(
mduExeUnits
++
al
uExeUnits
)
def
needWakeup
(
cfg
:
ExuConfig
)
:
Boolean
=
(
cfg
.
readIntRf
&&
cfg
.
writeIntRf
)
||
(
cfg
.
readFpRf
&&
cfg
.
writeFpRf
)
...
...
@@ -148,6 +151,7 @@ class IntegerBlock
val
src2Value
=
VecInit
((
0
until
4
).
map
(
i
=>
intRf
.
io
.
readPorts
(
i
*
2
+
1
).
data
))
rsData
.
io
.
srcRegValue
(
0
)
:=
src1Value
(
readPortIndex
(
i
))
if
(
cfg
.
intSrcCnt
>
1
)
rsData
.
io
.
srcRegValue
(
1
)
:=
src2Value
(
readPortIndex
(
i
))
if
(
cfg
==
Exu
.
jumpExeUnitCfg
)
rsData
.
io
.
jumpPc
:=
io
.
fromCtrlBlock
.
jumpPc
rsData
.
io
.
redirect
<>
redirect
rsData
.
io
.
writeBackedData
<>
writeBackData
...
...
@@ -218,8 +222,9 @@ class IntegerBlock
(
0
until
NRMemReadPorts
).
foreach
(
i
=>
io
.
toMemBlock
.
readIntRf
(
i
).
data
:=
intRf
.
io
.
readPorts
(
i
+
8
).
data
)
// write int rf arbiter
val
intWbArbiter
=
Module
(
new
Wb
(
(
exeUnits
.
map
(
_
.
config
)
++
fastWakeUpIn
++
slowWakeUpIn
).
map
(
_
.
wbIntPriority
),
NRIntWritePorts
(
exeUnits
.
map
(
_
.
config
)
++
fastWakeUpIn
++
slowWakeUpIn
),
NRIntWritePorts
,
isFp
=
false
))
intWbArbiter
.
io
.
in
<>
exeUnits
.
map
(
_
.
io
.
toInt
)
++
io
.
wakeUpIn
.
fast
++
io
.
wakeUpIn
.
slow
...
...
src/main/scala/xiangshan/backend/brq/Brq.scala
浏览文件 @
0393f8ed
...
...
@@ -5,6 +5,7 @@ import chisel3.util._
import
xiangshan._
import
utils._
import
chisel3.ExcitingUtils._
import
xiangshan.backend.decode.ImmUnion
class
BrqPtr
extends
CircularQueuePtr
(
BrqPtr
.
BrqSize
)
with
HasCircularQueuePtrHelper
{
...
...
@@ -44,6 +45,11 @@ class BrqEnqIO extends XSBundle {
val
resp
=
Vec
(
RenameWidth
,
Output
(
new
BrqPtr
))
}
class
BrqPcRead
extends
XSBundle
{
val
brqIdx
=
Input
(
new
BrqPtr
)
val
pc
=
Output
(
UInt
(
VAddrBits
.
W
))
}
class
BrqIO
extends
XSBundle
{
val
redirect
=
Input
(
ValidIO
(
new
Redirect
))
// receive branch/jump calculated target
...
...
@@ -57,6 +63,8 @@ class BrqIO extends XSBundle{
val
cfiInfo
=
ValidIO
(
new
CfiUpdateInfo
)
// commit cnt of branch instr
val
bcommit
=
Input
(
UInt
(
BrTagWidth
.
W
))
// read pc for jump unit
val
pcReadReq
=
new
BrqPcRead
}
class
Brq
extends
XSModule
with
HasCircularQueuePtrHelper
{
...
...
@@ -69,8 +77,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val
s_idle
::
s_wb
::
Nil
=
Enum
(
2
)
class
DecodeEnqBrqData
extends
Bundle
{
val
cfiUpdateInfo
=
new
CfiUpdateInfo
// we use this to calculate branch target
val
imm12
=
UInt
(
12.
W
)
}
// data and state
val
decodeData
=
Module
(
new
SyncDataModuleTemplate
(
new
ExuOutput
,
BrqSize
,
2
,
DecodeWidth
))
val
decodeData
=
Module
(
new
SyncDataModuleTemplate
(
new
DecodeEnqBrqData
,
BrqSize
,
3
,
DecodeWidth
))
val
writebackData
=
Module
(
new
SyncDataModuleTemplate
(
new
ExuOutput
,
BrqSize
,
2
,
exuParameters
.
AluCnt
+
exuParameters
.
JmpCnt
))
val
ptrFlagVec
=
Reg
(
Vec
(
BrqSize
,
Bool
()))
val
stateQueue
=
RegInit
(
VecInit
(
Seq
.
fill
(
BrqSize
)(
s_idle
)))
...
...
@@ -109,9 +123,14 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
}
val
brUpdateReadIdx
=
Mux
(
io
.
redirect
.
bits
.
flushItself
(),
io
.
redirect
.
bits
.
brTag
-
1.
U
,
io
.
redirect
.
bits
.
brTag
)
val
brUpdateReadEntry
=
Wire
(
new
ExuOutput
)
val
brUpdateReadEntry
=
Wire
(
new
CfiUpdateInfo
)
io
.
cfiInfo
.
valid
:=
RegNext
(
io
.
redirect
.
valid
||
wbValid
)
io
.
cfiInfo
.
bits
:=
brUpdateReadEntry
.
brUpdate
io
.
cfiInfo
.
bits
:=
brUpdateReadEntry
io
.
cfiInfo
.
bits
.
target
:=
RegNext
(
Mux
(
io
.
redirect
.
bits
.
flushItself
(),
io
.
redirect
.
bits
.
target
,
wbEntry
.
brUpdate
.
target
))
io
.
cfiInfo
.
bits
.
brTarget
:=
io
.
cfiInfo
.
bits
.
target
io
.
cfiInfo
.
bits
.
brTag
:=
RegNext
(
brUpdateReadIdx
)
io
.
cfiInfo
.
bits
.
isReplay
:=
RegNext
(
io
.
redirect
.
bits
.
flushItself
())
io
.
cfiInfo
.
bits
.
isMisPred
:=
RegNext
(
wbIsMisPred
)
...
...
@@ -183,31 +202,48 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
}
}
def
merge
DecodeWbData
(
dec
:
ExuOutput
,
wb
:
ExuOutput
)
:
ExuOutput
=
{
def
merge
WbEntry
(
dec
:
DecodeEnqBrqData
,
wb
:
ExuOutput
)
:
ExuOutput
=
{
val
mergeData
=
Wire
(
new
ExuOutput
)
mergeData
:=
dec
// only writeback necessary information
mergeData
.
uop
:=
wb
.
uop
mergeData
.
data
:=
wb
.
data
mergeData
.
fflags
:=
wb
.
fflags
mergeData
.
redirectValid
:=
wb
.
redirectValid
// calculate target pc
val
pc
=
dec
.
cfiUpdateInfo
.
pc
val
offset
=
SignExt
(
ImmUnion
.
B
.
toImm32
(
dec
.
imm12
),
VAddrBits
)
val
snpc
=
pc
+
Mux
(
dec
.
cfiUpdateInfo
.
pd
.
isRVC
,
2.
U
,
4.
U
)
val
bnpc
=
pc
+
offset
val
branch_pc
=
Mux
(
wb
.
brUpdate
.
taken
,
bnpc
,
snpc
)
val
redirectTarget
=
Mux
(
dec
.
cfiUpdateInfo
.
pd
.
isBr
,
branch_pc
,
wb
.
redirect
.
target
)
mergeData
.
redirect
:=
wb
.
redirect
mergeData
.
redirect
.
target
:=
redirectTarget
mergeData
.
debug
:=
wb
.
debug
mergeData
.
brUpdate
.
target
:=
wb
.
brUpdate
.
target
mergeData
.
brUpdate
.
brTarget
:=
wb
.
brUpdate
.
brTarget
mergeData
.
brUpdate
:=
dec
.
cfiUpdateInfo
mergeData
.
brUpdate
.
target
:=
redirectTarget
mergeData
.
brUpdate
.
brTarget
:=
redirectTarget
mergeData
.
brUpdate
.
taken
:=
wb
.
brUpdate
.
taken
mergeData
}
def
mergeBrUpdateEntry
(
dec
:
DecodeEnqBrqData
,
wb
:
ExuOutput
)
:
CfiUpdateInfo
=
{
val
mergeData
=
WireInit
(
dec
.
cfiUpdateInfo
)
mergeData
.
taken
:=
wb
.
brUpdate
.
taken
mergeData
}
decodeData
.
io
.
raddr
(
0
)
:=
writebackPtr_next
.
value
decodeData
.
io
.
raddr
(
1
)
:=
brUpdateReadIdx
.
value
decodeData
.
io
.
raddr
(
2
)
:=
io
.
pcReadReq
.
brqIdx
.
value
decodeData
.
io
.
wen
:=
VecInit
(
io
.
enq
.
req
.
map
(
_
.
fire
()))
decodeData
.
io
.
waddr
:=
VecInit
(
enqBrTag
.
map
(
_
.
value
))
decodeData
.
io
.
wdata
.
zip
(
io
.
enq
.
req
).
map
{
case
(
wdata
,
req
)
=>
{
wdata
:=
DontCar
e
wdata
.
brUpdate
:=
req
.
bits
.
brUpdate
wdata
.
brUpdate
.
pc
:=
req
.
bits
.
pc
}
}
decodeData
.
io
.
wdata
.
zip
(
io
.
enq
.
req
).
foreach
{
case
(
wdata
,
req
)
=>
wdata
.
cfiUpdateInfo
:=
req
.
bits
.
brUpdat
e
wdata
.
cfiUpdateInfo
.
pc
:=
req
.
bits
.
pc
wdata
.
imm12
:=
ImmUnion
.
B
.
minBitsFromInstr
(
req
.
bits
.
instr
)
}
writebackData
.
io
.
raddr
(
0
)
:=
writebackPtr_next
.
value
writebackData
.
io
.
raddr
(
1
)
:=
brUpdateReadIdx
.
value
...
...
@@ -215,9 +251,10 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
writebackData
.
io
.
waddr
:=
VecInit
(
io
.
exuRedirectWb
.
map
(
_
.
bits
.
redirect
.
brTag
.
value
))
writebackData
.
io
.
wdata
:=
VecInit
(
io
.
exuRedirectWb
.
map
(
_
.
bits
))
wbEntry
:=
merge
DecodeWbData
(
decodeData
.
io
.
rdata
(
0
),
writebackData
.
io
.
rdata
(
0
))
brUpdateReadEntry
:=
merge
DecodeWbData
(
decodeData
.
io
.
rdata
(
1
),
writebackData
.
io
.
rdata
(
1
))
wbEntry
:=
merge
WbEntry
(
decodeData
.
io
.
rdata
(
0
),
writebackData
.
io
.
rdata
(
0
))
brUpdateReadEntry
:=
merge
BrUpdateEntry
(
decodeData
.
io
.
rdata
(
1
),
writebackData
.
io
.
rdata
(
1
))
io
.
pcReadReq
.
pc
:=
decodeData
.
io
.
rdata
(
2
).
cfiUpdateInfo
.
pc
// Debug info
val
debug_roq_redirect
=
io
.
redirect
.
valid
&&
io
.
redirect
.
bits
.
isUnconditional
()
...
...
@@ -269,16 +306,16 @@ class Brq extends XSModule with HasCircularQueuePtrHelper {
val
mbpRWrong
=
predWrong
&&
isRType
if
(!
env
.
FPGAPlatform
){
ExcitingUtils
.
addSource
(
mbpInstr
,
"perfCntCond
Mb
pInstr"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpRight
,
"perfCntCond
Mb
pRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpWrong
,
"perfCntCond
Mb
pWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpBRight
,
"perfCntCond
Mb
pBRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpBWrong
,
"perfCntCond
Mb
pBWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpJRight
,
"perfCntCond
Mb
pJRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpJWrong
,
"perfCntCond
Mb
pJWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpIRight
,
"perfCntCond
Mb
pIRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpIWrong
,
"perfCntCond
Mb
pIWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpRRight
,
"perfCntCond
Mb
pRRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpRWrong
,
"perfCntCond
Mb
pRWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpInstr
,
"perfCntCond
B
pInstr"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpRight
,
"perfCntCond
B
pRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpWrong
,
"perfCntCond
B
pWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpBRight
,
"perfCntCond
B
pBRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpBWrong
,
"perfCntCond
B
pBWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpJRight
,
"perfCntCond
B
pJRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpJWrong
,
"perfCntCond
B
pJWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpIRight
,
"perfCntCond
B
pIRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpIWrong
,
"perfCntCond
B
pIWrong"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpRRight
,
"perfCntCond
B
pRRight"
,
Perf
)
ExcitingUtils
.
addSource
(
mbpRWrong
,
"perfCntCond
B
pRWrong"
,
Perf
)
}
}
src/main/scala/xiangshan/backend/decode/DecodeUnit.scala
浏览文件 @
0393f8ed
...
...
@@ -150,9 +150,9 @@ object XDecode extends DecodeConstants {
CSRRS
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
set
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_I
),
CSRRC
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
clr
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_I
),
CSRRWI
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
wrti
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_
I
),
CSRRSI
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
seti
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_
I
),
CSRRCI
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
clri
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_
I
),
CSRRWI
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
wrti
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_
Z
),
CSRRSI
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
seti
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_
Z
),
CSRRCI
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
clri
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_
Z
),
SFENCE_VMA
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
fence
,
FenceOpType
.
sfence
,
N
,
N
,
N
,
Y
,
Y
,
Y
,
N
,
SelImm
.
IMM_X
),
ECALL
->
List
(
SrcType
.
reg
,
SrcType
.
imm
,
SrcType
.
DC
,
FuType
.
csr
,
CSROpType
.
jmp
,
Y
,
N
,
N
,
Y
,
Y
,
N
,
N
,
SelImm
.
IMM_X
),
...
...
@@ -316,26 +316,98 @@ class RVCExpander extends XSModule {
}
}
object
Imm32Gen
{
def
apply
(
sel
:
UInt
,
inst
:
UInt
)
=
{
val
sign
=
Mux
(
sel
===
SelImm
.
IMM_Z
,
0.
S
,
inst
(
31
).
asSInt
)
val
b30_20
=
Mux
(
sel
===
SelImm
.
IMM_U
,
inst
(
30
,
20
).
asSInt
,
sign
)
val
b19_12
=
Mux
(
sel
=/=
SelImm
.
IMM_U
&&
sel
=/=
SelImm
.
IMM_UJ
,
sign
,
inst
(
19
,
12
).
asSInt
)
val
b11
=
Mux
(
sel
===
SelImm
.
IMM_U
||
sel
===
SelImm
.
IMM_Z
,
0.
S
,
Mux
(
sel
===
SelImm
.
IMM_UJ
,
inst
(
20
).
asSInt
,
Mux
(
sel
===
SelImm
.
IMM_SB
,
inst
(
7
).
asSInt
,
sign
)))
val
b10_5
=
Mux
(
sel
===
SelImm
.
IMM_U
||
sel
===
SelImm
.
IMM_Z
,
0.
U
(
1.
W
),
inst
(
30
,
25
))
val
b4_1
=
Mux
(
sel
===
SelImm
.
IMM_U
,
0.
U
(
1.
W
),
Mux
(
sel
===
SelImm
.
IMM_S
||
sel
===
SelImm
.
IMM_SB
,
inst
(
11
,
8
),
Mux
(
sel
===
SelImm
.
IMM_Z
,
inst
(
19
,
16
),
inst
(
24
,
21
))))
val
b0
=
Mux
(
sel
===
SelImm
.
IMM_S
,
inst
(
7
),
Mux
(
sel
===
SelImm
.
IMM_I
,
inst
(
20
),
Mux
(
sel
===
SelImm
.
IMM_Z
,
inst
(
15
),
0.
U
(
1.
W
))))
Cat
(
sign
,
b30_20
,
b19_12
,
b11
,
b10_5
,
b4_1
,
b0
)
//object Imm32Gen {
// def apply(sel: UInt, inst: UInt) = {
// val sign = Mux(sel === SelImm.IMM_Z, 0.S, inst(31).asSInt)
// val b30_20 = Mux(sel === SelImm.IMM_U, inst(30,20).asSInt, sign)
// val b19_12 = Mux(sel =/= SelImm.IMM_U && sel =/= SelImm.IMM_UJ, sign, inst(19,12).asSInt)
// val b11 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.S,
// Mux(sel === SelImm.IMM_UJ, inst(20).asSInt,
// Mux(sel === SelImm.IMM_SB, inst(7).asSInt, sign)))
// val b10_5 = Mux(sel === SelImm.IMM_U || sel === SelImm.IMM_Z, 0.U(1.W), inst(30,25))
// val b4_1 = Mux(sel === SelImm.IMM_U, 0.U(1.W),
// Mux(sel === SelImm.IMM_S || sel === SelImm.IMM_SB, inst(11,8),
// Mux(sel === SelImm.IMM_Z, inst(19,16), inst(24,21))))
// val b0 = Mux(sel === SelImm.IMM_S, inst(7),
// Mux(sel === SelImm.IMM_I, inst(20),
// Mux(sel === SelImm.IMM_Z, inst(15), 0.U(1.W))))
//
// Cat(sign, b30_20, b19_12, b11, b10_5, b4_1, b0)
// }
//}
abstract
class
Imm
(
val
len
:
Int
)
extends
Bundle
{
def
toImm32
(
minBits
:
UInt
)
:
UInt
=
do_toImm32
(
minBits
(
len
-
1
,
0
))
def
do_toImm32
(
minBits
:
UInt
)
:
UInt
def
minBitsFromInstr
(
instr
:
UInt
)
:
UInt
}
case
class
Imm_I
()
extends
Imm
(
12
)
{
override
def
do_toImm32
(
minBits
:
UInt
)
:
UInt
=
SignExt
(
minBits
,
32
)
override
def
minBitsFromInstr
(
instr
:
UInt
)
:
UInt
=
Cat
(
instr
(
31
,
20
))
}
case
class
Imm_S
()
extends
Imm
(
12
)
{
override
def
do_toImm32
(
minBits
:
UInt
)
:
UInt
=
SignExt
(
minBits
,
32
)
override
def
minBitsFromInstr
(
instr
:
UInt
)
:
UInt
=
Cat
(
instr
(
31
,
25
),
instr
(
11
,
7
))
}
case
class
Imm_B
()
extends
Imm
(
12
)
{
override
def
do_toImm32
(
minBits
:
UInt
)
:
UInt
=
SignExt
(
Cat
(
minBits
,
0.
U
(
1.
W
)),
32
)
override
def
minBitsFromInstr
(
instr
:
UInt
)
:
UInt
=
Cat
(
instr
(
31
),
instr
(
7
),
instr
(
30
,
25
),
instr
(
11
,
8
))
}
case
class
Imm_U
()
extends
Imm
(
20
){
override
def
do_toImm32
(
minBits
:
UInt
)
:
UInt
=
Cat
(
minBits
,
0.
U
(
12.
W
))
override
def
minBitsFromInstr
(
instr
:
UInt
)
:
UInt
=
{
instr
(
31
,
12
)
}
}
case
class
Imm_J
()
extends
Imm
(
20
){
override
def
do_toImm32
(
minBits
:
UInt
)
:
UInt
=
SignExt
(
Cat
(
minBits
,
0.
U
(
1.
W
)),
32
)
override
def
minBitsFromInstr
(
instr
:
UInt
)
:
UInt
=
{
Cat
(
instr
(
31
),
instr
(
19
,
12
),
instr
(
20
),
instr
(
30
,
25
),
instr
(
24
,
21
))
}
}
case
class
Imm_Z
()
extends
Imm
(
12
+
5
){
override
def
do_toImm32
(
minBits
:
UInt
)
:
UInt
=
minBits
override
def
minBitsFromInstr
(
instr
:
UInt
)
:
UInt
=
{
Cat
(
instr
(
19
,
15
),
instr
(
31
,
20
))
}
}
object
ImmUnion
{
val
I
=
Imm_I
()
val
S
=
Imm_S
()
val
B
=
Imm_B
()
val
U
=
Imm_U
()
val
J
=
Imm_J
()
val
Z
=
Imm_Z
()
val
imms
=
Seq
(
I
,
S
,
B
,
U
,
J
,
Z
)
val
maxLen
=
imms
.
maxBy
(
_
.
len
).
len
val
immSelMap
=
Seq
(
SelImm
.
IMM_I
,
SelImm
.
IMM_S
,
SelImm
.
IMM_SB
,
SelImm
.
IMM_U
,
SelImm
.
IMM_UJ
,
SelImm
.
IMM_Z
).
zip
(
imms
)
println
(
s
"ImmUnion max len: $maxLen"
)
}
/**
* IO bundle for the Decode unit
*/
...
...
@@ -403,19 +475,27 @@ class DecodeUnit extends XSModule with DecodeUnitConstants {
cs
.
lsrc1
:=
XSTrapDecode
.
lsrc1
}
cs
.
imm
:=
SignExt
(
Imm32Gen
(
cs
.
selImm
,
ctrl_flow
.
instr
),
XLEN
)
val
instr
=
io
.
enq
.
ctrl_flow
.
instr
cs
.
imm
:=
LookupTree
(
cs
.
selImm
,
ImmUnion
.
immSelMap
.
map
(
x
=>
{
val
minBits
=
x
.
_2
.
minBitsFromInstr
(
instr
)
require
(
minBits
.
getWidth
==
x
.
_2
.
len
)
x
.
_1
->
minBits
}
))
cf_ctrl
.
ctrl
:=
cs
// TODO: do we still need this?
// fix ret and call
when
(
cs
.
fuType
===
FuType
.
jmp
)
{
def
isLink
(
reg
:
UInt
)
=
(
reg
===
1.
U
||
reg
===
5.
U
)
when
(
isLink
(
cs
.
ldest
)
&&
cs
.
fuOpType
===
JumpOpType
.
jal
)
{
cf_ctrl
.
ctrl
.
fuOpType
:=
JumpOpType
.
call
}
when
(
cs
.
fuOpType
===
JumpOpType
.
jalr
)
{
when
(
isLink
(
cs
.
lsrc1
))
{
cf_ctrl
.
ctrl
.
fuOpType
:=
JumpOpType
.
ret
}
when
(
isLink
(
cs
.
ldest
))
{
cf_ctrl
.
ctrl
.
fuOpType
:=
JumpOpType
.
call
}
}
}
//
when (cs.fuType === FuType.jmp) {
//
def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
//
when (isLink(cs.ldest) && cs.fuOpType === JumpOpType.jal) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
//
when (cs.fuOpType === JumpOpType.jalr) {
//
when (isLink(cs.lsrc1)) { cf_ctrl.ctrl.fuOpType := JumpOpType.ret }
//
when (isLink(cs.ldest)) { cf_ctrl.ctrl.fuOpType := JumpOpType.call }
//
}
//
}
io
.
deq
.
cf_ctrl
:=
cf_ctrl
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch2Int.scala
浏览文件 @
0393f8ed
...
...
@@ -17,37 +17,40 @@ class Dispatch2Int extends XSModule {
val
readPortIndex
=
Vec
(
exuParameters
.
IntExuCnt
,
Output
(
UInt
(
log2Ceil
(
8
/
2
).
W
)))
})
val
jmpCnt
=
exuParameters
.
JmpCnt
val
mduCnt
=
exuParameters
.
MduCnt
val
aluCnt
=
exuParameters
.
AluCnt
/**
* Part 1: generate indexes for reservation stations
*/
assert
(
jmpCnt
==
1
)
val
jmpCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
jumpExeUnitCfg
.
canAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
aluCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
aluExeUnitCfg
.
canAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
mduCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
mulDivExeUnitCfg
.
canAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
assert
(
exuParameters
.
JmpCnt
==
1
)
val
jmpIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
exuParameters
.
JmpCnt
,
false
))
val
aluIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
exuParameters
.
AluCnt
,
true
))
val
mduIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
exuParameters
.
MduCnt
,
true
))
val
aluPriority
=
PriorityGen
((
0
until
exuParameters
.
AluCnt
).
map
(
i
=>
io
.
numExist
(
i
+
exuParameters
.
JmpCnt
)))
val
mduPriority
=
PriorityGen
((
0
until
exuParameters
.
MduCnt
).
map
(
i
=>
io
.
numExist
(
i
+
exuParameters
.
JmpCnt
+
exuParameters
.
AluCnt
)))
val
aluCanAccept
=
VecInit
(
io
.
fromDq
.
map
(
deq
=>
deq
.
valid
&&
aluExeUnitCfg
.
canAccept
(
deq
.
bits
.
ctrl
.
fuType
)))
val
jmpIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
jmpCnt
,
false
))
val
mduIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
mduCnt
,
true
))
val
aluIndexGen
=
Module
(
new
IndexMapping
(
dpParams
.
IntDqDeqWidth
,
aluCnt
,
true
))
val
mduPriority
=
PriorityGen
(
io
.
numExist
.
slice
(
jmpCnt
,
jmpCnt
+
mduCnt
))
val
aluPriority
=
PriorityGen
(
io
.
numExist
.
drop
(
jmpCnt
+
mduCnt
))
jmpIndexGen
.
io
.
validBits
:=
jmpCanAccept
aluIndexGen
.
io
.
validBits
:=
aluCanAccept
mduIndexGen
.
io
.
validBits
:=
mduCanAccept
aluIndexGen
.
io
.
validBits
:=
aluCanAccept
jmpIndexGen
.
io
.
priority
:=
DontCare
aluIndexGen
.
io
.
priority
:=
aluPriority
mduIndexGen
.
io
.
priority
:=
mduPriority
aluIndexGen
.
io
.
priority
:=
aluPriority
val
allIndexGen
=
Seq
(
jmpIndexGen
,
aluIndexGen
,
mduIndexGen
)
val
validVec
=
allIndexGen
.
map
(
_
.
io
.
mapping
.
map
(
_
.
valid
)).
reduceLeft
(
_
++
_
)
val
indexVec
=
allIndexGen
.
map
(
_
.
io
.
mapping
.
map
(
_
.
bits
)).
reduceLeft
(
_
++
_
)
for
(
i
<-
validVec
.
indices
)
{
// XSDebug(p"mapping $i: valid ${validVec(i)} index ${indexVec(i)}\n")
}
val
allIndexGen
=
Seq
(
jmpIndexGen
,
mduIndexGen
,
aluIndexGen
)
val
validVec
=
allIndexGen
.
flatMap
(
_
.
io
.
mapping
.
map
(
_
.
valid
))
val
indexVec
=
allIndexGen
.
flatMap
(
_
.
io
.
mapping
.
map
(
_
.
bits
))
/**
* Part 2: assign regfile read ports
*/
val
intStaticIndex
=
Seq
(
1
,
2
,
3
,
4
)
val
intDynamicIndex
=
Seq
(
0
,
5
,
6
)
val
intStaticIndex
=
Seq
(
3
,
4
,
5
,
6
)
val
intDynamicIndex
=
Seq
(
0
,
1
,
2
)
val
intStaticMappedValid
=
intStaticIndex
.
map
(
i
=>
validVec
(
i
))
val
intDynamicMappedValid
=
intDynamicIndex
.
map
(
i
=>
validVec
(
i
))
val
(
intReadPortSrc
,
intDynamicExuSrc
)
=
RegfileReadPortGen
(
intStaticMappedValid
,
intDynamicMappedValid
)
...
...
@@ -66,18 +69,18 @@ class Dispatch2Int extends XSModule {
* Part 3: dispatch to reservation stations
*/
val
jmpReady
=
io
.
enqIQCtrl
(
0
).
ready
val
aluReady
=
Cat
(
io
.
enqIQCtrl
.
take
(
exuParameters
.
JmpCnt
+
exuParameters
.
AluCnt
).
drop
(
exuParameters
.
Jmp
Cnt
).
map
(
_
.
ready
)).
andR
val
mduReady
=
Cat
(
io
.
enqIQCtrl
.
drop
(
exuParameters
.
JmpCnt
+
exuParameters
.
Al
uCnt
).
map
(
_
.
ready
)).
andR
val
mduReady
=
Cat
(
io
.
enqIQCtrl
.
slice
(
jmpCnt
,
jmpCnt
+
mdu
Cnt
).
map
(
_
.
ready
)).
andR
val
aluReady
=
Cat
(
io
.
enqIQCtrl
.
drop
(
jmpCnt
+
md
uCnt
).
map
(
_
.
ready
)).
andR
for
(
i
<-
0
until
exuParameters
.
IntExuCnt
)
{
val
enq
=
io
.
enqIQCtrl
(
i
)
if
(
i
<
exuParameters
.
J
mpCnt
)
{
if
(
i
<
j
mpCnt
)
{
enq
.
valid
:=
jmpIndexGen
.
io
.
mapping
(
i
).
valid
// && jmpReady
}
else
if
(
i
<
exuParameters
.
JmpCnt
+
exuParameters
.
Al
uCnt
)
{
enq
.
valid
:=
aluIndexGen
.
io
.
mapping
(
i
-
exuParameters
.
JmpCnt
).
valid
&&
al
uReady
else
if
(
i
<
jmpCnt
+
md
uCnt
)
{
enq
.
valid
:=
mduIndexGen
.
io
.
mapping
(
i
-
jmpCnt
).
valid
&&
md
uReady
}
else
{
enq
.
valid
:=
mduIndexGen
.
io
.
mapping
(
i
-
(
exuParameters
.
JmpCnt
+
exuParameters
.
AluCnt
)).
valid
&&
md
uReady
else
{
// alu
enq
.
valid
:=
aluIndexGen
.
io
.
mapping
(
i
-
(
jmpCnt
+
mduCnt
)).
valid
&&
al
uReady
}
enq
.
bits
:=
io
.
fromDq
(
indexVec
(
i
)).
bits
...
...
src/main/scala/xiangshan/backend/dispatch/IndexMapping.scala
浏览文件 @
0393f8ed
...
...
@@ -85,7 +85,7 @@ object RegfileReadPortGen {
val
choiceCount
=
dynamicMappedValid
.
length
+
1
val
readPortSrc
=
Wire
(
Vec
(
staticMappedValid
.
length
,
UInt
(
log2Ceil
(
choiceCount
).
W
)))
var
hasAssigned
=
(
0
until
choiceCount
).
map
(
_
=>
false
.
B
)
for
(
i
<-
0
until
staticMappedValid
.
length
)
{
for
(
i
<-
staticMappedValid
.
indices
)
{
val
valid
=
staticMappedValid
(
i
)
+:
dynamicMappedValid
val
wantReadPort
=
(
0
until
choiceCount
).
map
(
j
=>
valid
(
j
)
&&
((
j
==
0
).
asBool
()
||
!
hasAssigned
(
j
)))
readPortSrc
(
i
)
:=
PriorityEncoder
(
wantReadPort
)
...
...
@@ -93,8 +93,8 @@ object RegfileReadPortGen {
hasAssigned
=
(
0
until
choiceCount
).
map
(
i
=>
hasAssigned
(
i
)
||
onehot
(
i
))
}
val
dynamicExuSrc
=
Wire
(
Vec
(
dynamicMappedValid
.
length
,
UInt
(
log2Ceil
(
staticMappedValid
.
length
).
W
)))
for
(
i
<-
0
until
dynamicMappedValid
.
length
)
{
val
targetMatch
=
(
0
until
staticMappedValid
.
length
)
.
map
(
j
=>
readPortSrc
(
j
)
===
(
i
+
1
).
U
)
for
(
i
<-
dynamicMappedValid
.
indices
)
{
val
targetMatch
=
staticMappedValid
.
indices
.
map
(
j
=>
readPortSrc
(
j
)
===
(
i
+
1
).
U
)
dynamicExuSrc
(
i
)
:=
PriorityEncoder
(
targetMatch
)
}
(
readPortSrc
,
dynamicExuSrc
)
...
...
src/main/scala/xiangshan/backend/exu/Exu.scala
浏览文件 @
0393f8ed
...
...
@@ -183,6 +183,7 @@ abstract class Exu(val config: ExuConfig) extends XSModule {
out
.
fflags
:=
DontCare
out
.
debug
<>
DontCare
out
.
debug
.
isMMIO
:=
false
.
B
out
.
debug
.
isPerfCnt
:=
false
.
B
out
.
redirect
<>
DontCare
out
.
redirectValid
:=
false
.
B
}
...
...
src/main/scala/xiangshan/backend/exu/JumpExeUnit.scala
浏览文件 @
0393f8ed
...
...
@@ -21,6 +21,9 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
val
memExceptionVAddr
=
Input
(
UInt
(
VAddrBits
.
W
))
val
externalInterrupt
=
new
ExternalInterruptIO
val
tlb
=
Output
(
new
TlbCsrBundle
)
val
perfinfo
=
new
Bundle
{
val
retiredInstr
=
Input
(
UInt
(
3.
W
))
}
})
val
fenceio
=
IO
(
new
Bundle
{
val
sfence
=
Output
(
new
SfenceBundle
)
...
...
@@ -42,6 +45,7 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
}.
get
csr
.
csrio
.
perf
<>
DontCare
csr
.
csrio
.
perf
.
retiredInstr
<>
csrio
.
perfinfo
.
retiredInstr
csr
.
csrio
.
fpu
.
fflags
<>
csrio
.
fflags
csr
.
csrio
.
fpu
.
isIllegal
:=
false
.
B
csr
.
csrio
.
fpu
.
dirty_fs
<>
csrio
.
dirty_fs
...
...
@@ -73,6 +77,7 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
io
.
toInt
.
bits
.
redirect
.
roqIdx
:=
uop
.
roqIdx
io
.
toInt
.
bits
.
redirect
.
target
:=
csr
.
csrio
.
redirectOut
.
bits
io
.
toInt
.
bits
.
redirect
.
pc
:=
uop
.
cf
.
pc
io
.
toInt
.
bits
.
debug
.
isPerfCnt
:=
csr
.
csrio
.
isPerfCnt
}.
elsewhen
(
jmp
.
io
.
out
.
valid
){
io
.
toInt
.
bits
.
redirectValid
:=
jmp
.
redirectOutValid
io
.
toInt
.
bits
.
redirect
:=
jmp
.
redirectOut
...
...
src/main/scala/xiangshan/backend/exu/Wb.scala
浏览文件 @
0393f8ed
...
...
@@ -6,9 +6,12 @@ import xiangshan._
import
utils._
class
Wb
(
priorities
:
Seq
[
Int
],
numOut
:
Int
)
extends
XSModule
{
class
Wb
(
cfgs
:
Seq
[
ExuConfig
],
numOut
:
Int
,
isFp
:
Boolean
)
extends
XSModule
{
val
priorities
=
cfgs
.
map
(
c
=>
if
(
isFp
)
c
.
wbFpPriority
else
c
.
wbIntPriority
)
val
io
=
IO
(
new
Bundle
()
{
val
in
=
Vec
(
prioritie
s
.
size
,
Flipped
(
DecoupledIO
(
new
ExuOutput
)))
val
in
=
Vec
(
cfg
s
.
size
,
Flipped
(
DecoupledIO
(
new
ExuOutput
)))
val
out
=
Vec
(
numOut
,
ValidIO
(
new
ExuOutput
))
})
...
...
@@ -35,7 +38,7 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
}
def
splitN
[
T
](
in
:
Seq
[
T
],
n
:
Int
)
:
Seq
[
Option
[
Seq
[
T
]]]
=
{
require
(
n
>
0
)
if
(
n
==
0
)
return
Seq
(
)
if
(
n
==
1
){
Seq
(
Some
(
in
))
}
else
{
...
...
@@ -48,24 +51,38 @@ class Wb(priorities: Seq[Int], numOut: Int) extends XSModule {
}
}
if
(
mulReq
.
nonEmpty
){
val
arbReq
=
splitN
(
otherReq
,
mulReq
.
size
)
for
(
i
<-
mulReq
.
indices
)
{
val
other
=
arbReq
(
i
).
getOrElse
(
Seq
())
val
arb
=
Module
(
new
Arbiter
(
new
ExuOutput
,
1
+
other
.
size
))
arb
.
io
.
in
<>
mulReq
(
i
)
+:
other
val
out
=
io
.
out
(
directConnect
.
size
+
i
)
out
.
valid
:=
arb
.
io
.
out
.
valid
out
.
bits
:=
arb
.
io
.
out
.
bits
arb
.
io
.
out
.
ready
:=
true
.
B
}
val
arbReq
=
splitN
(
otherReq
,
mulReq
.
size
)
val
arbiters
=
for
(
i
<-
mulReq
.
indices
)
yield
{
val
other
=
arbReq
(
i
).
getOrElse
(
Seq
())
val
arb
=
Module
(
new
Arbiter
(
new
ExuOutput
,
1
+
other
.
size
))
arb
.
io
.
in
<>
mulReq
(
i
)
+:
other
val
out
=
io
.
out
(
directConnect
.
size
+
i
)
out
.
valid
:=
arb
.
io
.
out
.
valid
out
.
bits
:=
arb
.
io
.
out
.
bits
arb
.
io
.
out
.
ready
:=
true
.
B
arb
}
if
(
portUsed
<
numOut
){
println
(
s
"Warning: ${numOut - portUsed} ports are not used!"
)
io
.
out
.
drop
(
portUsed
).
foreach
(
_
<>
DontCare
)
}
val
sb
=
new
StringBuffer
(
s
"\n${if(isFp) "
fp
" else "
int
"} wb arbiter:\n"
)
for
((
conn
,
i
)
<-
directConnect
.
zipWithIndex
){
sb
.
append
(
s
"[ ${cfgs(io.in.indexOf(conn)).name} ] -> out #$i\n"
)
}
for
(
i
<-
mulReq
.
indices
){
sb
.
append
(
s
"[ ${cfgs(io.in.indexOf(mulReq(i))).name} "
)
for
(
req
<-
arbReq
(
i
).
getOrElse
(
Nil
)){
sb
.
append
(
s
"${cfgs(io.in.indexOf(req)).name} "
)
}
sb
.
append
(
s
"] -> arb -> out #${directConnect.size + i}\n"
)
}
println
(
sb
)
}
\ No newline at end of file
src/main/scala/xiangshan/backend/fu/Alu.scala
浏览文件 @
0393f8ed
...
...
@@ -8,15 +8,16 @@ import xiangshan.backend.ALUOpType
class
Alu
extends
FunctionUnit
with
HasRedirectOut
{
val
(
src1
,
src2
,
offset
,
func
,
pc
,
uop
)
=
(
val
(
src1
,
src2
,
func
,
pc
,
uop
)
=
(
io
.
in
.
bits
.
src
(
0
),
io
.
in
.
bits
.
src
(
1
),
io
.
in
.
bits
.
uop
.
ctrl
.
imm
,
io
.
in
.
bits
.
uop
.
ctrl
.
fuOpType
,
SignExt
(
io
.
in
.
bits
.
uop
.
cf
.
pc
,
AddrBits
),
io
.
in
.
bits
.
uop
)
val
offset
=
src2
val
valid
=
io
.
in
.
valid
val
isAdderSub
=
(
func
=/=
ALUOpType
.
add
)
&&
(
func
=/=
ALUOpType
.
addw
)
...
...
@@ -63,21 +64,30 @@ class Alu extends FunctionUnit with HasRedirectOut {
val
snpc
=
Mux
(
isRVC
,
pc
+
2.
U
,
pc
+
4.
U
)
redirectOutValid
:=
io
.
out
.
valid
&&
isBranch
redirectOut
.
pc
:=
uop
.
cf
.
pc
redirectOut
.
target
:=
Mux
(!
taken
&&
isBranch
,
snpc
,
target
)
// Only brTag, level, roqIdx are needed
// other infos are stored in brq
redirectOut
:=
DontCare
redirectOut
.
brTag
:=
uop
.
brTag
redirectOut
.
level
:=
RedirectLevel
.
flushAfter
redirectOut
.
interrupt
:=
DontCare
redirectOut
.
roqIdx
:=
uop
.
roqIdx
brUpdate
:=
uop
.
cf
.
brUpdate
// override brUpdate
brUpdate
.
pc
:=
uop
.
cf
.
pc
brUpdate
.
target
:=
Mux
(!
taken
&&
isBranch
,
snpc
,
target
)
brUpdate
.
brTarget
:=
target
// redirectOut.pc := DontCare//uop.cf.pc
// redirectOut.target := DontCare//Mux(!taken && isBranch, snpc, target)
// redirectOut.interrupt := DontCare//DontCare
// Only taken really needed, do we need brTag ?
brUpdate
:=
DontCare
brUpdate
.
taken
:=
isBranch
&&
taken
brUpdate
.
brTag
:=
uop
.
brTag
// brUpdate := uop.cf.brUpdate
// // override brUpdate
// brUpdate.pc := uop.cf.pc
// brUpdate.target := Mux(!taken && isBranch, snpc, target)
// brUpdate.brTarget := target
// brUpdate.taken := isBranch && taken
// brUpdate.brTag := uop.brTag
io
.
in
.
ready
:=
io
.
out
.
ready
io
.
out
.
valid
:=
valid
io
.
out
.
bits
.
uop
<>
io
.
in
.
bits
.
uop
...
...
src/main/scala/xiangshan/backend/fu/CSR.scala
浏览文件 @
0393f8ed
此差异已折叠。
点击以展开。
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
浏览文件 @
0393f8ed
...
...
@@ -29,7 +29,7 @@ case class FuConfig
writeIntRf
:
Boolean
,
writeFpRf
:
Boolean
,
hasRedirect
:
Boolean
,
latency
:
HasFuLatency
=
CertainLatency
(
0
)
latency
:
HasFuLatency
=
CertainLatency
(
0
)
,
)
{
def
srcCnt
:
Int
=
math
.
max
(
numIntSrc
,
numFpSrc
)
}
...
...
@@ -159,7 +159,7 @@ object FunctionUnit extends HasXSParameter {
numFpSrc
=
0
,
writeIntRf
=
true
,
writeFpRf
=
false
,
hasRedirect
=
true
hasRedirect
=
true
,
)
val
jmpCfg
=
FuConfig
(
...
...
@@ -170,7 +170,7 @@ object FunctionUnit extends HasXSParameter {
numFpSrc
=
0
,
writeIntRf
=
true
,
writeFpRf
=
false
,
hasRedirect
=
true
hasRedirect
=
true
,
)
val
fenceCfg
=
FuConfig
(
...
...
src/main/scala/xiangshan/backend/fu/Jump.scala
浏览文件 @
0393f8ed
...
...
@@ -5,6 +5,7 @@ import chisel3.util._
import
xiangshan._
import
utils._
import
xiangshan.backend._
import
xiangshan.backend.decode.ImmUnion
import
xiangshan.backend.fu.FunctionUnit._
import
xiangshan.backend.decode.isa._
...
...
@@ -16,7 +17,7 @@ trait HasRedirectOut { this: RawModule =>
class
Jump
extends
FunctionUnit
with
HasRedirectOut
{
val
(
src1
,
offset
,
func
,
pc
,
uop
)
=
(
val
(
src1
,
immMin
,
func
,
pc
,
uop
)
=
(
io
.
in
.
bits
.
src
(
0
),
io
.
in
.
bits
.
uop
.
ctrl
.
imm
,
io
.
in
.
bits
.
uop
.
ctrl
.
fuOpType
,
...
...
@@ -24,6 +25,11 @@ class Jump extends FunctionUnit with HasRedirectOut {
io
.
in
.
bits
.
uop
)
val
offset
=
SignExt
(
Mux
(
JumpOpType
.
jumpOpIsJal
(
func
),
ImmUnion
.
J
.
toImm32
(
immMin
),
ImmUnion
.
I
.
toImm32
(
immMin
)
),
XLEN
)
val
redirectHit
=
uop
.
roqIdx
.
needFlush
(
io
.
redirectIn
)
val
valid
=
io
.
in
.
valid
...
...
@@ -32,15 +38,16 @@ class Jump extends FunctionUnit with HasRedirectOut {
val
target
=
src1
+
offset
// NOTE: src1 is (pc/rf(rs1)), src2 is (offset)
redirectOutValid
:=
valid
redirectOut
.
pc
:=
uop
.
cf
.
pc
redirectOut
:=
DontCare
// redirectOut.pc := uop.cf.pc
redirectOut
.
target
:=
target
redirectOut
.
brTag
:=
uop
.
brTag
redirectOut
.
level
:=
RedirectLevel
.
flushAfter
redirectOut
.
interrupt
:=
DontCare
//
redirectOut.interrupt := DontCare
redirectOut
.
roqIdx
:=
uop
.
roqIdx
brUpdate
:=
uop
.
cf
.
brUpdate
brUpdate
.
pc
:=
uop
.
cf
.
pc
brUpdate
:=
DontCare
//
uop.cf.brUpdate
//
brUpdate.pc := uop.cf.pc
brUpdate
.
target
:=
target
brUpdate
.
brTarget
:=
target
brUpdate
.
taken
:=
true
.
B
...
...
src/main/scala/xiangshan/backend/fu/util/CSRConst.scala
0 → 100644
浏览文件 @
0393f8ed
package
xiangshan.backend.fu.util
import
chisel3._
import
chisel3.ExcitingUtils.
{
ConnectionType
,
Debug
}
import
chisel3.util._
import
utils._
import
xiangshan._
import
xiangshan.backend._
import
utils.XSDebug
trait
HasCSRConst
{
// User Trap Setup
val
Ustatus
=
0x000
val
Uie
=
0x004
val
Utvec
=
0x005
// User Trap Handling
val
Uscratch
=
0x040
val
Uepc
=
0x041
val
Ucause
=
0x042
val
Utval
=
0x043
val
Uip
=
0x044
// User Floating-Point CSRs (not implemented)
val
Fflags
=
0x001
val
Frm
=
0x002
val
Fcsr
=
0x003
// User Counter/Timers
val
Cycle
=
0xC00
val
Time
=
0xC01
val
Instret
=
0xC02
// Supervisor Trap Setup
val
Sstatus
=
0x100
val
Sedeleg
=
0x102
val
Sideleg
=
0x103
val
Sie
=
0x104
val
Stvec
=
0x105
val
Scounteren
=
0x106
// Supervisor Trap Handling
val
Sscratch
=
0x140
val
Sepc
=
0x141
val
Scause
=
0x142
val
Stval
=
0x143
val
Sip
=
0x144
// Supervisor Protection and Translation
val
Satp
=
0x180
// Machine Information Registers
val
Mvendorid
=
0xF11
val
Marchid
=
0xF12
val
Mimpid
=
0xF13
val
Mhartid
=
0xF14
// Machine Trap Setup
val
Mstatus
=
0x300
val
Misa
=
0x301
val
Medeleg
=
0x302
val
Mideleg
=
0x303
val
Mie
=
0x304
val
Mtvec
=
0x305
val
Mcounteren
=
0x306
// Machine Trap Handling
val
Mscratch
=
0x340
val
Mepc
=
0x341
val
Mcause
=
0x342
val
Mtval
=
0x343
val
Mip
=
0x344
// Machine Memory Protection
// TBD
val
Pmpcfg0
=
0x3A0
val
Pmpcfg1
=
0x3A1
val
Pmpcfg2
=
0x3A2
val
Pmpcfg3
=
0x3A3
val
PmpaddrBase
=
0x3B0
// Machine Counter/Timers
// Currently, we uses perfcnt csr set instead of standard Machine Counter/Timers
// 0xB80 - 0x89F are also used as perfcnt csr
val
Mcycle
=
0xb00
val
Minstret
=
0xb02
val
Mhpmcounter3
=
0xB03
val
Mhpmcounter4
=
0xB04
val
Mhpmcounter5
=
0xB05
val
Mhpmcounter6
=
0xB06
val
Mhpmcounter7
=
0xB07
val
Mhpmcounter8
=
0xB08
val
Mhpmcounter9
=
0xB09
val
Mhpmcounter10
=
0xB0A
val
Mhpmcounter11
=
0xB0B
val
Mhpmcounter12
=
0xB0C
val
Mhpmcounter13
=
0xB0D
val
Mhpmcounter14
=
0xB0E
val
Mhpmcounter15
=
0xB0F
val
Mhpmcounter16
=
0xB10
val
Mhpmcounter17
=
0xB11
val
Mhpmcounter18
=
0xB12
val
Mhpmcounter19
=
0xB13
val
Mhpmcounter20
=
0xB14
val
Mhpmcounter21
=
0xB15
val
Mhpmcounter22
=
0xB16
val
Mhpmcounter23
=
0xB17
val
Mhpmcounter24
=
0xB18
val
Mhpmcounter25
=
0xB19
val
Mhpmcounter26
=
0xB1A
val
Mhpmcounter27
=
0xB1B
val
Mhpmcounter28
=
0xB1C
val
Mhpmcounter29
=
0xB1D
val
Mhpmcounter30
=
0xB1E
val
Mhpmcounter31
=
0xB1F
// Machine Counter Setup (not implemented)
val
Mcountinhibit
=
0x320
val
Mhpmevent3
=
0x323
val
Mhpmevent4
=
0x324
val
Mhpmevent5
=
0x325
val
Mhpmevent6
=
0x326
val
Mhpmevent7
=
0x327
val
Mhpmevent8
=
0x328
val
Mhpmevent9
=
0x329
val
Mhpmevent10
=
0x32A
val
Mhpmevent11
=
0x32B
val
Mhpmevent12
=
0x32C
val
Mhpmevent13
=
0x32D
val
Mhpmevent14
=
0x32E
val
Mhpmevent15
=
0x32F
val
Mhpmevent16
=
0x330
val
Mhpmevent17
=
0x331
val
Mhpmevent18
=
0x332
val
Mhpmevent19
=
0x333
val
Mhpmevent20
=
0x334
val
Mhpmevent21
=
0x335
val
Mhpmevent22
=
0x336
val
Mhpmevent23
=
0x337
val
Mhpmevent24
=
0x338
val
Mhpmevent25
=
0x339
val
Mhpmevent26
=
0x33A
val
Mhpmevent27
=
0x33B
val
Mhpmevent28
=
0x33C
val
Mhpmevent29
=
0x33D
val
Mhpmevent30
=
0x33E
val
Mhpmevent31
=
0x33F
// Debug/Trace Registers (shared with Debug Mode) (not implemented)
// Debug Mode Registers (not implemented)
def
privEcall
=
0x000
.
U
def
privEbreak
=
0x001
.
U
def
privMret
=
0x302
.
U
def
privSret
=
0x102
.
U
def
privUret
=
0x002
.
U
def
ModeM
=
0x3
.
U
def
ModeH
=
0x2
.
U
def
ModeS
=
0x1
.
U
def
ModeU
=
0x0
.
U
def
IRQ_UEIP
=
0
def
IRQ_SEIP
=
1
def
IRQ_MEIP
=
3
def
IRQ_UTIP
=
4
def
IRQ_STIP
=
5
def
IRQ_MTIP
=
7
def
IRQ_USIP
=
8
def
IRQ_SSIP
=
9
def
IRQ_MSIP
=
11
val
IntPriority
=
Seq
(
IRQ_MEIP
,
IRQ_MSIP
,
IRQ_MTIP
,
IRQ_SEIP
,
IRQ_SSIP
,
IRQ_STIP
,
IRQ_UEIP
,
IRQ_USIP
,
IRQ_UTIP
)
def
csrAccessPermissionCheck
(
addr
:
UInt
,
wen
:
Bool
,
mode
:
UInt
)
:
Bool
=
{
val
readOnly
=
addr
(
11
,
10
)
===
"b11"
.
U
val
lowestAccessPrivilegeLevel
=
addr
(
9
,
8
)
mode
>=
lowestAccessPrivilegeLevel
&&
!(
wen
&&
readOnly
)
}
}
\ No newline at end of file
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
浏览文件 @
0393f8ed
...
...
@@ -4,8 +4,10 @@ import chisel3._
import
chisel3.util._
import
xiangshan._
import
utils._
import
xiangshan.backend.decode.ImmUnion
import
xiangshan.backend.exu.
{
Exu
,
ExuConfig
}
import
xiangshan.backend.regfile.RfReadPort
import
scala.math.max
class
BypassQueue
(
number
:
Int
)
extends
XSModule
{
...
...
@@ -336,6 +338,7 @@ class ReservationStationData
// read src op value
val
srcRegValue
=
Vec
(
srcNum
,
Input
(
UInt
((
XLEN
+
1
).
W
)))
val
jumpPc
=
if
(
exuCfg
==
Exu
.
jumpExeUnitCfg
)
Input
(
UInt
(
VAddrBits
.
W
))
else
null
// broadcast selected uop to other issue queues
val
selectedUop
=
ValidIO
(
new
MicroOp
)
...
...
@@ -404,6 +407,7 @@ class ReservationStationData
val
deq
=
RegEnable
(
sel
.
bits
,
sel
.
valid
)
val
enqCtrl
=
io
.
ctrl
.
enqCtrl
val
enqUop
=
enqCtrl
.
bits
val
enqUopReg
=
RegEnable
(
enqUop
,
enqCtrl
.
fire
())
// enq
val
enqPtr
=
enq
(
log2Up
(
IssQueSize
)-
1
,
0
)
...
...
@@ -418,7 +422,33 @@ class ReservationStationData
}
when
(
enqEnReg
)
{
(
0
until
srcNum
).
foreach
(
i
=>
dataWrite
(
enqPtrReg
,
i
,
io
.
srcRegValue
(
i
)))
exuCfg
match
{
case
Exu
.
jumpExeUnitCfg
=>
val
src1Mux
=
Mux
(
enqUopReg
.
ctrl
.
src1Type
===
SrcType
.
pc
,
SignExt
(
io
.
jumpPc
,
XLEN
),
io
.
srcRegValue
(
0
)
)
dataWrite
(
enqPtrReg
,
0
,
src1Mux
)
case
Exu
.
aluExeUnitCfg
=>
val
src1Mux
=
Mux
(
enqUopReg
.
ctrl
.
src1Type
===
SrcType
.
pc
,
SignExt
(
enqUopReg
.
cf
.
pc
,
XLEN
),
io
.
srcRegValue
(
0
)
)
dataWrite
(
enqPtrReg
,
0
,
src1Mux
)
// TODO: opt this, a full map is not necesscary here
val
imm32
=
LookupTree
(
enqUopReg
.
ctrl
.
selImm
,
ImmUnion
.
immSelMap
.
map
(
x
=>
x
.
_1
->
x
.
_2
.
toImm32
(
enqUopReg
.
ctrl
.
imm
))
)
val
imm64
=
SignExt
(
imm32
,
XLEN
)
val
src2Mux
=
Mux
(
enqUopReg
.
ctrl
.
src2Type
===
SrcType
.
imm
,
imm64
,
io
.
srcRegValue
(
1
)
)
dataWrite
(
enqPtrReg
,
1
,
src2Mux
)
case
_
=>
(
0
until
srcNum
).
foreach
(
i
=>
dataWrite
(
enqPtrReg
,
i
,
io
.
srcRegValue
(
i
)))
}
XSDebug
(
p
"${exuCfg.name}: enqPtrReg:${enqPtrReg} pc: ${Hexadecimal(uop(enqPtrReg).cf.pc)}\n"
)
XSDebug
(
p
"[srcRegValue] "
+
List
.
tabulate
(
srcNum
)(
idx
=>
p
"src$idx: ${Hexadecimal(io.srcRegValue(idx))}"
).
reduce
((
p1
,
p2
)
=>
p1
+
" "
+
p2
)
+
"\n"
)
}
...
...
@@ -472,8 +502,8 @@ class ReservationStationData
exuInput
.
uop
:=
uop
(
deq
)
val
regValues
=
List
.
tabulate
(
srcNum
)(
i
=>
dataRead
(
Mux
(
sel
.
valid
,
sel
.
bits
,
deq
),
i
))
XSDebug
(
io
.
deq
.
fire
(),
p
"[regValues] "
+
List
.
tabulate
(
srcNum
)(
idx
=>
p
"reg$idx: ${Hexadecimal(regValues(idx))}"
).
reduce
((
p1
,
p2
)
=>
p1
+
" "
+
p2
)
+
"\n"
)
exuInput
.
src1
:=
Mux
(
uop
(
deq
).
ctrl
.
src1Type
===
SrcType
.
pc
,
SignExt
(
uop
(
deq
).
cf
.
pc
,
XLEN
+
1
),
regValues
(
0
)
)
if
(
srcNum
>
1
)
exuInput
.
src2
:=
Mux
(
uop
(
deq
).
ctrl
.
src2Type
===
SrcType
.
imm
,
uop
(
deq
).
ctrl
.
imm
,
regValues
(
1
)
)
exuInput
.
src1
:=
regValues
(
0
)
if
(
srcNum
>
1
)
exuInput
.
src2
:=
regValues
(
1
)
if
(
srcNum
>
2
)
exuInput
.
src3
:=
regValues
(
2
)
io
.
deq
.
valid
:=
RegNext
(
sel
.
valid
)
...
...
@@ -496,7 +526,7 @@ class ReservationStationData
io
.
ctrl
.
feedback
:=
DontCare
if
(
feedback
)
{
(
0
until
IssQueSize
).
map
(
i
=>
(
0
until
IssQueSize
).
foreach
(
i
=>
io
.
ctrl
.
feedback
(
i
)
:=
uop
(
i
).
roqIdx
.
asUInt
===
io
.
feedback
.
bits
.
roqIdx
.
asUInt
&&
io
.
feedback
.
valid
)
io
.
ctrl
.
feedback
(
IssQueSize
)
:=
io
.
feedback
.
bits
.
hit
}
...
...
src/main/scala/xiangshan/backend/package.scala
浏览文件 @
0393f8ed
...
...
@@ -19,8 +19,10 @@ package object backend {
object
JumpOpType
{
def
jal
=
"b11_000"
.
U
def
jalr
=
"b11_010"
.
U
def
call
=
"b11_011"
.
U
def
ret
=
"b11_100"
.
U
// def call = "b11_011".U
// def ret = "b11_100".U
def
jumpOpIsJal
(
op
:
UInt
)
=
!
op
(
1
)
def
jumpOpisJalr
(
op
:
UInt
)
=
op
(
1
)
}
object
FenceOpType
{
...
...
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
0393f8ed
...
...
@@ -38,6 +38,9 @@ class RoqCSRIO extends XSBundle {
val
fflags
=
Output
(
Valid
(
UInt
(
5.
W
)))
val
dirty_fs
=
Output
(
Bool
())
val
perfinfo
=
new
Bundle
{
val
retiredInstr
=
Output
(
UInt
(
3.
W
))
}
}
class
RoqEnqIO
extends
XSBundle
{
...
...
@@ -671,11 +674,10 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
if
(
i
%
4
==
3
)
XSDebug
(
false
,
true
.
B
,
"\n"
)
}
val
id
=
roqDebugId
()
val
difftestIntrNO
=
WireInit
(
0.
U
(
XLEN
.
W
))
val
difftestCause
=
WireInit
(
0.
U
(
XLEN
.
W
))
ExcitingUtils
.
addSink
(
difftestIntrNO
,
s
"difftestIntrNOfromCSR$id"
)
ExcitingUtils
.
addSink
(
difftestCause
,
s
"difftestCausefromCSR$id"
)
val
instrCnt
=
RegInit
(
0.
U
(
64.
W
))
val
retireCounter
=
Mux
(
state
===
s_idle
,
commitCnt
,
0.
U
)
instrCnt
:=
instrCnt
+
retireCounter
io
.
csr
.
perfinfo
.
retiredInstr
:=
RegNext
(
retireCounter
)
if
(!
env
.
FPGAPlatform
)
{
...
...
@@ -696,10 +698,11 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val
uop
=
debug_microOp
(
idx
)
val
DifftestSkipSC
=
false
if
(!
DifftestSkipSC
){
skip
(
i
)
:=
debug_exuDebug
(
idx
).
isMMIO
&&
io
.
commits
.
valid
(
i
)
skip
(
i
)
:=
(
debug_exuDebug
(
idx
).
isMMIO
||
debug_exuDebug
(
idx
).
isPerfCnt
)
&&
io
.
commits
.
valid
(
i
)
}
else
{
skip
(
i
)
:=
(
debug_exuDebug
(
idx
).
isMMIO
||
debug_exuDebug
(
idx
).
isPerfCnt
||
uop
.
ctrl
.
fuType
===
FuType
.
mou
&&
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_d
||
uop
.
ctrl
.
fuType
===
FuType
.
mou
&&
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_w
)
&&
io
.
commits
.
valid
(
i
)
...
...
@@ -717,10 +720,10 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
debug_deqUop
.
ctrl
.
fuType
===
FuType
.
mou
&&
(
debug_deqUop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_d
||
debug_deqUop
.
ctrl
.
fuOpType
===
LSUOpType
.
sc_w
)
val
instrCnt
=
RegInit
(
0.
U
(
64
.
W
))
val
retireCounter
=
Mux
(
state
===
s_idle
,
commitCnt
,
0.
U
)
instrCnt
:=
instrCnt
+
retireCounter
val
difftestIntrNO
=
WireInit
(
0.
U
(
XLEN
.
W
))
val
difftestCause
=
WireInit
(
0.
U
(
XLEN
.
W
)
)
ExcitingUtils
.
addSink
(
difftestIntrNO
,
"difftestIntrNOfromCSR"
)
ExcitingUtils
.
addSink
(
difftestCause
,
"difftestCausefromCSR"
)
XSDebug
(
difftestIntrNO
=/=
0.
U
,
"difftest intrNO set %x\n"
,
difftestIntrNO
)
val
retireCounterFix
=
Mux
(
io
.
redirectOut
.
valid
,
1.
U
,
retireCounter
)
val
retirePCFix
=
SignExt
(
Mux
(
io
.
redirectOut
.
valid
,
debug_deqUop
.
cf
.
pc
,
debug_microOp
(
firstValidCommit
).
cf
.
pc
),
XLEN
)
...
...
src/main/scala/xiangshan/cache/dcacheWrapper.scala
浏览文件 @
0393f8ed
...
...
@@ -398,7 +398,7 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
// sync with prober
missQueue
.
io
.
probe_wb_req
.
valid
:=
prober
.
io
.
wb_req
.
fire
()
missQueue
.
io
.
probe_wb_req
.
bits
:=
prober
.
io
.
wb_req
.
bits
missQueue
.
io
.
probe_active
:=
prober
.
io
.
inflight_req_
block_addr
missQueue
.
io
.
probe_active
:=
prober
.
io
.
inflight_req_
idx
//----------------------------------------
// prober
...
...
src/main/scala/xiangshan/cache/dtlb.scala
浏览文件 @
0393f8ed
...
...
@@ -5,7 +5,7 @@ import chisel3.util._
import
xiangshan._
import
utils._
import
xiangshan.backend.roq.RoqPtr
import
xiangshan.backend.fu.HasCSRConst
import
xiangshan.backend.fu.
util.
HasCSRConst
import
chisel3.ExcitingUtils._
trait
HasTlbConst
extends
HasXSParameter
{
...
...
src/main/scala/xiangshan/cache/missQueue.scala
浏览文件 @
0393f8ed
...
...
@@ -306,7 +306,7 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
// if it releases the block we are trying to acquire, we don't care, since we will get it back eventually
// but we need to know whether it releases the block we are trying to evict
val
prober_writeback_our_block
=
(
state
===
s_refill_req
||
state
===
s_refill_resp
||
state
===
s_mem_finish
||
state
===
s_wait_probe_exit
||
state
===
s_send_resp
||
state
===
s_wb_req
)
&&
state
===
s_mem_finish
||
state
===
s_wait_probe_exit
)
&&
io
.
probe_wb_req
.
valid
&&
!
io
.
probe_wb_req
.
bits
.
voluntary
&&
io
.
probe_wb_req
.
bits
.
tag
===
req_old_meta
.
tag
&&
io
.
probe_wb_req
.
bits
.
idx
===
req_idx
&&
...
...
src/main/scala/xiangshan/cache/wbu.scala
浏览文件 @
0393f8ed
...
...
@@ -126,14 +126,14 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
val
id
=
cfg
.
nMissEntries
val
probeResponse
=
edge
.
ProbeAck
(
fromSource
=
id
.
U
,
fromSource
=
req
.
source
,
toAddress
=
r_address
,
lgSize
=
log2Ceil
(
cfg
.
blockBytes
).
U
,
reportPermissions
=
req
.
param
)
val
probeResponseData
=
edge
.
ProbeAck
(
fromSource
=
id
.
U
,
fromSource
=
req
.
source
,
toAddress
=
r_address
,
lgSize
=
log2Ceil
(
cfg
.
blockBytes
).
U
,
reportPermissions
=
req
.
param
,
...
...
src/main/scala/xiangshan/frontend/LoopPredictor.scala
浏览文件 @
0393f8ed
...
...
@@ -403,7 +403,9 @@ class LoopPredictor extends BasePredictor with LTBParams {
io
.
meta
.
specCnts
(
i
)
:=
ltbResps
(
i
).
meta
}
ExcitingUtils
.
addSource
(
io
.
resp
.
exit
.
reduce
(
_
||
_
),
"perfCntLoopExit"
,
Perf
)
if
(!
env
.
FPGAPlatform
)
{
ExcitingUtils
.
addSource
(
io
.
resp
.
exit
.
reduce
(
_
||
_
),
"perfCntLoopExit"
,
Perf
)
}
if
(
BPUDebug
&&
debug
)
{
// debug info
...
...
@@ -422,4 +424,4 @@ class LoopPredictor extends BasePredictor with LTBParams {
XSDebug
(
false
,
out_fire
&&
(
i
.
U
===
3.
U
||
i
.
U
===
7.
U
||
i
.
U
===
11.
U
||
i
.
U
===
15.
U
),
"\n"
)
}
}
}
\ No newline at end of file
}
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
浏览文件 @
0393f8ed
...
...
@@ -362,6 +362,7 @@ class LoadQueue extends XSModule
io
.
ldout
(
i
).
bits
.
redirect
:=
DontCare
io
.
ldout
(
i
).
bits
.
brUpdate
:=
DontCare
io
.
ldout
(
i
).
bits
.
debug
.
isMMIO
:=
debug_mmio
(
loadWbSel
(
i
))
io
.
ldout
(
i
).
bits
.
debug
.
isPerfCnt
:=
false
.
B
io
.
ldout
(
i
).
bits
.
fflags
:=
DontCare
io
.
ldout
(
i
).
valid
:=
loadWbSelV
(
i
)
...
...
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
浏览文件 @
0393f8ed
...
...
@@ -264,6 +264,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
io
.
mmioStout
.
bits
.
redirect
:=
DontCare
io
.
mmioStout
.
bits
.
brUpdate
:=
DontCare
io
.
mmioStout
.
bits
.
debug
.
isMMIO
:=
true
.
B
io
.
mmioStout
.
bits
.
debug
.
isPerfCnt
:=
false
.
B
io
.
mmioStout
.
bits
.
fflags
:=
DontCare
when
(
io
.
mmioStout
.
fire
())
{
writebacked
(
deqPtr
)
:=
true
.
B
...
...
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
浏览文件 @
0393f8ed
...
...
@@ -4,6 +4,7 @@ import chisel3._
import
chisel3.util._
import
utils._
import
xiangshan._
import
xiangshan.backend.decode.ImmUnion
import
xiangshan.cache._
// import xiangshan.cache.{DCacheWordIO, TlbRequestIO, TlbCmd, MemoryOpConstants, TlbReq, DCacheLoadReq, DCacheWordResp}
import
xiangshan.backend.LSUOpType
...
...
@@ -25,7 +26,7 @@ class LoadUnit_S0 extends XSModule {
})
val
s0_uop
=
io
.
in
.
bits
.
uop
val
s0_vaddr
=
io
.
in
.
bits
.
src1
+
s0_uop
.
ctrl
.
imm
val
s0_vaddr
=
io
.
in
.
bits
.
src1
+
SignExt
(
ImmUnion
.
I
.
toImm32
(
s0_uop
.
ctrl
.
imm
),
XLEN
)
val
s0_mask
=
genWmask
(
s0_vaddr
,
s0_uop
.
ctrl
.
fuOpType
(
1
,
0
))
// query DTLB
...
...
@@ -280,6 +281,7 @@ class LoadUnit extends XSModule with HasLoadHelper {
intHitLoadOut
.
bits
.
redirect
:=
DontCare
intHitLoadOut
.
bits
.
brUpdate
:=
DontCare
intHitLoadOut
.
bits
.
debug
.
isMMIO
:=
load_s2
.
io
.
out
.
bits
.
mmio
intHitLoadOut
.
bits
.
debug
.
isPerfCnt
:=
false
.
B
intHitLoadOut
.
bits
.
fflags
:=
DontCare
load_s2
.
io
.
out
.
ready
:=
true
.
B
...
...
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
浏览文件 @
0393f8ed
...
...
@@ -4,6 +4,7 @@ import chisel3._
import
chisel3.util._
import
utils._
import
xiangshan._
import
xiangshan.backend.decode.ImmUnion
import
xiangshan.cache._
// Store Pipeline Stage 0
...
...
@@ -16,7 +17,7 @@ class StoreUnit_S0 extends XSModule {
})
// send req to dtlb
val
saddr
=
io
.
in
.
bits
.
src1
+
io
.
in
.
bits
.
uop
.
ctrl
.
imm
val
saddr
=
io
.
in
.
bits
.
src1
+
SignExt
(
ImmUnion
.
S
.
toImm32
(
io
.
in
.
bits
.
uop
.
ctrl
.
imm
),
XLEN
)
io
.
dtlbReq
.
bits
.
vaddr
:=
saddr
io
.
dtlbReq
.
valid
:=
io
.
in
.
valid
...
...
@@ -114,6 +115,7 @@ class StoreUnit_S2 extends XSModule {
io
.
stout
.
bits
.
redirect
:=
DontCare
io
.
stout
.
bits
.
brUpdate
:=
DontCare
io
.
stout
.
bits
.
debug
.
isMMIO
:=
io
.
in
.
bits
.
mmio
io
.
stout
.
bits
.
debug
.
isPerfCnt
:=
false
.
B
io
.
stout
.
bits
.
fflags
:=
DontCare
}
...
...
src/main/scala/xiangshan/mem/sbuffer/NewSbuffer.scala
浏览文件 @
0393f8ed
...
...
@@ -13,6 +13,10 @@ trait HasSbufferCst extends HasXSParameter {
def
s_prepare
=
2.
U
(
2.
W
)
def
s_inflight
=
3.
U
(
2.
W
)
val
evictCycle
=
8192
require
(
isPow2
(
evictCycle
))
val
countBits
=
1
+
log2Up
(
evictCycle
)
val
SbufferIndexWidth
:
Int
=
log2Up
(
StoreBufferSize
)
// paddr = tag + offset
val
CacheLineBytes
:
Int
=
CacheLineSize
/
8
...
...
@@ -37,7 +41,6 @@ class SbufferLine extends SbufferBundle {
class
ChooseReplace
(
nWay
:
Int
)
extends
XSModule
{
val
io
=
IO
(
new
Bundle
{
val
mask
=
Vec
(
nWay
,
Input
(
Bool
()))
val
fire
=
Input
(
Bool
())
val
way
=
Output
(
UInt
(
nWay
.
W
))
val
flush
=
Input
(
Bool
())
})
...
...
@@ -49,12 +52,9 @@ class ChooseReplace(nWay: Int) extends XSModule {
val
nextWay
=
PriorityEncoder
(
Cat
(
stateMask
,
loMask
))(
log2Up
(
nWay
)-
1
,
0
)
XSDebug
(
p
"nextWay[${nextWay}]\n"
)
wayReg
:=
nextWay
io
.
way
:=
wayReg
when
(
io
.
fire
){
wayReg
:=
nextWay
}
when
(
io
.
flush
){
wayReg
:=
0.
U
}
...
...
@@ -116,11 +116,11 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val
buffer
=
Mem
(
StoreBufferSize
,
new
SbufferLine
)
val
stateVec
=
RegInit
(
VecInit
(
Seq
.
fill
(
StoreBufferSize
)(
s_invalid
)))
val
cohCount
=
Reg
(
Vec
(
StoreBufferSize
,
UInt
(
countBits
.
W
)))
/*
idle --[flush]--> drian_sbuffer --[buf empty]--> idle
--[buf full]--> replace --[dcache resp]--> idle
*/
*/
val
x_idle
::
x_drain_sbuffer
::
x_replace
::
Nil
=
Enum
(
3
)
val
sbuffer_state
=
RegInit
(
x_idle
)
...
...
@@ -150,7 +150,6 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val
invalidCount
=
RegInit
(
StoreBufferSize
.
U
((
log2Up
(
StoreBufferSize
)
+
1
).
W
))
val
validCount
=
RegInit
(
0.
U
((
log2Up
(
StoreBufferSize
)
+
1
).
W
))
val
full
=
invalidCount
===
0.
U
// val oneSpace = invalidCount === 1.U
val
bufferRead
=
VecInit
((
0
until
StoreBufferSize
).
map
(
i
=>
buffer
(
i
)))
val
stateRead
=
VecInit
((
0
until
StoreBufferSize
).
map
(
i
=>
stateVec
(
i
)))
...
...
@@ -171,8 +170,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val
lru
=
Module
(
new
ChooseReplace
(
StoreBufferSize
))
val
evictionIdx
=
lru
.
io
.
way
lru
.
io
.
fire
:=
false
.
B
lru
.
io
.
mask
:=
stateRead
.
map
(
_
===
s_valid
)
val
tags
=
io
.
in
.
map
(
in
=>
getTag
(
in
.
bits
.
addr
))
...
...
@@ -212,6 +210,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
def
wordReqToBufLine
(
req
:
DCacheWordReq
,
tag
:
UInt
,
insertIdx
:
UInt
,
wordOffset
:
UInt
,
flushMask
:
Bool
)
:
Unit
=
{
stateUpdate
(
insertIdx
)
:=
s_valid
tagUpdate
(
insertIdx
)
:=
tag
cohCount
(
insertIdx
)
:=
0.
U
when
(
flushMask
){
for
(
j
<-
0
until
CacheLineWords
){
...
...
@@ -230,6 +229,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
}
def
mergeWordReq
(
req
:
DCacheWordReq
,
mergeIdx
:
UInt
,
wordOffset
:
UInt
)
:
Unit
=
{
cohCount
(
mergeIdx
)
:=
0.
U
for
(
i
<-
0
until
DataBytes
){
when
(
req
.
mask
(
i
)){
maskUpdate
(
mergeIdx
)(
wordOffset
)(
i
)
:=
true
.
B
...
...
@@ -267,7 +267,7 @@ class NewSbuffer extends XSModule with HasSbufferCst {
for
(
i
<-
0
until
StoreBufferSize
){
XSDebug
(
stateVec
(
i
)=/=
s_invalid
,
p
"[$i] state:${stateVec(i)} buf:${bufferRead(i)}\n"
p
"[$i]
timeout:${cohCount(i)(countBits-1)}
state:${stateVec(i)} buf:${bufferRead(i)}\n"
)
}
...
...
@@ -338,16 +338,14 @@ class NewSbuffer extends XSModule with HasSbufferCst {
//
// evictionEntry.bits := evictionIdx
val
prepareValid
=
((
do_eviction
&&
sbuffer_state
===
x_replace
)||
(
sbuffer_state
===
x_drain_sbuffer
))
&&
val
prepareValid
=
((
do_eviction
&&
sbuffer_state
===
x_replace
)
||
(
sbuffer_state
===
x_drain_sbuffer
))
&&
stateVec
(
evictionIdx
)===
s_valid
&&
noSameBlockInflight
(
evictionIdx
)
when
(
prepareValid
){
stateVec
(
evictionIdx
)
:=
s_prepare
lru
.
io
.
fire
:=
true
.
B
}
val
prepareMask
=
stateVec
.
map
(
s
=>
s
===
s_prepare
)
val
(
prepareIdx
,
prepareEn
)
=
PriorityEncoderWithFlag
(
prepareMask
)
...
...
@@ -383,6 +381,21 @@ class NewSbuffer extends XSModule with HasSbufferCst {
XSDebug
(
p
"needSpace[$needSpace] invalidCount[$invalidCount] validCount[$validCount]\n"
)
//-------------------------cohCount-----------------------------
// insert and merge: cohCount=0
// every cycle cohCount+=1
// if cohCount(countBits-1)==1,evict
for
(
i
<-
0
until
StoreBufferSize
){
when
(
stateVec
(
i
)
===
s_valid
){
when
(
cohCount
(
i
)(
countBits
-
1
)){
assert
(
stateVec
(
i
)
===
s_valid
)
stateUpdate
(
i
)
:=
s_prepare
}
cohCount
(
i
)
:=
cohCount
(
i
)+
1.
U
}
}
// ---------------------- Load Data Forward ---------------------
for
((
forward
,
i
)
<-
io
.
forward
.
zipWithIndex
)
{
...
...
src/test/scala/xiangshan/memend/SbufferTest.scala
浏览文件 @
0393f8ed
...
...
@@ -44,9 +44,87 @@ class SbufferTest extends AnyFlatSpec
top
.
Parameters
.
set
(
top
.
Parameters
.
debugParameters
)
it
should
"random req"
in
{
// it should "random req" in {
// test(new SbufferWapper{AddSinks()}){ c =>
//
// def store_enq(addr: Seq[UInt], data: Seq[UInt], mask: Seq[UInt]) ={
// (0 until StorePipelineWidth).map { i =>
// c.io.in(i).valid.poke(true.B)
// c.io.in(i).bits.pokePartial(chiselTypeOf(c.io.in(i).bits).Lit(
// _.mask -> mask(i),
// _.addr -> addr(i),
// _.data -> data(i)
// ))
// }
// c.clock.step(1)
// for (in <- c.io.in){ in.valid.poke(false.B)}
// }
//
// def forward_req_and_resp(addr: Seq[UInt], data: Seq[UInt], mask:Seq[UInt]) = {
// (0 until LoadPipelineWidth).map{ i =>
// c.io.forward(i).paddr.poke(addr(i))
// c.io.forward(i).mask.poke(mask(i))
// if(c.io.in(i).ready.peek() == true.B) {
// (0 until 8).map { j =>
// c.io.forward(i).forwardData(j).expect(data(i)(j * 8 + 7, j * 8))
// }
// }
// }
// }
//
// val TEST_SIZE = 100
// for(i <- 0 until TEST_SIZE) {
// val addr = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7ffffffff8L).U)// align to block size
// val data = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7fffffffffffffffL).U)
// val mask = Seq.fill(StorePipelineWidth)(0xff.U)
// store_enq(addr, data, mask)
// forward_req_and_resp(addr, data, mask)
// }
// }
// }
//
// it should "sequence req" in {
// test(new SbufferWapper{AddSinks()}){ c =>
//
// def store_enq(addr: Seq[UInt], data: Seq[UInt], mask: Seq[UInt]) = {
// (0 until StorePipelineWidth).map { i =>
// c.io.in(i).valid.poke(true.B)
// c.io.in(i).bits.pokePartial(chiselTypeOf(c.io.in(i).bits).Lit(
// _.mask -> mask(i),
// _.addr -> addr(i),
// _.data -> data(i)
// ))
// }
// c.clock.step(1)
// for (in <- c.io.in){ in.valid.poke(false.B)}
// }
//
// def forward_req_and_resp(addr: Seq[UInt], data: Seq[UInt], mask:Seq[UInt]) = {
// (0 until LoadPipelineWidth).map{ i =>
// c.io.forward(i).paddr.poke(addr(i))
// c.io.forward(i).mask.poke(mask(i))
// if(c.io.in(i).ready.peek() == true.B) {
// (0 until 8).map { j =>
// c.io.forward(i).forwardData(j).expect(data(i)(j * 8 + 7, j * 8))
// }
// }
// }
// }
//
// val TEST_SIZE = 100
// val start_addr = Random.nextLong() & 0x7ffffffff8L
// for(i <- 0 until TEST_SIZE) {
// val addr = Seq(((i<<4) + start_addr).U,((i<<4)+8+start_addr).U)
// val data = Seq.fill(StorePipelineWidth)((Random.nextLong() & 0x7fffffffffffffffL).U)
// val mask = Seq.fill(StorePipelineWidth)(0xff.U)
// store_enq(addr, data, mask)
// forward_req_and_resp(addr, data, mask)
// }
// }
// }
it
should
"sbuffer coherence"
in
{
test
(
new
SbufferWapper
{
AddSinks
()}){
c
=>
def
store_enq
(
addr
:
Seq
[
UInt
],
data
:
Seq
[
UInt
],
mask
:
Seq
[
UInt
])
={
(
0
until
StorePipelineWidth
).
map
{
i
=>
c
.
io
.
in
(
i
).
valid
.
poke
(
true
.
B
)
...
...
@@ -59,7 +137,6 @@ class SbufferTest extends AnyFlatSpec
c
.
clock
.
step
(
1
)
for
(
in
<-
c
.
io
.
in
){
in
.
valid
.
poke
(
false
.
B
)}
}
def
forward_req_and_resp
(
addr
:
Seq
[
UInt
],
data
:
Seq
[
UInt
],
mask
:
Seq
[
UInt
])
=
{
(
0
until
LoadPipelineWidth
).
map
{
i
=>
c
.
io
.
forward
(
i
).
paddr
.
poke
(
addr
(
i
))
...
...
@@ -71,55 +148,16 @@ class SbufferTest extends AnyFlatSpec
}
}
}
val
TEST_SIZE
=
100
val
TEST_SIZE
=
10
for
(
i
<-
0
until
TEST_SIZE
)
{
val
addr
=
Seq
.
fill
(
StorePipelineWidth
)((
Random
.
nextLong
()
&
0x7ffffffff8
L
).
U
)
// align to
block size
val
addr
=
Seq
.
fill
(
StorePipelineWidth
)((
Random
.
nextLong
()
&
0x7ffffffff8
L
).
U
)
// align to
val
data
=
Seq
.
fill
(
StorePipelineWidth
)((
Random
.
nextLong
()
&
0x7fffffffffffffff
L
).
U
)
val
mask
=
Seq
.
fill
(
StorePipelineWidth
)(
0xff
.
U
)
store_enq
(
addr
,
data
,
mask
)
forward_req_and_resp
(
addr
,
data
,
mask
)
}
}
}
it
should
"sequence req"
in
{
test
(
new
SbufferWapper
{
AddSinks
()}){
c
=>
def
store_enq
(
addr
:
Seq
[
UInt
],
data
:
Seq
[
UInt
],
mask
:
Seq
[
UInt
])
=
{
(
0
until
StorePipelineWidth
).
map
{
i
=>
c
.
io
.
in
(
i
).
valid
.
poke
(
true
.
B
)
c
.
io
.
in
(
i
).
bits
.
pokePartial
(
chiselTypeOf
(
c
.
io
.
in
(
i
).
bits
).
Lit
(
_
.
mask
->
mask
(
i
),
_
.
addr
->
addr
(
i
),
_
.
data
->
data
(
i
)
))
}
c
.
clock
.
step
(
1
)
for
(
in
<-
c
.
io
.
in
){
in
.
valid
.
poke
(
false
.
B
)}
}
def
forward_req_and_resp
(
addr
:
Seq
[
UInt
],
data
:
Seq
[
UInt
],
mask
:
Seq
[
UInt
])
=
{
(
0
until
LoadPipelineWidth
).
map
{
i
=>
c
.
io
.
forward
(
i
).
paddr
.
poke
(
addr
(
i
))
c
.
io
.
forward
(
i
).
mask
.
poke
(
mask
(
i
))
if
(
c
.
io
.
in
(
i
).
ready
.
peek
()
==
true
.
B
)
{
(
0
until
8
).
map
{
j
=>
c
.
io
.
forward
(
i
).
forwardData
(
j
).
expect
(
data
(
i
)(
j
*
8
+
7
,
j
*
8
))
}
}
}
}
val
TEST_SIZE
=
100
val
start_addr
=
Random
.
nextLong
()
&
0x7ffffffff8
L
for
(
i
<-
0
until
TEST_SIZE
)
{
val
addr
=
Seq
(((
i
<<
4
)
+
start_addr
).
U
,((
i
<<
4
)+
8
+
start_addr
).
U
)
val
data
=
Seq
.
fill
(
StorePipelineWidth
)((
Random
.
nextLong
()
&
0x7fffffffffffffff
L
).
U
)
val
mask
=
Seq
.
fill
(
StorePipelineWidth
)(
0xff
.
U
)
store_enq
(
addr
,
data
,
mask
)
forward_req_and_resp
(
addr
,
data
,
mask
)
}
c
.
clock
.
step
(
512
+
10
)
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录