Skip to content

Commit 0c42f15

Browse files
DSLX DMA: Implement FIFO and CSR
Signed-off-by: Michal Czyz <[email protected]>
1 parent aebb40c commit 0c42f15

File tree

6 files changed

+836
-0
lines changed

6 files changed

+836
-0
lines changed

xls/modules/axi4/dma/BUILD

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Copyright 2023 The XLS Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
load(
16+
"//xls/build_rules:xls_build_defs.bzl",
17+
"xls_dslx_ir",
18+
"xls_dslx_library",
19+
"xls_dslx_test",
20+
)
21+
22+
package(
23+
default_applicable_licenses = ["//:license"],
24+
default_visibility = ["//xls:xls_users"],
25+
licenses = ["notice"],
26+
)
27+
28+
xls_dslx_library(
29+
name = 'dma_common',
30+
srcs = [
31+
'config.x',
32+
'axi_pkg.x'
33+
]
34+
)
35+
36+
xls_dslx_test(
37+
name = "test_common",
38+
library = "dma_common",
39+
)
40+
41+
xls_dslx_library(
42+
name = 'csr',
43+
srcs = [
44+
'csr.x',
45+
'axi_csr.x'
46+
],
47+
deps = [
48+
':dma_common',
49+
]
50+
)
51+
52+
xls_dslx_test(
53+
name = "test_csr",
54+
library = "csr",
55+
)
56+
57+
58+
xls_dslx_library(
59+
name = 'fifo',
60+
srcs = [
61+
'fifo.x'
62+
],
63+
deps = [
64+
':dma_common',
65+
'//xls/examples:ram_dslx'
66+
]
67+
)
68+
69+
xls_dslx_test(
70+
name = "test_fifo",
71+
library = "fifo",
72+
)
73+

xls/modules/axi4/dma/axi_csr.x

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
// Copyright 2023 The XLS Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import std
16+
import xls.modules.axi4.dma.config as config
17+
import xls.modules.axi4.dma.axi_pkg as axi_pkg
18+
import xls.modules.axi4.dma.csr as csr
19+
20+
// FIXME: casting imported types is a workaround
21+
// https://github.com/google/xls/issues/1030
22+
const ID_W = config::AXI_0_ID_W;
23+
const ADDR_W = config::AXI_0_ADDR_W;
24+
const DATA_W = config::AXI_0_DATA_W;
25+
const STRB_W = config::AXI_0_STRB_W;
26+
27+
type axi_aw_t = axi_pkg::axi_aw_t<ID_W, ADDR_W>;
28+
type axi_w_t = axi_pkg::axi_w_t<DATA_W, STRB_W>;
29+
type axi_b_t = axi_pkg::axi_b_t<ID_W>;
30+
31+
// AXI4 Manager behavioral model
32+
// Request new AXI transaction by sending a message on the ctrl_data channel.
33+
// Model responds on channel ctrl_done channel once done.
34+
proc axi_manager_beh<ID_W: u32, ADDR_W: u32, DATA_W: u32, STRB_W: u32> {
35+
aw_req: chan<axi_aw_t> out;
36+
aw_rsp: chan<()> in;
37+
w_req: chan<axi_w_t> out;
38+
w_rsp: chan<()> in;
39+
b_req: chan<axi_b_t> in;
40+
b_rsp: chan<()> out;
41+
ctrl_done: chan<()> out;
42+
ctrl_data: chan<(uN[ADDR_W], uN[DATA_W])> in;
43+
44+
config(aw_req: chan<axi_aw_t> out, aw_rsp: chan<()> in, w_req: chan<axi_w_t> out, w_rsp
45+
:
46+
chan<()> in,
47+
b_req: chan<axi_b_t> in, b_rsp: chan<()> out, ctrl_done: chan<()> out, ctrl_data
48+
:
49+
chan<(uN[ADDR_W], uN[DATA_W])> in) {
50+
(aw_req, aw_rsp, w_req, w_rsp, b_req, b_rsp, ctrl_done, ctrl_data)
51+
}
52+
53+
init { () }
54+
55+
next(tok: token, state:()) {
56+
// Wait for data to write to registers
57+
let (tok, payload) = recv(tok, ctrl_data);
58+
let (addr, data) = payload;
59+
let req = axi_aw_t {
60+
awid: uN[ID_W]:0x0,
61+
awaddr: addr,
62+
awsize: axi_pkg::AXI_AXSIZE_ENCODING::MAX_8B_TRANSFER,
63+
awprot: u3:0
64+
};
65+
// AW Handshake
66+
let tok = send(tok, aw_req, req);
67+
let (tok, _) = recv(tok, aw_rsp);
68+
69+
// Write channel handler
70+
let w_data = axi_w_t { wdata: data, wstrb: std::unsigned_max_value<STRB_W>(), wlast: u1:1 };
71+
let tok = send(tok, w_req, w_data);
72+
let (tok, _) = recv(tok, w_rsp);
73+
74+
// Response channel handler
75+
let (tok, bresp) = recv(tok, b_req);
76+
let tok = send(tok, b_rsp, ());
77+
78+
let tok = send(tok, ctrl_done, ());
79+
state
80+
}
81+
}
82+
83+
// AXI4 subordinate receives AXI4 transactions and translates them into simple
84+
// read/Writes for CSR
85+
proc axi_subordinate_beh<ID_W: u32, ADDR_W: u32, DATA_W: u32, STRB_W: u32> {
86+
aw_req: chan<axi_aw_t> in;
87+
aw_rsp: chan<()> out;
88+
w_req: chan<axi_w_t> in;
89+
w_rsp: chan<()> out;
90+
b_req: chan<axi_b_t> out;
91+
b_rsp: chan<()> in;
92+
read_req: chan<csr::ReadReq> out;
93+
read_resp: chan<csr::ReadResp> in;
94+
write_req: chan<csr::WriteReq> out;
95+
write_resp: chan<csr::WriteResp> in;
96+
97+
config(aw_req: chan<axi_aw_t> in, aw_rsp: chan<()> out, w_req: chan<axi_w_t> in, w_rsp
98+
:
99+
chan<()> out,
100+
b_req: chan<axi_b_t> out, b_rsp: chan<()> in) {
101+
let (read_req_s, read_req_r) = chan<csr::ReadReq>;
102+
let (read_resp_s, read_resp_r) = chan<csr::ReadResp>;
103+
let (write_req_s, write_req_r) = chan<csr::WriteReq>;
104+
let (write_resp_s, write_resp_r) = chan<csr::WriteResp>;
105+
spawn csr::CSR(read_req_r, read_resp_s, write_req_r, write_resp_s);
106+
107+
(
108+
aw_req, aw_rsp, w_req, w_rsp, b_req, b_rsp, read_req_s, read_resp_r, write_req_s,
109+
write_resp_r,
110+
)
111+
}
112+
113+
init { (u32:0) }
114+
115+
next(tok: token, state: u32) {
116+
// AW Channel Handler
117+
let (tok, req) = recv(tok, aw_req);
118+
let tok = send(tok, aw_rsp, ());
119+
120+
// W channel Handler
121+
let (tok, w_data) = recv(tok, w_req);
122+
let tok = send(tok, w_rsp, ());
123+
124+
// Handle write to CSR
125+
let tok = send(tok, write_req, csr::WriteWordReq(req.awaddr, w_data.wdata));
126+
let (tok, _) = recv(tok, write_resp);
127+
128+
// B Channel Handlers
129+
let req = axi_b_t { bresp: axi_pkg::AXI_WRITE_RESPONSE_CODES::OKAY, bid: uN[ID_W]:0 };
130+
let tok = send(tok, b_req, req);
131+
let (tok, rsp) = recv(tok, b_rsp);
132+
state
133+
}
134+
}
135+
136+
const TEST_0_OP_NUM = u32:512;
137+
138+
#[test_proc]
139+
proc test_axi_beh {
140+
ctrl_done: chan<()> in;
141+
ctrl_data: chan<(uN[ADDR_W], uN[DATA_W])> out;
142+
terminator: chan<bool> out;
143+
144+
config(terminator: chan<bool> out) {
145+
let (aw_req_s, aw_req_r) = chan<axi_aw_t>;
146+
let (aw_rsp_s, aw_rsp_r) = chan<()>;
147+
let (w_req_s, w_req_r) = chan<axi_w_t>;
148+
let (w_rsp_s, w_rsp_r) = chan<()>;
149+
let (b_req_s, b_req_r) = chan<axi_b_t>;
150+
let (b_rsp_s, b_rsp_r) = chan<()>;
151+
let (ctrl_done_s, ctrl_done_r) = chan<()>;
152+
let (ctrl_data_s, ctrl_data_r) = chan<(uN[ADDR_W], uN[DATA_W])>;
153+
spawn axi_manager_beh<ID_W, ADDR_W, DATA_W, STRB_W>(
154+
aw_req_s, aw_rsp_r, w_req_s, w_rsp_r, b_req_r, b_rsp_s, ctrl_done_s, ctrl_data_r);
155+
spawn axi_subordinate_beh<ID_W, ADDR_W, DATA_W, STRB_W>(
156+
aw_req_r, aw_rsp_s, w_req_r, w_rsp_s, b_req_s, b_rsp_r);
157+
(ctrl_done_r, ctrl_data_s, terminator)
158+
}
159+
160+
init { () }
161+
162+
next(tok: token, state: ()) {
163+
for (i, tok): (u32, token) in u32:0..TEST_0_OP_NUM {
164+
let addr = i as uN[ADDR_W];
165+
let data = (u32:0x4000 + i) as uN[DATA_W];
166+
trace_fmt!("TEST_{}: ADDR=[{}] DATA=[{}]", i, addr, data);
167+
let tok = send(tok, ctrl_data, (addr, data));
168+
let (tok, _) = recv(tok, ctrl_done);
169+
(tok)
170+
}(tok);
171+
let tok = send(tok, terminator, true);
172+
}
173+
}

xls/modules/axi4/dma/axi_pkg.x

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright 2023 The XLS Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
pub enum AXI_AXSIZE_ENCODING : u3 {
16+
MAX_1B_TRANSFER = 0,
17+
MAX_2B_TRANSFER = 1,
18+
MAX_4B_TRANSFER = 2,
19+
MAX_8B_TRANSFER = 3,
20+
MAX_16B_TRANSFER = 4,
21+
MAX_32B_TRANSFER = 5,
22+
MAX_64B_TRANSFER = 6,
23+
MAX_128B_TRANSFER = 7,
24+
}
25+
26+
pub enum AXI_WRITE_RESPONSE_CODES : u3 {
27+
OKAY = 0,
28+
EXOKAY = 1,
29+
SLVERR = 2,
30+
DECERR = 3,
31+
DEFER = 4,
32+
TRANSFAULT = 5,
33+
RESERVED = 6,
34+
UNSUPPORTED = 7,
35+
}
36+
37+
pub enum AXI_READ_RESPONSE_CODES : u3 {
38+
OKAY = 0,
39+
EXOKAY = 1,
40+
SLVERR = 2,
41+
DECERR = 3,
42+
PREFETCHED = 4,
43+
TRANSFAULT = 5,
44+
OKAYDIRTY = 6,
45+
RESERVED = 7,
46+
}
47+
48+
pub enum AXI_AXBURST_ENCODING : u2 {
49+
FIXED = 0,
50+
INCR = 1,
51+
WRAP = 2,
52+
RESERVED = 3,
53+
}
54+
55+
pub enum AXI_AWCACHE_ENCODING : u4 {
56+
DEV_NO_BUF = 0b0000,
57+
DEV_BUF = 0b0001,
58+
NON_C_NON_BUF = 0b0010,
59+
NON_C_BUF = 0b0011,
60+
WT_NO_ALLOC = 0b0110,
61+
WT_RD_ALLOC = 0b0110,
62+
WT_WR_ALLOC = 0b1110,
63+
WT_ALLOC = 0b1110,
64+
WB_NO_ALLOC = 0b0111,
65+
WB_RD_ALLOC = 0b0111,
66+
WB_WR_ALLOC = 0b1111,
67+
WB_ALLOC = 0b1111,
68+
}
69+
70+
pub enum AXI_ARCACHE_ENCODING : u4 {
71+
DEV_NO_BUF = 0b0000,
72+
DEV_BUF = 0b0001,
73+
NON_C_NON_BUF = 0b0010,
74+
NON_C_BUF = 0b0011,
75+
WT_NO_ALLOC = 0b1010,
76+
WT_RD_ALLOC = 0b1110,
77+
WT_WR_ALLOC = 0b1010,
78+
WT_ALLOC = 0b1110,
79+
WB_NO_ALLOC = 0b1011,
80+
WB_RD_ALLOC = 0b1111,
81+
WB_WR_ALLOC = 0b1011,
82+
WB_ALLOC = 0b1111,
83+
}
84+
85+
// AXI Write Request Channel Source Manager
86+
pub struct axi_aw_t<ID_W: u32, ADDR_W: u32> {
87+
awid: uN[ID_W],
88+
awaddr: uN[ADDR_W],
89+
awsize: AXI_AXSIZE_ENCODING,
90+
awprot: u3,
91+
}
92+
93+
// AXI Write Channel Source Manager
94+
pub struct axi_w_t<DATA_W: u32, STRB_W: u32> { wdata: uN[DATA_W], wstrb: uN[STRB_W], wlast: u1 }
95+
96+
// AXI Write Response (B) Channel Source Subordinate
97+
pub struct axi_b_t<ID_W: u32> { bresp: AXI_WRITE_RESPONSE_CODES, bid: uN[ID_W] }
98+
99+
// AXI Read Request Channel
100+
pub struct AR_channel<ID_W: u32, ADDR_W: u32> {
101+
arid: uN[ID_W],
102+
araddr: uN[ADDR_W],
103+
arregion: uN[4],
104+
arlen: uN[8],
105+
arsize: AXI_AXSIZE_ENCODING,
106+
arburst: AXI_AXBURST_ENCODING,
107+
arcache: AXI_ARCACHE_ENCODING,
108+
arprot: uN[3],
109+
arqos: uN[4],
110+
}
111+
112+
// AXI Read Response Channel
113+
pub struct R_channel<ID_W: u32, DATA_W: u32> {
114+
rid: uN[ID_W],
115+
rdata: uN[DATA_W],
116+
rresp: AXI_READ_RESPONSE_CODES,
117+
rlast: uN[1],
118+
}

0 commit comments

Comments
 (0)