Skip to content

Commit 2a32286

Browse files
committed
xilinx: added xilinx 7 series architecture definitions and configuration packet
1 parent 2f49a1c commit 2a32286

23 files changed

+1915
-20
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ jobs:
6262

6363
- name: Install Dependencies
6464
run: |
65-
sudo apt-get install clang-format-18
65+
sudo apt-get install clang-format-17
6666
6767
- name: Run formatting style check
6868
run: |
69-
clang-format-18 --version
70-
RUNNING_IN_CI=1 CLANG_FORMAT=clang-format-18 \
69+
clang-format-17 --version
70+
RUNNING_IN_CI=1 CLANG_FORMAT=clang-format-17 \
7171
scripts/run-clang-format.sh
7272
7373
ClangTidy:

MODULE.bazel

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,7 @@ git_override(
1616
bazel_dep(name = "abseil-cpp", version = "20240722.0.bcr.2")
1717
bazel_dep(name = "googletest", version = "1.15.2")
1818
bazel_dep(name = "rapidjson", version = "1.1.0.bcr.20241007")
19-
20-
## C/C++ deps from local registry.
21-
bazel_dep(name = "prjxray", version = "0.0-583-t1e53270")
22-
git_override(
23-
module_name = "prjxray",
24-
commit = "3a95169e555de315c6b4cb71249107972d944303",
25-
patch_strip = 1,
26-
patches = ["//bazel:prjxray-add-module-bazel.patch"],
27-
remote = "https://github.com/f4pga/prjxray.git",
28-
)
19+
bazel_dep(name = "rules_license", version = "1.0.0")
2920

3021
# compilation DB; build_cleaner
3122
bazel_dep(name = "bant", version = "0.1.14", dev_dependency = True)

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ or install in system directory that requires root-access:
3030
sudo install -D --strip bazel-bin/fpga/fpga-as /usr/local/bin/fpga-as
3131
```
3232

33-
[fasm-spec]: https://fasm.readthedocs.io/en/stable/#
34-
[bazel]: https://bazel.build/
35-
[counter-example]: https://github.com/chipsalliance/f4pga-examples/blob/13f11197b33dae1cde3bf146f317d63f0134eacf/xc7/counter_test/counter.v
36-
3733
# How it works
3834

3935
## Frames generation
@@ -59,3 +55,7 @@ The next step is to locate the tile metadata in the FPGA fabric's `tilegrid.json
5955
* offset: `77`
6056

6157
Using this metadata, you can search the segbits database for the specific feature. By matching the tile_type and the FASM feature name, you can identify the correct configuration bits in the tile type segbits file (`segbits_clblm_r.db`). In this case, you would look for the entry corresponding to CLBLM_R.SLICEM_X0.ALUT.INIT and find the entry for address `[34]`. The value 34_06 then provides the coordinates for the word index and the specific bit index to be set.
58+
59+
[fasm-spec]: https://fasm.readthedocs.io/en/stable/#
60+
[bazel]: https://bazel.build/
61+
[counter-example]: https://github.com/chipsalliance/f4pga-examples/blob/13f11197b33dae1cde3bf146f317d63f0134eacf/xc7/counter_test/counter.v

fpga/assembler.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ int main(int argc, char *argv[]) {
430430
<< '\n';
431431
return EXIT_FAILURE;
432432
}
433-
434433
PrintFrames(frames, std::cout, false);
434+
// Write bitstream
435435
return EXIT_SUCCESS;
436436
}

fpga/database-parsers_test.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "gtest/gtest.h"
1111

1212
namespace fpga {
13-
1413
template <typename Sink>
1514
void AbslStringify(Sink &sink, const TileFeature &e) {
1615
absl::Format(&sink, "(tile_feature=\"%s\", address=%d)", e.tile_feature,

fpga/xilinx/BUILD

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
2+
load("@rules_license//rules:license.bzl", "license")
3+
4+
package(
5+
default_applicable_licenses = [":license"],
6+
default_visibility = ["//:__subpackages__"],
7+
)
8+
9+
license(
10+
name = "license",
11+
package_name = "xilinx",
12+
license_kind = "@rules_license//licenses/spdx:ISC",
13+
)
14+
15+
cc_library(
16+
name = "big-endian-span",
17+
hdrs = [
18+
"big-endian-span.h",
19+
],
20+
deps = [
21+
"@abseil-cpp//absl/types:span",
22+
],
23+
)
24+
25+
cc_test(
26+
name = "big-endian-span_test",
27+
srcs = [
28+
"big-endian-span_test.cc",
29+
],
30+
deps = [
31+
":big-endian-span",
32+
"@googletest//:gtest",
33+
"@googletest//:gtest_main",
34+
],
35+
)
36+
37+
cc_library(
38+
name = "bit-ops",
39+
hdrs = [
40+
"bit-ops.h",
41+
],
42+
)
43+
44+
cc_test(
45+
name = "bit-ops_test",
46+
srcs = [
47+
"bit-ops_test.cc",
48+
],
49+
deps = [
50+
":bit-ops",
51+
"@googletest//:gtest",
52+
"@googletest//:gtest_main",
53+
],
54+
)
55+
56+
cc_library(
57+
name = "configuration-packet",
58+
hdrs = [
59+
"configuration-packet.h",
60+
],
61+
deps = [
62+
"@abseil-cpp//absl/types:optional",
63+
"@abseil-cpp//absl/types:span",
64+
],
65+
)
66+
67+
cc_library(
68+
name = "arch-xc7-defs",
69+
srcs = [
70+
"arch-xc7-defs.cc",
71+
],
72+
hdrs = [
73+
"arch-xc7-defs.h",
74+
],
75+
)
76+
77+
cc_library(
78+
name = "arch-xc7-configuration-packet",
79+
srcs = [
80+
"arch-xc7-configuration-packet.cc",
81+
],
82+
hdrs = [
83+
"arch-xc7-configuration-packet.h",
84+
],
85+
deps = [
86+
":arch-xc7-defs",
87+
":bit-ops",
88+
":configuration-packet",
89+
"@abseil-cpp//absl/types:span",
90+
],
91+
)
92+
93+
cc_test(
94+
name = "arch-xc7-configuration-packet_test",
95+
srcs = [
96+
"arch-xc7-configuration-packet_test.cc",
97+
],
98+
deps = [
99+
":arch-xc7-configuration-packet",
100+
":arch-xc7-defs",
101+
":bit-ops",
102+
"@abseil-cpp//absl/types:span",
103+
"@googletest//:gtest",
104+
"@googletest//:gtest_main",
105+
],
106+
)
107+
108+
cc_library(
109+
name = "arch-xc7-frame-address",
110+
srcs = [
111+
"arch-xc7-frame-address.cc",
112+
],
113+
hdrs = [
114+
"arch-xc7-frame-address.h",
115+
],
116+
deps = [
117+
":arch-xc7-defs",
118+
":bit-ops",
119+
],
120+
)
121+
122+
cc_library(
123+
name = "arch-xc7-part",
124+
srcs = [
125+
"arch-xc7-part.cc",
126+
],
127+
hdrs = [
128+
"arch-xc7-part.h",
129+
],
130+
deps = [
131+
":arch-xc7-defs",
132+
":arch-xc7-frame-address",
133+
],
134+
)
135+
136+
cc_test(
137+
name = "arch-xc7-part_test",
138+
srcs = [
139+
"arch-xc7-part_test.cc",
140+
],
141+
deps = [
142+
":arch-xc7-defs",
143+
":arch-xc7-frame-address",
144+
":arch-xc7-part",
145+
"@googletest//:gtest",
146+
"@googletest//:gtest_main",
147+
],
148+
)

fpga/xilinx/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Xilinx Bitstream Generation
2+
3+
Most of this code originates from [prjxray][prjxray]. It was imported into this repository to simplify type interfacing and eliminate the dependency on yaml-cpp, which requires exceptions to be enabled.
4+
5+
[prjxray]: https://github.com/f4pga/prjxray/tree/faf9c774a340e39cf6802d009996ed6016e63521/lib
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include "fpga/xilinx/arch-xc7-configuration-packet.h"
2+
3+
#include <cstdint>
4+
#include <optional>
5+
6+
#include "absl/types/span.h"
7+
#include "fpga/xilinx/arch-xc7-defs.h"
8+
#include "fpga/xilinx/bit-ops.h"
9+
#include "fpga/xilinx/configuration-packet.h"
10+
11+
namespace fpga {
12+
namespace xilinx {
13+
namespace xc7 {
14+
ConfigurationPacket::ParseResult ConfigurationPacket::InitWithWordsImpl(
15+
absl::Span<uint32_t> words, const ConfigurationPacket *previous_packet) {
16+
using ConfigurationRegister = ConfigurationRegister;
17+
// Need at least one 32-bit word to have a valid packet header.
18+
if (words.empty()) {
19+
return {words, {}};
20+
}
21+
const ConfigurationPacketType header_type =
22+
static_cast<ConfigurationPacketType>(bit_field_get(words[0], 31, 29));
23+
switch (header_type) {
24+
case ConfigurationPacketType::kNONE:
25+
// Type 0 is emitted at the end of a configuration row
26+
// when BITSTREAM.GENERAL.DEBUGBITSTREAM is set to YES.
27+
// These seem to be padding that are interepreted as
28+
// NOPs. Since Type 0 packets don't exist according to
29+
// UG470 and they seem to be zero-filled, just consume
30+
// the bytes without generating a packet.
31+
return {words.subspan(1),
32+
{{static_cast<uint32_t>(header_type),
33+
Opcode::kNOP,
34+
ConfigurationRegister::kCRC,
35+
{}}}};
36+
case ConfigurationPacketType::kTYPE1: {
37+
const Opcode opcode = static_cast<Opcode>(bit_field_get(words[0], 28, 27));
38+
const ConfigurationRegister address =
39+
static_cast<ConfigurationRegister>(bit_field_get(words[0], 26, 13));
40+
const uint32_t data_word_count = bit_field_get(words[0], 10, 0);
41+
42+
// If the full packet has not been received, return as
43+
// though no valid packet was found.
44+
if (data_word_count > words.size() - 1) {
45+
return {words, {}};
46+
}
47+
48+
return {words.subspan(data_word_count + 1),
49+
{{static_cast<uint32_t>(header_type), opcode, address,
50+
words.subspan(1, data_word_count)}}};
51+
}
52+
case ConfigurationPacketType::kTYPE2: {
53+
std::optional<ConfigurationPacket> packet;
54+
const Opcode opcode = static_cast<Opcode>(bit_field_get(words[0], 28, 27));
55+
const uint32_t data_word_count = bit_field_get(words[0], 26, 0);
56+
57+
// If the full packet has not been received, return as
58+
// though no valid packet was found.
59+
if (data_word_count > words.size() - 1) {
60+
return {words, {}};
61+
}
62+
63+
if (previous_packet) {
64+
packet = ConfigurationPacket(static_cast<uint32_t>(header_type), opcode,
65+
previous_packet->address(),
66+
words.subspan(1, data_word_count));
67+
}
68+
69+
return {words.subspan(data_word_count + 1), packet};
70+
}
71+
default: return {{}, {}};
72+
}
73+
}
74+
} // namespace xc7
75+
} // namespace xilinx
76+
} // namespace fpga
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (C) 2017-2020 The Project X-Ray Authors.
3+
*
4+
* Use of this source code is governed by a ISC-style
5+
* license that can be found in the LICENSE file or at
6+
* https://opensource.org/licenses/ISC
7+
*
8+
* SPDX-License-Identifier: ISC
9+
*/
10+
#ifndef FPGA_XILINX_ARCH_XC7_CONFIGURATION_PACKET_H
11+
#define FPGA_XILINX_ARCH_XC7_CONFIGURATION_PACKET_H
12+
13+
#include <cstdint>
14+
#include <memory>
15+
#include <vector>
16+
17+
#include "absl/types/span.h"
18+
#include "fpga/xilinx/arch-xc7-defs.h"
19+
#include "fpga/xilinx/configuration-packet.h"
20+
21+
namespace fpga {
22+
namespace xilinx {
23+
namespace xc7 {
24+
class ConfigurationPacket
25+
: public ConfigurationPacketBase<ConfigurationRegister,
26+
ConfigurationPacket> {
27+
private:
28+
using BaseType =
29+
ConfigurationPacketBase<ConfigurationRegister, ConfigurationPacket>;
30+
31+
public:
32+
using BaseType::BaseType;
33+
34+
private:
35+
friend BaseType;
36+
static ParseResult InitWithWordsImpl(
37+
absl::Span<uint32_t> words,
38+
const ConfigurationPacket *previous_packet = nullptr);
39+
};
40+
41+
using ConfigurationPackage = std::vector<std::unique_ptr<ConfigurationPacket>>;
42+
} // namespace xc7
43+
} // namespace xilinx
44+
} // namespace fpga
45+
#endif // FPGA_XILINX_ARCH_XC7_CONFIGURATION_PACKET_H

0 commit comments

Comments
 (0)