Unify configuration data in one data structure

This commit is contained in:
Miodrag Milanovic 2024-12-07 16:37:05 +01:00
parent 83345aeddb
commit d8d6835029
7 changed files with 76 additions and 39 deletions

View File

@ -53,7 +53,7 @@ class ChipConfig
string chip_package;
std::map<CfgLoc, TileConfig> tiles;
std::map<CfgLoc, TileConfig> brams;
std::map<int, TileConfig> plls;
std::map<int, TileConfig> configs;
// Block RAM initialisation
std::map<CfgLoc, std::vector<uint8_t>> bram_data;

View File

@ -42,7 +42,9 @@ class Die
static constexpr int PLL_CFG_SIZE = 12;
static constexpr int CLKIN_CFG_SIZE = 4;
static constexpr int GLBOUT_CFG_SIZE = 8;
static constexpr int PLL_CONFIG_SIZE = PLL_CFG_SIZE * MAX_PLL * 2 + CLKIN_CFG_SIZE + GLBOUT_CFG_SIZE;
static constexpr int STATUS_CFG_SIZE = 12;
static constexpr int STATUS_CFG_START = PLL_CFG_SIZE * MAX_PLL * 2 + CLKIN_CFG_SIZE + GLBOUT_CFG_SIZE;
static constexpr int DIE_CONFIG_SIZE = STATUS_CFG_START + STATUS_CFG_SIZE;
static constexpr int FF_INIT_RESET = 2;
static constexpr int FF_INIT_SET = 3;
@ -62,24 +64,26 @@ class Die
bool is_pll_cfg_empty(int index) const;
bool is_clkin_cfg_empty() const;
bool is_glbout_cfg_empty() const;
bool is_status_cfg_empty() 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; }
void write_die_cfg(const std::vector<uint8_t> &data) { die_cfg = data; }
void write_ff_init(int x, int y, uint8_t data);
void write_status(const std::vector<uint8_t> &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; }
const std::vector<uint8_t> get_die_config() const { return die_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
std::vector<uint8_t> die_cfg; // Config for all PLLs, CLKIN and GLBOUT
};
} // namespace GateMate

View File

@ -87,10 +87,10 @@ class RamBitDatabase : public BaseBitDatabase
RamBitDatabase();
};
class PLLBitDatabase : public BaseBitDatabase
class ConfigBitDatabase : public BaseBitDatabase
{
public:
PLLBitDatabase();
ConfigBitDatabase();
};
class DatabaseConflictError : public runtime_error

View File

@ -552,6 +552,8 @@ Chip Bitstream::deserialise_chip()
// Read data block
rd.get_vector(block, length);
die.write_status(block);
// Check data CRC
check_crc(rd);
@ -618,7 +620,7 @@ Bitstream Bitstream::serialise_chip(const Chip &chip)
BitstreamReadWriter wr;
wr.write_cmd_path(0x10);
auto &die = chip.get_die(0);
std::vector<uint8_t> pll_data = die.get_pll_config();
std::vector<uint8_t> die_config = die.get_die_config();
bool pll_written = false;
for (int i = 0; i < Die::MAX_PLL; i++) {
bool cfg_a = !die.is_pll_cfg_empty(i * 2 + 0);
@ -630,10 +632,10 @@ Bitstream Bitstream::serialise_chip(const Chip &chip)
size = Die::PLL_CFG_SIZE + Die::CLKIN_CFG_SIZE + Die::GLBOUT_CFG_SIZE;
if (cfg_a || cfg_b) {
wr.write_cmd_spll(1 << i);
wr.write_cmd_pll(i * 2, pll_data, size);
wr.write_cmd_pll(i * 2, die_config, size);
if (cfg_b) {
wr.write_cmd_spll(1 << i | 1 << (i + 4));
wr.write_cmd_pll(i * 2, pll_data, size);
wr.write_cmd_pll(i * 2, die_config, size);
}
pll_written = true;
}
@ -699,16 +701,8 @@ Bitstream Bitstream::serialise_chip(const Chip &chip)
wr.write_header(CMD_CHG_STATUS, 12);
wr.write_byte(0x13); // 0
wr.write_byte(0x00); // 1
wr.write_byte(0x33); // 2
wr.write_byte(0x33); // 3
wr.write_byte(0x00); // 4
wr.write_byte(0x00); // 5
wr.write_byte(0x00); // 6
wr.write_byte(0x00); // 7
wr.write_byte(0x00); // 8
wr.write_byte(0x00); // 9
wr.write_byte(0x00); // 10
wr.write_byte(0x00); // 11
for (int i = 2; i < 12; i++)
wr.write_byte(die_config[Die::STATUS_CFG_START + i]); // 2
wr.insert_crc16();
wr.write_nops(4);
wr.write_byte(0x33);

View File

@ -31,10 +31,10 @@ 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;
for (const auto &config : configs) {
if (!config.second.empty()) {
ss << ".config " << config.first << " " << endl;
ss << config.second;
ss << endl;
}
}
@ -79,12 +79,12 @@ ChipConfig ChipConfig::from_string(const std::string &config)
ss >> verb;
if (verb == ".device") {
ss >> cc.chip_name;
} else if (verb == ".pll") {
} else if (verb == ".config") {
int die;
ss >> die;
TileConfig tc;
ss >> tc;
cc.plls.emplace(die, tc);
cc.configs.emplace(die, tc);
} else if (verb == ".tile") {
CfgLoc loc;
ss >> loc.die;
@ -151,10 +151,10 @@ 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));
ConfigBitDatabase cfg_db;
if (configs.count(d)) {
const TileConfig &cfg = configs.at(d);
die.write_die_cfg(cfg_db.config_to_data(cfg));
}
}
@ -191,8 +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()));
ConfigBitDatabase cfg_db;
cc.configs.emplace(d, cfg_db.data_to_config(die.get_die_config()));
}
return cc;
}

View File

@ -37,7 +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);
die_cfg = std::vector<u_int8_t>(DIE_CONFIG_SIZE, 0x00);
}
bool Die::is_latch_empty(int x, int y) const { return latch.at(std::make_pair(x, y)).empty(); }
@ -59,7 +59,7 @@ bool Die::is_pll_cfg_empty(int index) const
{
int pos = index * PLL_CFG_SIZE;
for (int i = 0; i < PLL_CFG_SIZE; i++)
if (pll_cfg[i + pos] != 0x00)
if (die_cfg[i + pos] != 0x00)
return false;
return true;
}
@ -68,7 +68,7 @@ bool Die::is_clkin_cfg_empty() const
{
int pos = PLL_CFG_SIZE * MAX_PLL * 2;
for (int i = 0; i < CLKIN_CFG_SIZE; i++)
if (pll_cfg[i + pos] != 0x00)
if (die_cfg[i + pos] != 0x00)
return false;
return true;
}
@ -77,7 +77,17 @@ bool Die::is_glbout_cfg_empty() const
{
int pos = PLL_CFG_SIZE * MAX_PLL * 2 + CLKIN_CFG_SIZE;
for (int i = 0; i < GLBOUT_CFG_SIZE; i++)
if (pll_cfg[i + pos] != 0x00)
if (die_cfg[i + pos] != 0x00)
return false;
return true;
}
bool Die::is_status_cfg_empty() const
{
int pos = STATUS_CFG_START;
// First two bytes contain status change commands
for (int i = 2; i < STATUS_CFG_SIZE; i++)
if (die_cfg[i + pos] != 0x00)
return false;
return true;
}
@ -116,6 +126,13 @@ void Die::write_ram_data(int x, int y, const std::vector<uint8_t> &data, uint16_
block[pos++] = d;
}
void Die::write_status(const std::vector<uint8_t> &data)
{
int pos = STATUS_CFG_START;
for (auto d : data)
die_cfg[pos++] = d;
}
void Die::write_pll_select(uint8_t select, const std::vector<uint8_t> &data)
{
for (int i = 0; i < MAX_PLL; i++) {
@ -125,12 +142,12 @@ void Die::write_pll_select(uint8_t select, const std::vector<uint8_t> &data)
pos += PLL_CFG_SIZE;
}
for (size_t j = 0; j < PLL_CFG_SIZE; j++)
pll_cfg[pos++] = data[j];
die_cfg[pos++] = data[j];
}
}
int pos = PLL_CFG_SIZE * MAX_PLL * 2; // start after PLL data;
for (size_t j = PLL_CFG_SIZE; j < data.size(); j++)
pll_cfg[pos++] = data[j];
die_cfg[pos++] = data[j];
}
} // namespace GateMate

View File

@ -255,7 +255,7 @@ RamBitDatabase::RamBitDatabase() : BaseBitDatabase(Die::RAM_BLOCK_SIZE * 8)
add_unknowns();
}
PLLBitDatabase::PLLBitDatabase() : BaseBitDatabase(Die::PLL_CONFIG_SIZE * 8)
ConfigBitDatabase::ConfigBitDatabase() : BaseBitDatabase(Die::DIE_CONFIG_SIZE * 8)
{
int pos = 0;
for (int i = 0; i < 4; i++) {
@ -272,6 +272,28 @@ PLLBitDatabase::PLLBitDatabase() : BaseBitDatabase(Die::PLL_CONFIG_SIZE * 8)
add_word_settings("GLBOUT.PLL1", pos + 48, 16);
add_word_settings("GLBOUT.PLL2", pos + 64, 16);
add_word_settings("GLBOUT.PLL3", pos + 80, 16);
pos = Die::STATUS_CFG_START * 8;
add_word_settings("GPIO.BANK_S1", pos + 16, 1);
add_word_settings("GPIO.BANK_S2", pos + 17, 1);
add_word_settings("GPIO.BANK_CFG", pos + 19, 1);
add_word_settings("GPIO.BANK_E1", pos + 20, 1);
add_word_settings("GPIO.BANK_E2", pos + 21, 1);
add_word_settings("GPIO.BANK_N1", pos + 24, 1);
add_word_settings("GPIO.BANK_N2", pos + 25, 1);
add_word_settings("GPIO.BANK_W1", pos + 28, 1);
add_word_settings("GPIO.BANK_W2", pos + 29, 1);
add_word_settings("PLL0.CTRL", pos + 32, 8);
add_word_settings("PLL0.START", pos + 40, 8);
add_word_settings("PLL1.CTRL", pos + 48, 8);
add_word_settings("PLL1.START", pos + 56, 8);
add_word_settings("PLL2.CTRL", pos + 64, 8);
add_word_settings("PLL2.START", pos + 72, 8);
add_word_settings("PLL3.CTRL", pos + 80, 8);
add_word_settings("PLL3.START", pos + 88, 8);
}
vector<bool> WordSettingBits::get_value(const vector<bool> &tile) const