Skip to content

Commit 6d5d9be

Browse files
committed
xilinx: added xilinx 7 series architecture definitions and configuration packet
1 parent b14ce2e commit 6d5d9be

File tree

11 files changed

+717
-12
lines changed

11 files changed

+717
-12
lines changed

MODULE.bazel

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,5 @@ 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")
1919

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-
)
29-
3020
# compilation DB; build_cleaner
3121
bazel_dep(name = "bant", version = "0.1.14", dev_dependency = True)

fpga/assembler.cc

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

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: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
2+
3+
package(
4+
default_visibility = ["//:__subpackages__"],
5+
)
6+
7+
cc_library(
8+
name = "big-endian-span",
9+
hdrs = [
10+
"big-endian-span.h",
11+
],
12+
deps = [
13+
"@abseil-cpp//absl/types:span",
14+
],
15+
)
16+
17+
cc_test(
18+
name = "big-endian-span_test",
19+
srcs = [
20+
"big-endian-span_test.cc",
21+
],
22+
deps = [
23+
":big-endian-span",
24+
"@googletest//:gtest",
25+
"@googletest//:gtest_main",
26+
],
27+
)
28+
29+
cc_library(
30+
name = "bit-ops",
31+
hdrs = [
32+
"bit-ops.h",
33+
],
34+
)
35+
36+
cc_test(
37+
name = "bit-ops_test",
38+
srcs = [
39+
"bit-ops_test.cc",
40+
],
41+
deps = [
42+
":bit-ops",
43+
"@googletest//:gtest",
44+
"@googletest//:gtest_main",
45+
],
46+
)
47+
48+
cc_library(
49+
name = "architecture-xc7",
50+
srcs = [
51+
"architecture-xc7.cc",
52+
],
53+
hdrs = [
54+
"architecture-xc7.h",
55+
],
56+
deps = [
57+
":bit-ops",
58+
":configuration-packet",
59+
"@abseil-cpp//absl/types:span",
60+
],
61+
)
62+
63+
cc_library(
64+
name = "configuration-packet",
65+
hdrs = [
66+
"configuration-packet.h",
67+
],
68+
deps = [
69+
"@abseil-cpp//absl/types:optional",
70+
"@abseil-cpp//absl/types:span",
71+
],
72+
)

fpga/xilinx/architecture-xc7.cc

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "architecture-xc7.h"
2+
3+
#include <cstdint>
4+
#include <optional>
5+
#include <ostream>
6+
7+
#include "absl/types/span.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+
std::ostream &operator<<(std::ostream &o, const ConfigurationRegister &value) {
15+
switch (value) {
16+
case ConfigurationRegister::kCRC: return o << "CRC";
17+
case ConfigurationRegister::kFAR: return o << "Frame Address";
18+
case ConfigurationRegister::kFDRI: return o << "Frame Data Input";
19+
case ConfigurationRegister::kFDRO: return o << "Frame Data Output";
20+
case ConfigurationRegister::kCMD: return o << "Command";
21+
case ConfigurationRegister::kCTL0: return o << "Control 0";
22+
case ConfigurationRegister::kMASK: return o << "Mask for CTL0 and CTL1";
23+
case ConfigurationRegister::kSTAT: return o << "Status";
24+
case ConfigurationRegister::kLOUT: return o << "Legacy Output";
25+
case ConfigurationRegister::kCOR0: return o << "Configuration Option 0";
26+
case ConfigurationRegister::kMFWR: return o << "Multiple Frame Write";
27+
case ConfigurationRegister::kCBC: return o << "Initial CBC Value";
28+
case ConfigurationRegister::kIDCODE: return o << "Device ID";
29+
case ConfigurationRegister::kAXSS: return o << "User Access";
30+
case ConfigurationRegister::kCOR1: return o << "Configuration Option 1";
31+
case ConfigurationRegister::kWBSTAR: return o << "Warm Boot Start Address";
32+
case ConfigurationRegister::kTIMER: return o << "Watchdog Timer";
33+
case ConfigurationRegister::kBOOTSTS: return o << "Boot History Status";
34+
case ConfigurationRegister::kCTL1: return o << "Control 1";
35+
case ConfigurationRegister::kBSPI:
36+
return o << "BPI/SPI Configuration Options";
37+
default: return o << "Unknown";
38+
}
39+
}
40+
41+
ConfigurationPacket::ParseResult ConfigurationPacket::InitWithWordsImpl(
42+
absl::Span<uint32_t> words, const ConfigurationPacket *previous_packet) {
43+
using ConfigurationRegister = ConfigurationRegister;
44+
// Need at least one 32-bit word to have a valid packet header.
45+
if (words.empty() < 1) {
46+
return {words, {}};
47+
}
48+
const ConfigurationPacketType header_type =
49+
static_cast<ConfigurationPacketType>(bit_field_get(words[0], 31, 29));
50+
switch (header_type) {
51+
case ConfigurationPacketType::kNONE:
52+
// Type 0 is emitted at the end of a configuration row
53+
// when BITSTREAM.GENERAL.DEBUGBITSTREAM is set to YES.
54+
// These seem to be padding that are interepreted as
55+
// NOPs. Since Type 0 packets don't exist according to
56+
// UG470 and they seem to be zero-filled, just consume
57+
// the bytes without generating a packet.
58+
return {words.subspan(1),
59+
{{static_cast<uint32_t>(header_type),
60+
Opcode::kNOP,
61+
ConfigurationRegister::kCRC,
62+
{}}}};
63+
case ConfigurationPacketType::kTYPE1: {
64+
const Opcode opcode = static_cast<Opcode>(bit_field_get(words[0], 28, 27));
65+
const ConfigurationRegister address =
66+
static_cast<ConfigurationRegister>(bit_field_get(words[0], 26, 13));
67+
const uint32_t data_word_count = bit_field_get(words[0], 10, 0);
68+
69+
// If the full packet has not been received, return as
70+
// though no valid packet was found.
71+
if (data_word_count > words.size() - 1) {
72+
return {words, {}};
73+
}
74+
75+
return {words.subspan(data_word_count + 1),
76+
{{static_cast<uint32_t>(header_type), opcode, address,
77+
words.subspan(1, data_word_count)}}};
78+
}
79+
case ConfigurationPacketType::kTYPE2: {
80+
std::optional<ConfigurationPacket> packet;
81+
const Opcode opcode = static_cast<Opcode>(bit_field_get(words[0], 28, 27));
82+
const uint32_t data_word_count = bit_field_get(words[0], 26, 0);
83+
84+
// If the full packet has not been received, return as
85+
// though no valid packet was found.
86+
if (data_word_count > words.size() - 1) {
87+
return {words, {}};
88+
}
89+
90+
if (previous_packet) {
91+
packet = ConfigurationPacket(static_cast<uint32_t>(header_type), opcode,
92+
previous_packet->address(),
93+
words.subspan(1, data_word_count));
94+
}
95+
96+
return {words.subspan(data_word_count + 1), packet};
97+
}
98+
default: return {{}, {}};
99+
}
100+
}
101+
} // namespace xc7
102+
} // namespace xilinx
103+
} // namespace fpga

fpga/xilinx/architecture-xc7.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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_ARCHITECTURE_H
11+
#define FPGA_XILINX_ARCHITECTURE_H
12+
13+
#include <cstdint>
14+
#include <memory>
15+
#include <ostream>
16+
#include <vector>
17+
18+
#include "absl/types/span.h"
19+
#include "fpga/xilinx/configuration-packet.h"
20+
21+
namespace fpga {
22+
namespace xilinx {
23+
namespace xc7 {
24+
// Series-7 configuration register addresses
25+
// according to UG470, pg. 109
26+
enum class ConfigurationRegister : unsigned int {
27+
kCRC = 0x00,
28+
kFAR = 0x01,
29+
kFDRI = 0x02,
30+
kFDRO = 0x03,
31+
kCMD = 0x04,
32+
kCTL0 = 0x05,
33+
kMASK = 0x06,
34+
kSTAT = 0x07,
35+
kLOUT = 0x08,
36+
kCOR0 = 0x09,
37+
kMFWR = 0x0a,
38+
kCBC = 0x0b,
39+
kIDCODE = 0x0c,
40+
kAXSS = 0x0d,
41+
kCOR1 = 0x0e,
42+
kWBSTAR = 0x10,
43+
kTIMER = 0x11,
44+
kUNKNOWN = 0x13,
45+
kBOOTSTS = 0x16,
46+
kCTL1 = 0x18,
47+
kBSPI = 0x1F,
48+
};
49+
50+
std::ostream &operator<<(std::ostream &o, const ConfigurationRegister &value);
51+
52+
enum class Architecture {
53+
kBase,
54+
kUltrascale,
55+
kUltrascalePlus,
56+
};
57+
58+
template <Architecture arch>
59+
struct frame_words_count;
60+
61+
template <>
62+
struct frame_words_count<Architecture::kBase> {
63+
static constexpr int value = 101;
64+
};
65+
66+
template <>
67+
struct frame_words_count<Architecture::kUltrascale> {
68+
static constexpr int value = 123;
69+
};
70+
71+
template <>
72+
struct frame_words_count<Architecture::kUltrascalePlus> {
73+
static constexpr int value = 93;
74+
};
75+
76+
template <Architecture arch>
77+
using frame_words_count_v = frame_words_count<arch>::value;
78+
79+
struct Part {};
80+
81+
class ConfigurationPacket
82+
: public ConfigurationPacketBase<ConfigurationRegister,
83+
ConfigurationPacket> {
84+
private:
85+
using BaseType =
86+
ConfigurationPacketBase<ConfigurationRegister, ConfigurationPacket>;
87+
88+
public:
89+
using BaseType::BaseType;
90+
91+
private:
92+
friend BaseType;
93+
static ParseResult InitWithWordsImpl(
94+
absl::Span<uint32_t> words,
95+
const ConfigurationPacket *previous_packet = nullptr);
96+
};
97+
98+
using ConfigurationPackage = std::vector<std::unique_ptr<ConfigurationPacket>>;
99+
} // namespace xc7
100+
} // namespace xilinx
101+
} // namespace fpga
102+
#endif // FPGA_XILINX_ARCHITECTURE_H

0 commit comments

Comments
 (0)