Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
c1a19bbb
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,发现更多精彩内容 >>
提交
c1a19bbb
编写于
10月 20, 2020
作者:
Y
Yinan Xu
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master' into opt-load-to-use
上级
1b47a4fe
d27b07e3
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
123 addition
and
70 deletion
+123
-70
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
+1
-1
src/main/scala/xiangshan/backend/issue/ReservationStation.scala
...in/scala/xiangshan/backend/issue/ReservationStation.scala
+3
-3
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+2
-1
src/main/scala/xiangshan/cache/dcacheWrapper.scala
src/main/scala/xiangshan/cache/dcacheWrapper.scala
+5
-3
src/main/scala/xiangshan/cache/icache.scala
src/main/scala/xiangshan/cache/icache.scala
+7
-40
src/main/scala/xiangshan/cache/missQueue.scala
src/main/scala/xiangshan/cache/missQueue.scala
+15
-2
src/main/scala/xiangshan/cache/probe.scala
src/main/scala/xiangshan/cache/probe.scala
+6
-0
src/main/scala/xiangshan/cache/wbu.scala
src/main/scala/xiangshan/cache/wbu.scala
+30
-3
src/main/scala/xiangshan/frontend/IFU.scala
src/main/scala/xiangshan/frontend/IFU.scala
+2
-2
src/main/scala/xiangshan/mem/AtomicsUnit.scala
src/main/scala/xiangshan/mem/AtomicsUnit.scala
+3
-6
src/main/scala/xiangshan/mem/Lsroq.scala
src/main/scala/xiangshan/mem/Lsroq.scala
+2
-2
src/test/csrc/difftest.cpp
src/test/csrc/difftest.cpp
+9
-0
src/test/csrc/difftest.h
src/test/csrc/difftest.h
+3
-2
src/test/csrc/emu.cpp
src/test/csrc/emu.cpp
+21
-0
src/test/csrc/sdcard.cpp
src/test/csrc/sdcard.cpp
+3
-2
src/test/csrc/sdcard.h
src/test/csrc/sdcard.h
+8
-0
src/test/csrc/uart.cpp
src/test/csrc/uart.cpp
+3
-3
未找到文件。
src/main/scala/xiangshan/backend/issue/IssueQueue.scala
浏览文件 @
c1a19bbb
...
...
@@ -94,7 +94,7 @@ class IssueQueue
def
writeBackHit
(
src
:
UInt
,
srcType
:
UInt
,
wbUop
:
(
Bool
,
MicroOp
))
:
Bool
=
{
val
(
v
,
uop
)
=
wbUop
val
isSameType
=
(
SrcType
.
isReg
(
srcType
)
&&
uop
.
ctrl
.
rfWen
)
||
(
SrcType
.
isFp
(
srcType
)
&&
uop
.
ctrl
.
fpWen
)
(
SrcType
.
isReg
(
srcType
)
&&
uop
.
ctrl
.
rfWen
&&
src
=/=
0.
U
)
||
(
SrcType
.
isFp
(
srcType
)
&&
uop
.
ctrl
.
fpWen
)
v
&&
isSameType
&&
(
src
===
uop
.
pdest
)
}
...
...
src/main/scala/xiangshan/backend/issue/ReservationStation.scala
浏览文件 @
c1a19bbb
...
...
@@ -287,7 +287,7 @@ class ReservationStation
for
(
i
<-
idQue
.
indices
)
{
// Should be IssQue.indices but Mem() does not support
for
(
j
<-
0
until
srcListenNum
)
{
val
hitVec
=
cdbValid
.
indices
.
map
(
k
=>
psrc
(
i
)(
j
)
===
cdbPdest
(
k
)
&&
cdbValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
cdbrfWen
(
k
)
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
cdbfpWen
(
k
)))
val
hitVec
=
cdbValid
.
indices
.
map
(
k
=>
psrc
(
i
)(
j
)
===
cdbPdest
(
k
)
&&
cdbValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
cdbrfWen
(
k
)
&&
cdbPdest
(
k
)
=/=
0.
U
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
cdbfpWen
(
k
)))
val
hit
=
ParallelOR
(
hitVec
).
asBool
val
data
=
ParallelMux
(
hitVec
zip
cdbData
)
when
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
)
{
...
...
@@ -309,7 +309,7 @@ class ReservationStation
for
(
i
<-
idQue
.
indices
)
{
// Should be IssQue.indices but Mem() does not support
for
(
j
<-
0
until
srcListenNum
)
{
val
hitVec
=
bpValid
.
indices
.
map
(
k
=>
psrc
(
i
)(
j
)
===
bpPdest
(
k
)
&&
bpValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
bprfWen
(
k
)
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
bpfpWen
(
k
)))
val
hitVec
=
bpValid
.
indices
.
map
(
k
=>
psrc
(
i
)(
j
)
===
bpPdest
(
k
)
&&
bpValid
(
k
)
&&
(
srcType
(
i
)(
j
)===
SrcType
.
reg
&&
bprfWen
(
k
)
&&
bpPdest
(
k
)
=/=
0.
U
||
srcType
(
i
)(
j
)===
SrcType
.
fp
&&
bpfpWen
(
k
)))
val
hitVecNext
=
hitVec
.
map
(
RegNext
(
_
))
val
hit
=
ParallelOR
(
hitVec
).
asBool
when
(
validQue
(
i
)
&&
!
srcRdyVec
(
i
)(
j
)
&&
hit
)
{
...
...
@@ -336,7 +336,7 @@ class ReservationStation
val
enqPsrc
=
List
(
enqCtrl
.
bits
.
psrc1
,
enqCtrl
.
bits
.
psrc2
,
enqCtrl
.
bits
.
psrc3
)
val
enqSrcType
=
List
(
enqCtrl
.
bits
.
ctrl
.
src1Type
,
enqCtrl
.
bits
.
ctrl
.
src2Type
,
enqCtrl
.
bits
.
ctrl
.
src3Type
)
for
(
i
<-
0
until
srcListenNum
)
{
val
hitVec
=
bpValid
.
indices
.
map
(
j
=>
enqPsrc
(
i
)===
bpPdest
(
j
)
&&
bpValid
(
j
)
&&
(
enqSrcType
(
i
)===
SrcType
.
reg
&&
bprfWen
(
j
)
||
enqSrcType
(
i
)===
SrcType
.
fp
&&
bpfpWen
(
j
)))
val
hitVec
=
bpValid
.
indices
.
map
(
j
=>
enqPsrc
(
i
)===
bpPdest
(
j
)
&&
bpValid
(
j
)
&&
(
enqSrcType
(
i
)===
SrcType
.
reg
&&
bprfWen
(
j
)
&&
bpPdest
(
j
)
=/=
0.
U
||
enqSrcType
(
i
)===
SrcType
.
fp
&&
bpfpWen
(
j
)))
val
hitVecNext
=
hitVec
.
map
(
RegNext
(
_
))
val
hit
=
ParallelOR
(
hitVec
).
asBool
when
(
enqFire
&&
hit
&&
!
enqSrcRdy
(
i
))
{
...
...
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
c1a19bbb
...
...
@@ -120,7 +120,8 @@ class Roq extends XSModule {
val
deqUop
=
microOp
(
deqPtr
)
val
deqPtrWritebacked
=
writebacked
(
deqPtr
)
&&
valid
(
deqPtr
)
val
intrEnable
=
intrBitSet
&&
!
isEmpty
&&
!
hasNoSpec
// TODO: wanna check why has hasCsr(hasNoSpec)
val
intrEnable
=
intrBitSet
&&
!
isEmpty
&&
!
hasNoSpec
&&
deqUop
.
ctrl
.
commitType
=/=
CommitType
.
STORE
&&
deqUop
.
ctrl
.
commitType
=/=
CommitType
.
LOAD
// TODO: wanna check why has hasCsr(hasNoSpec)
val
exceptionEnable
=
deqPtrWritebacked
&&
Cat
(
deqUop
.
cf
.
exceptionVec
).
orR
()
val
isFlushPipe
=
deqPtrWritebacked
&&
deqUop
.
ctrl
.
flushPipe
io
.
redirect
:=
DontCare
...
...
src/main/scala/xiangshan/cache/dcacheWrapper.scala
浏览文件 @
c1a19bbb
...
...
@@ -393,6 +393,11 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
}
// sync with prober
missQueue
.
io
.
probe_wb_req
.
valid
:=
prober
.
io
.
wb_req
.
fire
()
missQueue
.
io
.
probe_wb_req
.
bits
:=
prober
.
io
.
wb_req
.
bits
missQueue
.
io
.
probe_active
:=
prober
.
io
.
probe_active
//----------------------------------------
// prober
prober
.
io
.
block
:=
block_probe
(
prober
.
io
.
inflight_req_block_addr
.
bits
)
...
...
@@ -410,9 +415,6 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
prober
.
io
.
wb_resp
:=
wb
.
io
.
resp
wb
.
io
.
mem_grant
:=
bus
.
d
.
fire
()
&&
bus
.
d
.
bits
.
source
===
cfg
.
nMissEntries
.
U
missQueue
.
io
.
probe_wb_req
.
valid
:=
prober
.
io
.
wb_req
.
fire
()
missQueue
.
io
.
probe_wb_req
.
bits
:=
prober
.
io
.
wb_req
.
bits
TLArbiter
.
lowestFromSeq
(
edge
,
bus
.
c
,
Seq
(
prober
.
io
.
rep
,
wb
.
io
.
release
))
// synchronization stuff
...
...
src/main/scala/xiangshan/cache/icache.scala
浏览文件 @
c1a19bbb
...
...
@@ -224,7 +224,7 @@ class ICacheImp(outer: ICache) extends ICacheModule(outer)
val
metas
=
metaArray
.
io
.
r
.
resp
.
asTypeOf
(
Vec
(
nWays
,
new
ICacheMetaBundle
))
val
datas
=
dataArray
.
map
(
b
=>
RegEnable
(
next
=
b
.
io
.
r
.
resp
.
asTypeOf
(
Vec
(
nWays
,
new
ICacheDataBundle
)),
enable
=
s2_fire
))
val
validMeta
=
Cat
((
0
until
nWays
).
map
{
w
=>
validArray
(
Cat
(
s2_idx
,
w
.
U
))}.
reverse
).
asUInt
val
validMeta
=
Cat
((
0
until
nWays
).
map
{
w
=>
validArray
(
Cat
(
s2_idx
,
w
.
U
(
2.
W
)
))}.
reverse
).
asUInt
// hit check and generate victim cacheline mask
val
hitVec
=
VecInit
((
0
until
nWays
).
map
{
w
=>
metas
(
w
).
tag
===
s2_tag
&&
validMeta
(
w
)
===
1.
U
})
...
...
@@ -254,14 +254,11 @@ class ICacheImp(outer: ICache) extends ICacheModule(outer)
val
s3_hit
=
RegEnable
(
next
=
s2_hit
,
init
=
false
.
B
,
enable
=
s2_fire
)
val
s3_wayMask
=
RegEnable
(
next
=
waymask
,
init
=
0.
U
,
enable
=
s2_fire
)
val
s3_miss
=
s3_valid
&&
!
s3_hit
val
s3_mmio
=
s3_valid
&&
AddressSpace
.
isMMIO
(
s3_tlb_resp
.
paddr
)
when
(
io
.
flush
(
1
))
{
s3_valid
:=
false
.
B
}
.
elsewhen
(
s2_fire
)
{
s3_valid
:=
s2_valid
}
.
elsewhen
(
io
.
resp
.
fire
())
{
s3_valid
:=
false
.
B
}
val
refillDataReg
=
Reg
(
Vec
(
refillCycles
,
UInt
(
beatBits
.
W
)))
assert
(!(
s3_hit
&&
s3_mmio
),
"MMIO address should not hit in ICache!"
)
// icache hit
// simply cut the hit cacheline
val
dataHitWay
=
s3_data
.
map
(
b
=>
Mux1H
(
s3_wayMask
,
b
).
asUInt
)
...
...
@@ -269,15 +266,10 @@ class ICacheImp(outer: ICache) extends ICacheModule(outer)
outPacket
:=
cutHelper
(
VecInit
(
dataHitWay
),
s3_req_pc
(
5
,
1
).
asUInt
,
s3_req_mask
.
asUInt
)
//icache miss
val
s_idle
::
s_m
mioReq
::
s_mmioResp
::
s_memReadReq
::
s_memReadResp
::
s_wait_resp
::
Nil
=
Enum
(
6
)
val
s_idle
::
s_m
emReadReq
::
s_memReadResp
::
s_wait_resp
::
Nil
=
Enum
(
4
)
val
state
=
RegInit
(
s_idle
)
val
readBeatCnt
=
Counter
(
refillCycles
)
//uncache request
val
mmioBeatCnt
=
Counter
(
blockWords
)
val
mmioAddrReg
=
RegInit
(
0.
U
(
PAddrBits
.
W
))
val
mmioReg
=
Reg
(
Vec
(
blockWords
/
2
,
UInt
(
blockWords
.
W
)))
//pipeline flush register
val
needFlush
=
RegInit
(
false
.
B
)
when
(
io
.
flush
(
1
)
&&
(
state
=/=
s_idle
)
&&
(
state
=/=
s_wait_resp
)){
needFlush
:=
true
.
B
}
...
...
@@ -295,35 +287,14 @@ class ICacheImp(outer: ICache) extends ICacheModule(outer)
// state change to wait for a cacheline refill
val
countFull
=
readBeatCnt
.
value
===
(
refillCycles
-
1
).
U
val
mmioCntFull
=
mmioBeatCnt
.
value
===
(
blockWords
-
1
).
U
switch
(
state
){
is
(
s_idle
){
when
(
s3_mmio
&&
io
.
flush
===
0.
U
){
state
:=
s_mmioReq
mmioBeatCnt
.
value
:=
0.
U
mmioAddrReg
:=
s3_tlb_resp
.
paddr
}
.
elsewhen
(
s3_miss
&&
io
.
flush
===
0.
U
){
when
(
s3_miss
&&
io
.
flush
===
0.
U
){
state
:=
s_memReadReq
readBeatCnt
.
value
:=
0.
U
}
}
//mmio request
is
(
s_mmioReq
){
when
(
bus
.
a
.
fire
()){
state
:=
s_mmioResp
mmioAddrReg
:=
mmioAddrReg
+
8.
U
//consider MMIO response 64 bits valid data
}
}
is
(
s_mmioResp
){
when
(
edge
.
hasData
(
bus
.
d
.
bits
)
&&
bus
.
d
.
fire
())
{
mmioBeatCnt
.
inc
()
assert
(
refill_done
,
"MMIO response should be one beat only!"
)
mmioReg
(
mmioBeatCnt
.
value
)
:=
bus
.
d
.
bits
.
data
(
wordBits
-
1
,
0
)
state
:=
Mux
(
mmioCntFull
,
s_wait_resp
,
s_mmioReq
)
}
}
// memory request
is
(
s_memReadReq
){
...
...
@@ -353,9 +324,9 @@ class ICacheImp(outer: ICache) extends ICacheModule(outer)
//refill write
val
metaWrite
=
Wire
(
new
ICacheMetaBundle
)
val
refillFinalOneBeat
=
(
state
===
s_memReadResp
)
&&
bus
.
d
.
fire
()
&&
refill_done
val
wayNum
=
OHToUInt
(
waymask
)
val
wayNum
=
OHToUInt
(
s3_wayMask
.
asTypeOf
(
Vec
(
nWays
,
Bool
()))
)
val
validPtr
=
Cat
(
get_idx
(
s3_req_pc
),
wayNum
)
metaWrite
.
tag
:=
get_tag
(
s3_req_pc
)
metaWrite
.
tag
:=
s3_tag
metaArray
.
io
.
w
.
req
.
valid
:=
refillFinalOneBeat
metaArray
.
io
.
w
.
req
.
bits
.
apply
(
data
=
metaWrite
,
setIdx
=
get_idx
(
s3_req_pc
),
waymask
=
s3_wayMask
)
...
...
@@ -445,16 +416,12 @@ class ICacheImp(outer: ICache) extends ICacheModule(outer)
bus
.
b
.
ready
:=
true
.
B
bus
.
c
.
valid
:=
false
.
B
bus
.
e
.
valid
:=
false
.
B
bus
.
a
.
valid
:=
(
state
===
s_memReadReq
)
||
(
state
===
s_mmioReq
)
bus
.
a
.
valid
:=
(
state
===
s_memReadReq
)
val
memTileReq
=
edge
.
Get
(
fromSource
=
cacheID
.
U
,
toAddress
=
groupPC
(
s3_tlb_resp
.
paddr
),
lgSize
=
(
log2Up
(
cacheParams
.
blockBytes
)).
U
).
_2
val
mmioTileReq
=
edge
.
Get
(
fromSource
=
cacheID
.
U
,
toAddress
=
mmioAddrReg
,
lgSize
=
(
log2Up
(
wordBits
)).
U
).
_2
bus
.
a
.
bits
:=
Mux
((
state
===
s_mmioReq
),
mmioTileReq
,
memTileReq
)
bus
.
a
.
bits
:=
memTileReq
bus
.
d
.
ready
:=
true
.
B
XSDebug
(
"[flush] flush_0:%d flush_1:%d\n"
,
io
.
flush
(
0
),
io
.
flush
(
1
))
...
...
src/main/scala/xiangshan/cache/missQueue.scala
浏览文件 @
c1a19bbb
...
...
@@ -60,6 +60,8 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
// watch prober's write back requests
val
probe_wb_req
=
Flipped
(
ValidIO
(
new
WritebackReq
(
edge
.
bundle
.
sourceBits
)))
val
probe_active
=
Flipped
(
ValidIO
(
UInt
()))
})
// MSHR:
...
...
@@ -70,7 +72,7 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
// 5. wait for client's finish
// 6. update meta data
// 7. done
val
s_invalid
::
s_meta_read_req
::
s_meta_read_resp
::
s_decide_next_state
::
s_
wb_req
::
s_wb_resp
::
s_refill_req
::
s_refill_resp
::
s_data_write_req
::
s_mem_finish
::
s_send_resp
::
s_client_finish
::
s_meta_write_req
::
Nil
=
Enum
(
13
)
val
s_invalid
::
s_meta_read_req
::
s_meta_read_resp
::
s_decide_next_state
::
s_
refill_req
::
s_refill_resp
::
s_mem_finish
::
s_wait_probe_exit
::
s_send_resp
::
s_wb_req
::
s_wb_resp
::
s_data_write_req
::
s_meta_write_req
::
s_client_finish
::
Nil
=
Enum
(
14
)
val
state
=
RegInit
(
s_invalid
)
...
...
@@ -332,7 +334,14 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
when
(
io
.
mem_finish
.
fire
())
{
grantack
.
valid
:=
false
.
B
state
:=
s_wait_probe_exit
}
}
when
(
state
===
s_wait_probe_exit
)
{
// we only wait for probe, when prober is manipulating our set
val
should_wait_for_probe_exit
=
io
.
probe_active
.
valid
&&
io
.
probe_active
.
bits
===
req_idx
when
(!
should_wait_for_probe_exit
)
{
// no data
when
(
early_response
)
{
// load miss respond right after finishing tilelink transactions
...
...
@@ -359,10 +368,12 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
}
}
// during refill, probe may step in, it may release our blocks
// if it releases the block we are trying to acquire, we don't care, since we will get it back eventually
// but we need to know whether it releases the block we are trying to evict
val
prober_writeback_our_block
=
(
state
===
s_refill_req
||
state
===
s_refill_resp
)
&&
val
prober_writeback_our_block
=
(
state
===
s_refill_req
||
state
===
s_refill_resp
||
state
===
s_mem_finish
||
state
===
s_wait_probe_exit
||
state
===
s_send_resp
||
state
===
s_wb_req
)
&&
io
.
probe_wb_req
.
valid
&&
!
io
.
probe_wb_req
.
bits
.
voluntary
&&
io
.
probe_wb_req
.
bits
.
tag
===
req_old_meta
.
tag
&&
io
.
probe_wb_req
.
bits
.
idx
===
req_idx
&&
...
...
@@ -475,6 +486,7 @@ class MissQueue(edge: TLEdgeOut) extends DCacheModule with HasTLDump
val
wb_resp
=
Input
(
Bool
())
val
probe_wb_req
=
Flipped
(
ValidIO
(
new
WritebackReq
(
edge
.
bundle
.
sourceBits
)))
val
probe_active
=
Flipped
(
ValidIO
(
UInt
()))
val
inflight_req_idxes
=
Output
(
Vec
(
cfg
.
nMissEntries
,
Valid
(
UInt
())))
val
inflight_req_block_addrs
=
Output
(
Vec
(
cfg
.
nMissEntries
,
Valid
(
UInt
())))
...
...
@@ -527,6 +539,7 @@ class MissQueue(edge: TLEdgeOut) extends DCacheModule with HasTLDump
wb_req_arb
.
io
.
in
(
i
)
<>
entry
.
io
.
wb_req
entry
.
io
.
wb_resp
:=
io
.
wb_resp
entry
.
io
.
probe_wb_req
<>
io
.
probe_wb_req
entry
.
io
.
probe_active
<>
io
.
probe_active
entry
.
io
.
mem_grant
.
valid
:=
false
.
B
entry
.
io
.
mem_grant
.
bits
:=
DontCare
...
...
src/main/scala/xiangshan/cache/probe.scala
浏览文件 @
c1a19bbb
...
...
@@ -19,6 +19,7 @@ class ProbeUnit(edge: TLEdgeOut) extends DCacheModule with HasTLDump {
val
block
=
Input
(
Bool
())
val
inflight_req_idx
=
Output
(
Valid
(
UInt
()))
val
inflight_req_block_addr
=
Output
(
Valid
(
UInt
()))
val
probe_active
=
Output
(
Valid
(
UInt
()))
})
val
s_invalid
::
s_wait_sync
::
s_meta_read_req
::
s_meta_read_resp
::
s_decide_next_state
::
s_release
::
s_wb_req
::
s_wb_resp
::
s_meta_write_req
::
Nil
=
Enum
(
9
)
...
...
@@ -54,6 +55,11 @@ class ProbeUnit(edge: TLEdgeOut) extends DCacheModule with HasTLDump {
io
.
inflight_req_block_addr
.
valid
:=
state
=/=
s_invalid
io
.
inflight_req_block_addr
.
bits
:=
req_block_addr
// active means nobody is blocking it anymore
// it will run free
io
.
probe_active
.
valid
:=
state
=/=
s_invalid
&&
state
=/=
s_wait_sync
io
.
probe_active
.
bits
:=
req_idx
XSDebug
(
"state: %d\n"
,
state
)
when
(
state
===
s_invalid
)
{
...
...
src/main/scala/xiangshan/cache/wbu.scala
浏览文件 @
c1a19bbb
...
...
@@ -30,6 +30,7 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
val
req
=
Reg
(
new
WritebackReq
(
edge
.
bundle
.
sourceBits
))
val
s_invalid
::
s_data_read_req
::
s_data_read_resp
::
s_active
::
s_grant
::
s_resp
::
Nil
=
Enum
(
6
)
val
state
=
RegInit
(
s_invalid
)
val
should_writeback_data
=
Reg
(
Bool
())
val
data_req_cnt
=
RegInit
(
0.
U
(
log2Up
(
refillCycles
+
1
).
W
))
...
...
@@ -58,11 +59,19 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
when
(
io
.
req
.
fire
())
{
// for report types: TtoT, BtoB, NtoN, we do nothing
import
freechips.rocketchip.tilelink.TLPermissions._
def
is_dirty
(
x
:
UInt
)
=
x
<=
TtoN
def
do_nothing
(
x
:
UInt
)
=
x
>
BtoN
when
(
do_nothing
(
io
.
req
.
bits
.
param
))
{
should_writeback_data
:=
false
.
B
state
:=
s_resp
}
.
otherwise
{
state
:=
s_data_read_req
when
(
is_dirty
(
io
.
req
.
bits
.
param
))
{
state
:=
s_data_read_req
should_writeback_data
:=
true
.
B
}
.
otherwise
{
state
:=
s_active
should_writeback_data
:=
false
.
B
}
data_req_cnt
:=
0.
U
req
:=
io
.
req
.
bits
acked
:=
false
.
B
...
...
@@ -115,6 +124,13 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
val
id
=
cfg
.
nMissEntries
val
probeResponse
=
edge
.
ProbeAck
(
fromSource
=
id
.
U
,
toAddress
=
r_address
,
lgSize
=
log2Ceil
(
cfg
.
blockBytes
).
U
,
reportPermissions
=
req
.
param
)
val
probeResponseData
=
edge
.
ProbeAck
(
fromSource
=
id
.
U
,
toAddress
=
r_address
,
lgSize
=
log2Ceil
(
cfg
.
blockBytes
).
U
,
...
...
@@ -123,6 +139,13 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
)
val
voluntaryRelease
=
edge
.
Release
(
fromSource
=
id
.
U
,
toAddress
=
r_address
,
lgSize
=
log2Ceil
(
cfg
.
blockBytes
).
U
,
shrinkPermissions
=
req
.
param
).
_2
val
voluntaryReleaseData
=
edge
.
Release
(
fromSource
=
id
.
U
,
toAddress
=
r_address
,
lgSize
=
log2Ceil
(
cfg
.
blockBytes
).
U
,
...
...
@@ -132,7 +155,9 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
when
(
state
===
s_active
)
{
io
.
release
.
valid
:=
data_req_cnt
<
refillCycles
.
U
io
.
release
.
bits
:=
Mux
(
req
.
voluntary
,
voluntaryRelease
,
probeResponse
)
io
.
release
.
bits
:=
Mux
(
req
.
voluntary
,
Mux
(
should_writeback_data
,
voluntaryReleaseData
,
voluntaryRelease
),
Mux
(
should_writeback_data
,
probeResponseData
,
probeResponse
))
when
(
io
.
mem_grant
)
{
acked
:=
true
.
B
...
...
@@ -141,7 +166,9 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
when
(
io
.
release
.
fire
())
{
data_req_cnt
:=
data_req_cnt
+
1.
U
when
(
data_req_cnt
===
(
refillCycles
-
1
).
U
)
{
val
last_beat
=
Mux
(
should_writeback_data
,
data_req_cnt
===
(
refillCycles
-
1
).
U
,
true
.
B
)
when
(
last_beat
)
{
state
:=
Mux
(
req
.
voluntary
,
s_grant
,
s_resp
)
}
}
...
...
src/main/scala/xiangshan/frontend/IFU.scala
浏览文件 @
c1a19bbb
...
...
@@ -169,8 +169,8 @@ class IFU extends XSModule with HasIFUConst
// the previous half of RVI instruction waits until it meets its last half
val
if3_hasPrevHalfInstr
=
prevHalfInstr
.
valid
&&
(
prevHalfInstr
.
pc
+
2.
U
)
===
if3_pc
// set to invalid once consumed
val
prevHalfConsumed
=
if3_hasPrevHalfInstr
&&
if3_fire
// set to invalid once consumed
or redirect from backend
val
prevHalfConsumed
=
if3_hasPrevHalfInstr
&&
if3_fire
||
if4_flush
when
(
prevHalfConsumed
)
{
if3_prevHalfInstr
.
valid
:=
false
.
B
}
...
...
src/main/scala/xiangshan/mem/AtomicsUnit.scala
浏览文件 @
c1a19bbb
...
...
@@ -24,8 +24,6 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
val
s_invalid
::
s_tlb
::
s_flush_sbuffer_req
::
s_flush_sbuffer_resp
::
s_cache_req
::
s_cache_resp
::
s_finish
::
Nil
=
Enum
(
7
)
val
state
=
RegInit
(
s_invalid
)
val
in
=
Reg
(
new
ExuInput
())
// vaddr for stored for exception
val
vaddr
=
Reg
(
UInt
())
val
atom_override_xtval
=
RegInit
(
false
.
B
)
// paddr after translation
val
paddr
=
Reg
(
UInt
())
...
...
@@ -33,7 +31,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
val
resp_data
=
Reg
(
UInt
())
val
is_lrsc_valid
=
Reg
(
Bool
())
ExcitingUtils
.
addSource
(
vaddr
,
"ATOM_EXECPTION_VADDR"
)
ExcitingUtils
.
addSource
(
in
.
src1
,
"ATOM_EXECPTION_VADDR"
)
ExcitingUtils
.
addSource
(
atom_override_xtval
,
"ATOM_OVERRIDE_XTVAL"
)
// assign default value to output signals
...
...
@@ -58,7 +56,6 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
when
(
io
.
in
.
fire
())
{
in
:=
io
.
in
.
bits
state
:=
s_tlb
vaddr
:=
in
.
src1
}
}
...
...
@@ -179,7 +176,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
resp_data
:=
LookupTree
(
in
.
uop
.
ctrl
.
fuOpType
,
List
(
LSUOpType
.
lr_w
->
SignExt
(
rdataSel
(
31
,
0
),
XLEN
),
LSUOpType
.
sc_w
->
SignExt
(
rdataSel
(
31
,
0
),
XLEN
)
,
LSUOpType
.
sc_w
->
rdata
,
LSUOpType
.
amoswap_w
->
SignExt
(
rdataSel
(
31
,
0
),
XLEN
),
LSUOpType
.
amoadd_w
->
SignExt
(
rdataSel
(
31
,
0
),
XLEN
),
LSUOpType
.
amoxor_w
->
SignExt
(
rdataSel
(
31
,
0
),
XLEN
),
...
...
@@ -191,7 +188,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
LSUOpType
.
amomaxu_w
->
SignExt
(
rdataSel
(
31
,
0
),
XLEN
),
LSUOpType
.
lr_d
->
SignExt
(
rdataSel
(
63
,
0
),
XLEN
),
LSUOpType
.
sc_d
->
SignExt
(
rdataSel
(
63
,
0
),
XLEN
)
,
LSUOpType
.
sc_d
->
rdata
,
LSUOpType
.
amoswap_d
->
SignExt
(
rdataSel
(
63
,
0
),
XLEN
),
LSUOpType
.
amoadd_d
->
SignExt
(
rdataSel
(
63
,
0
),
XLEN
),
LSUOpType
.
amoxor_d
->
SignExt
(
rdataSel
(
63
,
0
),
XLEN
),
...
...
src/main/scala/xiangshan/mem/Lsroq.scala
浏览文件 @
c1a19bbb
...
...
@@ -282,12 +282,12 @@ class Lsroq extends XSModule with HasDCacheParameters {
val
loadWbSelVec
=
VecInit
((
0
until
LsroqSize
).
map
(
i
=>
{
allocated
(
i
)
&&
valid
(
i
)
&&
!
writebacked
(
i
)
&&
!
store
(
i
)
})).
asUInt
()
// use uint instead vec to reduce verilog lines
val
loadWbSel
=
Wire
(
Vec
(
Store
PipelineWidth
,
UInt
(
log2Up
(
LsroqSize
).
W
)))
val
loadWbSel
=
Wire
(
Vec
(
Load
PipelineWidth
,
UInt
(
log2Up
(
LsroqSize
).
W
)))
val
lselvec0
=
PriorityEncoderOH
(
loadWbSelVec
)
val
lselvec1
=
PriorityEncoderOH
(
loadWbSelVec
&
(~
lselvec0
).
asUInt
)
loadWbSel
(
0
)
:=
OHToUInt
(
lselvec0
)
loadWbSel
(
1
)
:=
OHToUInt
(
lselvec1
)
(
0
until
Store
PipelineWidth
).
map
(
i
=>
{
(
0
until
Load
PipelineWidth
).
map
(
i
=>
{
// data select
val
rdata
=
data
(
loadWbSel
(
i
)).
data
val
func
=
uop
(
loadWbSel
(
i
)).
ctrl
.
fuOpType
...
...
src/test/csrc/difftest.cpp
浏览文件 @
c1a19bbb
...
...
@@ -18,6 +18,8 @@ void (*ref_difftest_getregs)(void *c) = NULL;
void
(
*
ref_difftest_setregs
)(
const
void
*
c
)
=
NULL
;
void
(
*
ref_difftest_get_mastatus
)(
void
*
s
)
=
NULL
;
void
(
*
ref_difftest_set_mastatus
)(
const
void
*
s
)
=
NULL
;
void
(
*
ref_difftest_get_csr
)(
void
*
c
)
=
NULL
;
void
(
*
ref_difftest_set_csr
)(
const
void
*
c
)
=
NULL
;
vaddr_t
(
*
ref_disambiguate_exec
)(
void
*
disambiguate_para
)
=
NULL
;
static
void
(
*
ref_difftest_exec
)(
uint64_t
n
)
=
NULL
;
static
void
(
*
ref_difftest_raise_intr
)(
uint64_t
NO
)
=
NULL
;
...
...
@@ -66,6 +68,12 @@ void init_difftest() {
ref_difftest_set_mastatus
=
(
void
(
*
)(
const
void
*
))
dlsym
(
handle
,
"difftest_set_mastatus"
);
assert
(
ref_difftest_set_mastatus
);
ref_difftest_get_csr
=
(
void
(
*
)(
void
*
))
dlsym
(
handle
,
"difftest_get_csr"
);
assert
(
ref_difftest_get_csr
);
ref_difftest_set_csr
=
(
void
(
*
)(
const
void
*
))
dlsym
(
handle
,
"difftest_set_csr"
);
assert
(
ref_difftest_set_csr
);
ref_disambiguate_exec
=
(
vaddr_t
(
*
)(
void
*
))
dlsym
(
handle
,
"disambiguate_exec"
);
assert
(
ref_disambiguate_exec
);
...
...
@@ -158,6 +166,7 @@ int difftest_step(DiffState *s) {
if
(
s
->
sync
.
scFailed
){
struct
SyncState
sync
;
sync
.
lrscValid
=
0
;
sync
.
lrscAddr
=
0
;
ref_difftest_set_mastatus
((
uint64_t
*
)
&
sync
);
// sync lr/sc microarchitectural regs
}
...
...
src/test/csrc/difftest.h
浏览文件 @
c1a19bbb
...
...
@@ -44,6 +44,7 @@ struct SyncChannel {
struct
SyncState
{
uint64_t
lrscValid
;
uint64_t
lrscAddr
;
};
struct
DiffState
{
...
...
@@ -72,10 +73,10 @@ extern void (*ref_difftest_memcpy_from_dut)(paddr_t dest, void *src, size_t n);
extern
void
(
*
ref_difftest_memcpy_from_ref
)(
void
*
dest
,
paddr_t
src
,
size_t
n
);
extern
void
(
*
ref_difftest_getregs
)(
void
*
c
);
extern
void
(
*
ref_difftest_setregs
)(
const
void
*
c
);
extern
void
(
*
ref_difftest_getregs
)(
void
*
c
);
extern
void
(
*
ref_difftest_setregs
)(
const
void
*
c
);
extern
void
(
*
ref_difftest_get_mastatus
)(
void
*
s
);
extern
void
(
*
ref_difftest_set_mastatus
)(
const
void
*
s
);
extern
void
(
*
ref_difftest_get_csr
)(
void
*
c
);
extern
void
(
*
ref_difftest_set_csr
)(
const
void
*
c
);
extern
vaddr_t
(
*
ref_disambiguate_exec
)(
void
*
disambiguate_para
);
void
init_difftest
();
...
...
src/test/csrc/emu.cpp
浏览文件 @
c1a19bbb
#include "emu.h"
#include "sdcard.h"
#include "difftest.h"
#include <getopt.h>
...
...
@@ -373,6 +374,17 @@ void Emulator::snapshot_save(const char *filename) {
ref_difftest_get_mastatus
(
&
sync_mastate
);
stream
.
unbuf_write
(
&
sync_mastate
,
sizeof
(
struct
SyncState
));
uint64_t
csr_buf
[
4096
];
ref_difftest_get_csr
(
csr_buf
);
stream
.
unbuf_write
(
&
csr_buf
,
sizeof
(
csr_buf
));
long
sdcard_offset
;
if
(
fp
)
sdcard_offset
=
ftell
(
fp
);
else
sdcard_offset
=
0
;
stream
.
unbuf_write
(
&
sdcard_offset
,
sizeof
(
sdcard_offset
));
// actually write to file in snapshot_finalize()
}
...
...
@@ -402,4 +414,13 @@ void Emulator::snapshot_load(const char *filename) {
struct
SyncState
sync_mastate
;
stream
.
read
(
&
sync_mastate
,
sizeof
(
struct
SyncState
));
ref_difftest_set_mastatus
(
&
sync_mastate
);
uint64_t
csr_buf
[
4096
];
stream
.
read
(
&
csr_buf
,
sizeof
(
csr_buf
));
ref_difftest_set_csr
(
csr_buf
);
long
sdcard_offset
=
0
;
stream
.
read
(
&
sdcard_offset
,
sizeof
(
sdcard_offset
));
if
(
fp
)
fseek
(
fp
,
sdcard_offset
,
SEEK_SET
);
}
src/test/csrc/sdcard.cpp
浏览文件 @
c1a19bbb
#include "common.h"
#include "sdcard.h"
extern
"C"
{
FILE
*
fp
=
NULL
;
static
FILE
*
fp
=
NULL
;
extern
"C"
{
void
sd_setaddr
(
uint32_t
addr
)
{
fseek
(
fp
,
addr
,
SEEK_SET
);
...
...
src/test/csrc/sdcard.h
0 → 100644
浏览文件 @
c1a19bbb
#ifndef __SDCARD_H
#define __SDCARD_H
#include "common.h"
extern
FILE
*
fp
;
#endif // __SDCARD_H
src/test/csrc/uart.cpp
浏览文件 @
c1a19bbb
...
...
@@ -40,9 +40,9 @@ uint8_t uart_getc() {
eprintf
(
ANSI_COLOR_RED
"now = %ds
\n
"
ANSI_COLOR_RESET
,
now
/
1000
);
lasttime
=
now
;
}
if
(
now
>
4
*
3600
*
1000
)
{
// 4 hours
ch
=
uart_dequeue
();
}
//
if (now > 4 * 3600 * 1000) { // 4 hours
//
ch = uart_dequeue();
//
}
return
ch
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录