Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
88e6e3a1
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
10 个月 前同步成功
通知
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,体验更适合开发者的 AI 搜索 >>
提交
88e6e3a1
编写于
1月 27, 2021
作者:
A
Allen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
DCache: implemented atomics.
上级
8c1d8581
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
95 addition
and
25 deletion
+95
-25
src/main/scala/xiangshan/cache/AtomicsReplayUnit.scala
src/main/scala/xiangshan/cache/AtomicsReplayUnit.scala
+4
-2
src/main/scala/xiangshan/cache/DCacheWrapper.scala
src/main/scala/xiangshan/cache/DCacheWrapper.scala
+1
-5
src/main/scala/xiangshan/cache/MainPipe.scala
src/main/scala/xiangshan/cache/MainPipe.scala
+90
-18
未找到文件。
src/main/scala/xiangshan/cache/AtomicsReplayUnit.scala
浏览文件 @
88e6e3a1
...
...
@@ -18,7 +18,7 @@ class AtomicsReplayEntry extends DCacheModule
val
s_invalid
::
s_pipe_req
::
s_pipe_resp
::
s_resp
::
Nil
=
Enum
(
4
)
val
state
=
RegInit
(
s_invalid
)
val
req
=
Reg
(
new
DCache
Line
Req
)
val
req
=
Reg
(
new
DCache
Word
Req
)
// assign default values to output signals
io
.
lsu
.
req
.
ready
:=
state
===
s_invalid
...
...
@@ -67,6 +67,7 @@ class AtomicsReplayEntry extends DCacheModule
}
val
resp_data
=
Reg
(
UInt
())
val
resp_id
=
Reg
(
UInt
())
when
(
state
===
s_pipe_resp
)
{
// when not miss
// everything is OK, simply send response back to sbuffer
...
...
@@ -84,6 +85,7 @@ class AtomicsReplayEntry extends DCacheModule
}
}
.
otherwise
{
resp_data
:=
io
.
pipe_resp
.
bits
.
data
resp_id
:=
io
.
pipe_resp
.
bits
.
id
state
:=
s_resp
}
}
...
...
@@ -94,7 +96,7 @@ class AtomicsReplayEntry extends DCacheModule
io
.
lsu
.
resp
.
valid
:=
true
.
B
io
.
lsu
.
resp
.
bits
:=
DontCare
io
.
lsu
.
resp
.
bits
.
data
:=
resp_data
io
.
lsu
.
resp
.
bits
.
id
:=
re
q
.
id
io
.
lsu
.
resp
.
bits
.
id
:=
re
sp_
id
when
(
io
.
lsu
.
resp
.
fire
())
{
state
:=
s_invalid
...
...
src/main/scala/xiangshan/cache/DCacheWrapper.scala
浏览文件 @
88e6e3a1
...
...
@@ -229,11 +229,7 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
//----------------------------------------
// atomics
// atomics not finished yet
io
.
lsu
.
atomics
:=
DontCare
atomicsReplayUnit
.
io
:=
DontCare
// sanity check
val
atomicsReq
=
io
.
lsu
.
atomics
.
req
io
.
lsu
.
atomics
<>
atomicsReplayUnit
.
io
.
lsu
//----------------------------------------
// miss queue
...
...
src/main/scala/xiangshan/cache/MainPipe.scala
浏览文件 @
88e6e3a1
...
...
@@ -168,8 +168,6 @@ class MainPipe extends DCacheModule
when
(
s0_req
.
miss
)
{
assert
(
full_overwrite
)
}
// AMO not yet finished
assert
(
s0_req
.
source
=/=
AMO_SOURCE
.
U
)
OneHot
.
checkOneHot
(
Seq
(
s0_req
.
miss
,
s0_req
.
probe
))
}
...
...
@@ -386,6 +384,61 @@ class MainPipe extends DCacheModule
io
.
meta_write
.
bits
.
way_en
:=
s2_way_en
// --------------------------------------------------------------------------------
// LR, SC and AMO
val
debug_sc_fail_addr
=
RegInit
(
0.
U
)
val
debug_sc_fail_cnt
=
RegInit
(
0.
U
(
8.
W
))
val
lrsc_count
=
RegInit
(
0.
U
(
log2Ceil
(
lrscCycles
).
W
))
val
lrsc_valid
=
lrsc_count
>
lrscBackoff
.
U
val
lrsc_addr
=
Reg
(
UInt
())
val
s2_lr
=
!
s2_req
.
probe
&&
s2_req
.
source
===
AMO_SOURCE
.
U
&&
s2_req
.
cmd
===
M_XLR
val
s2_sc
=
!
s2_req
.
probe
&&
s2_req
.
source
===
AMO_SOURCE
.
U
&&
s2_req
.
cmd
===
M_XSC
val
s2_lrsc_addr_match
=
lrsc_valid
&&
lrsc_addr
===
get_block_addr
(
s2_req
.
addr
)
val
s2_sc_fail
=
s2_sc
&&
!
s2_lrsc_addr_match
val
s2_sc_resp
=
Mux
(
s2_sc_fail
,
1.
U
,
0.
U
)
val
s2_can_do_amo
=
(
s2_req
.
miss
&&
!
s2_req
.
probe
&&
s2_req
.
source
===
AMO_SOURCE
.
U
)
||
s2_amo_hit
val
s2_can_do_amo_write
=
s2_can_do_amo
&&
isWrite
(
s2_req
.
cmd
)
&&
!
s2_sc_fail
when
(
s2_valid
&&
(
s2_lr
||
s2_sc
))
{
when
(
s2_can_do_amo
&&
s2_lr
)
{
lrsc_count
:=
(
lrscCycles
-
1
).
U
lrsc_addr
:=
get_block_addr
(
s2_req
.
addr
)
}
.
otherwise
{
lrsc_count
:=
0.
U
}
}
.
elsewhen
(
lrsc_count
>
0.
U
)
{
lrsc_count
:=
lrsc_count
-
1.
U
}
io
.
lrsc_locked_block
.
valid
:=
lrsc_valid
io
.
lrsc_locked_block
.
bits
:=
lrsc_addr
// when we release this block,
// we invalidate this reservation set
when
(
io
.
wb_req
.
fire
())
{
when
(
io
.
wb_req
.
bits
.
addr
===
lrsc_addr
)
{
lrsc_count
:=
0.
U
}
}
when
(
s2_valid
)
{
when
(
s2_req
.
addr
===
debug_sc_fail_addr
)
{
when
(
s2_sc_fail
)
{
debug_sc_fail_cnt
:=
debug_sc_fail_cnt
+
1.
U
}
.
elsewhen
(
s2_sc
)
{
debug_sc_fail_cnt
:=
0.
U
}
}
.
otherwise
{
when
(
s2_sc_fail
)
{
debug_sc_fail_addr
:=
s2_req
.
addr
debug_sc_fail_cnt
:=
1.
U
}
}
}
assert
(
debug_sc_fail_cnt
<
100.
U
,
"L1DCache failed too many SCs in a row"
)
// --------------------------------------------------------------------------------
// Write to DataArray
// Miss:
...
...
@@ -402,7 +455,7 @@ class MainPipe extends DCacheModule
// which word do we need to write
val
wmask
=
Mux
(
s2_req
.
miss
,
s2_full_wmask
,
Mux
(
s2_store_hit
,
s2_store_wmask
,
Mux
(
s2_
amo_hit
,
s2_amo_wmask
,
Mux
(
s2_
can_do_amo_write
,
s2_amo_wmask
,
s2_none_wmask
)))
val
need_write_data
=
VecInit
(
wmask
.
map
(
w
=>
w
.
orR
)).
asUInt
.
orR
...
...
@@ -416,6 +469,7 @@ class MainPipe extends DCacheModule
val
s2_data
=
Mux1H
(
s2_way_en
,
s2_data_resp
)
// TODO: deal with ECC errors
val
s2_data_decoded
=
(
0
until
blockRows
)
map
{
r
=>
(
0
until
rowWords
)
map
{
w
=>
val
data
=
s2_data
(
r
)(
encWordBits
*
(
w
+
1
)
-
1
,
encWordBits
*
w
)
...
...
@@ -425,32 +479,44 @@ class MainPipe extends DCacheModule
}
}
// TODO: deal with ECC errors
for
(
i
<-
0
until
blockRows
)
{
store_data_merged
(
i
)
:=
Cat
((
0
until
rowWords
).
reverse
map
{
w
=>
val
old_data
=
s2_data_decoded
(
i
)(
w
)
val
new_data
=
s2_req
.
store_data
(
rowBits
*
(
i
+
1
)
-
1
,
rowBits
*
i
)(
wordBits
*
(
w
+
1
)
-
1
,
wordBits
*
w
)
val
wmask
=
s2_req
.
store_mask
(
rowBytes
*
(
i
+
1
)
-
1
,
rowBytes
*
i
)(
wordBytes
*
(
w
+
1
)
-
1
,
wordBytes
*
w
)
// for amo hit, we should use read out SRAM data
// do not merge with store data
val
wmask
=
Mux
(
s2_amo_hit
,
0.
U
(
wordBytes
.
W
),
s2_req
.
store_mask
(
rowBytes
*
(
i
+
1
)
-
1
,
rowBytes
*
i
)(
wordBytes
*
(
w
+
1
)
-
1
,
wordBytes
*
w
))
val
store_data
=
mergePutData
(
old_data
,
new_data
,
wmask
)
store_data
})
}
// AMO hits
val
s2_amo_row
=
store_data_merged
(
get_row
(
s2_req
.
addr
))
val
s2_amo_words
=
VecInit
((
0
until
rowWords
)
map
(
w
=>
s2_amo_row
(
wordBits
*
(
w
+
1
)
-
1
,
wordBits
*
w
)))
val
s2_word_idx
=
if
(
rowWords
==
1
)
0.
U
else
s2_req
.
addr
(
log2Up
(
rowWords
*
wordBytes
)-
1
,
log2Up
(
wordBytes
))
val
s2_data_word
=
s2_amo_words
(
s2_word_idx
)
val
amoalu
=
Module
(
new
AMOALU
(
wordBits
))
amoalu
.
io
.
mask
:=
s2_req
.
amo_mask
amoalu
.
io
.
cmd
:=
s2_req
.
cmd
amoalu
.
io
.
lhs
:=
s2_data_word
amoalu
.
io
.
rhs
:=
s2_req
.
amo_data
// merge amo write data
val
amo_data_merged
=
Wire
(
Vec
(
blockRows
,
UInt
(
rowBits
.
W
)))
for
(
i
<-
0
until
blockRows
)
{
amo_data_merged
(
i
)
:=
store_data_merged
(
i
)
}
// TODO: do amo calculation
// and merge amo data
/*
for (i <- 0 until blockRows) {
store_data_merged(i) := Cat((0 until rowWords).reverse map { w =>
val old_data = store_data_merged(i)(w)
val wmask = Mux(s2_req.source === AMO_SOURCE.U && (s2_req.miss || s2_hit) && s2_req.word_idx === i.U, s2_req.amo_mask, 0.U)
val store_data = mergePutData(old_data, new_data, wmask)
amo_data_merged
(
i
)
:=
Cat
((
0
until
rowWords
).
reverse
map
{
w
=>
val
old_data
=
store_data_merged
(
i
)(
wordBits
*
(
w
+
1
)
-
1
,
wordBits
*
w
)
val
new_data
=
amoalu
.
io
.
out
val
wmask
=
Mux
(
s2_can_do_amo_write
&&
i
.
U
===
get_row
(
s2_req
.
addr
)
&&
w
.
U
===
s2_word_idx
,
~
0.
U
(
wordBytes
.
W
),
0.
U
(
wordBytes
.
W
))
val
data
=
mergePutData
(
old_data
,
new_data
,
wmask
)
data
})
}
*/
// ECC encode data
val
wdata_merged
=
Wire
(
Vec
(
blockRows
,
UInt
(
encRowBits
.
W
)))
...
...
@@ -534,8 +600,14 @@ class MainPipe extends DCacheModule
io
.
store_resp
.
valid
:=
s2_fire
&&
s2_req
.
source
===
STORE_SOURCE
.
U
io
.
store_resp
.
bits
:=
resp
io
.
amo_resp
.
valid
:=
s2_fire
&&
s2_req
.
source
===
AMO_SOURCE
.
U
io
.
amo_resp
.
bits
:=
resp
io
.
amo_resp
.
valid
:=
s2_fire
&&
s2_req
.
source
===
AMO_SOURCE
.
U
io
.
amo_resp
.
bits
:=
resp
io
.
amo_resp
.
bits
.
data
:=
Mux
(
s2_sc
,
s2_sc_resp
,
s2_data_word
)
// reuse this field to pass lr sc valid to commit
// nemu use this to see whether lr sc counter is still valid
io
.
amo_resp
.
bits
.
id
:=
lrsc_valid
when
(
io
.
req
.
fire
())
{
io
.
req
.
bits
.
dump
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录