Pack/unpack PLL related configuration
This commit is contained in:
parent
97cb94755f
commit
246ddc9c11
|
|
@ -53,6 +53,7 @@ class ChipConfig
|
|||
string chip_package;
|
||||
std::map<CfgLoc, TileConfig> tiles;
|
||||
std::map<CfgLoc, TileConfig> brams;
|
||||
std::map<int, TileConfig> plls;
|
||||
|
||||
// Block RAM initialisation
|
||||
std::map<CfgLoc, std::vector<uint8_t>> bram_data;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class Die
|
|||
static constexpr int LATCH_BLOCK_SIZE = 112;
|
||||
static constexpr int RAM_BLOCK_SIZE = 27;
|
||||
static constexpr int MEMORY_SIZE = 5120;
|
||||
static constexpr int PLL_CONFIG_SIZE = 12 * 8 + 4 + 8;
|
||||
|
||||
public:
|
||||
explicit Die();
|
||||
|
|
@ -51,19 +52,24 @@ class Die
|
|||
bool is_latch_empty(int x, int y) const;
|
||||
bool is_ram_empty(int x, int y) const;
|
||||
bool is_ram_data_empty(int x, int y) const;
|
||||
bool is_pll_cfg_empty(int index) const;
|
||||
|
||||
void write_latch(int x, int y, const std::vector<uint8_t> &data);
|
||||
void write_ram(int x, int y, const std::vector<uint8_t> &data);
|
||||
void write_ram_data(int x, int y, const std::vector<uint8_t> &data, uint16_t addr);
|
||||
void write_pll_select(uint8_t select, const std::vector<uint8_t> &data);
|
||||
void write_pll(const std::vector<uint8_t> &data) { pll_cfg = data; }
|
||||
|
||||
const std::vector<uint8_t> get_latch_config(int x, int y) const { return latch.at(std::make_pair(x, y)); }
|
||||
const std::vector<uint8_t> get_ram_config(int x, int y) const { return ram.at(std::make_pair(x, y)); }
|
||||
const std::vector<uint8_t> get_ram_data(int x, int y) const { return ram_data.at(std::make_pair(x, y)); }
|
||||
const std::vector<uint8_t> get_pll_config() const { return pll_cfg; }
|
||||
|
||||
private:
|
||||
std::map<std::pair<int, int>, std::vector<uint8_t>> latch; // Config latches
|
||||
std::map<std::pair<int, int>, std::vector<uint8_t>> ram; // Config RAM
|
||||
std::map<std::pair<int, int>, std::vector<uint8_t>> ram_data; // RAM data content FRAM
|
||||
std::vector<uint8_t> pll_cfg; // Config for all PLLs, CLKIN and GLBOUT
|
||||
};
|
||||
|
||||
} // namespace GateMate
|
||||
|
|
|
|||
|
|
@ -86,6 +86,12 @@ class RamBitDatabase : public BaseBitDatabase
|
|||
RamBitDatabase();
|
||||
};
|
||||
|
||||
class PLLBitDatabase : public BaseBitDatabase
|
||||
{
|
||||
public:
|
||||
PLLBitDatabase();
|
||||
};
|
||||
|
||||
class DatabaseConflictError : public runtime_error
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ class BitstreamReadWriter
|
|||
insert_crc16();
|
||||
}
|
||||
|
||||
void write_cmd_pll()
|
||||
void write_cmd_pll_empty()
|
||||
{
|
||||
write_header(CMD_PLL, 12);
|
||||
for (int i = 0; i < 12; i++)
|
||||
|
|
@ -323,6 +323,17 @@ class BitstreamReadWriter
|
|||
insert_crc16();
|
||||
write_nops(6);
|
||||
}
|
||||
|
||||
void write_cmd_pll(int index, std::vector<uint8_t> data)
|
||||
{
|
||||
write_header(CMD_PLL, 24);
|
||||
for (int i = 0; i < 12; i++)
|
||||
write_byte(data[i + index * 12]);
|
||||
for (int i = 12 * 8; i < 12 * 8 + 12; i++)
|
||||
write_byte(data[i]);
|
||||
insert_crc16();
|
||||
write_nops(6);
|
||||
}
|
||||
};
|
||||
|
||||
void check_crc(BitstreamReadWriter &rd)
|
||||
|
|
@ -371,6 +382,7 @@ Chip Bitstream::deserialise_chip()
|
|||
BitstreamReadWriter rd(data);
|
||||
bool is_block_ram = false;
|
||||
uint8_t x_pos = 0, y_pos = 0;
|
||||
uint8_t pll_select = 0x0f;
|
||||
uint16_t aclcu = 0;
|
||||
while (!rd.is_end()) {
|
||||
rd.crc16.reset_crc16();
|
||||
|
|
@ -423,7 +435,7 @@ Chip Bitstream::deserialise_chip()
|
|||
// Check header CRC
|
||||
check_crc(rd);
|
||||
// Read data block
|
||||
rd.get_byte();
|
||||
pll_select = rd.get_byte();
|
||||
// Check data CRC
|
||||
check_crc(rd);
|
||||
break;
|
||||
|
|
@ -438,6 +450,7 @@ Chip Bitstream::deserialise_chip()
|
|||
|
||||
// Read data block
|
||||
rd.get_vector(block, length);
|
||||
die.write_pll_select(pll_select, block);
|
||||
// Check data CRC
|
||||
check_crc(rd);
|
||||
|
||||
|
|
@ -576,8 +589,25 @@ Bitstream Bitstream::serialise_chip(const Chip &chip)
|
|||
{
|
||||
BitstreamReadWriter wr;
|
||||
wr.write_cmd_path(0x10);
|
||||
wr.write_cmd_pll();
|
||||
auto &die = chip.get_die(0);
|
||||
std::vector<uint8_t> pll_data = die.get_pll_config();
|
||||
bool pll_written = false;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bool cfg_a = !die.is_pll_cfg_empty(i * 2 + 0);
|
||||
bool cfg_b = !die.is_pll_cfg_empty(i * 2 + 1);
|
||||
if (cfg_a || cfg_b) {
|
||||
wr.write_cmd_spll(1 << i);
|
||||
wr.write_cmd_pll(i * 2, pll_data);
|
||||
if (cfg_b) {
|
||||
wr.write_cmd_spll(1 << i | 1 << (i + 4));
|
||||
wr.write_cmd_pll(i * 2, pll_data);
|
||||
}
|
||||
pll_written = true;
|
||||
}
|
||||
}
|
||||
if (!pll_written)
|
||||
wr.write_cmd_pll_empty();
|
||||
|
||||
for (int iteration = 0; iteration < 2; iteration++) {
|
||||
for (int y = 0; y < Die::MAX_ROWS; y++) {
|
||||
for (int x = 0; x < Die::MAX_COLS; x++) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ std::string ChipConfig::to_string() const
|
|||
{
|
||||
std::stringstream ss;
|
||||
ss << ".device " << chip_name << endl << endl;
|
||||
for (const auto &pll : plls) {
|
||||
if (!pll.second.empty()) {
|
||||
ss << ".pll " << pll.first << " " << endl;
|
||||
ss << pll.second;
|
||||
ss << endl;
|
||||
}
|
||||
}
|
||||
for (const auto &tile : tiles) {
|
||||
if (!tile.second.empty()) {
|
||||
ss << ".tile " << tile.first.die << " " << tile.first.x << " " << tile.first.y << endl;
|
||||
|
|
@ -72,6 +79,12 @@ ChipConfig ChipConfig::from_string(const std::string &config)
|
|||
ss >> verb;
|
||||
if (verb == ".device") {
|
||||
ss >> cc.chip_name;
|
||||
} else if (verb == ".pll") {
|
||||
int die;
|
||||
ss >> die;
|
||||
TileConfig tc;
|
||||
ss >> tc;
|
||||
cc.plls.emplace(die, tc);
|
||||
} else if (verb == ".tile") {
|
||||
CfgLoc loc;
|
||||
ss >> loc.die;
|
||||
|
|
@ -138,6 +151,11 @@ Chip ChipConfig::to_chip() const
|
|||
die.write_ram_data(x, y, bram_data.at(loc), 0);
|
||||
}
|
||||
}
|
||||
PLLBitDatabase plldb;
|
||||
if (plls.count(d)) {
|
||||
const TileConfig &cfg = plls.at(d);
|
||||
die.write_pll(plldb.config_to_data(cfg));
|
||||
}
|
||||
}
|
||||
|
||||
return chip;
|
||||
|
|
@ -173,6 +191,8 @@ ChipConfig ChipConfig::from_chip(const Chip &chip)
|
|||
}
|
||||
}
|
||||
}
|
||||
PLLBitDatabase pll_db;
|
||||
cc.plls.emplace(d, pll_db.data_to_config(die.get_pll_config()));
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ Die::Die()
|
|||
ram_data[std::make_pair(x, y)] = std::vector<u_int8_t>();
|
||||
}
|
||||
}
|
||||
pll_cfg = std::vector<u_int8_t>(PLL_CONFIG_SIZE, 0x00);
|
||||
}
|
||||
|
||||
bool Die::is_latch_empty(int x, int y) const { return latch.at(std::make_pair(x, y)).empty(); }
|
||||
|
|
@ -45,6 +46,15 @@ bool Die::is_ram_empty(int x, int y) const { return ram.at(std::make_pair(x, y))
|
|||
|
||||
bool Die::is_ram_data_empty(int x, int y) const { return ram_data.at(std::make_pair(x, y)).empty(); }
|
||||
|
||||
bool Die::is_pll_cfg_empty(int index) const
|
||||
{
|
||||
int pos = index * 12;
|
||||
for (int i = 0; i < 12; i++)
|
||||
if (pll_cfg[i + pos] != 0x00)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Die::write_latch(int x, int y, const std::vector<uint8_t> &data)
|
||||
{
|
||||
int pos = 0;
|
||||
|
|
@ -72,4 +82,21 @@ void Die::write_ram_data(int x, int y, const std::vector<uint8_t> &data, uint16_
|
|||
block[pos++] = d;
|
||||
}
|
||||
|
||||
void Die::write_pll_select(uint8_t select, const std::vector<uint8_t> &data)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (select & (1 << i)) {
|
||||
int pos = i * 2 * 12;
|
||||
if (select & (1 << (i + 4))) {
|
||||
pos += 12;
|
||||
}
|
||||
for (size_t j = 0; j < 12; j++)
|
||||
pll_cfg[pos++] = data[j];
|
||||
}
|
||||
}
|
||||
int pos = 8 * 12; // start after PLL data;
|
||||
for (size_t j = 12; j < data.size(); j++)
|
||||
pll_cfg[pos++] = data[j];
|
||||
}
|
||||
|
||||
} // namespace GateMate
|
||||
|
|
|
|||
|
|
@ -249,6 +249,25 @@ RamBitDatabase::RamBitDatabase() : BaseBitDatabase(Die::RAM_BLOCK_SIZE * 8)
|
|||
add_unknowns();
|
||||
}
|
||||
|
||||
PLLBitDatabase::PLLBitDatabase() : BaseBitDatabase(Die::PLL_CONFIG_SIZE * 8)
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
add_word_settings(stringf("PLL%d.CFG_A", i), pos, 96);
|
||||
pos += 96;
|
||||
add_word_settings(stringf("PLL%d.CFG_B", i), pos, 96);
|
||||
pos += 96;
|
||||
}
|
||||
add_word_settings("CLKIN.PLL0", pos + 0, 8);
|
||||
add_word_settings("CLKIN.PLL1", pos + 8, 8);
|
||||
add_word_settings("CLKIN.PLL2", pos + 16, 8);
|
||||
add_word_settings("CLKIN.PLL3", pos + 24, 8);
|
||||
add_word_settings("GLBOUT.PLL0", pos + 32, 16);
|
||||
add_word_settings("GLBOUT.PLL1", pos + 48, 16);
|
||||
add_word_settings("GLBOUT.PLL2", pos + 64, 16);
|
||||
add_word_settings("GLBOUT.PLL3", pos + 80, 16);
|
||||
}
|
||||
|
||||
vector<bool> WordSettingBits::get_value(const vector<bool> &tile) const
|
||||
{
|
||||
std::vector<bool> val;
|
||||
|
|
|
|||
Loading…
Reference in New Issue