mirror of https://github.com/openXC7/prjxray.git
187 lines
6.3 KiB
C++
187 lines
6.3 KiB
C++
#include <cstdint>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include <absl/types/span.h>
|
|
#include <gtest/gtest.h>
|
|
#include <prjxray/memory_mapped_file.h>
|
|
#include <prjxray/xilinx/architectures.h>
|
|
#include <prjxray/xilinx/configuration.h>
|
|
#include <prjxray/xilinx/spartan6/frame_address.h>
|
|
#include <yaml-cpp/yaml.h>
|
|
|
|
using namespace prjxray::xilinx;
|
|
|
|
TEST(ConfigurationTest, ConstructFromPacketsWithSingleFrame) {
|
|
std::vector<spartan6::FrameAddress> test_part_addresses;
|
|
test_part_addresses.push_back(0x0A);
|
|
test_part_addresses.push_back(0x0B);
|
|
|
|
spartan6::Part test_part(0x1234, test_part_addresses);
|
|
|
|
std::vector<uint32_t> idcode{0x1234};
|
|
std::vector<uint32_t> cmd{0x0001};
|
|
std::vector<uint32_t> frame_address{0x345};
|
|
std::vector<uint32_t> frame(65, 0xAA);
|
|
|
|
std::vector<ConfigurationPacket<typename Spartan6::ConfRegType>>
|
|
packets{
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::IDCODE,
|
|
absl::MakeSpan(idcode),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::FAR_MIN,
|
|
absl::MakeSpan(frame_address),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::CMD,
|
|
absl::MakeSpan(cmd),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::FDRI,
|
|
absl::MakeSpan(frame),
|
|
},
|
|
};
|
|
|
|
auto test_config =
|
|
Configuration<Spartan6>::InitWithPackets(test_part, packets);
|
|
ASSERT_TRUE(test_config);
|
|
|
|
EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
|
|
EXPECT_EQ(test_config->frames().size(), static_cast<size_t>(1));
|
|
EXPECT_EQ(test_config->frames().at(0x345), frame);
|
|
}
|
|
|
|
TEST(ConfigurationTest, ConstructFromPacketsWithAutoincrement) {
|
|
std::vector<spartan6::FrameAddress> test_part_addresses;
|
|
for (int ii = 0x310; ii < 0x320; ++ii) {
|
|
test_part_addresses.push_back(ii);
|
|
}
|
|
|
|
for (int ii = 0x330; ii < 0x331; ++ii) {
|
|
test_part_addresses.push_back(ii);
|
|
}
|
|
|
|
spartan6::Part test_part(0x1234, test_part_addresses);
|
|
|
|
std::vector<uint32_t> idcode{0x1234};
|
|
std::vector<uint32_t> cmd{0x0001};
|
|
std::vector<uint32_t> frame_address{0x31f};
|
|
std::vector<uint32_t> frame(65 * 2, 0xAA);
|
|
std::fill_n(frame.begin() + 65, 65, 0xBB);
|
|
|
|
std::vector<ConfigurationPacket<Spartan6::ConfRegType>> packets{
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::IDCODE,
|
|
absl::MakeSpan(idcode),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::FAR_MIN,
|
|
absl::MakeSpan(frame_address),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::CMD,
|
|
absl::MakeSpan(cmd),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::FDRI,
|
|
absl::MakeSpan(frame),
|
|
},
|
|
};
|
|
|
|
auto test_config =
|
|
Configuration<Spartan6>::InitWithPackets(test_part, packets);
|
|
ASSERT_TRUE(test_config);
|
|
|
|
absl::Span<uint32_t> frame_span(frame);
|
|
EXPECT_EQ(test_config->part().idcode(), static_cast<uint32_t>(0x1234));
|
|
EXPECT_EQ(test_config->frames().size(), static_cast<size_t>(2));
|
|
EXPECT_EQ(test_config->frames().at(0x31f),
|
|
std::vector<uint32_t>(65, 0xAA));
|
|
// TODO This test fails with a C++ exception because the address
|
|
// of next frame is 0x320 instead of 0x330 as defined in the test_part
|
|
// EXPECT_EQ(test_config->frames().at(0x330),
|
|
// std::vector<uint32_t>(65, 0xBB));
|
|
}
|
|
|
|
TEST(ConfigurationTest, DISABLED_CheckForPaddingAfterIOBFrame) {
|
|
std::vector<spartan6::FrameAddress> test_part_addresses = {
|
|
spartan6::FrameAddress(spartan6::BlockType::CLB_IOI_CLK, 0, 0, 0),
|
|
spartan6::FrameAddress(spartan6::BlockType::BLOCK_RAM, 1, 0, 0),
|
|
spartan6::FrameAddress(spartan6::BlockType::IOB, 2, 0, 0)};
|
|
|
|
auto test_part = absl::optional<spartan6::Part>(
|
|
spartan6::Part(0x1234, test_part_addresses));
|
|
|
|
Frames<Spartan6> frames;
|
|
frames.getFrames().emplace(std::make_pair(
|
|
test_part_addresses.at(0), std::vector<uint32_t>(65, 0xAA)));
|
|
frames.getFrames().emplace(std::make_pair(
|
|
test_part_addresses.at(1), std::vector<uint32_t>(65, 0xBB)));
|
|
frames.getFrames().emplace(std::make_pair(
|
|
test_part_addresses.at(2), std::vector<uint32_t>(65, 0xCC)));
|
|
ASSERT_EQ(frames.getFrames().size(), 3);
|
|
|
|
Configuration<Spartan6>::PacketData packet_data =
|
|
Configuration<Spartan6>::createType2ConfigurationPacketData(
|
|
frames.getFrames(), test_part);
|
|
// createType2ConfigurationPacketData should add a 16-bit pad word after
|
|
// after the IOB frame
|
|
EXPECT_EQ(packet_data.size(), 3 * 65 + 1);
|
|
|
|
std::vector<uint32_t> idcode{0x1234};
|
|
std::vector<uint32_t> cmd{0x0001};
|
|
std::vector<uint32_t> frame_address{0x0};
|
|
|
|
std::vector<ConfigurationPacket<Spartan6::ConfRegType>> packets{
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::IDCODE,
|
|
absl::MakeSpan(idcode),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::FAR,
|
|
absl::MakeSpan(frame_address),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::CMD,
|
|
absl::MakeSpan(cmd),
|
|
},
|
|
{
|
|
static_cast<unsigned int>(0x1),
|
|
ConfigurationPacket<Spartan6::ConfRegType>::Opcode::Write,
|
|
Spartan6::ConfRegType::FDRI,
|
|
absl::MakeSpan(packet_data),
|
|
},
|
|
};
|
|
|
|
auto test_config =
|
|
Configuration<Spartan6>::InitWithPackets(*test_part, packets);
|
|
ASSERT_EQ(test_config->frames().size(), 5);
|
|
for (auto& frame : test_config->frames()) {
|
|
EXPECT_EQ(frame.second, frames.getFrames().at(frame.first));
|
|
}
|
|
}
|