Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
ada67687
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
11 个月 前同步成功
通知
1183
Star
3914
Fork
526
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
XiangShan
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ada67687
编写于
11月 27, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master' into debian-gogogo
上级
01693179
b3e798d7
变更
24
展开全部
隐藏空白更改
内联
并排
Showing
24 changed file
with
585 addition
and
858 deletion
+585
-858
.gitignore
.gitignore
+1
-0
Makefile
Makefile
+1
-1
src/main/scala/xiangshan/backend/FloatBlock.scala
src/main/scala/xiangshan/backend/FloatBlock.scala
+17
-15
src/main/scala/xiangshan/backend/IntegerBlock.scala
src/main/scala/xiangshan/backend/IntegerBlock.scala
+22
-17
src/main/scala/xiangshan/backend/MemBlock.scala
src/main/scala/xiangshan/backend/MemBlock.scala
+22
-17
src/main/scala/xiangshan/backend/exu/AluExeUnit.scala
src/main/scala/xiangshan/backend/exu/AluExeUnit.scala
+15
-1
src/main/scala/xiangshan/backend/exu/Exu.scala
src/main/scala/xiangshan/backend/exu/Exu.scala
+1
-1
src/main/scala/xiangshan/backend/fu/Fence.scala
src/main/scala/xiangshan/backend/fu/Fence.scala
+6
-3
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
+2
-1
src/main/scala/xiangshan/backend/issue/ReservationStation.scala
...in/scala/xiangshan/backend/issue/ReservationStation.scala
+0
-443
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
...scala/xiangshan/backend/issue/ReservationStationNew.scala
+280
-201
src/main/scala/xiangshan/cache/dtlb.scala
src/main/scala/xiangshan/cache/dtlb.scala
+16
-20
src/main/scala/xiangshan/cache/ptw.scala
src/main/scala/xiangshan/cache/ptw.scala
+2
-0
src/main/scala/xiangshan/frontend/uBTB.scala
src/main/scala/xiangshan/frontend/uBTB.scala
+21
-12
src/main/scala/xiangshan/mem/Memend.scala
src/main/scala/xiangshan/mem/Memend.scala
+2
-2
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
+39
-88
src/main/scala/xiangshan/mem/pipeline/AtomicsUnit.scala
src/main/scala/xiangshan/mem/pipeline/AtomicsUnit.scala
+5
-3
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
+5
-4
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
+2
-1
src/test/csrc/emu.cpp
src/test/csrc/emu.cpp
+25
-10
src/test/csrc/emu.h
src/test/csrc/emu.h
+4
-1
src/test/csrc/main.cpp
src/test/csrc/main.cpp
+1
-1
src/test/csrc/ram.cpp
src/test/csrc/ram.cpp
+95
-15
src/test/csrc/ram.h
src/test/csrc/ram.h
+1
-1
未找到文件。
.gitignore
浏览文件 @
ada67687
...
...
@@ -348,3 +348,4 @@ mill.rdiB
stale_outputs_checked
*.snapshot
Makefile
浏览文件 @
ada67687
...
...
@@ -66,7 +66,7 @@ EMU_VFILES = $(shell find $(EMU_VSRC_DIR) -name "*.v" -or -name "*.sv")
EMU_CXXFLAGS
+=
-std
=
c++11
-static
-Wall
-I
$(EMU_CSRC_DIR)
EMU_CXXFLAGS
+=
-DVERILATOR
-Wno-maybe-uninitialized
EMU_LDFLAGS
+=
-lpthread
-lSDL2
-ldl
EMU_LDFLAGS
+=
-lpthread
-lSDL2
-ldl
-lz
VEXTRA_FLAGS
=
-I
$(
abspath
$(BUILD_DIR)
)
--x-assign
unique
-O3
-CFLAGS
"
$(EMU_CXXFLAGS)
"
-LDFLAGS
"
$(EMU_LDFLAGS)
"
...
...
src/main/scala/xiangshan/backend/FloatBlock.scala
浏览文件 @
ada67687
...
...
@@ -5,7 +5,7 @@ import chisel3.util._
import
xiangshan._
import
xiangshan.backend.regfile.Regfile
import
xiangshan.backend.exu._
import
xiangshan.backend.issue.
ReservationStationNew
import
xiangshan.backend.issue.
{
ReservationStationCtrl
,
ReservationStationData
}
class
FpBlockToCtrlIO
extends
XSBundle
{
...
...
@@ -78,28 +78,30 @@ class FloatBlock
s
"delay:${certainLatency}"
)
val
rs
=
Module
(
new
ReservationStationNew
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
false
))
val
rsCtrl
=
Module
(
new
ReservationStationCtrl
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
false
))
val
rsData
=
Module
(
new
ReservationStationData
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
false
))
rs
.
io
.
redirect
<>
redirect
rs
.
io
.
numExist
<>
io
.
toCtrlBlock
.
numExist
(
i
)
rs
.
io
.
enqCtrl
<>
io
.
fromCtrlBlock
.
enqIqCtrl
(
i
)
rs
.
io
.
enqData
<>
io
.
fromCtrlBlock
.
enqIqData
(
i
)
rsCtrl
.
io
.
data
<>
rsData
.
io
.
ctrl
rsCtrl
.
io
.
redirect
<>
redirect
// TODO: remove it
rsCtrl
.
io
.
numExist
<>
io
.
toCtrlBlock
.
numExist
(
i
)
rsCtrl
.
io
.
enqCtrl
<>
io
.
fromCtrlBlock
.
enqIqCtrl
(
i
)
rsData
.
io
.
enqData
<>
io
.
fromCtrlBlock
.
enqIqData
(
i
)
rsData
.
io
.
redirect
<>
redirect
rs
.
io
.
writeBackedData
<>
writeBackData
for
((
x
,
y
)
<-
rs
.
io
.
extraListenPorts
.
zip
(
extraListenPorts
))
{
rs
Data
.
io
.
writeBackedData
<>
writeBackData
for
((
x
,
y
)
<-
rs
Data
.
io
.
extraListenPorts
.
zip
(
extraListenPorts
))
{
x
.
valid
:=
y
.
fire
()
x
.
bits
:=
y
.
bits
}
exeUnits
(
i
).
io
.
redirect
<>
redirect
exeUnits
(
i
).
io
.
fromFp
<>
rs
.
io
.
deq
rs
.
io
.
tlbF
eedback
:=
DontCare
exeUnits
(
i
).
io
.
fromFp
<>
rs
Data
.
io
.
deq
rs
Data
.
io
.
f
eedback
:=
DontCare
rs
.
suggestName
(
s
"rs_${cfg.name}"
)
rsCtrl
.
suggestName
(
s
"rsc_${cfg.name}"
)
rsData
.
suggestName
(
s
"rsd_${cfg.name}"
)
rs
rs
Data
})
for
(
rs
<-
reservedStations
){
...
...
@@ -157,4 +159,4 @@ class FloatBlock
rf
.
data
:=
wb
.
bits
.
data
}
}
}
\ No newline at end of file
src/main/scala/xiangshan/backend/IntegerBlock.scala
浏览文件 @
ada67687
...
...
@@ -6,7 +6,7 @@ import xiangshan._
import
xiangshan.backend.exu.Exu.
{
jumpExeUnitCfg
,
ldExeUnitCfg
,
stExeUnitCfg
}
import
xiangshan.backend.exu.
{
AluExeUnit
,
ExuConfig
,
JumpExeUnit
,
MulDivExeUnit
,
Wb
}
import
xiangshan.backend.fu.FenceToSbuffer
import
xiangshan.backend.issue.
ReservationStationNew
import
xiangshan.backend.issue.
{
ReservationStationCtrl
,
ReservationStationData
}
import
xiangshan.backend.regfile.Regfile
import
xiangshan.backend.fu.fpu.Fflags
...
...
@@ -131,28 +131,33 @@ class IntegerBlock
println
(
s
"${i}: exu:${cfg.name} wakeupCnt: ${wakeupCnt} extraListenPorts: ${extraListenPortsCnt} delay:${certainLatency} feedback:${feedback}"
)
val
rs
=
Module
(
new
ReservationStationNew
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
feedback
))
rs
.
io
.
redirect
<>
redirect
rs
.
io
.
numExist
<>
io
.
toCtrlBlock
.
numExist
(
i
)
rs
.
io
.
enqCtrl
<>
io
.
fromCtrlBlock
.
enqIqCtrl
(
i
)
rs
.
io
.
enqData
<>
io
.
fromCtrlBlock
.
enqIqData
(
i
)
rs
.
io
.
writeBackedData
<>
writeBackData
for
((
x
,
y
)
<-
rs
.
io
.
extraListenPorts
.
zip
(
extraListenPorts
))
{
// val rs = Module(new ReservationStationNew(
// cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback
// ))
val
rsCtrl
=
Module
(
new
ReservationStationCtrl
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
feedback
))
val
rsData
=
Module
(
new
ReservationStationData
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
feedback
))
rsCtrl
.
io
.
data
<>
rsData
.
io
.
ctrl
rsCtrl
.
io
.
redirect
<>
redirect
// TODO: remove it
rsCtrl
.
io
.
numExist
<>
io
.
toCtrlBlock
.
numExist
(
i
)
rsCtrl
.
io
.
enqCtrl
<>
io
.
fromCtrlBlock
.
enqIqCtrl
(
i
)
rsData
.
io
.
enqData
<>
io
.
fromCtrlBlock
.
enqIqData
(
i
)
rsData
.
io
.
redirect
<>
redirect
rsData
.
io
.
writeBackedData
<>
writeBackData
for
((
x
,
y
)
<-
rsData
.
io
.
extraListenPorts
.
zip
(
extraListenPorts
))
{
x
.
valid
:=
y
.
fire
()
x
.
bits
:=
y
.
bits
}
exeUnits
(
i
).
io
.
redirect
<>
redirect
exeUnits
(
i
).
io
.
fromInt
<>
rs
.
io
.
deq
rs
.
io
.
tlbF
eedback
:=
DontCare
exeUnits
(
i
).
io
.
fromInt
<>
rs
Data
.
io
.
deq
rs
Data
.
io
.
f
eedback
:=
DontCare
rs
.
suggestName
(
s
"rs_${cfg.name}"
)
rsCtrl
.
suggestName
(
s
"rsc_${cfg.name}"
)
rsData
.
suggestName
(
s
"rsd_${cfg.name}"
)
rs
rs
Data
})
for
(
rs
<-
reservationStations
){
...
...
@@ -220,4 +225,4 @@ class IntegerBlock
rf
.
addr
:=
wb
.
bits
.
uop
.
pdest
rf
.
data
:=
wb
.
bits
.
data
}
}
}
\ No newline at end of file
src/main/scala/xiangshan/backend/MemBlock.scala
浏览文件 @
ada67687
...
...
@@ -9,7 +9,7 @@ import xiangshan.backend.exu._
import
xiangshan.cache._
import
xiangshan.mem._
import
xiangshan.backend.fu.FenceToSbuffer
import
xiangshan.backend.issue.
ReservationStationNew
import
xiangshan.backend.issue.
{
ReservationStationCtrl
,
ReservationStationData
}
import
xiangshan.backend.fu.FunctionUnit.
{
lduCfg
,
mouCfg
,
stuCfg
}
class
LsBlockToCtrlIO
extends
XSBundle
{
...
...
@@ -105,26 +105,30 @@ class MemBlock
println
(
s
"${i}: exu:${cfg.name} wakeupCnt: ${wakeupCnt} extraListenPorts: ${extraListenPortsCnt} delay:${certainLatency} feedback:${feedback}"
)
val
rs
=
Module
(
new
ReservationStationNew
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
feedback
))
val
rsCtrl
=
Module
(
new
ReservationStationCtrl
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
feedback
))
val
rsData
=
Module
(
new
ReservationStationData
(
cfg
,
wakeupCnt
,
extraListenPortsCnt
,
fixedDelay
=
certainLatency
,
feedback
=
feedback
))
rs
.
io
.
redirect
<>
redirect
rs
.
io
.
numExist
<>
io
.
toCtrlBlock
.
numExist
(
i
)
rs
.
io
.
enqCtrl
<>
io
.
fromCtrlBlock
.
enqIqCtrl
(
i
)
rs
.
io
.
enqData
<>
io
.
fromCtrlBlock
.
enqIqData
(
i
)
rsCtrl
.
io
.
data
<>
rsData
.
io
.
ctrl
rsCtrl
.
io
.
redirect
<>
redirect
// TODO: remove it
rsCtrl
.
io
.
numExist
<>
io
.
toCtrlBlock
.
numExist
(
i
)
rsCtrl
.
io
.
enqCtrl
<>
io
.
fromCtrlBlock
.
enqIqCtrl
(
i
)
rsData
.
io
.
enqData
<>
io
.
fromCtrlBlock
.
enqIqData
(
i
)
rsData
.
io
.
redirect
<>
redirect
rs
.
io
.
writeBackedData
<>
writeBackData
for
((
x
,
y
)
<-
rs
.
io
.
extraListenPorts
.
zip
(
extraListenPorts
))
{
rs
Data
.
io
.
writeBackedData
<>
writeBackData
for
((
x
,
y
)
<-
rs
Data
.
io
.
extraListenPorts
.
zip
(
extraListenPorts
))
{
x
.
valid
:=
y
.
fire
()
x
.
bits
:=
y
.
bits
}
rs
.
io
.
tlbFeedback
:=
DontCare
// exeUnits(i).io.redirect <> redirect
// exeUnits(i).io.fromInt <> rsData.io.deq
rsData
.
io
.
feedback
:=
DontCare
rs
.
suggestName
(
s
"rs_${cfg.name}"
)
rsCtrl
.
suggestName
(
s
"rsc_${cfg.name}"
)
rsData
.
suggestName
(
s
"rsd_${cfg.name}"
)
rs
rs
Data
})
for
(
rs
<-
reservationStations
){
...
...
@@ -166,7 +170,7 @@ class MemBlock
// LoadUnit
for
(
i
<-
0
until
exuParameters
.
LduCnt
)
{
loadUnits
(
i
).
io
.
redirect
<>
io
.
fromCtrlBlock
.
redirect
loadUnits
(
i
).
io
.
tlbFeedback
<>
reservationStations
(
i
).
io
.
tlbF
eedback
loadUnits
(
i
).
io
.
tlbFeedback
<>
reservationStations
(
i
).
io
.
f
eedback
loadUnits
(
i
).
io
.
dtlb
<>
dtlb
.
io
.
requestor
(
i
)
// get input form dispatch
loadUnits
(
i
).
io
.
ldin
<>
reservationStations
(
i
).
io
.
deq
...
...
@@ -184,7 +188,7 @@ class MemBlock
// StoreUnit
for
(
i
<-
0
until
exuParameters
.
StuCnt
)
{
storeUnits
(
i
).
io
.
redirect
<>
io
.
fromCtrlBlock
.
redirect
storeUnits
(
i
).
io
.
tlbFeedback
<>
reservationStations
(
exuParameters
.
LduCnt
+
i
).
io
.
tlbF
eedback
storeUnits
(
i
).
io
.
tlbFeedback
<>
reservationStations
(
exuParameters
.
LduCnt
+
i
).
io
.
f
eedback
storeUnits
(
i
).
io
.
dtlb
<>
dtlb
.
io
.
requestor
(
exuParameters
.
LduCnt
+
i
)
// get input form dispatch
storeUnits
(
i
).
io
.
stin
<>
reservationStations
(
exuParameters
.
LduCnt
+
i
).
io
.
deq
...
...
@@ -232,6 +236,7 @@ class MemBlock
atomicsUnit
.
io
.
dtlb
.
resp
.
valid
:=
false
.
B
atomicsUnit
.
io
.
dtlb
.
resp
.
bits
:=
DontCare
atomicsUnit
.
io
.
dtlb
.
req
.
ready
:=
dtlb
.
io
.
requestor
(
0
).
req
.
ready
// dispatch 0 takes priority
atomicsUnit
.
io
.
in
.
valid
:=
st0_atomics
...
...
@@ -251,7 +256,7 @@ class MemBlock
when
(
atomicsUnit
.
io
.
tlbFeedback
.
valid
)
{
assert
(!
storeUnits
(
0
).
io
.
tlbFeedback
.
valid
)
atomicsUnit
.
io
.
tlbFeedback
<>
reservationStations
(
exuParameters
.
LduCnt
+
0
).
io
.
tlbF
eedback
atomicsUnit
.
io
.
tlbFeedback
<>
reservationStations
(
exuParameters
.
LduCnt
+
0
).
io
.
f
eedback
}
atomicsUnit
.
io
.
dcache
<>
io
.
dcache
.
atomics
...
...
@@ -269,4 +274,4 @@ class MemBlock
lsq
.
io
.
exceptionAddr
.
isStore
:=
io
.
lsqio
.
exceptionAddr
.
isStore
io
.
lsqio
.
exceptionAddr
.
vaddr
:=
Mux
(
atomicsUnit
.
io
.
exceptionAddr
.
valid
,
atomicsUnit
.
io
.
exceptionAddr
.
bits
,
lsq
.
io
.
exceptionAddr
.
vaddr
)
}
}
\ No newline at end of file
src/main/scala/xiangshan/backend/exu/AluExeUnit.scala
浏览文件 @
ada67687
package
xiangshan.backend.exu
import
chisel3._
...
...
@@ -15,4 +16,17 @@ class AluExeUnit extends Exu(aluExeUnitCfg)
io
.
toInt
.
bits
.
redirectValid
:=
alu
.
redirectOutValid
io
.
toInt
.
bits
.
redirect
:=
alu
.
redirectOut
io
.
toInt
.
bits
.
brUpdate
:=
alu
.
brUpdate
}
XSDebug
(
io
.
fromInt
.
valid
||
io
.
redirect
.
valid
,
p
"fromInt(${io.fromInt.valid} ${io.fromInt.ready}) toInt(${io.toInt.valid} ${io.toInt.ready})"
+
p
"Redirect:(${io.redirect.valid} ${io.redirect.bits.isException}${io.redirect.bits.isFlushPipe}${io.redirect.bits.isMisPred}${io.redirect.bits.isReplay}) roqIdx:${io.redirect.bits.roqIdx}\n"
,
)
XSDebug
(
io
.
fromInt
.
valid
,
p
"src1:${Hexadecimal(io.fromInt.bits.src1)} src2:${Hexadecimal(io.fromInt.bits.src2)} "
+
p
"src3:${Hexadecimal(io.fromInt.bits.src3)} func:${Binary(io.fromInt.bits.uop.ctrl.fuOpType)} "
+
p
"pc:${Hexadecimal(io.fromInt.bits.uop.cf.pc)} roqIdx:${io.fromInt.bits.uop.roqIdx}\n"
)
XSDebug
(
io
.
toInt
.
valid
,
p
"res:${Hexadecimal(io.toInt.bits.data)}\n"
)
}
\ No newline at end of file
src/main/scala/xiangshan/backend/exu/Exu.scala
浏览文件 @
ada67687
...
...
@@ -100,7 +100,7 @@ abstract class Exu(val config: ExuConfig) extends XSModule {
val
src2
=
in
.
bits
.
src2
val
src3
=
in
.
bits
.
src3
fu
.
io
.
in
.
valid
:=
in
.
valid
&&
sel
fu
.
io
.
in
.
valid
:=
in
.
valid
&&
sel
&&
!
in
.
bits
.
uop
.
roqIdx
.
needFlush
(
io
.
redirect
)
fu
.
io
.
in
.
bits
.
uop
:=
in
.
bits
.
uop
fu
.
io
.
in
.
bits
.
src
.
foreach
(
_
<>
DontCare
)
if
(
fuCfg
.
srcCnt
>
0
)
{
...
...
src/main/scala/xiangshan/backend/fu/Fence.scala
浏览文件 @
ada67687
...
...
@@ -11,7 +11,10 @@ class FenceToSbuffer extends XSBundle {
val
sbIsEmpty
=
Input
(
Bool
())
}
class
Fence
extends
FunctionUnit
{
// class Fence extends FunctionUnit(FuConfig(
// /*FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,*/ latency = UncertainLatency()
// )){
class
Fence
extends
FunctionUnit
{
// TODO: check it
val
sfence
=
IO
(
Output
(
new
SfenceBundle
))
val
fencei
=
IO
(
Output
(
Bool
()))
...
...
@@ -43,7 +46,7 @@ class Fence extends FunctionUnit{
when
(
state
===
s_sb
&&
valid
&&
func
===
FenceOpType
.
fencei
&&
!
sbEmpty
)
{
state
:=
s_icache
}
when
(
state
===
s_sb
&&
valid
&&
func
===
FenceOpType
.
sfence
&&
!
sbEmpty
)
{
state
:=
s_tlb
}
when
(
state
===
s_sb
&&
valid
&&
func
===
FenceOpType
.
fence
&&
!
sbEmpty
)
{
state
:=
s_none
}
when
(
state
=/=
s_sb
&&
sbEmpty
)
{
state
:=
s_sb
}
when
(
state
=/=
s_sb
&&
sbEmpty
)
{
state
:=
s_sb
}
assert
(!(
io
.
out
.
valid
&&
io
.
out
.
bits
.
uop
.
ctrl
.
rfWen
))
io
.
in
.
ready
:=
state
===
s_sb
...
...
@@ -54,4 +57,4 @@ class Fence extends FunctionUnit{
assert
(!(
valid
||
state
=/=
s_sb
)
||
io
.
out
.
ready
)
// NOTE: fence instr must be the first(only one) instr, so io.out.ready must be true
XSDebug
(
valid
||
state
=/=
s_sb
||
io
.
out
.
valid
,
p
"In(${io.in.valid} ${io.in.ready}) Out(${io.out.valid} ${io.out.ready}) state:${state} sbuffer(flush:${sbuffer} empty:${sbEmpty}) fencei:${fencei} sfence:${sfence} Inpc:0x${Hexadecimal(io.in.bits.uop.cf.pc)} InroqIdx:${io.in.bits.uop.roqIdx} Outpc:0x${Hexadecimal(io.out.bits.uop.cf.pc)} OutroqIdx:${io.out.bits.uop.roqIdx}\n"
)
}
}
\ No newline at end of file
src/main/scala/xiangshan/backend/fu/FunctionUnit.scala
浏览文件 @
ada67687
...
...
@@ -175,7 +175,8 @@ object FunctionUnit extends HasXSParameter {
val
fenceCfg
=
FuConfig
(
fuGen
=
fence
_
,
fuSel
=
(
x
:
FunctionUnit
)
=>
x
.
io
.
in
.
bits
.
uop
.
ctrl
.
fuType
===
FuType
.
fence
,
FuType
.
fence
,
1
,
0
,
writeIntRf
=
false
,
writeFpRf
=
false
,
hasRedirect
=
false
FuType
.
fence
,
1
,
0
,
writeIntRf
=
false
,
writeFpRf
=
false
,
hasRedirect
=
false
,
UncertainLatency
()
// TODO: need rewrite latency structure, not just this value
)
val
csrCfg
=
FuConfig
(
...
...
src/main/scala/xiangshan/backend/issue/ReservationStation.scala
已删除
100644 → 0
浏览文件 @
01693179
此差异已折叠。
点击以展开。
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
浏览文件 @
ada67687
此差异已折叠。
点击以展开。
src/main/scala/xiangshan/cache/dtlb.scala
浏览文件 @
ada67687
...
...
@@ -154,10 +154,8 @@ class TlbResp extends TlbBundle {
}
class
TlbRequestIO
()
extends
TlbBundle
{
val
req
=
Valid
(
new
TlbReq
)
val
resp
=
Flipped
(
Valid
(
new
TlbResp
))
// override def cloneType: this.type = (new TlbRequestIO(Width)).asInstanceOf[this.type]
val
req
=
DecoupledIO
(
new
TlbReq
)
val
resp
=
Flipped
(
DecoupledIO
(
new
TlbResp
))
}
class
BlockTlbRequestIO
()
extends
TlbBundle
{
...
...
@@ -231,6 +229,7 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
2.
U
->
Cat
(
hitppn
(
i
),
reqAddr
(
i
).
off
)
))
req
(
i
).
ready
:=
resp
(
i
).
ready
resp
(
i
).
valid
:=
valid
(
i
)
resp
(
i
).
bits
.
paddr
:=
Mux
(
vmEnable
,
paddr
,
SignExt
(
req
(
i
).
bits
.
vaddr
,
PAddrBits
))
resp
(
i
).
bits
.
miss
:=
miss
(
i
)
...
...
@@ -279,7 +278,7 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
}
// reset pf when pf hit
val
pfHitReset
=
ParallelOR
(
widthMap
{
i
=>
Mux
(
valid
(
i
),
VecInit
(
pfHitVec
(
i
)).
asUInt
,
0.
U
)
})
val
pfHitReset
=
ParallelOR
(
widthMap
{
i
=>
Mux
(
resp
(
i
).
fire
(
),
VecInit
(
pfHitVec
(
i
)).
asUInt
,
0.
U
)
})
val
pfHitRefill
=
ParallelOR
(
pfHitReset
.
asBools
)
// refill
...
...
@@ -356,8 +355,8 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
// Log
for
(
i
<-
0
until
Width
)
{
XSDebug
(
req
(
i
).
valid
,
p
"req(${i.U}): ${req(i).bits}\n"
)
XSDebug
(
resp
(
i
).
valid
,
p
"resp(${i.U}): ${resp(i).bits}\n"
)
XSDebug
(
req
(
i
).
valid
,
p
"req(${i.U}):
(${req(i).valid} ${req(i).ready})
${req(i).bits}\n"
)
XSDebug
(
resp
(
i
).
valid
,
p
"resp(${i.U}):
(${resp(i).valid} ${resp(i).ready})
${resp(i).bits}\n"
)
}
XSDebug
(
sfence
.
valid
,
p
"Sfence: ${sfence}\n"
)
...
...
@@ -412,27 +411,24 @@ object TLB {
if
(!
shouldBlock
)
{
// dtlb
for
(
i
<-
0
until
width
)
{
tlb
.
io
.
requestor
(
i
).
req
.
valid
:=
in
(
i
).
req
.
valid
tlb
.
io
.
requestor
(
i
).
req
.
bits
:=
in
(
i
).
req
.
bits
in
(
i
).
req
.
ready
:=
DontCare
in
(
i
).
resp
.
valid
:=
tlb
.
io
.
requestor
(
i
).
resp
.
valid
in
(
i
).
resp
.
bits
:=
tlb
.
io
.
requestor
(
i
).
resp
.
bits
tlb
.
io
.
requestor
(
i
)
<>
in
(
i
)
// tlb.io.requestor(i).req.valid := in(i).req.valid
// tlb.io.requestor(i).req.bits := in(i).req.bits
// in(i).req.ready := tlb.io.requestor(i).req.ready
// in(i).resp.valid := tlb.io.requestor(i).resp.valid
// in(i).resp.bits := tlb.io.requestor(i).resp.bits
// tlb.io.requestor(i).resp.ready := in(i).resp.ready
}
}
else
{
// itlb
require
(
width
==
1
)
tlb
.
io
.
requestor
(
0
).
req
.
valid
:=
in
(
0
).
req
.
valid
tlb
.
io
.
requestor
(
0
).
req
.
bits
:=
in
(
0
).
req
.
bits
in
(
0
).
req
.
ready
:=
!
tlb
.
io
.
requestor
(
0
).
resp
.
bits
.
miss
&&
in
(
0
).
resp
.
ready
// val pf = LookupTree(tlb.io.requestor(0).req.bits.cmd, List(
// TlbCmd.read -> tlb.io.requestor(0).resp.bits.excp.pf.ld,
// TlbCmd.write -> tlb.io.requestor(0).resp.bits.excp.pf.st,
// TlbCmd.exec -> tlb.io.requestor(0).resp.bits.excp.pf.instr
// ))
in
(
0
).
req
.
ready
:=
!
tlb
.
io
.
requestor
(
0
).
resp
.
bits
.
miss
&&
in
(
0
).
resp
.
ready
&&
tlb
.
io
.
requestor
(
0
).
req
.
ready
in
(
0
).
resp
.
valid
:=
tlb
.
io
.
requestor
(
0
).
resp
.
valid
&&
!
tlb
.
io
.
requestor
(
0
).
resp
.
bits
.
miss
in
(
0
).
resp
.
bits
:=
tlb
.
io
.
requestor
(
0
).
resp
.
bits
tlb
.
io
.
requestor
(
0
).
resp
.
ready
:=
in
(
0
).
resp
.
ready
}
tlb
.
io
.
ptw
...
...
src/main/scala/xiangshan/cache/ptw.scala
浏览文件 @
ada67687
...
...
@@ -459,4 +459,6 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
XSDebug
(
memRespFire
,
p
"mem resp fire rdata:0x${Hexadecimal(mem.d.bits.data)} Pte:${memPte}\n"
)
XSDebug
(
sfenceLatch
,
p
"ptw has a flushed req waiting for resp... state:${state} mem.a(${mem.a.valid} ${mem.a.ready}) d($memValid} ${memRespReady})\n"
)
// TODO: add ptw perf cnt
}
src/main/scala/xiangshan/frontend/uBTB.scala
浏览文件 @
ada67687
...
...
@@ -9,13 +9,17 @@ import scala.math.min
trait
MicroBTBPatameter
{
val
nWays
=
16
val
offsetSize
=
20
val
lowerBitsSize
=
20
val
tagSize
=
20
val
extended_stat
=
false
}
class
MicroBTB
extends
BasePredictor
with
MicroBTBPatameter
{
val
tagSize
=
VAddrBits
-
log2Ceil
(
PredictWidth
)
-
1
// val tagSize = VAddrBits - log2Ceil(PredictWidth) - 1
val
untaggedBits
=
PredictWidth
+
1
class
MicroBTBResp
extends
Resp
{
...
...
@@ -44,7 +48,7 @@ class MicroBTB extends BasePredictor
override
val
io
=
IO
(
new
MicroBTBIO
)
io
.
uBTBBranchInfo
<>
out_ubtb_br_info
def
getTag
(
pc
:
UInt
)
=
(
pc
>>
(
log2Ceil
(
PredictWidth
)
+
1
)).
asUInt
(
)
def
getTag
(
pc
:
UInt
)
=
(
pc
>>
untaggedBits
)(
tagSize
-
1
,
0
)
def
getBank
(
pc
:
UInt
)
=
pc
(
log2Ceil
(
PredictWidth
)
,
1
)
class
MicroBTBMeta
extends
XSBundle
...
...
@@ -58,7 +62,7 @@ class MicroBTB extends BasePredictor
class
MicroBTBEntry
extends
XSBundle
{
val
offset
=
SInt
(
offset
Size
.
W
)
val
lower
=
UInt
(
lowerBits
Size
.
W
)
}
// val uBTBMeta = RegInit((0.U).asTypeOf(Vec(nWays, Vec(PredictWidth, new MicroBTBMeta))))
...
...
@@ -173,9 +177,9 @@ class MicroBTB extends BasePredictor
val
read_resp
=
Wire
(
Vec
(
PredictWidth
,
new
ReadRespEntry
))
val
read_bank_inOrder
=
VecInit
((
0
until
PredictWidth
).
map
(
b
=>
(
read_req_basebank
+
b
.
U
)(
log2Up
(
PredictWidth
)-
1
,
0
)
))
val
isInNextRow
=
VecInit
((
0
until
PredictWidth
).
map
(
_
.
U
<
read_req_basebank
))
//
val isInNextRow = VecInit((0 until PredictWidth).map(_.U < read_req_basebank))
(
0
until
PredictWidth
).
map
{
b
=>
metas
(
b
).
rtag
:=
Mux
(
isInNextRow
(
b
),
read_req_tag
+
1.
U
,
read_req_tag
)
}
(
0
until
PredictWidth
).
map
{
b
=>
metas
(
b
).
rtag
:=
read_req_tag
}
val
read_hit_ohs
=
read_bank_inOrder
.
map
{
b
=>
metas
(
b
).
hit_ohs
}
val
read_hit_vec
=
VecInit
(
read_hit_ohs
.
map
{
oh
=>
ParallelOR
(
oh
).
asBool
})
val
read_hit_ways
=
VecInit
(
read_hit_ohs
.
map
{
oh
=>
PriorityEncoder
(
oh
)})
...
...
@@ -193,7 +197,7 @@ class MicroBTB extends BasePredictor
read_resp
(
i
).
valid
:=
read_hit_vec
(
i
)
&&
io
.
inMask
(
i
)
read_resp
(
i
).
taken
:=
read_resp
(
i
).
valid
&&
uBTBMeta_resp
(
i
).
pred
(
1
)
read_resp
(
i
).
is_Br
:=
read_resp
(
i
).
valid
&&
uBTBMeta_resp
(
i
).
is_Br
read_resp
(
i
).
target
:=
((
io
.
pc
.
bits
).
asSInt
+
(
i
<<
1
).
S
+
btb_resp
(
i
).
offset
).
asUInt
read_resp
(
i
).
target
:=
Cat
(
io
.
pc
.
bits
(
VAddrBits
-
1
,
lowerBitsSize
+
1
),
btb_resp
(
i
).
asUInt
,
0.
U
(
1.
W
))
read_resp
(
i
).
is_RVC
:=
read_resp
(
i
).
valid
&&
uBTBMeta_resp
(
i
).
is_RVC
out_ubtb_br_info
.
hits
(
i
)
:=
read_hit_vec
(
i
)
...
...
@@ -250,7 +254,7 @@ class MicroBTB extends BasePredictor
val
update_base_bank
=
getBank
(
update_fetch_pc
)
val
update_tag
=
getTag
(
update_br_pc
)
val
update_target
=
Mux
(
u
.
pd
.
isBr
,
u
.
brTarget
,
u
.
target
)
val
update_ta
get_offset
=
update_target
.
asSInt
-
update_br_pc
.
asSInt
val
update_ta
rget_lower
=
update_target
(
lowerBitsSize
,
1
)
val
update_is_BR_or_JAL
=
(
u
.
pd
.
brType
===
BrType
.
branch
)
||
(
u
.
pd
.
brType
===
BrType
.
jal
)
...
...
@@ -260,12 +264,12 @@ class MicroBTB extends BasePredictor
//write btb target when miss prediction
// when(entry_write_valid)
// {
// uBTB(update_write_way)(update_bank).offset := update_taget_offset
// uBTB(update_write_way)(update_bank).offset := update_ta
r
get_offset
// }
for
(
b
<-
0
until
PredictWidth
)
{
datas
(
b
).
wen
:=
do_reset
||
(
entry_write_valid
&&
b
.
U
===
update_bank
)
datas
(
b
).
wWay
:=
Mux
(
do_reset
,
reset_way
,
update_write_way
)
datas
(
b
).
wdata
:=
Mux
(
do_reset
,
0.
U
.
asTypeOf
(
new
MicroBTBEntry
),
update_ta
get_offset
.
asTypeOf
(
new
MicroBTBEntry
))
datas
(
b
).
wdata
:=
Mux
(
do_reset
,
0.
U
.
asTypeOf
(
new
MicroBTBEntry
),
update_ta
rget_lower
.
asTypeOf
(
new
MicroBTBEntry
))
}
...
...
@@ -296,8 +300,8 @@ class MicroBTB extends BasePredictor
i
.
U
,
read_hit_vec
(
i
),
read_hit_ways
(
i
),
read_resp
(
i
).
valid
,
read_resp
(
i
).
is_RVC
,
read_resp
(
i
).
taken
,
read_resp
(
i
).
is_Br
,
read_resp
(
i
).
target
,
out_ubtb_br_info
.
writeWay
(
i
))
}
XSDebug
(
meta_write_valid
,
"uBTB update: update | pc:0x%x | update hits:%b | | update_write_way:%d | update_bank: %d| update_br_index:%d | update_tag:%x | up
adate_offset
0x%x\n "
,
update_br_pc
,
update_hits
,
update_write_way
,
update_bank
,
update_br_idx
,
update_tag
,
update_ta
get_offset
(
offset
Size
-
1
,
0
))
XSDebug
(
meta_write_valid
,
"uBTB update: update | pc:0x%x | update hits:%b | | update_write_way:%d | update_bank: %d| update_br_index:%d | update_tag:%x | up
date_lower
0x%x\n "
,
update_br_pc
,
update_hits
,
update_write_way
,
update_bank
,
update_br_idx
,
update_tag
,
update_ta
rget_lower
(
lowerBits
Size
-
1
,
0
))
XSDebug
(
meta_write_valid
,
"uBTB update: update_taken:%d | old_pred:%b | new_pred:%b\n"
,
update_taken
,
metas
(
update_bank
).
rpred
,
Mux
(!
update_hits
,
...
...
@@ -306,6 +310,11 @@ class MicroBTB extends BasePredictor
))
}
if
(
extended_stat
)
{
val
high_identical
=
update_target
(
VAddrBits
-
1
,
lowerBitsSize
)
=/=
update_fetch_pc
(
VAddrBits
-
1
,
lowerBitsSize
)
XSDebug
(
io
.
update
.
valid
,
"extended_stat: identical %d\n"
,
high_identical
)
}
//bypass:read-after-write
// for( b <- 0 until PredictWidth) {
...
...
src/main/scala/xiangshan/mem/Memend.scala
浏览文件 @
ada67687
...
...
@@ -53,10 +53,10 @@ class LoadForwardQueryIO extends XSBundle {
val
uop
=
Output
(
new
MicroOp
)
// for replay
val
pc
=
Output
(
UInt
(
VAddrBits
.
W
))
//for debug
val
valid
=
Output
(
Bool
())
//for debug
val
forwardMask
=
Input
(
Vec
(
8
,
Bool
()))
val
forwardData
=
Input
(
Vec
(
8
,
UInt
(
8.
W
)))
// val lqIdx = Output(UInt(LoadQueueIdxWidth.W))
val
sqIdx
=
Output
(
new
SqPtr
)
}
}
\ No newline at end of file
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
浏览文件 @
ada67687
...
...
@@ -46,11 +46,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val
dataModule
=
Module
(
new
LSQueueData
(
StoreQueueSize
,
StorePipelineWidth
))
dataModule
.
io
:=
DontCare
val
allocated
=
RegInit
(
VecInit
(
List
.
fill
(
StoreQueueSize
)(
false
.
B
)))
// sq entry has been allocated
val
valid
=
RegInit
(
VecInit
(
List
.
fill
(
StoreQueueSize
)(
false
.
B
)))
//
data is valid
val
datavalid
=
RegInit
(
VecInit
(
List
.
fill
(
StoreQueueSize
)(
false
.
B
)))
// non-mmio
data is valid
val
writebacked
=
RegInit
(
VecInit
(
List
.
fill
(
StoreQueueSize
)(
false
.
B
)))
// inst has been writebacked to CDB
val
commited
=
Reg
(
Vec
(
StoreQueueSize
,
Bool
()))
// inst has been writebacked to CDB
val
miss
=
Reg
(
Vec
(
StoreQueueSize
,
Bool
()))
// load inst missed, waiting for miss queue to accept miss request
val
listening
=
Reg
(
Vec
(
StoreQueueSize
,
Bool
()))
// waiting for refill result
val
commited
=
Reg
(
Vec
(
StoreQueueSize
,
Bool
()))
// inst has been commited by roq
val
pending
=
Reg
(
Vec
(
StoreQueueSize
,
Bool
()))
// mmio pending: inst is an mmio inst, it will not be executed until it reachs the end of roq
val
ringBufferHeadExtended
=
RegInit
(
0.
U
.
asTypeOf
(
new
SqPtr
))
...
...
@@ -70,8 +68,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val
enqDeqMask1
=
tailMask
^
headMask
val
enqDeqMask
=
Mux
(
ringBufferSameFlag
,
enqDeqMask1
,
~
enqDeqMask1
)
// TODO: misc arbitor
// Enqueue at dispatch
val
emptyEntries
=
StoreQueueSize
.
U
-
distanceBetween
(
ringBufferHeadExtended
,
ringBufferTailExtended
)
XSDebug
(
"(ready, valid): "
)
...
...
@@ -82,11 +78,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
when
(
io
.
dp1Req
(
i
).
fire
())
{
uop
(
index
)
:=
io
.
dp1Req
(
i
).
bits
allocated
(
index
)
:=
true
.
B
valid
(
index
)
:=
false
.
B
data
valid
(
index
)
:=
false
.
B
writebacked
(
index
)
:=
false
.
B
commited
(
index
)
:=
false
.
B
miss
(
index
)
:=
false
.
B
listening
(
index
)
:=
false
.
B
pending
(
index
)
:=
false
.
B
}
val
numTryEnqueue
=
offset
+&
io
.
dp1Req
(
i
).
valid
...
...
@@ -108,9 +102,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
dataModule
.
io
.
wb
(
i
).
wen
:=
false
.
B
when
(
io
.
storeIn
(
i
).
fire
())
{
val
stWbIndex
=
io
.
storeIn
(
i
).
bits
.
uop
.
sqIdx
.
value
val
id
(
stWbIndex
)
:=
!
io
.
storeIn
(
i
).
bits
.
mmio
||
io
.
storeIn
(
i
).
bits
.
uop
.
cf
.
exceptionVec
.
asUInt
.
orR
miss
(
stWbIndex
)
:=
io
.
storeIn
(
i
).
bits
.
miss
pending
(
stWbIndex
)
:=
io
.
storeIn
(
i
).
bits
.
mmio
&&
!
io
.
storeIn
(
i
).
bits
.
uop
.
cf
.
exceptionVec
.
asUInt
.
orR
val
hasException
=
io
.
storeIn
(
i
).
bits
.
uop
.
cf
.
exceptionVec
.
asUInt
.
orR
datavalid
(
stWbIndex
)
:=
!
io
.
storeIn
(
i
).
bits
.
mmio
||
hasException
pending
(
stWbIndex
)
:=
io
.
storeIn
(
i
).
bits
.
mmio
&&
!
hasException
val
storeWbData
=
Wire
(
new
LsqEntry
)
storeWbData
:=
DontCare
...
...
@@ -124,13 +118,12 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
dataModule
.
io
.
wbWrite
(
i
,
stWbIndex
,
storeWbData
)
dataModule
.
io
.
wb
(
i
).
wen
:=
true
.
B
XSInfo
(
"store write to sq idx %d pc 0x%x vaddr %x paddr %x data %x m
iss %x m
mio %x roll %x exc %x\n"
,
XSInfo
(
"store write to sq idx %d pc 0x%x vaddr %x paddr %x data %x mmio %x roll %x exc %x\n"
,
io
.
storeIn
(
i
).
bits
.
uop
.
sqIdx
.
value
,
io
.
storeIn
(
i
).
bits
.
uop
.
cf
.
pc
,
io
.
storeIn
(
i
).
bits
.
vaddr
,
io
.
storeIn
(
i
).
bits
.
paddr
,
io
.
storeIn
(
i
).
bits
.
data
,
io
.
storeIn
(
i
).
bits
.
miss
,
io
.
storeIn
(
i
).
bits
.
mmio
,
io
.
storeIn
(
i
).
bits
.
rollback
,
io
.
storeIn
(
i
).
bits
.
uop
.
cf
.
exceptionVec
.
asUInt
...
...
@@ -185,15 +178,15 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
}
// select the last writebacked instruction
val
validStoreVec
=
VecInit
((
0
until
StoreQueueSize
).
map
(
i
=>
!(
allocated
(
i
)
&&
valid
(
i
))))
val
validStoreVec
=
VecInit
((
0
until
StoreQueueSize
).
map
(
i
=>
!(
allocated
(
i
)
&&
data
valid
(
i
))))
val
storeNotValid
=
SqPtr
(
false
.
B
,
getFirstOne
(
validStoreVec
,
tailMask
))
val
storeValidIndex
=
(
storeNotValid
-
1.
U
).
value
io
.
oldestStore
.
valid
:=
allocated
(
ringBufferTailExtended
.
value
)
&&
valid
(
ringBufferTailExtended
.
value
)
&&
!
commited
(
storeValidIndex
)
io
.
oldestStore
.
valid
:=
allocated
(
ringBufferTailExtended
.
value
)
&&
data
valid
(
ringBufferTailExtended
.
value
)
&&
!
commited
(
storeValidIndex
)
io
.
oldestStore
.
bits
:=
uop
(
storeValidIndex
).
roqIdx
// writeback up to 2 store insts to CDB
// choose the first two valid store requests from deqPtr
val
storeWbSelVec
=
VecInit
((
0
until
StoreQueueSize
).
map
(
i
=>
allocated
(
i
)
&&
valid
(
i
)
&&
!
writebacked
(
i
)))
val
storeWbSelVec
=
VecInit
((
0
until
StoreQueueSize
).
map
(
i
=>
allocated
(
i
)
&&
data
valid
(
i
)
&&
!
writebacked
(
i
)))
val
(
storeWbValid
,
storeWbSel
)
=
selectFirstTwo
(
storeWbSelVec
,
tailMask
)
(
0
until
StorePipelineWidth
).
map
(
i
=>
{
...
...
@@ -215,6 +208,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
// remove retired insts from sq, add retired store to sbuffer
// move tailPtr
// TailPtr slow recovery: recycle bubbles in store queue
// allocatedMask: dequeuePtr can go to the next 1-bit
val
allocatedMask
=
VecInit
((
0
until
StoreQueueSize
).
map
(
i
=>
allocated
(
i
)
||
!
enqDeqMask
(
i
)))
// find the first one from deqPtr (ringBufferTail)
...
...
@@ -222,6 +216,16 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val
nextTail
=
Mux
(
Cat
(
allocatedMask
).
orR
,
nextTail1
,
ringBufferHeadExtended
)
ringBufferTailExtended
:=
nextTail
// TailPtr fast recovery
val
tailRecycle
=
VecInit
(
List
(
io
.
uncache
.
resp
.
fire
()
||
io
.
sbuffer
(
0
).
fire
(),
io
.
sbuffer
(
1
).
fire
()
))
when
(
tailRecycle
.
asUInt
.
orR
){
ringBufferTailExtended
:=
ringBufferTailExtended
+
PopCount
(
tailRecycle
.
asUInt
)
}
// load forward query
// check over all lq entries and forward data from the first matched store
(
0
until
LoadPipelineWidth
).
map
(
i
=>
{
...
...
@@ -239,7 +243,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val
forwardMask
=
((
1.
U
((
StoreQueueSize
+
1
).
W
))
<<
io
.
forward
(
i
).
sqIdx
.
value
).
asUInt
-
1.
U
val
storeWritebackedVec
=
WireInit
(
VecInit
(
Seq
.
fill
(
StoreQueueSize
)(
false
.
B
)))
for
(
j
<-
0
until
StoreQueueSize
)
{
storeWritebackedVec
(
j
)
:=
valid
(
j
)
&&
allocated
(
j
)
// all
valid terms need to be checked
storeWritebackedVec
(
j
)
:=
datavalid
(
j
)
&&
allocated
(
j
)
// all data
valid terms need to be checked
}
val
needForward1
=
Mux
(
differentFlag
,
~
tailMask
,
tailMask
^
forwardMask
)
&
storeWritebackedVec
.
asUInt
val
needForward2
=
Mux
(
differentFlag
,
forwardMask
,
0.
U
(
StoreQueueSize
.
W
))
&
storeWritebackedVec
.
asUInt
...
...
@@ -258,80 +262,31 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
io
.
forward
(
i
).
forwardData
:=
dataModule
.
io
.
forward
(
i
).
forwardData
})
// CommitedStoreQueue for timing opt
// send commited store inst to sbuffer
// select up to 2 writebacked store insts
val
commitedStoreQueue
=
Module
(
new
MIMOQueue
(
UInt
(
log2Up
(
StoreQueueSize
).
W
),
entries
=
64
,
//FIXME
inCnt
=
6
,
outCnt
=
2
,
mem
=
false
,
perf
=
true
))
commitedStoreQueue
.
io
.
flush
:=
false
.
B
// When store commited, mark it as commited (will not be influenced by redirect),
// then add store's sq ptr into commitedStoreQueue
(
0
until
CommitWidth
).
map
(
i
=>
{
when
(
storeCommit
(
i
))
{
commited
(
mcommitIdx
(
i
))
:=
true
.
B
XSDebug
(
"store commit %d: idx %d %x\n"
,
i
.
U
,
mcommitIdx
(
i
),
uop
(
mcommitIdx
(
i
)).
cf
.
pc
)
}
commitedStoreQueue
.
io
.
enq
(
i
).
valid
:=
storeCommit
(
i
)
commitedStoreQueue
.
io
.
enq
(
i
).
bits
:=
mcommitIdx
(
i
)
// We assume commitedStoreQueue.io.enq(i).ready === true.B,
// for commitedStoreQueue.size = 64
})
class
SbufferCandidateEntry
extends
XSBundle
{
val
sbuffer
=
new
DCacheWordReq
val
sqIdx
=
UInt
(
log2Up
(
StoreQueueSize
).
W
)
}
val
ensbufferCandidateQueue
=
Module
(
new
MIMOQueue
(
new
SbufferCandidateEntry
,
entries
=
2
,
inCnt
=
2
,
outCnt
=
2
,
mem
=
false
,
perf
=
true
))
ensbufferCandidateQueue
.
io
.
flush
:=
false
.
B
val
sbufferCandidate
=
Wire
(
Vec
(
2
,
Decoupled
(
new
SbufferCandidateEntry
)))
(
0
until
2
).
map
(
i
=>
{
val
ptr
=
commitedStoreQueue
.
io
.
deq
(
i
).
bits
val
ptr
=
(
ringBufferTailExtended
+
i
.
U
).
value
val
mmio
=
dataModule
.
io
.
rdata
(
ptr
).
mmio
sbufferCandidate
(
i
).
valid
:=
commitedStoreQueue
.
io
.
deq
(
i
).
valid
&&
!
mmio
sbufferCandidate
(
i
).
bits
.
sqIdx
:=
ptr
sbufferCandidate
(
i
).
bits
.
sbuffer
.
cmd
:=
MemoryOpConstants
.
M_XWR
sbufferCandidate
(
i
).
bits
.
sbuffer
.
addr
:=
dataModule
.
io
.
rdata
(
ptr
).
paddr
sbufferCandidate
(
i
).
bits
.
sbuffer
.
data
:=
dataModule
.
io
.
rdata
(
ptr
).
data
sbufferCandidate
(
i
).
bits
.
sbuffer
.
mask
:=
dataModule
.
io
.
rdata
(
ptr
).
mask
sbufferCandidate
(
i
).
bits
.
sbuffer
.
meta
:=
DontCare
sbufferCandidate
(
i
).
bits
.
sbuffer
.
meta
.
tlb_miss
:=
false
.
B
sbufferCandidate
(
i
).
bits
.
sbuffer
.
meta
.
uop
:=
DontCare
sbufferCandidate
(
i
).
bits
.
sbuffer
.
meta
.
mmio
:=
mmio
sbufferCandidate
(
i
).
bits
.
sbuffer
.
meta
.
mask
:=
dataModule
.
io
.
rdata
(
ptr
).
mask
when
(
mmio
&&
commitedStoreQueue
.
io
.
deq
(
i
).
valid
)
{
io
.
sbuffer
(
i
).
valid
:=
allocated
(
ptr
)
&&
commited
(
ptr
)
&&
!
mmio
io
.
sbuffer
(
i
).
bits
.
cmd
:=
MemoryOpConstants
.
M_XWR
io
.
sbuffer
(
i
).
bits
.
addr
:=
dataModule
.
io
.
rdata
(
ptr
).
paddr
io
.
sbuffer
(
i
).
bits
.
data
:=
dataModule
.
io
.
rdata
(
ptr
).
data
io
.
sbuffer
(
i
).
bits
.
mask
:=
dataModule
.
io
.
rdata
(
ptr
).
mask
io
.
sbuffer
(
i
).
bits
.
meta
:=
DontCare
io
.
sbuffer
(
i
).
bits
.
meta
.
tlb_miss
:=
false
.
B
io
.
sbuffer
(
i
).
bits
.
meta
.
uop
:=
DontCare
io
.
sbuffer
(
i
).
bits
.
meta
.
mmio
:=
mmio
io
.
sbuffer
(
i
).
bits
.
meta
.
mask
:=
dataModule
.
io
.
rdata
(
ptr
).
mask
when
(
io
.
sbuffer
(
i
).
fire
())
{
allocated
(
ptr
)
:=
false
.
B
}
commitedStoreQueue
.
io
.
deq
(
i
).
ready
:=
sbufferCandidate
(
i
).
fire
()
||
mmio
sbufferCandidate
(
i
).
ready
:=
ensbufferCandidateQueue
.
io
.
enq
(
i
).
ready
ensbufferCandidateQueue
.
io
.
enq
(
i
).
valid
:=
sbufferCandidate
(
i
).
valid
ensbufferCandidateQueue
.
io
.
enq
(
i
).
bits
.
sqIdx
:=
sbufferCandidate
(
i
).
bits
.
sqIdx
ensbufferCandidateQueue
.
io
.
enq
(
i
).
bits
.
sbuffer
:=
sbufferCandidate
(
i
).
bits
.
sbuffer
ensbufferCandidateQueue
.
io
.
deq
(
i
).
ready
:=
io
.
sbuffer
(
i
).
fire
()
io
.
sbuffer
(
i
).
valid
:=
ensbufferCandidateQueue
.
io
.
deq
(
i
).
valid
io
.
sbuffer
(
i
).
bits
:=
ensbufferCandidateQueue
.
io
.
deq
(
i
).
bits
.
sbuffer
// update sq meta if store inst is send to sbuffer
when
(
ensbufferCandidateQueue
.
io
.
deq
(
i
).
valid
&&
io
.
sbuffer
(
i
).
ready
)
{
allocated
(
ensbufferCandidateQueue
.
io
.
deq
(
i
).
bits
.
sqIdx
)
:=
false
.
B
XSDebug
(
"sbuffer "
+
i
+
" fire: ptr %d\n"
,
ptr
)
}
})
...
...
@@ -366,7 +321,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
}
when
(
io
.
uncache
.
resp
.
fire
()){
valid
(
ringBufferTail
)
:=
true
.
B
datavalid
(
ringBufferTail
)
:=
true
.
B
// will be writeback to CDB in the next cycle
// TODO: write back exception info
}
...
...
@@ -390,10 +345,8 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
needCancel
(
i
)
:=
uop
(
i
).
roqIdx
.
needFlush
(
io
.
brqRedirect
)
&&
allocated
(
i
)
&&
!
commited
(
i
)
when
(
needCancel
(
i
))
{
when
(
io
.
brqRedirect
.
bits
.
isReplay
){
valid
(
i
)
:=
false
.
B
data
valid
(
i
)
:=
false
.
B
writebacked
(
i
)
:=
false
.
B
listening
(
i
)
:=
false
.
B
miss
(
i
)
:=
false
.
B
pending
(
i
)
:=
false
.
B
}.
otherwise
{
allocated
(
i
)
:=
false
.
B
...
...
@@ -419,11 +372,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
if
(
i
%
4
==
0
)
XSDebug
(
""
)
XSDebug
(
false
,
true
.
B
,
"%x [%x] "
,
uop
(
i
).
cf
.
pc
,
dataModule
.
io
.
rdata
(
i
).
paddr
)
PrintFlag
(
allocated
(
i
),
"a"
)
PrintFlag
(
allocated
(
i
)
&&
valid
(
i
),
"v"
)
PrintFlag
(
allocated
(
i
)
&&
data
valid
(
i
),
"v"
)
PrintFlag
(
allocated
(
i
)
&&
writebacked
(
i
),
"w"
)
PrintFlag
(
allocated
(
i
)
&&
commited
(
i
),
"c"
)
PrintFlag
(
allocated
(
i
)
&&
miss
(
i
),
"m"
)
PrintFlag
(
allocated
(
i
)
&&
listening
(
i
),
"l"
)
PrintFlag
(
allocated
(
i
)
&&
pending
(
i
),
"p"
)
XSDebug
(
false
,
true
.
B
,
" "
)
if
(
i
%
4
==
3
||
i
==
StoreQueueSize
-
1
)
XSDebug
(
false
,
true
.
B
,
"\n"
)
...
...
src/main/scala/xiangshan/mem/pipeline/AtomicsUnit.scala
浏览文件 @
ada67687
...
...
@@ -46,6 +46,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
io
.
dtlb
.
req
.
valid
:=
false
.
B
io
.
dtlb
.
req
.
bits
:=
DontCare
io
.
dtlb
.
resp
.
ready
:=
false
.
B
io
.
flush_sbuffer
.
valid
:=
false
.
B
...
...
@@ -75,11 +76,12 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
io
.
dtlb
.
req
.
valid
:=
true
.
B
io
.
dtlb
.
req
.
bits
.
vaddr
:=
in
.
src1
io
.
dtlb
.
req
.
bits
.
roqIdx
:=
in
.
uop
.
roqIdx
io
.
dtlb
.
resp
.
ready
:=
true
.
B
val
is_lr
=
in
.
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
lr_w
||
in
.
uop
.
ctrl
.
fuOpType
===
LSUOpType
.
lr_d
io
.
dtlb
.
req
.
bits
.
cmd
:=
Mux
(
is_lr
,
TlbCmd
.
read
,
TlbCmd
.
write
)
io
.
dtlb
.
req
.
bits
.
debug
.
pc
:=
in
.
uop
.
cf
.
pc
when
(
io
.
dtlb
.
resp
.
valid
&&
!
io
.
dtlb
.
resp
.
bits
.
miss
){
when
(
io
.
dtlb
.
resp
.
fire
&&
!
io
.
dtlb
.
resp
.
bits
.
miss
){
// exception handling
val
addrAligned
=
LookupTree
(
in
.
uop
.
ctrl
.
fuOpType
(
1
,
0
),
List
(
"b00"
.
U
->
true
.
B
,
//b
...
...
@@ -143,7 +145,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
LSUOpType
.
amomaxu_d
->
M_XA_MAXU
))
io
.
dcache
.
req
.
bits
.
addr
:=
paddr
io
.
dcache
.
req
.
bits
.
addr
:=
paddr
io
.
dcache
.
req
.
bits
.
data
:=
genWdata
(
in
.
src2
,
in
.
uop
.
ctrl
.
fuOpType
(
1
,
0
))
// TODO: atomics do need mask: fix mask
io
.
dcache
.
req
.
bits
.
mask
:=
genWmask
(
paddr
,
in
.
uop
.
ctrl
.
fuOpType
(
1
,
0
))
...
...
@@ -221,4 +223,4 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
when
(
io
.
redirect
.
valid
){
atom_override_xtval
:=
false
.
B
}
}
}
\ No newline at end of file
src/main/scala/xiangshan/mem/pipeline/LoadUnit.scala
浏览文件 @
ada67687
...
...
@@ -22,8 +22,8 @@ class LoadUnit_S0 extends XSModule {
val
in
=
Flipped
(
Decoupled
(
new
ExuInput
))
val
out
=
Decoupled
(
new
LsPipelineBundle
)
val
redirect
=
Flipped
(
ValidIO
(
new
Redirect
))
val
dtlbReq
=
Valid
(
new
TlbReq
)
val
dtlbResp
=
Flipped
(
Valid
(
new
TlbResp
))
val
dtlbReq
=
DecoupledIO
(
new
TlbReq
)
val
dtlbResp
=
Flipped
(
DecoupledIO
(
new
TlbResp
))
val
tlbFeedback
=
ValidIO
(
new
TlbFeedback
)
val
dcacheReq
=
DecoupledIO
(
new
DCacheLoadReq
)
})
...
...
@@ -40,6 +40,7 @@ class LoadUnit_S0 extends XSModule {
io
.
dtlbReq
.
bits
.
cmd
:=
TlbCmd
.
read
io
.
dtlbReq
.
bits
.
roqIdx
:=
s0_uop
.
roqIdx
io
.
dtlbReq
.
bits
.
debug
.
pc
:=
s0_uop
.
cf
.
pc
io
.
dtlbResp
.
ready
:=
io
.
out
.
ready
// TODO: check it: io.out.fire()?
// feedback tlb result to RS
// Note: can be moved to s1
...
...
@@ -104,7 +105,7 @@ class LoadUnit_S1 extends XSModule {
val
s1_uop
=
io
.
in
.
bits
.
uop
val
s1_paddr
=
io
.
in
.
bits
.
paddr
val
s1_tlb_miss
=
io
.
in
.
bits
.
tlbMiss
val
s1_mmio
=
!
s1_tlb_miss
&&
AddressSpace
.
isMMIO
(
s1_paddr
)
val
s1_mmio
=
!
s1_tlb_miss
&&
AddressSpace
.
isMMIO
(
s1_paddr
)
&&
!
io
.
out
.
bits
.
uop
.
cf
.
exceptionVec
.
asUInt
.
orR
val
s1_mask
=
io
.
in
.
bits
.
mask
io
.
out
.
bits
:=
io
.
in
.
bits
// forwardXX field will be updated in s1
...
...
@@ -293,4 +294,4 @@ class LoadUnit extends XSModule {
when
(
io
.
ldout
.
fire
()){
XSDebug
(
"ldout %x iw %x fw %x\n"
,
io
.
ldout
.
bits
.
uop
.
cf
.
pc
,
io
.
ldout
.
bits
.
uop
.
ctrl
.
rfWen
,
io
.
ldout
.
bits
.
uop
.
ctrl
.
fpWen
)
}
}
}
\ No newline at end of file
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
浏览文件 @
ada67687
...
...
@@ -58,6 +58,7 @@ class StoreUnit extends XSModule {
io
.
dtlb
.
req
.
bits
.
cmd
:=
TlbCmd
.
write
io
.
dtlb
.
req
.
bits
.
roqIdx
:=
io
.
stin
.
bits
.
uop
.
roqIdx
io
.
dtlb
.
req
.
bits
.
debug
.
pc
:=
io
.
stin
.
bits
.
uop
.
cf
.
pc
io
.
dtlb
.
resp
.
ready
:=
s2_out
.
ready
s2_out
.
bits
:=
DontCare
s2_out
.
bits
.
vaddr
:=
saddr
...
...
@@ -134,4 +135,4 @@ class StoreUnit extends XSModule {
// update store buffer according to store fill buffer
}
}
\ No newline at end of file
src/test/csrc/emu.cpp
浏览文件 @
ada67687
...
...
@@ -15,6 +15,7 @@ static inline void print_help(const char *file) {
printf
(
"
\n
"
);
printf
(
" -s, --seed=NUM use this seed
\n
"
);
printf
(
" -C, --max-cycles=NUM execute at most NUM cycles
\n
"
);
printf
(
" -I, --max-instr=NUM execute at most NUM instructions
\n
"
);
printf
(
" -i, --image=FILE run with this image file
\n
"
);
printf
(
" -b, --log-begin=NUM display log from NUM th cycle
\n
"
);
printf
(
" -e, --log-end=NUM stop display log at NUM th cycle
\n
"
);
...
...
@@ -32,6 +33,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
{
"dump-wave"
,
0
,
NULL
,
0
},
{
"seed"
,
1
,
NULL
,
's'
},
{
"max-cycles"
,
1
,
NULL
,
'C'
},
{
"max-instr"
,
1
,
NULL
,
'I'
},
{
"image"
,
1
,
NULL
,
'i'
},
{
"log-begin"
,
1
,
NULL
,
'b'
},
{
"log-end"
,
1
,
NULL
,
'e'
},
...
...
@@ -41,7 +43,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
int
o
;
while
(
(
o
=
getopt_long
(
argc
,
const_cast
<
char
*
const
*>
(
argv
),
"-s:C:hi:m:b:e:"
,
long_options
,
&
long_index
))
!=
-
1
)
{
"-s:C:
I:
hi:m:b:e:"
,
long_options
,
&
long_index
))
!=
-
1
)
{
switch
(
o
)
{
case
0
:
switch
(
long_index
)
{
...
...
@@ -59,6 +61,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
}
break
;
case
'C'
:
args
.
max_cycles
=
atoll
(
optarg
);
break
;
case
'I'
:
args
.
max_instr
=
atoll
(
optarg
);
break
;
case
'i'
:
args
.
image
=
optarg
;
break
;
case
'b'
:
args
.
log_begin
=
atoll
(
optarg
);
break
;
case
'e'
:
args
.
log_end
=
atoll
(
optarg
);
break
;
...
...
@@ -122,9 +125,8 @@ Emulator::Emulator(int argc, const char *argv[]):
}
Emulator
::~
Emulator
()
{
#ifdef WITH_DRAMSIM3
dramsim3_finish
();
#endif
ram_finish
();
#ifdef VM_SAVABLE
snapshot_slot
[
0
].
save
();
snapshot_slot
[
1
].
save
();
...
...
@@ -222,12 +224,13 @@ inline void Emulator::single_cycle() {
cycles
++
;
}
uint64_t
Emulator
::
execute
(
uint64_t
n
)
{
uint64_t
Emulator
::
execute
(
uint64_t
max_cycle
,
uint64_t
max_instr
)
{
extern
void
poll_event
(
void
);
extern
uint32_t
uptime
(
void
);
uint32_t
lasttime_poll
=
0
;
uint32_t
lasttime_snapshot
=
0
;
uint64_t
lastcommit
=
n
;
uint64_t
lastcommit
=
max_cycle
;
uint64_t
instr_left_last_cycle
=
max_instr
;
const
int
stuck_limit
=
2000
;
uint32_t
wdst
[
DIFFTEST_WIDTH
];
...
...
@@ -240,14 +243,19 @@ uint64_t Emulator::execute(uint64_t n) {
diff
.
wdata
=
wdata
;
diff
.
wdst
=
wdst
;
while
(
trapCode
==
STATE_RUNNING
&&
n
>
0
)
{
while
(
trapCode
==
STATE_RUNNING
)
{
if
(
!
(
max_cycle
>
0
&&
max_instr
>
0
&&
instr_left_last_cycle
>=
max_instr
/* handle overflow */
))
{
trapCode
=
STATE_LIMIT_EXCEEDED
;
break
;
}
single_cycle
();
n
--
;
max_cycle
--
;
if
(
dut_ptr
->
io_trap_valid
)
trapCode
=
dut_ptr
->
io_trap_code
;
if
(
trapCode
!=
STATE_RUNNING
)
break
;
if
(
lastcommit
-
n
>
stuck_limit
&&
hascommit
)
{
if
(
lastcommit
-
max_cycle
>
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
"
,
stuck_limit
,
stuck_limit
);
...
...
@@ -283,7 +291,11 @@ uint64_t Emulator::execute(uint64_t n) {
if
(
difftest_step
(
&
diff
))
{
trapCode
=
STATE_ABORT
;
}
lastcommit
=
n
;
lastcommit
=
max_cycle
;
// update instr_cnt
instr_left_last_cycle
=
max_instr
;
max_instr
-=
diff
.
commit
;
}
uint32_t
t
=
uptime
();
...
...
@@ -355,6 +367,9 @@ void Emulator::display_trapinfo() {
case
STATE_ABORT
:
eprintf
(
ANSI_COLOR_RED
"ABORT at pc = 0x%"
PRIx64
"
\n
"
ANSI_COLOR_RESET
,
pc
);
break
;
case
STATE_LIMIT_EXCEEDED
:
eprintf
(
ANSI_COLOR_YELLOW
"EXCEEDING CYCLE/INSTR LIMIT at pc = 0x%"
PRIx64
"
\n
"
ANSI_COLOR_RESET
,
pc
);
break
;
default:
eprintf
(
ANSI_COLOR_RED
"Unknown trap code: %d
\n
"
,
trapCode
);
}
...
...
src/test/csrc/emu.h
浏览文件 @
ada67687
...
...
@@ -9,6 +9,7 @@
struct
EmuArgs
{
uint32_t
seed
;
uint64_t
max_cycles
;
uint64_t
max_instr
;
uint64_t
log_begin
,
log_end
;
const
char
*
image
;
const
char
*
snapshot_path
;
...
...
@@ -17,6 +18,7 @@ struct EmuArgs {
EmuArgs
()
{
seed
=
0
;
max_cycles
=
-
1
;
max_instr
=
-
1
;
log_begin
=
1
;
log_end
=
-
1
;
snapshot_path
=
NULL
;
...
...
@@ -38,6 +40,7 @@ class Emulator {
STATE_GOODTRAP
=
0
,
STATE_BADTRAP
,
STATE_ABORT
,
STATE_LIMIT_EXCEEDED
,
STATE_RUNNING
=
-
1
};
...
...
@@ -60,7 +63,7 @@ class Emulator {
public:
Emulator
(
int
argc
,
const
char
*
argv
[]);
~
Emulator
();
uint64_t
execute
(
uint64_t
n
);
uint64_t
execute
(
uint64_t
max_cycle
,
uint64_t
max_instr
);
uint64_t
get_cycles
()
const
{
return
cycles
;
}
EmuArgs
get_args
()
const
{
return
args
;
}
bool
is_good_trap
()
{
return
trapCode
==
STATE_GOODTRAP
;
};
...
...
src/test/csrc/main.cpp
浏览文件 @
ada67687
...
...
@@ -19,7 +19,7 @@ int main(int argc, const char** argv) {
};
auto
args
=
emu
->
get_args
();
uint64_t
cycles
=
emu
->
execute
(
args
.
max_cycles
);
uint64_t
cycles
=
emu
->
execute
(
args
.
max_cycles
,
args
.
max_instr
);
bool
is_good_trap
=
emu
->
is_good_trap
();
delete
emu
;
...
...
src/test/csrc/ram.cpp
浏览文件 @
ada67687
#include <sys/mman.h>
#include <zlib.h>
#include "common.h"
#include "ram.h"
#define RAMSIZE (
128 * 1024 * 1024
)
#define RAMSIZE (
256 * 1024 * 1024UL
)
#ifdef WITH_DRAMSIM3
#include "cosimulation.h"
CoDRAMsim3
*
dram
=
NULL
;
#endif
static
uint64_t
ram
[
RAMSIZE
/
sizeof
(
uint64_t
)]
;
static
uint64_t
*
ram
;
static
long
img_size
=
0
;
void
*
get_img_start
()
{
return
&
ram
[
0
];
}
long
get_img_size
()
{
return
img_size
;
}
void
*
get_ram_start
()
{
return
&
ram
[
0
];
}
long
get_ram_size
()
{
return
RAMSIZE
;
}
#ifdef TLB_UNITTEST
void
addpageSv39
()
{
//three layers
//addr range: 0x0000000080000000 - 0x0000000088000000 for 128MB from 2GB - 2GB128MB
...
...
@@ -97,31 +101,100 @@ void addpageSv39() {
memcpy
((
char
*
)
ram
+
(
RAMSIZE
-
PAGESIZE
*
(
PTENUM
+
PDENUM
)),
pde
,
PAGESIZE
*
PDENUM
);
memcpy
((
char
*
)
ram
+
(
RAMSIZE
-
PAGESIZE
*
PTENUM
),
pte
,
PAGESIZE
*
PTENUM
);
}
#endif
void
init_ram
(
const
char
*
img
)
{
assert
(
img
!=
NULL
);
FILE
*
fp
=
fopen
(
img
,
"rb"
);
if
(
fp
==
NULL
)
{
printf
(
"Can not open '%s'
\n
"
,
img
);
// Return whether the file is a gz file
int
isGzFile
(
const
char
*
img
)
{
assert
(
img
!=
NULL
&&
strlen
(
img
)
>=
4
);
return
!
strcmp
(
img
+
(
strlen
(
img
)
-
3
),
".gz"
);
}
// Read binary from .gz file
int
readFromGz
(
void
*
ptr
,
const
char
*
file_name
)
{
gzFile
compressed_mem
=
gzopen
(
file_name
,
"rb"
);
if
(
compressed_mem
==
NULL
)
{
printf
(
"Can't open compressed binary file '%s'"
,
file_name
);
return
-
1
;
}
uint64_t
curr_size
=
0
;
// read 16KB each time
const
uint32_t
chunk_size
=
16384
;
if
((
RAMSIZE
%
chunk_size
)
!=
0
)
{
printf
(
"RAMSIZE must be divisible by chunk_size
\n
"
);
assert
(
0
);
}
uint64_t
*
temp_page
=
new
uint64_t
[
chunk_size
];
uint64_t
*
pmem_current
=
(
uint64_t
*
)
ptr
;
while
(
curr_size
<
RAMSIZE
)
{
uint32_t
bytes_read
=
gzread
(
compressed_mem
,
temp_page
,
chunk_size
);
if
(
bytes_read
==
0
)
{
break
;
}
assert
(
bytes_read
%
sizeof
(
uint64_t
)
==
0
);
for
(
uint32_t
x
=
0
;
x
<
bytes_read
/
sizeof
(
uint64_t
);
x
++
)
{
if
(
*
(
temp_page
+
x
)
!=
0
)
{
pmem_current
=
(
uint64_t
*
)((
uint8_t
*
)
ptr
+
curr_size
+
x
*
sizeof
(
uint64_t
));
*
pmem_current
=
*
(
temp_page
+
x
);
}
}
curr_size
+=
bytes_read
;
}
// printf("Read 0x%lx bytes from gz stream in total.\n", curr_size);
delete
[]
temp_page
;
if
(
gzclose
(
compressed_mem
))
{
printf
(
"Error closing '%s'
\n
"
,
file_name
);
return
-
1
;
}
return
curr_size
;
}
void
init_ram
(
const
char
*
img
)
{
assert
(
img
!=
NULL
);
printf
(
"The image is %s
\n
"
,
img
);
fseek
(
fp
,
0
,
SEEK_END
);
img_size
=
ftell
(
fp
);
if
(
img_size
>
RAMSIZE
)
{
img_size
=
RAMSIZE
;
// initialize memory using Linux mmap
printf
(
"Using simulated %luMB RAM
\n
"
,
RAMSIZE
/
(
1024
*
1024
));
ram
=
(
uint64_t
*
)
mmap
(
NULL
,
RAMSIZE
,
PROT_READ
|
PROT_WRITE
,
MAP_ANON
|
MAP_PRIVATE
,
-
1
,
0
);
if
(
ram
==
(
uint64_t
*
)
MAP_FAILED
)
{
printf
(
"Cound not mmap 0x%lx bytes
\n
"
,
RAMSIZE
);
assert
(
0
);
}
int
ret
;
if
(
isGzFile
(
img
))
{
printf
(
"Gzip file detected and loading image from extracted gz file
\n
"
);
img_size
=
readFromGz
(
ram
,
img
);
assert
(
img_size
>=
0
);
}
else
{
FILE
*
fp
=
fopen
(
img
,
"rb"
);
if
(
fp
==
NULL
)
{
printf
(
"Can not open '%s'
\n
"
,
img
);
assert
(
0
);
}
fseek
(
fp
,
0
,
SEEK_END
);
img_size
=
ftell
(
fp
);
if
(
img_size
>
RAMSIZE
)
{
img_size
=
RAMSIZE
;
}
fseek
(
fp
,
0
,
SEEK_SET
);
ret
=
fread
(
ram
,
img_size
,
1
,
fp
);
fseek
(
fp
,
0
,
SEEK_SET
);
int
ret
=
fread
(
ram
,
img_size
,
1
,
fp
);
assert
(
ret
==
1
);
fclose
(
fp
);
assert
(
ret
==
1
);
fclose
(
fp
);
}
#ifdef TLB_UNITTEST
//new add
addpageSv39
();
//new end
#endif
#ifdef WITH_DRAMSIM3
#if !defined(DRAMSIM3_CONFIG) || !defined(DRAMSIM3_OUTDIR)
...
...
@@ -133,6 +206,13 @@ void init_ram(const char *img) {
}
void
ram_finish
()
{
munmap
(
ram
,
RAMSIZE
);
#ifdef WITH_DRAMSIM3
dramsim3_finish
();
#endif
}
extern
"C"
uint64_t
ram_read_helper
(
uint8_t
en
,
uint64_t
rIdx
)
{
if
(
en
&&
rIdx
>=
RAMSIZE
/
sizeof
(
uint64_t
))
{
printf
(
"ERROR: ram idx = 0x%lx out of bound!
\n
"
,
rIdx
);
...
...
src/test/csrc/ram.h
浏览文件 @
ada67687
...
...
@@ -3,8 +3,8 @@
#include "common.h"
// #define WITH_DRAMSIM3
void
init_ram
(
const
char
*
img
);
void
ram_finish
();
#ifdef WITH_DRAMSIM3
// 4*64 bits
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录