Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
4142e72c
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,发现更多精彩内容 >>
提交
4142e72c
编写于
11月 28, 2020
作者:
W
William Wang
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master' into opt-roq-timing
上级
58d6c396
eb1953df
变更
27
展开全部
隐藏空白更改
内联
并排
Showing
27 changed file
with
582 addition
and
818 deletion
+582
-818
.gitignore
.gitignore
+1
-0
Makefile
Makefile
+1
-1
src/main/scala/xiangshan/backend/CtrlBlock.scala
src/main/scala/xiangshan/backend/CtrlBlock.scala
+31
-12
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/dispatch/Dispatch.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch.scala
+2
-0
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
+5
-0
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/backend/rename/Rename.scala
src/main/scala/xiangshan/backend/rename/Rename.scala
+0
-37
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/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
+4
-3
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
src/main/scala/xiangshan/mem/pipeline/StoreUnit.scala
+1
-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
浏览文件 @
4142e72c
...
...
@@ -348,3 +348,4 @@ mill.rdiB
stale_outputs_checked
*.snapshot
Makefile
浏览文件 @
4142e72c
...
...
@@ -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/CtrlBlock.scala
浏览文件 @
4142e72c
...
...
@@ -4,7 +4,7 @@ import chisel3._
import
chisel3.util._
import
xiangshan._
import
xiangshan.backend.decode.
{
DecodeBuffer
,
DecodeStage
}
import
xiangshan.backend.rename.
Rename
import
xiangshan.backend.rename.
{
Rename
,
BusyTable
}
import
xiangshan.backend.brq.Brq
import
xiangshan.backend.dispatch.Dispatch
import
xiangshan.backend.exu._
...
...
@@ -59,9 +59,8 @@ class CtrlBlock extends XSModule {
val
decBuf
=
Module
(
new
DecodeBuffer
)
val
rename
=
Module
(
new
Rename
)
val
dispatch
=
Module
(
new
Dispatch
)
// TODO: move busyTable to dispatch1
// val fpBusyTable = Module(new BusyTable(NRFpReadPorts, NRFpWritePorts))
// val intBusyTable = Module(new BusyTable(NRIntReadPorts, NRIntWritePorts))
val
intBusyTable
=
Module
(
new
BusyTable
(
NRIntReadPorts
,
NRIntWritePorts
))
val
fpBusyTable
=
Module
(
new
BusyTable
(
NRFpReadPorts
,
NRFpWritePorts
))
val
roqWbSize
=
NRIntWritePorts
+
NRFpWritePorts
+
exuParameters
.
StuCnt
+
1
...
...
@@ -99,14 +98,6 @@ class CtrlBlock extends XSModule {
rename
.
io
.
redirect
<>
redirect
rename
.
io
.
roqCommits
<>
roq
.
io
.
commits
// they should be moved to busytables
rename
.
io
.
wbIntResults
<>
io
.
fromIntBlock
.
wbRegs
rename
.
io
.
wbFpResults
<>
io
.
fromFpBlock
.
wbRegs
rename
.
io
.
intRfReadAddr
<>
dispatch
.
io
.
readIntRf
.
map
(
_
.
addr
)
rename
.
io
.
fpRfReadAddr
<>
dispatch
.
io
.
readFpRf
.
map
(
_
.
addr
)
rename
.
io
.
intPregRdy
<>
dispatch
.
io
.
intPregRdy
rename
.
io
.
fpPregRdy
<>
dispatch
.
io
.
fpPregRdy
rename
.
io
.
replayPregReq
<>
dispatch
.
io
.
replayPregReq
rename
.
io
.
out
<>
dispatch
.
io
.
fromRename
dispatch
.
io
.
redirect
<>
redirect
...
...
@@ -121,11 +112,39 @@ class CtrlBlock extends XSModule {
)
dispatch
.
io
.
readIntRf
<>
io
.
toIntBlock
.
readRf
dispatch
.
io
.
readFpRf
<>
io
.
toFpBlock
.
readRf
dispatch
.
io
.
allocPregs
.
zipWithIndex
.
foreach
{
case
(
preg
,
i
)
=>
intBusyTable
.
io
.
allocPregs
(
i
).
valid
:=
preg
.
isInt
fpBusyTable
.
io
.
allocPregs
(
i
).
valid
:=
preg
.
isFp
intBusyTable
.
io
.
allocPregs
(
i
).
bits
:=
preg
.
preg
fpBusyTable
.
io
.
allocPregs
(
i
).
bits
:=
preg
.
preg
}
dispatch
.
io
.
numExist
<>
io
.
fromIntBlock
.
numExist
++
io
.
fromFpBlock
.
numExist
++
io
.
fromLsBlock
.
numExist
dispatch
.
io
.
enqIQCtrl
<>
io
.
toIntBlock
.
enqIqCtrl
++
io
.
toFpBlock
.
enqIqCtrl
++
io
.
toLsBlock
.
enqIqCtrl
dispatch
.
io
.
enqIQData
<>
io
.
toIntBlock
.
enqIqData
++
io
.
toFpBlock
.
enqIqData
++
io
.
toLsBlock
.
enqIqData
val
flush
=
redirect
.
valid
&&
(
redirect
.
bits
.
isException
||
redirect
.
bits
.
isFlushPipe
)
fpBusyTable
.
io
.
flush
:=
flush
intBusyTable
.
io
.
flush
:=
flush
for
((
wb
,
setPhyRegRdy
)
<-
io
.
fromIntBlock
.
wbRegs
.
zip
(
intBusyTable
.
io
.
wbPregs
)){
setPhyRegRdy
.
valid
:=
wb
.
valid
&&
wb
.
bits
.
uop
.
ctrl
.
rfWen
&&
(
wb
.
bits
.
uop
.
ctrl
.
ldest
=/=
0.
U
)
setPhyRegRdy
.
bits
:=
wb
.
bits
.
uop
.
pdest
}
for
((
wb
,
setPhyRegRdy
)
<-
io
.
fromFpBlock
.
wbRegs
.
zip
(
fpBusyTable
.
io
.
wbPregs
)){
setPhyRegRdy
.
valid
:=
wb
.
valid
&&
wb
.
bits
.
uop
.
ctrl
.
fpWen
setPhyRegRdy
.
bits
:=
wb
.
bits
.
uop
.
pdest
}
intBusyTable
.
io
.
rfReadAddr
<>
dispatch
.
io
.
readIntRf
.
map
(
_
.
addr
)
intBusyTable
.
io
.
pregRdy
<>
dispatch
.
io
.
intPregRdy
fpBusyTable
.
io
.
rfReadAddr
<>
dispatch
.
io
.
readFpRf
.
map
(
_
.
addr
)
fpBusyTable
.
io
.
pregRdy
<>
dispatch
.
io
.
fpPregRdy
for
(
i
<-
0
until
ReplayWidth
){
intBusyTable
.
io
.
replayPregs
(
i
).
valid
:=
dispatch
.
io
.
replayPregReq
(
i
).
isInt
fpBusyTable
.
io
.
replayPregs
(
i
).
valid
:=
dispatch
.
io
.
replayPregReq
(
i
).
isFp
intBusyTable
.
io
.
replayPregs
(
i
).
bits
:=
dispatch
.
io
.
replayPregReq
(
i
).
preg
fpBusyTable
.
io
.
replayPregs
(
i
).
bits
:=
dispatch
.
io
.
replayPregReq
(
i
).
preg
}
roq
.
io
.
memRedirect
<>
io
.
fromLsBlock
.
replay
roq
.
io
.
brqRedirect
<>
brq
.
io
.
redirect
roq
.
io
.
dp1Req
<>
dispatch
.
io
.
toRoq
...
...
src/main/scala/xiangshan/backend/FloatBlock.scala
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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/dispatch/Dispatch.scala
浏览文件 @
4142e72c
...
...
@@ -45,6 +45,7 @@ class Dispatch extends XSModule {
val
fpPregRdy
=
Vec
(
NRFpReadPorts
,
Input
(
Bool
()))
// replay: set preg status to not ready
val
replayPregReq
=
Output
(
Vec
(
ReplayWidth
,
new
ReplayPregReq
))
val
allocPregs
=
Vec
(
RenameWidth
,
Output
(
new
ReplayPregReq
))
// to reservation stations
val
numExist
=
Input
(
Vec
(
exuParameters
.
ExuCnt
,
UInt
(
log2Ceil
(
IssQueSize
).
W
)))
val
enqIQCtrl
=
Vec
(
exuParameters
.
ExuCnt
,
DecoupledIO
(
new
MicroOp
))
...
...
@@ -71,6 +72,7 @@ class Dispatch extends XSModule {
dispatch1
.
io
.
toIntDq
<>
intDq
.
io
.
enq
dispatch1
.
io
.
toFpDq
<>
fpDq
.
io
.
enq
dispatch1
.
io
.
toLsDq
<>
lsDq
.
io
.
enq
dispatch1
.
io
.
allocPregs
<>
io
.
allocPregs
// dispatch queue: queue uops and dispatch them to different reservation stations or issue queues
// it may cancel the uops
...
...
src/main/scala/xiangshan/backend/dispatch/Dispatch1.scala
浏览文件 @
4142e72c
...
...
@@ -22,6 +22,7 @@ class Dispatch1 extends XSModule {
val
toLsq
=
Vec
(
RenameWidth
,
DecoupledIO
(
new
MicroOp
))
// get LsIdx
val
lsIdx
=
Input
(
Vec
(
RenameWidth
,
new
LSIdx
))
val
allocPregs
=
Vec
(
RenameWidth
,
Output
(
new
ReplayPregReq
))
// to dispatch queue
val
toIntDq
=
Vec
(
dpParams
.
DqEnqWidth
,
DecoupledIO
(
new
MicroOp
))
val
toFpDq
=
Vec
(
dpParams
.
DqEnqWidth
,
DecoupledIO
(
new
MicroOp
))
...
...
@@ -147,6 +148,10 @@ class Dispatch1 extends XSModule {
*/
val
readyVector
=
(
0
until
RenameWidth
).
map
(
i
=>
!
io
.
fromRename
(
i
).
valid
||
io
.
recv
(
i
))
for
(
i
<-
0
until
RenameWidth
)
{
io
.
allocPregs
(
i
).
isInt
:=
io
.
fromRename
(
i
).
valid
&&
io
.
fromRename
(
i
).
bits
.
ctrl
.
rfWen
&&
(
io
.
fromRename
(
i
).
bits
.
ctrl
.
ldest
=/=
0.
U
)
io
.
allocPregs
(
i
).
isFp
:=
io
.
fromRename
(
i
).
valid
&&
io
.
fromRename
(
i
).
bits
.
ctrl
.
fpWen
io
.
allocPregs
(
i
).
preg
:=
io
.
fromRename
(
i
).
bits
.
pdest
val
enqFire
=
(
io
.
toIntDq
(
intIndex
.
io
.
reverseMapping
(
i
).
bits
).
fire
()
&&
intIndex
.
io
.
reverseMapping
(
i
).
valid
)
||
(
io
.
toFpDq
(
fpIndex
.
io
.
reverseMapping
(
i
).
bits
).
fire
()
&&
fpIndex
.
io
.
reverseMapping
(
i
).
valid
)
||
(
io
.
toLsDq
(
lsIndex
.
io
.
reverseMapping
(
i
).
bits
).
fire
()
&&
lsIndex
.
io
.
reverseMapping
(
i
).
valid
)
...
...
src/main/scala/xiangshan/backend/exu/AluExeUnit.scala
浏览文件 @
4142e72c
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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
58d6c396
此差异已折叠。
点击以展开。
src/main/scala/xiangshan/backend/issue/ReservationStationNew.scala
浏览文件 @
4142e72c
此差异已折叠。
点击以展开。
src/main/scala/xiangshan/backend/rename/Rename.scala
浏览文件 @
4142e72c
...
...
@@ -9,14 +9,6 @@ class Rename extends XSModule {
val
io
=
IO
(
new
Bundle
()
{
val
redirect
=
Flipped
(
ValidIO
(
new
Redirect
))
val
roqCommits
=
Vec
(
CommitWidth
,
Flipped
(
ValidIO
(
new
RoqCommit
)))
val
wbIntResults
=
Vec
(
NRIntWritePorts
,
Flipped
(
ValidIO
(
new
ExuOutput
)))
val
wbFpResults
=
Vec
(
NRFpWritePorts
,
Flipped
(
ValidIO
(
new
ExuOutput
)))
val
intRfReadAddr
=
Vec
(
NRIntReadPorts
,
Input
(
UInt
(
PhyRegIdxWidth
.
W
)))
val
fpRfReadAddr
=
Vec
(
NRFpReadPorts
,
Input
(
UInt
(
PhyRegIdxWidth
.
W
)))
val
intPregRdy
=
Vec
(
NRIntReadPorts
,
Output
(
Bool
()))
val
fpPregRdy
=
Vec
(
NRFpReadPorts
,
Output
(
Bool
()))
// set preg to busy when replay
val
replayPregReq
=
Vec
(
ReplayWidth
,
Input
(
new
ReplayPregReq
))
// from decode buffer
val
in
=
Vec
(
RenameWidth
,
Flipped
(
DecoupledIO
(
new
CfCtrl
)))
// to dispatch1
...
...
@@ -43,8 +35,6 @@ class Rename extends XSModule {
val
fpFreeList
,
intFreeList
=
Module
(
new
FreeList
).
io
val
fpRat
=
Module
(
new
RenameTable
(
float
=
true
)).
io
val
intRat
=
Module
(
new
RenameTable
(
float
=
false
)).
io
val
fpBusyTable
=
Module
(
new
BusyTable
(
NRFpReadPorts
,
NRFpWritePorts
)).
io
val
intBusyTable
=
Module
(
new
BusyTable
(
NRIntReadPorts
,
NRIntWritePorts
)).
io
fpFreeList
.
redirect
:=
io
.
redirect
intFreeList
.
redirect
:=
io
.
redirect
...
...
@@ -52,8 +42,6 @@ class Rename extends XSModule {
val
flush
=
io
.
redirect
.
valid
&&
(
io
.
redirect
.
bits
.
isException
||
io
.
redirect
.
bits
.
isFlushPipe
)
// TODO: need check by JiaWei
fpRat
.
flush
:=
flush
intRat
.
flush
:=
flush
fpBusyTable
.
flush
:=
flush
intBusyTable
.
flush
:=
flush
def
needDestReg
[
T
<:
CfCtrl
](
fp
:
Boolean
,
x
:
T
)
:
Bool
=
{
{
if
(
fp
)
x
.
ctrl
.
fpWen
else
x
.
ctrl
.
rfWen
&&
(
x
.
ctrl
.
ldest
=/=
0.
U
)}
...
...
@@ -125,7 +113,6 @@ class Rename extends XSModule {
def
writeRat
(
fp
:
Boolean
)
=
{
val
rat
=
if
(
fp
)
fpRat
else
intRat
val
freeList
=
if
(
fp
)
fpFreeList
else
intFreeList
val
busyTable
=
if
(
fp
)
fpBusyTable
else
intBusyTable
// speculative inst write
val
specWen
=
freeList
.
allocReqs
(
i
)
&&
freeList
.
canAlloc
(
i
)
// walk back write
...
...
@@ -153,9 +140,6 @@ class Rename extends XSModule {
freeList
.
deallocReqs
(
i
)
:=
rat
.
archWritePorts
(
i
).
wen
freeList
.
deallocPregs
(
i
)
:=
io
.
roqCommits
(
i
).
bits
.
uop
.
old_pdest
// set phy reg status to busy
busyTable
.
allocPregs
(
i
).
valid
:=
specWen
busyTable
.
allocPregs
(
i
).
bits
:=
freeList
.
pdests
(
i
)
}
writeRat
(
fp
=
false
)
...
...
@@ -190,26 +174,5 @@ class Rename extends XSModule {
}
def
updateBusyTable
(
fp
:
Boolean
)
=
{
val
wbResults
=
if
(
fp
)
io
.
wbFpResults
else
io
.
wbIntResults
val
busyTable
=
if
(
fp
)
fpBusyTable
else
intBusyTable
for
((
wb
,
setPhyRegRdy
)
<-
wbResults
.
zip
(
busyTable
.
wbPregs
)){
setPhyRegRdy
.
valid
:=
wb
.
valid
&&
needDestReg
(
fp
,
wb
.
bits
.
uop
)
setPhyRegRdy
.
bits
:=
wb
.
bits
.
uop
.
pdest
}
}
updateBusyTable
(
false
)
updateBusyTable
(
true
)
intBusyTable
.
rfReadAddr
<>
io
.
intRfReadAddr
intBusyTable
.
pregRdy
<>
io
.
intPregRdy
for
(
i
<-
io
.
replayPregReq
.
indices
){
intBusyTable
.
replayPregs
(
i
).
valid
:=
io
.
replayPregReq
(
i
).
isInt
fpBusyTable
.
replayPregs
(
i
).
valid
:=
io
.
replayPregReq
(
i
).
isFp
intBusyTable
.
replayPregs
(
i
).
bits
:=
io
.
replayPregReq
(
i
).
preg
fpBusyTable
.
replayPregs
(
i
).
bits
:=
io
.
replayPregReq
(
i
).
preg
}
fpBusyTable
.
rfReadAddr
<>
io
.
fpRfReadAddr
fpBusyTable
.
pregRdy
<>
io
.
fpPregRdy
}
src/main/scala/xiangshan/cache/dtlb.scala
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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/pipeline/AtomicsUnit.scala
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
...
...
@@ -309,4 +310,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
浏览文件 @
4142e72c
...
...
@@ -138,4 +138,4 @@ class StoreUnit extends XSModule {
printPipeLine
(
store_s0
.
io
.
out
.
bits
,
store_s0
.
io
.
out
.
valid
,
"S0"
)
printPipeLine
(
store_s1
.
io
.
out
.
bits
,
store_s1
.
io
.
out
.
valid
,
"S1"
)
}
}
\ No newline at end of file
src/test/csrc/emu.cpp
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
...
...
@@ -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
浏览文件 @
4142e72c
#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
浏览文件 @
4142e72c
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录