Unify configuration data in one data structure
This commit is contained in:
parent
83345aeddb
commit
d8d6835029
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue