diff --git a/gatemate/chip.py b/gatemate/chip.py index d48a37f..5a4df25 100644 --- a/gatemate/chip.py +++ b/gatemate/chip.py @@ -18,7 +18,7 @@ import die import os -from die import Die, Location +from die import Die, Location, Connection from dataclasses import dataclass from typing import List, Dict from timing import decompress_timing @@ -105,10 +105,38 @@ class Chip: die_num = x_die + y_die * self.die_width return die.get_tile_info(die_num, x_pos, y_pos) + def create_conn(self, conn, src_x,src_y, src, dst_x, dst_y, dst, delay=""): + key_val = f"{src_x}/{src_y}/{src}" + key = Connection(src_x, src_y, src, "") + item = Connection(dst_x, dst_y, dst, delay) + if key_val not in conn: + conn[key_val] = list() + conn[key_val].append(key) + conn[key_val].append(item) + def get_connections(self): conn = dict() for d in self.dies.values(): d.create_in_die_connections(conn) + if self.name=="CCGM1A2": + for x in range(27, 163): + if x == 27: + # only 7 signals only from bottom of upper to top of lower + p_range = range(2, 9) + else: + p_range = range(1, 9) + + for p in p_range: + plane = f"{p:02d}" + offset_y = 132 + 2 + sbb_y = -1 + offset_y if x % 2 == 1 else 0 + offset_y + sbt_y = 129 if x % 2 == 1 else 130 + + self.create_conn(conn, x, sbb_y, f"{die.get_sb_type(x,sbb_y-offset_y)}.P{plane}.Y4", x, sbt_y, f"{die.get_sb_type(x,sbt_y)}.P{plane}.D2_4") + + if x > 27 and (x != 28 or p > 4): + # no connection for 27, and for 28 just 4 signals from lower to upper + self.create_conn(conn, x, sbt_y, f"{die.get_sb_type(x,sbt_y)}.P{plane}.Y2", x, sbb_y, f"{die.get_sb_type(x,sbb_y-offset_y)}.P{plane}.D2_2") return conn.items() def get_packages(self): diff --git a/libgm/include/Die.hpp b/libgm/include/Die.hpp index 728a743..0866794 100644 --- a/libgm/include/Die.hpp +++ b/libgm/include/Die.hpp @@ -44,7 +44,7 @@ class Die static constexpr int GLBOUT_CFG_SIZE = 8; 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 DIE_CONFIG_SIZE = STATUS_CFG_START + STATUS_CFG_SIZE + 1; static constexpr int FF_INIT_RESET = 2; static constexpr int FF_INIT_SET = 3; static constexpr int SERDES_CFG_SIZE = 186; @@ -68,11 +68,13 @@ class Die bool is_status_cfg_empty() const; bool is_using_cfg_gpios() const; bool is_serdes_cfg_empty() const; + uint8_t get_d2d_config() const; void write_latch(int x, int y, const std::vector &data); void write_ram(int x, int y, const std::vector &data); void write_ram_data(int x, int y, const std::vector &data, uint16_t addr); void write_pll_select(uint8_t select, const std::vector &data); + void write_d2d_config(uint8_t data); void write_die_cfg(const std::vector &data) { die_cfg = data; } void write_serdes_cfg(const std::vector &data) { serdes_cfg = data; } void write_ff_init(int x, int y, uint8_t data); diff --git a/libgm/src/Bitstream.cpp b/libgm/src/Bitstream.cpp index 06c460c..7655b43 100644 --- a/libgm/src/Bitstream.cpp +++ b/libgm/src/Bitstream.cpp @@ -420,6 +420,7 @@ int Bitstream::determine_size(int *max_die_x, int *max_die_y) case CMD_LXLYS: case CMD_ACLCU: case CMD_RXRYS: + case CMD_D2D: // Check header CRC check_crc(rd); // Read data block @@ -579,6 +580,17 @@ Chip Bitstream::deserialise_chip() // Skip bytes rd.skip_bytes(9); break; + case CMD_D2D: + BITSTREAM_DEBUG("CMD_D2D"); + if (length != 1) + BITSTREAM_FATAL("CMD_D2D data must be one byte long", rd.get_offset()); + // Check header CRC + check_crc(rd); + // Read data block + die->write_d2d_config(rd.get_byte()); + // Check data CRC + check_crc(rd); + break; case CMD_SPLL: BITSTREAM_DEBUG("CMD_SPLL"); if (length != 1) @@ -794,6 +806,10 @@ Bitstream Bitstream::serialise_chip(const Chip &chip) } wr.write_cmd_path(0x10); + uint8_t d2d = die.get_d2d_config(); + if (d2d) + wr.write_cmd_d2d(d2d); + // PLL setup std::vector die_config = die.get_die_config(); bool pll_written = false; diff --git a/libgm/src/Die.cpp b/libgm/src/Die.cpp index 2f5e329..5d4d1bd 100644 --- a/libgm/src/Die.cpp +++ b/libgm/src/Die.cpp @@ -103,6 +103,8 @@ bool Die::is_serdes_cfg_empty() const bool Die::is_using_cfg_gpios() const { return die_cfg[STATUS_CFG_START + 2] & 0x08; } +uint8_t Die::get_d2d_config() const { return die_cfg[DIE_CONFIG_SIZE - 1]; } + void Die::write_latch(int x, int y, const std::vector &data) { int pos = 0; @@ -165,4 +167,6 @@ void Die::write_pll_select(uint8_t select, const std::vector &data) die_cfg[pos++] = data[j]; } +void Die::write_d2d_config(uint8_t data) { die_cfg[DIE_CONFIG_SIZE - 1] = data; } + } // namespace GateMate diff --git a/libgm/src/TileBitDatabase.cpp b/libgm/src/TileBitDatabase.cpp index 09edc1f..a0c7be8 100644 --- a/libgm/src/TileBitDatabase.cpp +++ b/libgm/src/TileBitDatabase.cpp @@ -841,6 +841,10 @@ ConfigBitDatabase::ConfigBitDatabase() : BaseBitDatabase(Die::DIE_CONFIG_SIZE * add_word_settings(stringf("PLL%d.USR_CLK_OUT", i), pos + 8 + 7, 1); pos += 16; } + add_word_settings("D2D.N", pos + 0, 1); + add_word_settings("D2D.E", pos + 1, 1); + add_word_settings("D2D.S", pos + 2, 1); + add_word_settings("D2D.W", pos + 3, 1); add_unknowns(); }