Skip to content

xilinx: added xilinx 7 series architecture definitions and configurat… #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ jobs:

- name: Install Dependencies
run: |
sudo apt-get install clang-format-18
sudo apt-get install clang-format-17

- name: Run formatting style check
run: |
clang-format-18 --version
RUNNING_IN_CI=1 CLANG_FORMAT=clang-format-18 \
clang-format-17 --version
RUNNING_IN_CI=1 CLANG_FORMAT=clang-format-17 \
scripts/run-clang-format.sh

ClangTidy:
Expand Down
11 changes: 1 addition & 10 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,7 @@ git_override(
bazel_dep(name = "abseil-cpp", version = "20240722.0.bcr.2")
bazel_dep(name = "googletest", version = "1.15.2")
bazel_dep(name = "rapidjson", version = "1.1.0.bcr.20241007")

## C/C++ deps from local registry.
bazel_dep(name = "prjxray", version = "0.0-583-t1e53270")
git_override(
module_name = "prjxray",
commit = "3a95169e555de315c6b4cb71249107972d944303",
patch_strip = 1,
patches = ["//bazel:prjxray-add-module-bazel.patch"],
remote = "https://github.com/f4pga/prjxray.git",
)
bazel_dep(name = "rules_license", version = "1.0.0")

# compilation DB; build_cleaner
bazel_dep(name = "bant", version = "0.1.14", dev_dependency = True)
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ or install in system directory that requires root-access:
sudo install -D --strip bazel-bin/fpga/fpga-as /usr/local/bin/fpga-as
```

[fasm-spec]: https://fasm.readthedocs.io/en/stable/#
[bazel]: https://bazel.build/
[counter-example]: https://github.com/chipsalliance/f4pga-examples/blob/13f11197b33dae1cde3bf146f317d63f0134eacf/xc7/counter_test/counter.v

# How it works

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

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.

[fasm-spec]: https://fasm.readthedocs.io/en/stable/#
[bazel]: https://bazel.build/
[counter-example]: https://github.com/chipsalliance/f4pga-examples/blob/13f11197b33dae1cde3bf146f317d63f0134eacf/xc7/counter_test/counter.v
2 changes: 1 addition & 1 deletion fpga/assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ int main(int argc, char *argv[]) {
<< '\n';
return EXIT_FAILURE;
}

PrintFrames(frames, std::cout, false);
// Write bitstream
return EXIT_SUCCESS;
}
1 change: 0 additions & 1 deletion fpga/database-parsers_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "gtest/gtest.h"

namespace fpga {

template <typename Sink>
void AbslStringify(Sink &sink, const TileFeature &e) {
absl::Format(&sink, "(tile_feature=\"%s\", address=%d)", e.tile_feature,
Expand Down
148 changes: 148 additions & 0 deletions fpga/xilinx/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_license//rules:license.bzl", "license")

package(
default_applicable_licenses = [":license"],
default_visibility = ["//:__subpackages__"],
)

license(
name = "license",
package_name = "xilinx",
license_kind = "@rules_license//licenses/spdx:ISC",
)

cc_library(
name = "big-endian-span",
hdrs = [
"big-endian-span.h",
],
deps = [
"@abseil-cpp//absl/types:span",
],
)

cc_test(
name = "big-endian-span_test",
srcs = [
"big-endian-span_test.cc",
],
deps = [
":big-endian-span",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
)

cc_library(
name = "bit-ops",
hdrs = [
"bit-ops.h",
],
)

cc_test(
name = "bit-ops_test",
srcs = [
"bit-ops_test.cc",
],
deps = [
":bit-ops",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
)

cc_library(
name = "configuration-packet",
hdrs = [
"configuration-packet.h",
],
deps = [
"@abseil-cpp//absl/types:optional",
"@abseil-cpp//absl/types:span",
],
)

cc_library(
name = "arch-xc7-defs",
srcs = [
"arch-xc7-defs.cc",
],
hdrs = [
"arch-xc7-defs.h",
],
)

cc_library(
name = "arch-xc7-configuration-packet",
srcs = [
"arch-xc7-configuration-packet.cc",
],
hdrs = [
"arch-xc7-configuration-packet.h",
],
deps = [
":arch-xc7-defs",
":bit-ops",
":configuration-packet",
"@abseil-cpp//absl/types:span",
],
)

cc_test(
name = "arch-xc7-configuration-packet_test",
srcs = [
"arch-xc7-configuration-packet_test.cc",
],
deps = [
":arch-xc7-configuration-packet",
":arch-xc7-defs",
":bit-ops",
"@abseil-cpp//absl/types:span",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
)

cc_library(
name = "arch-xc7-frame-address",
srcs = [
"arch-xc7-frame-address.cc",
],
hdrs = [
"arch-xc7-frame-address.h",
],
deps = [
":arch-xc7-defs",
":bit-ops",
],
)

cc_library(
name = "arch-xc7-part",
srcs = [
"arch-xc7-part.cc",
],
hdrs = [
"arch-xc7-part.h",
],
deps = [
":arch-xc7-defs",
":arch-xc7-frame-address",
],
)

cc_test(
name = "arch-xc7-part_test",
srcs = [
"arch-xc7-part_test.cc",
],
deps = [
":arch-xc7-defs",
":arch-xc7-frame-address",
":arch-xc7-part",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
)
5 changes: 5 additions & 0 deletions fpga/xilinx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Xilinx Bitstream Generation

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.

[prjxray]: https://github.com/f4pga/prjxray/tree/faf9c774a340e39cf6802d009996ed6016e63521/lib
76 changes: 76 additions & 0 deletions fpga/xilinx/arch-xc7-configuration-packet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "fpga/xilinx/arch-xc7-configuration-packet.h"

#include <cstdint>
#include <optional>

#include "absl/types/span.h"
#include "fpga/xilinx/arch-xc7-defs.h"
#include "fpga/xilinx/bit-ops.h"
#include "fpga/xilinx/configuration-packet.h"

namespace fpga {
namespace xilinx {
namespace xc7 {
ConfigurationPacket::ParseResult ConfigurationPacket::InitWithWordsImpl(
absl::Span<uint32_t> words, const ConfigurationPacket *previous_packet) {
using ConfigurationRegister = ConfigurationRegister;
// Need at least one 32-bit word to have a valid packet header.
if (words.empty()) {
return {words, {}};
}
const ConfigurationPacketType header_type =
static_cast<ConfigurationPacketType>(bit_field_get(words[0], 31, 29));
switch (header_type) {
case ConfigurationPacketType::kNONE:
// Type 0 is emitted at the end of a configuration row
// when BITSTREAM.GENERAL.DEBUGBITSTREAM is set to YES.
// These seem to be padding that are interepreted as
// NOPs. Since Type 0 packets don't exist according to
// UG470 and they seem to be zero-filled, just consume
// the bytes without generating a packet.
return {words.subspan(1),
{{static_cast<uint32_t>(header_type),
Opcode::kNOP,
ConfigurationRegister::kCRC,
{}}}};
case ConfigurationPacketType::kTYPE1: {
const Opcode opcode = static_cast<Opcode>(bit_field_get(words[0], 28, 27));
const ConfigurationRegister address =
static_cast<ConfigurationRegister>(bit_field_get(words[0], 26, 13));
const uint32_t data_word_count = bit_field_get(words[0], 10, 0);

// If the full packet has not been received, return as
// though no valid packet was found.
if (data_word_count > words.size() - 1) {
return {words, {}};
}

return {words.subspan(data_word_count + 1),
{{static_cast<uint32_t>(header_type), opcode, address,
words.subspan(1, data_word_count)}}};
}
case ConfigurationPacketType::kTYPE2: {
std::optional<ConfigurationPacket> packet;
const Opcode opcode = static_cast<Opcode>(bit_field_get(words[0], 28, 27));
const uint32_t data_word_count = bit_field_get(words[0], 26, 0);

// If the full packet has not been received, return as
// though no valid packet was found.
if (data_word_count > words.size() - 1) {
return {words, {}};
}

if (previous_packet) {
packet = ConfigurationPacket(static_cast<uint32_t>(header_type), opcode,
previous_packet->address(),
words.subspan(1, data_word_count));
}

return {words.subspan(data_word_count + 1), packet};
}
default: return {{}, {}};
}
}
} // namespace xc7
} // namespace xilinx
} // namespace fpga
45 changes: 45 additions & 0 deletions fpga/xilinx/arch-xc7-configuration-packet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2017-2020 The Project X-Ray Authors.
*
* Use of this source code is governed by a ISC-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/ISC
*
* SPDX-License-Identifier: ISC
*/
#ifndef FPGA_XILINX_ARCH_XC7_CONFIGURATION_PACKET_H
#define FPGA_XILINX_ARCH_XC7_CONFIGURATION_PACKET_H

#include <cstdint>
#include <memory>
#include <vector>

#include "absl/types/span.h"
#include "fpga/xilinx/arch-xc7-defs.h"
#include "fpga/xilinx/configuration-packet.h"

namespace fpga {
namespace xilinx {
namespace xc7 {
class ConfigurationPacket
: public ConfigurationPacketBase<ConfigurationRegister,
ConfigurationPacket> {
private:
using BaseType =
ConfigurationPacketBase<ConfigurationRegister, ConfigurationPacket>;

public:
using BaseType::BaseType;

private:
friend BaseType;
static ParseResult InitWithWordsImpl(
absl::Span<uint32_t> words,
const ConfigurationPacket *previous_packet = nullptr);
};

using ConfigurationPackage = std::vector<std::unique_ptr<ConfigurationPacket>>;
} // namespace xc7
} // namespace xilinx
} // namespace fpga
#endif // FPGA_XILINX_ARCH_XC7_CONFIGURATION_PACKET_H
Loading