From 96426ef8e3cd24586472977dbeeef7d9e193d737 Mon Sep 17 00:00:00 2001 From: Wanda Date: Fri, 6 Dec 2024 13:44:25 +0000 Subject: [PATCH] xrd2geom: handle some more versal insanity --- prjcombine_rawdump/src/bin/dump_noc.rs | 85 +++ prjcombine_rawdump/src/bin/rd2html.rs | 2 + prjcombine_ultrascale_rd2db/src/int_u.rs | 2 +- prjcombine_versal/src/expand.rs | 48 +- prjcombine_versal/src/grid.rs | 30 + prjcombine_versal_naming/src/lib.rs | 736 +++++++++++++++++++---- prjcombine_versal_rd2db/src/grid.rs | 90 ++- prjcombine_versal_rd2db/src/int.rs | 638 ++++++++++++++++---- prjcombine_versal_rdverify/src/lib.rs | 119 +++- 9 files changed, 1473 insertions(+), 277 deletions(-) diff --git a/prjcombine_rawdump/src/bin/dump_noc.rs b/prjcombine_rawdump/src/bin/dump_noc.rs index 50f4d239..6cbb9ee3 100644 --- a/prjcombine_rawdump/src/bin/dump_noc.rs +++ b/prjcombine_rawdump/src/bin/dump_noc.rs @@ -269,6 +269,16 @@ fn main() -> Result<(), Box> { &["AIE_NOC_TO_NOC"], &["AIE_NOC_FROM_NOC"], ), + // AI-ML2 + ( + "AIE2P_S_INTF_C_CORE", + &[ + "AIE_NOC_0_TO_NOC", + "AIE_NMU_ARBIT_TO_NOC_0", + "AIE_NMU_ARBIT_TO_NOC_1", + ], + &["AIE_NOC_0_FROM_NOC"], + ), // top XPIO ( "DDRMC_DMC_CORE_MX", @@ -740,6 +750,44 @@ fn main() -> Result<(), Box> { "NOC2_XBR4X2_ATOM_0_IN_DMC_1", ], ), + ( + "NOC2_NPS6X_TOP", + &[ + "NOC2_NPS6X_ATOM_0_OUT_0", + "NOC2_NPS6X_ATOM_0_OUT_1", + "NOC2_NPS6X_ATOM_0_OUT_2", + "NOC2_NPS6X_ATOM_0_OUT_3", + "NOC2_NPS6X_ATOM_0_OUT_4", + "NOC2_NPS6X_ATOM_0_OUT_5", + ], + &[ + "NOC2_NPS6X_ATOM_0_IN_0", + "NOC2_NPS6X_ATOM_0_IN_1", + "NOC2_NPS6X_ATOM_0_IN_2", + "NOC2_NPS6X_ATOM_0_IN_3", + "NOC2_NPS6X_ATOM_0_IN_4", + "NOC2_NPS6X_ATOM_0_IN_5", + ], + ), + ( + "NOC2_NPS6X_TOP_MX", + &[ + "NOC2_NPS6X_ATOM_0_OUT_0", + "NOC2_NPS6X_ATOM_0_OUT_1", + "NOC2_NPS6X_ATOM_0_OUT_2", + "NOC2_NPS6X_ATOM_0_OUT_3", + "NOC2_NPS6X_ATOM_0_OUT_4", + "NOC2_NPS6X_ATOM_0_OUT_5", + ], + &[ + "NOC2_NPS6X_ATOM_0_IN_0", + "NOC2_NPS6X_ATOM_0_IN_1", + "NOC2_NPS6X_ATOM_0_IN_2", + "NOC2_NPS6X_ATOM_0_IN_3", + "NOC2_NPS6X_ATOM_0_IN_4", + "NOC2_NPS6X_ATOM_0_IN_5", + ], + ), ( "NOC2_NCRB_TILE", &[ @@ -771,6 +819,11 @@ fn main() -> Result<(), Box> { &["NOC2_NMU128_ATOM_0_TO_NOC"], &["NOC2_NMU128_ATOM_0_FROM_NOC", "NOC2_NMU128_ATOM_0_AXI_IN"], ), + ( + "NOC2_NMU128_TOP_MX", + &["NOC2_NMU128_ATOM_0_TO_NOC"], + &["NOC2_NMU128_ATOM_0_FROM_NOC", "NOC2_NMU128_ATOM_0_AXI_IN"], + ), ( "NOC2_NMU128_TOP_MY", &["NOC2_NMU128_ATOM_0_TO_NOC"], @@ -796,11 +849,21 @@ fn main() -> Result<(), Box> { &["NOC2_NMU512_ATOM_0_TO_NOC"], &["NOC2_NMU512_ATOM_0_FROM_NOC"], ), + ( + "NOC2_NMU512_VNOC4_TILE", + &["NOC2_NMU512_ATOM_0_TO_NOC"], + &["NOC2_NMU512_ATOM_0_FROM_NOC"], + ), ( "NOC2_NSU128_TOP", &["NOC2_NSU128_ATOM_0_TO_NOC", "NOC2_NSU128_ATOM_0_AXI_OUT"], &["NOC2_NSU128_ATOM_0_FROM_NOC"], ), + ( + "NOC2_NSU128_TOP_MX", + &["NOC2_NSU128_ATOM_0_TO_NOC", "NOC2_NSU128_ATOM_0_AXI_OUT"], + &["NOC2_NSU128_ATOM_0_FROM_NOC"], + ), ( "NOC2_NSU256_TOP", &["NOC2_NSU256_ATOM_0_TO_NOC", "NOC2_NSU256_ATOM_0_AXI_OUT"], @@ -816,6 +879,11 @@ fn main() -> Result<(), Box> { &["NOC2_NSU512_ATOM_0_TO_NOC"], &["NOC2_NSU512_ATOM_0_FROM_NOC"], ), + ( + "NOC2_NSU512_VNOC4_TILE", + &["NOC2_NSU512_ATOM_0_TO_NOC"], + &["NOC2_NSU512_ATOM_0_FROM_NOC"], + ), // PSXL ( "PSXL_CORE", @@ -906,6 +974,23 @@ fn main() -> Result<(), Box> { "HNICX_ATOM_0_HNICX_NOC_AXIS_S3", ], ), + // ISP2 + ( + "ISP2_CORE", + &["ISP2_ATOM_0_NMU_ISP_0", "ISP2_ATOM_0_NMU_ISP_1"], + &["ISP2_ATOM_0_NSU_ISP"], + ), + // VCU2 + ( + "VCU2_TILE", + &[ + "VCU2_ATOM_0_NMU_VCU2_0", + "VCU2_ATOM_0_NMU_VCU2_1", + "VCU2_ATOM_0_NMU_VCU2_2", + "VCU2_ATOM_0_NMU_VCU2_3", + ], + &["VCU2_ATOM_0_NSU_VCU2"], + ), ] { for &crd in rd.tiles_by_kind_name(tkn) { let tile = &rd.tiles[&crd]; diff --git a/prjcombine_rawdump/src/bin/rd2html.rs b/prjcombine_rawdump/src/bin/rd2html.rs index 76c96848..d5f0679a 100644 --- a/prjcombine_rawdump/src/bin/rd2html.rs +++ b/prjcombine_rawdump/src/bin/rd2html.rs @@ -3980,6 +3980,8 @@ fn main() -> Result<(), Box> { td._rpad { padding: 5px; padding-right:1000px; border: none; position: relative; } td._bpad { padding: 5px; padding-bottom:1000px; border: none; position: relative; } td._unk { animation: unknown 1s infinite; } + td.NULL { border: none; } + td.PCIE_NULL { border: none; } @keyframes unknown { 0% { background: white; } 50% { background: red; } diff --git a/prjcombine_ultrascale_rd2db/src/int_u.rs b/prjcombine_ultrascale_rd2db/src/int_u.rs index a3bd3261..3e292c44 100644 --- a/prjcombine_ultrascale_rd2db/src/int_u.rs +++ b/prjcombine_ultrascale_rd2db/src/int_u.rs @@ -9,7 +9,7 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { let mut builder = IntBuilder::new(rd); builder.wire("VCC", WireKind::Tie1, &["VCC_WIRE"]); - builder.wire("GND", WireKind::Tie1, &["GND_WIRE"]); + builder.wire("GND", WireKind::Tie0, &["GND_WIRE"]); for i in 0..16 { builder.wire( diff --git a/prjcombine_versal/src/expand.rs b/prjcombine_versal/src/expand.rs index c9b9a7cf..a37ff976 100644 --- a/prjcombine_versal/src/expand.rs +++ b/prjcombine_versal/src/expand.rs @@ -4,9 +4,7 @@ use std::collections::BTreeSet; use unnamed_entity::{EntityId, EntityVec}; use crate::expanded::ExpandedDevice; -use crate::grid::{ - ColumnKind, CpmKind, DisabledPart, Grid, HardRowKind, Interposer, PsKind, RightKind, -}; +use crate::grid::{ColumnKind, DisabledPart, Grid, HardRowKind, Interposer, RightKind}; struct DieInfo { col_cfrm: ColId, @@ -24,13 +22,6 @@ impl Expander<'_> { fn fill_die(&mut self) { for (_, &grid) in &self.grids { self.egrid.add_die(grid.columns.len(), grid.regs * 48); - let ps_height = match (grid.ps, grid.cpm) { - (PsKind::Ps9, CpmKind::None) => 48 * 2, - (PsKind::Ps9, CpmKind::Cpm4) => 48 * 3, - (PsKind::Ps9, CpmKind::Cpm5) => 48 * 6, - (PsKind::PsX, CpmKind::Cpm5N) => 48 * 9, - _ => unreachable!(), - }; self.die.push(DieInfo { col_cfrm: grid .columns @@ -38,7 +29,7 @@ impl Expander<'_> { .find(|(_, cd)| cd.l == ColumnKind::Cfrm) .unwrap() .0, - ps_height, + ps_height: grid.get_ps_height(), }); } } @@ -308,8 +299,16 @@ impl Expander<'_> { if tile.nodes.is_empty() { continue; } - die.add_xnode((col, row), "CLE_R", &[(col, row)]); - die.add_xnode((col + 1, row), "CLE_L", &[(col + 1, row)]); + die.add_xnode( + (col, row), + if grid.is_vr { "CLE_R.VR" } else { "CLE_R" }, + &[(col, row)], + ); + die.add_xnode( + (col + 1, row), + if grid.is_vr { "CLE_L.VR" } else { "CLE_L" }, + &[(col + 1, row)], + ); } } } @@ -451,6 +450,9 @@ impl Expander<'_> { HardRowKind::DcmacB => ("DCMAC", true), HardRowKind::IlknB => ("ILKN", true), HardRowKind::HscB => ("HSC", true), + HardRowKind::SdfecA => ("SDFEC", false), + HardRowKind::DfeCfcB => ("DFE_CFC_BOT", false), + HardRowKind::DfeCfcT => ("DFE_CFC_TOP", false), }; let row = grid.row_reg_bot(reg); let mut crd = vec![]; @@ -471,7 +473,10 @@ impl Expander<'_> { for (dieid, grid) in &self.grids { let mut die = self.egrid.die_mut(dieid); for (col, cd) in &grid.columns { - if !matches!(cd.l, ColumnKind::VNoc | ColumnKind::VNoc2) { + if !matches!( + cd.l, + ColumnKind::VNoc | ColumnKind::VNoc2 | ColumnKind::VNoc4 + ) { continue; } if self.disabled.contains(&DisabledPart::Column(die.die, col)) { @@ -489,10 +494,17 @@ impl Expander<'_> { for i in 0..48 { crd.push((col, row + i)); } - if cd.l == ColumnKind::VNoc { - die.add_xnode((col, row), "VNOC", &crd); - } else { - die.add_xnode((col, row), "VNOC2", &crd); + match cd.l { + ColumnKind::VNoc => { + die.add_xnode((col, row), "VNOC", &crd); + } + ColumnKind::VNoc2 => { + die.add_xnode((col, row), "VNOC2", &crd); + } + ColumnKind::VNoc4 => { + die.add_xnode((col, row), "VNOC4", &crd); + } + _ => unreachable!(), } if grid.is_reg_top(reg) { die.add_xnode((col, row), "MISR", &crd); diff --git a/prjcombine_versal/src/grid.rs b/prjcombine_versal/src/grid.rs index 0e16fdc3..15e54d3e 100644 --- a/prjcombine_versal/src/grid.rs +++ b/prjcombine_versal/src/grid.rs @@ -19,6 +19,7 @@ pub struct Grid { pub ps: PsKind, pub cpm: CpmKind, pub has_xram_top: bool, + pub is_vr: bool, pub top: TopKind, pub bottom: BotKind, pub right: RightKind, @@ -57,6 +58,7 @@ pub enum BramKind { Plain, ClkBuf, ClkBufNoPd, + MaybeClkBufNoPd, } #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] @@ -70,6 +72,7 @@ pub enum ColumnKind { Cfrm, VNoc, VNoc2, + VNoc4, None, } @@ -83,6 +86,7 @@ pub enum ColSide { pub enum PsKind { Ps9, PsX, + PsXc, } #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] @@ -100,6 +104,9 @@ pub enum HardRowKind { Pcie4, Pcie5, Mrmac, + SdfecA, + DfeCfcB, + DfeCfcT, IlknB, IlknT, DcmacB, @@ -121,9 +128,14 @@ pub enum GtRowKind { Gty, Gtyp, Gtm, + RfAdc, + RfDac, Xram, Vdu, BfrB, + Isp2, + Vcu2B, + Vcu2T, } #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] @@ -197,6 +209,17 @@ impl Grid { pub fn get_col_hard(&self, col: ColId) -> Option<&HardColumn> { self.cols_hard.iter().find(|x| x.col == col) } + + pub fn get_ps_height(&self) -> usize { + match (self.ps, self.cpm) { + (PsKind::Ps9, CpmKind::None) => 48 * 2, + (PsKind::Ps9, CpmKind::Cpm4) => 48 * 3, + (PsKind::Ps9, CpmKind::Cpm5) => 48 * 6, + (PsKind::PsX, CpmKind::Cpm5N) => 48 * 9, + (PsKind::PsXc, CpmKind::None) => 48 * 6, + _ => unreachable!(), + } + } } impl std::fmt::Display for Grid { @@ -205,6 +228,7 @@ impl std::fmt::Display for Grid { writeln!(f, "\tPS: {v:?}", v = self.ps)?; writeln!(f, "\tCPM: {v:?}", v = self.cpm)?; writeln!(f, "\tXRAM TOP: {v:?}", v = self.has_xram_top)?; + writeln!(f, "\tIS VR: {v:?}", v = self.is_vr)?; writeln!(f, "\tTOP: {v:?}", v = self.top)?; writeln!(f, "\tBOTTOM: {v:?}", v = self.bottom)?; writeln!(f, "\tCOLS:")?; @@ -222,6 +246,7 @@ impl std::fmt::Display for Grid { | ColumnKind::Hard | ColumnKind::VNoc | ColumnKind::VNoc2 + | ColumnKind::VNoc4 ) { write!(f, "\t\tX{cl}.R-X{col}.L: ", cl = col - 1)?; } else { @@ -236,12 +261,14 @@ impl std::fmt::Display for Grid { ColumnKind::Bram(BramKind::Plain) => write!(f, "BRAM")?, ColumnKind::Bram(BramKind::ClkBuf) => write!(f, "BRAM.CLKBUF")?, ColumnKind::Bram(BramKind::ClkBufNoPd) => write!(f, "BRAM.CLKBUF.NOPD")?, + ColumnKind::Bram(BramKind::MaybeClkBufNoPd) => write!(f, "BRAM.MAYBE.CLKBUF.NOPD")?, ColumnKind::Uram => write!(f, "URAM")?, ColumnKind::Hard => write!(f, "HARD")?, ColumnKind::Gt => write!(f, "GT")?, ColumnKind::Cfrm => write!(f, "CFRM")?, ColumnKind::VNoc => write!(f, "VNOC")?, ColumnKind::VNoc2 => write!(f, "VNOC2")?, + ColumnKind::VNoc4 => write!(f, "VNOC4")?, } if cd.has_bli_bot_l { write!(f, " BLI.BOT")?; @@ -264,6 +291,7 @@ impl std::fmt::Display for Grid { | ColumnKind::Hard | ColumnKind::VNoc | ColumnKind::VNoc2 + | ColumnKind::VNoc4 ) { continue; } @@ -277,12 +305,14 @@ impl std::fmt::Display for Grid { ColumnKind::Bram(BramKind::Plain) => write!(f, "BRAM")?, ColumnKind::Bram(BramKind::ClkBuf) => write!(f, "BRAM.CLKBUF")?, ColumnKind::Bram(BramKind::ClkBufNoPd) => write!(f, "BRAM.CLKBUF.NOPD")?, + ColumnKind::Bram(BramKind::MaybeClkBufNoPd) => write!(f, "BRAM.MAYBE.CLKBUF.NOPD")?, ColumnKind::Uram => write!(f, "URAM")?, ColumnKind::Hard => write!(f, "HARD")?, ColumnKind::Gt => write!(f, "GT")?, ColumnKind::Cfrm => write!(f, "CFRM")?, ColumnKind::VNoc => write!(f, "VNOC")?, ColumnKind::VNoc2 => write!(f, "VNOC2")?, + ColumnKind::VNoc4 => write!(f, "VNOC4")?, } if cd.has_bli_bot_r { write!(f, " BLI.BOT")?; diff --git a/prjcombine_versal_naming/src/lib.rs b/prjcombine_versal_naming/src/lib.rs index c4ac1af7..9c9ffa09 100644 --- a/prjcombine_versal_naming/src/lib.rs +++ b/prjcombine_versal_naming/src/lib.rs @@ -18,6 +18,7 @@ use unnamed_entity::{entity_id, EntityId, EntityPartVec, EntityVec}; pub struct DeviceNaming { pub die: EntityVec, pub is_dsp_v2: bool, + pub is_vnoc2_scan_offset: bool, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -351,17 +352,24 @@ pub fn name_device<'a>( } }, ); - let rclk_dfx_grid = make_grid( + let rclk_dfx_grid = make_grid_complex( edev, |_, node, _| node == "RCLK_DFX.W", |_, node, _| node == "RCLK_DFX.E", - (1, 1), - (1, 1), + |_, _, _, _| (1, 1), + |_, _, _, nloc| { + let grid = edev.grids[nloc.0]; + if grid.columns[nloc.1].r == ColumnKind::Bram(BramKind::MaybeClkBufNoPd) { + (2, 1) + } else { + (1, 1) + } + }, ); let slice_grid = make_grid( edev, - |_, node, _| node == "CLE_L", - |_, node, _| node == "CLE_R", + |_, node, _| matches!(node, "CLE_L" | "CLE_L.VR"), + |_, node, _| matches!(node, "CLE_R" | "CLE_R.VR"), (2, 1), (2, 1), ); @@ -414,6 +422,27 @@ pub fn name_device<'a>( (1, 1), (0, 0), ); + let sdfec_grid = make_grid( + edev, + |_, node, _| node == "SDFEC", + |_, _, _| false, + (1, 1), + (0, 0), + ); + let dfe_cfc_bot_grid = make_grid( + edev, + |_, node, _| node == "DFE_CFC_BOT", + |_, _, _| false, + (1, 1), + (0, 0), + ); + let dfe_cfc_top_grid = make_grid( + edev, + |_, node, _| node == "DFE_CFC_TOP", + |_, _, _| false, + (1, 1), + (0, 0), + ); let dcmac_grid = make_grid( edev, |_, node, _| node == "DCMAC", @@ -481,11 +510,12 @@ pub fn name_device<'a>( } else { 'R' }; + let vr = if grid.is_vr { "_VR" } else { "" }; ngrid.name_node( nloc, "RCLK", [int_grid.name( - &format!("RCLK_INT_{lr}_FT"), + &format!("RCLK_INT_{lr}{vr}_FT"), die.die, col, ColSide::Left, @@ -551,7 +581,11 @@ pub fn name_device<'a>( unreachable!() }; let naming = &if cle_kind == CleKind::Plain { - kind.to_string() + if grid.is_vr { + format!("{kind}.VR") + } else { + kind.to_string() + } } else { format!("{kind}.LAG") }; @@ -560,7 +594,11 @@ pub fn name_device<'a>( naming, [int_grid.name( if cle_kind == CleKind::Plain { - "RCLK_CLE_CORE" + if grid.is_vr { + "RCLK_CLE_VR_CORE" + } else { + "RCLK_CLE_CORE" + } } else { "RCLK_CLE_LAG_CORE" }, @@ -572,7 +610,7 @@ pub fn name_device<'a>( 0, )], ); - let swz = if cle_kind == CleKind::Plain { + let swz = if cle_kind == CleKind::Plain && !grid.is_vr { BUFDIV_LEAF_SWZ_A } else { BUFDIV_LEAF_SWZ_B @@ -581,7 +619,11 @@ pub fn name_device<'a>( nnode.add_bel( i, bufdiv_grid.name( - "BUFDIV_LEAF", + if grid.is_vr { + "BUFDIV_LEAF_ULVT" + } else { + "BUFDIV_LEAF" + }, die.die, col, ColSide::Left, @@ -771,9 +813,13 @@ pub fn name_device<'a>( let srow = if reg.to_idx() % 2 == 1 { row - 1 } else { row }; let (subkind, name, swz, wide) = match grid.columns[col].l { ColumnKind::Dsp => ( - "DSP", + if grid.is_vr { "DSP.VR" } else { "DSP" }, int_grid.name( - "RCLK_DSP_CORE", + if grid.is_vr { + "RCLK_DSP_VR_CORE" + } else { + "RCLK_DSP_CORE" + }, die.die, col - 1, ColSide::Left, @@ -781,13 +827,21 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_AH, + if grid.is_vr { + BUFDIV_LEAF_SWZ_BH + } else { + BUFDIV_LEAF_SWZ_AH + }, true, ), ColumnKind::Bram(BramKind::Plain) => ( - "BRAM", + if grid.is_vr { "BRAM.VR" } else { "BRAM" }, int_grid.name( - "RCLK_BRAM_CORE", + if grid.is_vr { + "RCLK_BRAM_VR_CORE" + } else { + "RCLK_BRAM_CORE" + }, die.die, col, ColSide::Left, @@ -795,13 +849,21 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, false, ), ColumnKind::Uram => ( - "URAM", + if grid.is_vr { "URAM.VR" } else { "URAM" }, int_grid.name( - "RCLK_URAM_CORE", + if grid.is_vr { + "RCLK_URAM_VR_CORE" + } else { + "RCLK_URAM_CORE" + }, die.die, col, ColSide::Left, @@ -809,13 +871,21 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, false, ), ColumnKind::Gt => ( - "GT", + if grid.is_vr { "GT.VR" } else { "GT" }, int_grid.name( - "RCLK_INTF_TERM_LEFT_CORE", + if grid.is_vr { + "RCLK_INTF_TERM_LEFT_VR_CORE" + } else { + "RCLK_INTF_TERM_LEFT_CORE" + }, die.die, col, ColSide::Left, @@ -823,13 +893,21 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, false, ), ColumnKind::Cfrm => ( - "CFRM", + if grid.is_vr { "CFRM.VR" } else { "CFRM" }, int_grid.name( - "RCLK_INTF_OPT_CORE", + if grid.is_vr { + "RCLK_INTF_OPT_VR_CORE" + } else { + "RCLK_INTF_OPT_CORE" + }, die.die, col, ColSide::Left, @@ -837,13 +915,21 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, false, ), - ColumnKind::VNoc | ColumnKind::VNoc2 => ( - "VNOC", + ColumnKind::VNoc | ColumnKind::VNoc2 | ColumnKind::VNoc4 => ( + if grid.is_vr { "VNOC.VR" } else { "VNOC" }, int_grid.name( - "RCLK_INTF_L_CORE", + if grid.is_vr { + "RCLK_INTF_L_VR_CORE" + } else { + "RCLK_INTF_L_CORE" + }, die.die, col, ColSide::Left, @@ -859,9 +945,13 @@ pub fn name_device<'a>( if reg.to_idx() % 2 == 0 { if hc.regs[reg] == HardRowKind::Hdio { ( - "HDIO", + if grid.is_vr { "HDIO.VR" } else { "HDIO" }, int_grid.name( - "RCLK_HDIO_CORE", + if grid.is_vr { + "RCLK_HDIO_VR_CORE" + } else { + "RCLK_HDIO_CORE" + }, die.die, col - 1, ColSide::Left, @@ -869,14 +959,22 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_AH, + if grid.is_vr { + BUFDIV_LEAF_SWZ_BH + } else { + BUFDIV_LEAF_SWZ_AH + }, true, ) } else { ( - "HB", + if grid.is_vr { "HB.VR" } else { "HB" }, int_grid.name( - "RCLK_HB_CORE", + if grid.is_vr { + "RCLK_HB_VR_CORE" + } else { + "RCLK_HB_CORE" + }, die.die, col - 1, ColSide::Left, @@ -884,16 +982,24 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_AH, + if grid.is_vr { + BUFDIV_LEAF_SWZ_BH + } else { + BUFDIV_LEAF_SWZ_AH + }, true, ) } } else { if hc.regs[reg] == HardRowKind::Hdio { ( - "HDIO", + if grid.is_vr { "HDIO.VR" } else { "HDIO" }, int_grid.name( - "RCLK_HDIO_CORE", + if grid.is_vr { + "RCLK_HDIO_VR_CORE" + } else { + "RCLK_HDIO_CORE" + }, die.die, col - 1, ColSide::Left, @@ -901,14 +1007,37 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_AH, + if grid.is_vr { + BUFDIV_LEAF_SWZ_BH + } else { + BUFDIV_LEAF_SWZ_AH + }, true, ) } else if hc.regs[reg - 1] == HardRowKind::Hdio { ( - "HB_HDIO", + if grid.is_vr { "HB_HDIO.VR" } else { "HB_HDIO" }, + int_grid.name( + if grid.is_vr { + "RCLK_HB_HDIO_VR_CORE" + } else { + "RCLK_HB_HDIO_CORE" + }, + die.die, + col - 1, + ColSide::Left, + srow, + 0, + 0, + ), + BUFDIV_LEAF_SWZ_BH, + true, + ) + } else if hc.regs[reg - 1] == HardRowKind::DfeCfcB { + ( + "SDFEC", int_grid.name( - "RCLK_HB_HDIO_CORE", + "RCLK_SDFEC_CORE", die.die, col - 1, ColSide::Left, @@ -926,9 +1055,13 @@ pub fn name_device<'a>( | HardRowKind::IlknT ) { ( - "HB_FULL", + if grid.is_vr { "HB_FULL.VR" } else { "HB_FULL" }, int_grid.name( - "RCLK_HB_FULL_R_CORE", + if grid.is_vr { + "RCLK_HB_FULL_R_VR_CORE" + } else { + "RCLK_HB_FULL_R_CORE" + }, die.die, col, ColSide::Left, @@ -941,9 +1074,13 @@ pub fn name_device<'a>( ) } else { ( - "HB", + if grid.is_vr { "HB.VR" } else { "HB" }, int_grid.name( - "RCLK_HB_CORE", + if grid.is_vr { + "RCLK_HB_VR_CORE" + } else { + "RCLK_HB_CORE" + }, die.die, col - 1, ColSide::Left, @@ -951,7 +1088,11 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_AH, + if grid.is_vr { + BUFDIV_LEAF_SWZ_BH + } else { + BUFDIV_LEAF_SWZ_AH + }, true, ) } @@ -965,7 +1106,11 @@ pub fn name_device<'a>( i, if wide { bufdiv_grid.name( - "BUFDIV_LEAF", + if grid.is_vr { + "BUFDIV_LEAF_ULVT" + } else { + "BUFDIV_LEAF" + }, die.die, col - 1, ColSide::Right, @@ -975,7 +1120,11 @@ pub fn name_device<'a>( ) } else { bufdiv_grid.name( - "BUFDIV_LEAF", + if grid.is_vr { + "BUFDIV_LEAF_ULVT" + } else { + "BUFDIV_LEAF" + }, die.die, col, ColSide::Left, @@ -991,9 +1140,13 @@ pub fn name_device<'a>( let srow = if reg.to_idx() % 2 == 1 { row - 1 } else { row }; let (subkind, name, swz) = match grid.columns[col].r { ColumnKind::Dsp => ( - "DSP", + if grid.is_vr { "DSP.VR" } else { "DSP" }, int_grid.name( - "RCLK_DSP_CORE", + if grid.is_vr { + "RCLK_DSP_VR_CORE" + } else { + "RCLK_DSP_CORE" + }, die.die, col, ColSide::Left, @@ -1001,12 +1154,20 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ), ColumnKind::Bram(BramKind::Plain) => ( - "BRAM", + if grid.is_vr { "BRAM.VR" } else { "BRAM" }, int_grid.name( - "RCLK_BRAM_CORE", + if grid.is_vr { + "RCLK_BRAM_VR_CORE" + } else { + "RCLK_BRAM_CORE" + }, die.die, col, ColSide::Left, @@ -1014,12 +1175,24 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ), ColumnKind::Bram(BramKind::ClkBuf) => ( - "BRAM.CLKBUF", + if grid.is_vr { + "BRAM.CLKBUF.VR" + } else { + "BRAM.CLKBUF" + }, int_grid.name( - "RCLK_BRAM_CLKBUF_CORE", + if grid.is_vr { + "RCLK_BRAM_CLKBUF_VR_CORE" + } else { + "RCLK_BRAM_CLKBUF_CORE" + }, die.die, col, ColSide::Left, @@ -1027,12 +1200,61 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ), ColumnKind::Bram(BramKind::ClkBufNoPd) => ( - "BRAM.CLKBUF.NOPD", + if grid.is_vr { + "BRAM.CLKBUF.NOPD.VR" + } else { + "BRAM.CLKBUF.NOPD" + }, + int_grid.name( + if grid.is_vr { + "RCLK_BRAM_CLKBUF_NOPD_VR_CORE" + } else { + "RCLK_BRAM_CLKBUF_NOPD_CORE" + }, + die.die, + col, + ColSide::Left, + srow, + 0, + 0, + ), + BUFDIV_LEAF_SWZ_B, + ), + ColumnKind::Bram(BramKind::MaybeClkBufNoPd) => ( + if row.to_idx() < grid.get_ps_height() { + if grid.is_vr { + "BRAM.VR" + } else { + "BRAM" + } + } else { + if grid.is_vr { + "BRAM.CLKBUF.NOPD.VR" + } else { + "BRAM.CLKBUF.NOPD" + } + }, int_grid.name( - "RCLK_BRAM_CLKBUF_NOPD_CORE", + if row.to_idx() < grid.get_ps_height() { + if grid.is_vr { + "RCLK_BRAM_VR_CORE" + } else { + "RCLK_BRAM_CORE" + } + } else { + if grid.is_vr { + "RCLK_BRAM_CLKBUF_NOPD_VR_CORE" + } else { + "RCLK_BRAM_CLKBUF_NOPD_CORE" + } + }, die.die, col, ColSide::Left, @@ -1040,12 +1262,20 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr || row.to_idx() >= grid.get_ps_height() { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ), ColumnKind::Uram => ( - "URAM", + if grid.is_vr { "URAM.VR" } else { "URAM" }, int_grid.name( - "RCLK_URAM_CORE", + if grid.is_vr { + "RCLK_URAM_VR_CORE" + } else { + "RCLK_URAM_CORE" + }, die.die, col, ColSide::Left, @@ -1053,14 +1283,22 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ), ColumnKind::Gt => { if reg.to_idx() == 1 && matches!(grid.right, RightKind::Term2) { ( - "GT.ALT", + if grid.is_vr { "GT.ALT.VR" } else { "GT.ALT" }, int_grid.name( - "RCLK_INTF_TERM2_RIGHT_CORE", + if grid.is_vr { + "RCLK_INTF_TERM2_RIGHT_VR_CORE" + } else { + "RCLK_INTF_TERM2_RIGHT_CORE" + }, die.die, col, ColSide::Left, @@ -1072,9 +1310,13 @@ pub fn name_device<'a>( ) } else { ( - "GT", + if grid.is_vr { "GT.VR" } else { "GT" }, int_grid.name( - "RCLK_INTF_TERM_RIGHT_CORE", + if grid.is_vr { + "RCLK_INTF_TERM_RIGHT_VR_CORE" + } else { + "RCLK_INTF_TERM_RIGHT_CORE" + }, die.die, col, ColSide::Left, @@ -1082,14 +1324,22 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ) } } - ColumnKind::VNoc | ColumnKind::VNoc2 => ( - "VNOC", + ColumnKind::VNoc | ColumnKind::VNoc2 | ColumnKind::VNoc4 => ( + if grid.is_vr { "VNOC.VR" } else { "VNOC" }, int_grid.name( - "RCLK_INTF_R_CORE", + if grid.is_vr { + "RCLK_INTF_R_VR_CORE" + } else { + "RCLK_INTF_R_CORE" + }, die.die, col, ColSide::Left, @@ -1104,9 +1354,13 @@ pub fn name_device<'a>( if reg.to_idx() % 2 == 0 { if hc.regs[reg] == HardRowKind::Hdio { ( - "HDIO", + if grid.is_vr { "HDIO.VR" } else { "HDIO" }, int_grid.name( - "RCLK_HDIO_CORE", + if grid.is_vr { + "RCLK_HDIO_VR_CORE" + } else { + "RCLK_HDIO_CORE" + }, die.die, col, ColSide::Left, @@ -1114,13 +1368,21 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ) } else { ( - "HB", + if grid.is_vr { "HB.VR" } else { "HB" }, int_grid.name( - "RCLK_HB_CORE", + if grid.is_vr { + "RCLK_HB_VR_CORE" + } else { + "RCLK_HB_CORE" + }, die.die, col, ColSide::Left, @@ -1128,15 +1390,23 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ) } } else { if hc.regs[reg] == HardRowKind::Hdio { ( - "HDIO", + if grid.is_vr { "HDIO.VR" } else { "HDIO" }, int_grid.name( - "RCLK_HDIO_CORE", + if grid.is_vr { + "RCLK_HDIO_VR_CORE" + } else { + "RCLK_HDIO_CORE" + }, die.die, col, ColSide::Left, @@ -1144,13 +1414,35 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ) } else if hc.regs[reg - 1] == HardRowKind::Hdio { ( - "HB_HDIO", + if grid.is_vr { "HB_HDIO.VR" } else { "HB_HDIO" }, + int_grid.name( + if grid.is_vr { + "RCLK_HB_HDIO_VR_CORE" + } else { + "RCLK_HB_HDIO_CORE" + }, + die.die, + col, + ColSide::Left, + srow, + 0, + 0, + ), + BUFDIV_LEAF_SWZ_B, + ) + } else if hc.regs[reg - 1] == HardRowKind::DfeCfcB { + ( + "SDFEC", int_grid.name( - "RCLK_HB_HDIO_CORE", + "RCLK_SDFEC_CORE", die.die, col, ColSide::Left, @@ -1167,9 +1459,13 @@ pub fn name_device<'a>( | HardRowKind::IlknT ) { ( - "HB_FULL", + if grid.is_vr { "HB_FULL.VR" } else { "HB_FULL" }, int_grid.name( - "RCLK_HB_FULL_L_CORE", + if grid.is_vr { + "RCLK_HB_FULL_L_VR_CORE" + } else { + "RCLK_HB_FULL_L_CORE" + }, die.die, col, ColSide::Left, @@ -1181,9 +1477,13 @@ pub fn name_device<'a>( ) } else { ( - "HB", + if grid.is_vr { "HB.VR" } else { "HB" }, int_grid.name( - "RCLK_HB_CORE", + if grid.is_vr { + "RCLK_HB_VR_CORE" + } else { + "RCLK_HB_CORE" + }, die.die, col, ColSide::Left, @@ -1191,7 +1491,11 @@ pub fn name_device<'a>( 0, 0, ), - BUFDIV_LEAF_SWZ_A, + if grid.is_vr { + BUFDIV_LEAF_SWZ_B + } else { + BUFDIV_LEAF_SWZ_A + }, ) } } @@ -1203,7 +1507,11 @@ pub fn name_device<'a>( nnode.add_bel( i, bufdiv_grid.name( - "BUFDIV_LEAF", + if grid.is_vr { + "BUFDIV_LEAF_ULVT" + } else { + "BUFDIV_LEAF" + }, die.die, col, ColSide::Right, @@ -1220,7 +1528,11 @@ pub fn name_device<'a>( ColumnKind::Dsp => ( "DSP", int_grid.name( - "RCLK_DSP_CORE", + if grid.is_vr { + "RCLK_DSP_VR_CORE" + } else { + "RCLK_DSP_CORE" + }, die.die, col - 1, ColSide::Left, @@ -1232,7 +1544,11 @@ pub fn name_device<'a>( ColumnKind::Bram(BramKind::Plain) => ( "BRAM", int_grid.name( - "RCLK_BRAM_CORE", + if grid.is_vr { + "RCLK_BRAM_VR_CORE" + } else { + "RCLK_BRAM_CORE" + }, die.die, col, ColSide::Left, @@ -1244,7 +1560,11 @@ pub fn name_device<'a>( ColumnKind::Uram => ( "URAM", int_grid.name( - "RCLK_URAM_CORE", + if grid.is_vr { + "RCLK_URAM_VR_CORE" + } else { + "RCLK_URAM_CORE" + }, die.die, col, ColSide::Left, @@ -1255,7 +1575,9 @@ pub fn name_device<'a>( ), _ => unreachable!(), }; - let nnode = ngrid.name_node(nloc, &format!("{kind}.{subkind}"), [name]); + let vr = if grid.is_vr { ".VR" } else { "" }; + let nnode = + ngrid.name_node(nloc, &format!("{kind}.{subkind}{vr}"), [name]); nnode.add_bel( 0, rclk_dfx_grid.name("RCLK", die.die, col, ColSide::Left, row, 0, 0), @@ -1263,11 +1585,15 @@ pub fn name_device<'a>( } "RCLK_DFX.E" => { let srow = if reg.to_idx() % 2 == 1 { row - 1 } else { row }; - let (subkind, name) = match grid.columns[col].r { + let (subkind, name, dx) = match grid.columns[col].r { ColumnKind::Bram(BramKind::Plain) => ( "BRAM", int_grid.name( - "RCLK_BRAM_CORE", + if grid.is_vr { + "RCLK_BRAM_VR_CORE" + } else { + "RCLK_BRAM_CORE" + }, die.die, col, ColSide::Left, @@ -1275,11 +1601,16 @@ pub fn name_device<'a>( 0, 0, ), + 0, ), ColumnKind::Bram(BramKind::ClkBuf) => ( "BRAM.CLKBUF", int_grid.name( - "RCLK_BRAM_CLKBUF_CORE", + if grid.is_vr { + "RCLK_BRAM_CLKBUF_VR_CORE" + } else { + "RCLK_BRAM_CLKBUF_CORE" + }, die.die, col, ColSide::Left, @@ -1287,11 +1618,16 @@ pub fn name_device<'a>( 0, 0, ), + 0, ), ColumnKind::Bram(BramKind::ClkBufNoPd) => ( "BRAM.CLKBUF.NOPD", int_grid.name( - "RCLK_BRAM_CLKBUF_NOPD_CORE", + if grid.is_vr { + "RCLK_BRAM_CLKBUF_NOPD_VR_CORE" + } else { + "RCLK_BRAM_CLKBUF_NOPD_CORE" + }, die.die, col, ColSide::Left, @@ -1299,11 +1635,49 @@ pub fn name_device<'a>( 0, 0, ), + 0, + ), + ColumnKind::Bram(BramKind::MaybeClkBufNoPd) => ( + if row.to_idx() < grid.get_ps_height() { + "BRAM" + } else { + "BRAM.CLKBUF.NOPD" + }, + int_grid.name( + if row.to_idx() < grid.get_ps_height() { + if grid.is_vr { + "RCLK_BRAM_VR_CORE" + } else { + "RCLK_BRAM_CORE" + } + } else { + if grid.is_vr { + "RCLK_BRAM_CLKBUF_NOPD_VR_CORE" + } else { + "RCLK_BRAM_CLKBUF_NOPD_CORE" + } + }, + die.die, + col, + ColSide::Left, + srow, + 0, + 0, + ), + if row.to_idx() < grid.get_ps_height() { + 0 + } else { + 1 + }, ), ColumnKind::Uram => ( "URAM", int_grid.name( - "RCLK_URAM_CORE", + if grid.is_vr { + "RCLK_URAM_VR_CORE" + } else { + "RCLK_URAM_CORE" + }, die.die, col, ColSide::Left, @@ -1311,19 +1685,39 @@ pub fn name_device<'a>( 0, 0, ), + 0, ), _ => unreachable!(), }; - let nnode = ngrid.name_node(nloc, &format!("{kind}.{subkind}"), [name]); + let vr = if grid.is_vr { ".VR" } else { "" }; + let nnode = + ngrid.name_node(nloc, &format!("{kind}.{subkind}{vr}"), [name]); nnode.add_bel( 0, - rclk_dfx_grid.name("RCLK", die.die, col, ColSide::Right, row, 0, 0), + rclk_dfx_grid.name( + "RCLK", + die.die, + col, + ColSide::Right, + row, + dx, + 0, + ), ); } "RCLK_HDIO" | "RCLK_HB_HDIO" => { let srow = if reg.to_idx() % 2 == 1 { row - 1 } else { row }; + let naming = if grid.is_vr { + format!("{kind}.VR") + } else { + kind.to_string() + }; let name = int_grid.name( - &format!("{kind}_CORE"), + &if grid.is_vr { + format!("{kind}_VR_CORE") + } else { + format!("{kind}_CORE") + }, die.die, col - 1, ColSide::Left, @@ -1331,21 +1725,18 @@ pub fn name_device<'a>( 0, 0, ); - ngrid.name_node(nloc, kind, [name]); + ngrid.name_node(nloc, &naming, [name]); } - "CLE_L" => { + "CLE_L" | "CLE_L.VR" => { + let tkn = if !grid.is_vr { + "CLE_E_CORE" + } else { + "CLE_E_VR_CORE" + }; let nnode = ngrid.name_node( nloc, kind, - [int_grid.name( - "CLE_E_CORE", - die.die, - col, - ColSide::Left, - row, - 0, - 0, - )], + [int_grid.name(tkn, die.die, col, ColSide::Left, row, 0, 0)], ); for i in 0..2 { nnode.add_bel( @@ -1362,19 +1753,16 @@ pub fn name_device<'a>( ); } } - "CLE_R" => { + "CLE_R" | "CLE_R.VR" => { + let tkn = if !grid.is_vr { + "CLE_W_CORE" + } else { + "CLE_W_VR_CORE" + }; let nnode = ngrid.name_node( nloc, kind, - [int_grid.name( - "CLE_W_CORE", - die.die, - col, - ColSide::Left, - row, - 0, - 0, - )], + [int_grid.name(tkn, die.die, col, ColSide::Left, row, 0, 0)], ); for i in 0..2 { nnode.add_bel( @@ -1536,11 +1924,14 @@ pub fn name_device<'a>( ); } } - "PCIE4" | "PCIE5" | "MRMAC" => { + "PCIE4" | "PCIE5" | "MRMAC" | "SDFEC" | "DFE_CFC_BOT" | "DFE_CFC_TOP" => { let (tk, bk, bel_grid) = match &kind[..] { "PCIE4" => ("PCIEB", "PCIE40", &pcie4_grid), "PCIE5" => ("PCIEB5", "PCIE50", &pcie5_grid), "MRMAC" => ("MRMAC", "MRMAC", &mrmac_grid), + "SDFEC" => ("SDFECA", "SDFEC_A", &sdfec_grid), + "DFE_CFC_BOT" => ("DFE_CFC", "DFE_CFC_BOT", &dfe_cfc_bot_grid), + "DFE_CFC_TOP" => ("DFE_CFC", "DFE_CFC_TOP", &dfe_cfc_top_grid), _ => unreachable!(), }; let bt = if grid.is_reg_top(reg) { "TOP" } else { "BOT" }; @@ -1818,7 +2209,11 @@ pub fn name_device<'a>( int_grid.name( "NOC2_SCAN_TOP", die.die, - col - 1, + if dev_naming.is_vnoc2_scan_offset { + col + } else { + col - 1 + }, ColSide::Left, row + 7, 0, @@ -1873,6 +2268,105 @@ pub fn name_device<'a>( ), ); } + "VNOC4" => { + let nnode = ngrid.name_node( + nloc, + kind, + [ + int_grid.name( + "NOC2_NSU512_VNOC4_TILE", + die.die, + col - 1, + ColSide::Left, + row + 7, + 0, + 0, + ), + int_grid.name( + "NOC2_NPS6X_TOP", + die.die, + col - 1, + ColSide::Left, + row + 11, + 0, + 0, + ), + int_grid.name( + "NOC2_NPS6X_TOP", + die.die, + col - 1, + ColSide::Left, + row + 14, + 0, + 0, + ), + int_grid.name( + "NOC2_NMU512_VNOC4_TILE", + die.die, + col - 1, + ColSide::Left, + row + 16, + 0, + 0, + ), + int_grid.name( + "NOC2_SCAN_TOP", + die.die, + col - 1, + ColSide::Left, + row + 7, + 0, + 0, + ), + ], + ); + let naming = &dev_naming.die[die.die].vnoc2[&(col, reg)]; + nnode.add_bel( + 0, + vnoc_grid.name_manual( + "NOC2_NSU512", + die.die, + naming.nsu_xy.0, + naming.nsu_xy.1, + ), + ); + nnode.add_bel( + 1, + vnoc_grid.name_manual( + "NOC2_NPS6X", + die.die, + naming.nps_xy.0, + naming.nps_xy.1, + ), + ); + nnode.add_bel( + 2, + vnoc_grid.name_manual( + "NOC2_NPS6X", + die.die, + naming.nps_xy.0, + naming.nps_xy.1 + 1, + ), + ); + nnode.add_bel( + 3, + vnoc_grid.name_manual( + "NOC2_NMU512", + die.die, + naming.nmu_xy.0, + naming.nmu_xy.1, + ), + ); + nnode.add_bel( + 4, + vnoc_grid.name_manual( + "NOC2_SCAN", + die.die, + naming.scan_xy.0, + naming.scan_xy.1, + ), + ); + } "MISR" => { let nnode = ngrid.name_node( nloc, diff --git a/prjcombine_versal_rd2db/src/grid.rs b/prjcombine_versal_rd2db/src/grid.rs index 09fba4d5..23fae1b8 100644 --- a/prjcombine_versal_rd2db/src/grid.rs +++ b/prjcombine_versal_rd2db/src/grid.rs @@ -64,10 +64,14 @@ fn make_columns( for (tkn, kind) in [ ("CLE_W_CORE", ColumnKind::Cle(CleKind::Plain)), + ("CLE_W_VR_CORE", ColumnKind::Cle(CleKind::Plain)), + ("DSP_LOCF_B_TILE", ColumnKind::Dsp), + ("DSP_LOCF_T_TILE", ColumnKind::Dsp), ("DSP_ROCF_B_TILE", ColumnKind::Dsp), ("DSP_ROCF_T_TILE", ColumnKind::Dsp), ("NOC_NSU512_TOP", ColumnKind::VNoc), ("NOC2_NSU512_VNOC_TILE", ColumnKind::VNoc2), + ("NOC2_NSU512_VNOC4_TILE", ColumnKind::VNoc4), ] { for c in int.find_columns(&[tkn]) { let c = int.lookup_column_inter(c); @@ -89,6 +93,8 @@ fn make_columns( } } for (tkn, kind) in [ + ("BRAM_LOCF_TL_TILE", ColumnKind::Bram(BramKind::Plain)), + ("BRAM_LOCF_BL_TILE", ColumnKind::Bram(BramKind::Plain)), ("BRAM_ROCF_TL_TILE", ColumnKind::Bram(BramKind::Plain)), ("BRAM_ROCF_BL_TILE", ColumnKind::Bram(BramKind::Plain)), ("URAM_LOCF_TL_TILE", ColumnKind::Uram), @@ -117,19 +123,29 @@ fn make_columns( res[c].l = ColumnKind::Cle(CleKind::Sll2); res[c - 1].r = ColumnKind::Cle(CleKind::Sll2); } - for c in int.find_columns(&["RCLK_BRAM_CLKBUF_CORE"]) { + for c in int.find_columns(&["RCLK_BRAM_CLKBUF_CORE", "RCLK_BRAM_CLKBUF_VR_CORE"]) { let c = int.lookup_column_inter(c); assert_eq!(res[c - 1].r, ColumnKind::Bram(BramKind::Plain)); res[c - 1].r = ColumnKind::Bram(BramKind::ClkBuf); } - for c in int.find_columns(&["RCLK_BRAM_CLKBUF_NOPD_CORE"]) { + for c in int.find_columns(&[ + "RCLK_BRAM_CLKBUF_NOPD_CORE", + "RCLK_BRAM_CLKBUF_NOPD_VR_CORE", + ]) { let c = int.lookup_column_inter(c); assert_eq!(res[c - 1].r, ColumnKind::Bram(BramKind::Plain)); res[c - 1].r = ColumnKind::Bram(BramKind::ClkBufNoPd); } + for c in int.find_columns(&["RCLK_BRAM_CORE", "RCLK_BRAM_VR_CORE"]) { + let c = int.lookup_column_inter(c); + if res[c - 1].r == ColumnKind::Bram(BramKind::ClkBufNoPd) { + res[c - 1].r = ColumnKind::Bram(BramKind::MaybeClkBufNoPd); + } + } for c in int.find_columns(&[ "BLI_CLE_TOP_CORE", + "BLI_DSP_LOCF_TR_TILE", "BLI_DSP_ROCF_TR_TILE", "BLI_BRAM_LOCF_TR_TILE", "BLI_BRAM_ROCF_TR_TILE", @@ -139,6 +155,7 @@ fn make_columns( } for c in int.find_columns(&[ "BLI_CLE_TOP_CORE_MY", + "BLI_DSP_LOCF_TL_TILE", "BLI_DSP_ROCF_TL_TILE", "BLI_BRAM_ROCF_TL_TILE", "BLI_URAM_LOCF_TL_TILE", @@ -165,7 +182,10 @@ fn make_columns( res[c].has_bli_bot_l = true; } - let col_cfrm = int.lookup_column_inter(int.find_column(&["CFRM_PMC_TILE"]).unwrap()); + let col_cfrm = int.lookup_column_inter( + int.find_column(&["CFRM_PMC_TILE", "CFRM_PMC_VR_TILE"]) + .unwrap(), + ); res[col_cfrm].l = ColumnKind::Cfrm; let mut hard_cells = BTreeMap::new(); @@ -178,6 +198,9 @@ fn make_columns( ("PCIEB5_BOT_TILE", HardRowKind::Pcie5), ("MRMAC_TOP_TILE", HardRowKind::Mrmac), ("MRMAC_BOT_TILE", HardRowKind::Mrmac), + ("SDFECA_TOP_TILE", HardRowKind::SdfecA), + ("DFE_CFC_BOT_TILE", HardRowKind::DfeCfcB), + ("DFE_CFC_TOP_TILE", HardRowKind::DfeCfcT), ("CPM_EXT_TILE", HardRowKind::CpmExt), ] { for (x, y) in int.find_tiles(&[tt]) { @@ -312,10 +335,19 @@ fn get_rows_gt_right(int: &IntGrid) -> Option> { ("VDU_CORE_MY", GtRowKind::Vdu), ("BFR_TILE_B_BOT_CORE", GtRowKind::BfrB), ("BFR_TILE_B_TOP_CORE", GtRowKind::BfrB), + ("ISP2_CORE", GtRowKind::Isp2), + ("VCU2_TILE", GtRowKind::Vcu2B), + ("RFADC_BOT_CORE", GtRowKind::RfAdc), + ("RFADC_TOP_CORE", GtRowKind::RfAdc), + ("RFDAC_BOT_CORE", GtRowKind::RfDac), + ("RFDAC_TOP_CORE", GtRowKind::RfDac), ] { for row in int.find_rows(&[tkn]) { let reg = RegId::from_idx(int.lookup_row(row).to_idx() / 48); res[reg] = kind; + if kind == GtRowKind::Vcu2B { + res[reg + 1] = GtRowKind::Vcu2T; + } } } if res.values().any(|&x| x != GtRowKind::None) { @@ -325,7 +357,7 @@ fn get_rows_gt_right(int: &IntGrid) -> Option> { } } -fn get_vnoc_naming(int: &IntGrid, naming: &mut DieNaming) { +fn get_vnoc_naming(int: &IntGrid, naming: &mut DieNaming, is_vnoc2_scan_offset: &mut bool) { for (x, y) in int.find_tiles(&["AMS_SAT_VNOC_TILE"]) { let col = int.lookup_column_inter(x); let reg = RegId::from_idx(int.lookup_row(y + 1).to_idx() / 48); @@ -333,8 +365,9 @@ fn get_vnoc_naming(int: &IntGrid, naming: &mut DieNaming) { x: x as u16, y: y as u16, }]; - let xy = extract_site_xy(int.rd, tile, "SYSMON_SAT").unwrap(); - naming.sysmon_sat_vnoc.insert((col, reg), xy); + if let Some(xy) = extract_site_xy(int.rd, tile, "SYSMON_SAT") { + naming.sysmon_sat_vnoc.insert((col, reg), xy); + } } for (x, y) in int.find_tiles(&["NOC2_NSU512_VNOC_TILE"]) { let col = int.lookup_column_inter(x); @@ -343,8 +376,12 @@ fn get_vnoc_naming(int: &IntGrid, naming: &mut DieNaming) { x: x as u16, y: y as u16, }; - let nps_a_crd = nsu_crd.delta(0, 4); - let nmu_crd = nsu_crd.delta(0, 11); + let mut nps_a_crd = nsu_crd.delta(0, 4); + if int.rd.tile_kinds.key(int.rd.tiles[&nps_a_crd].kind) == "NULL" { + *is_vnoc2_scan_offset = true; + nps_a_crd = nps_a_crd.delta(-1, 0); + } + let nmu_crd = nps_a_crd.delta(0, 7); let scan_crd = nsu_crd.delta(1, 0); naming.vnoc2.insert( (col, reg), @@ -356,12 +393,37 @@ fn get_vnoc_naming(int: &IntGrid, naming: &mut DieNaming) { }, ); } + for (x, y) in int.find_tiles(&["NOC2_NSU512_VNOC4_TILE"]) { + let col = int.lookup_column_inter(x); + let reg = RegId::from_idx(int.lookup_row(y + 1).to_idx() / 48); + let nsu_crd = Coord { + x: x as u16, + y: y as u16, + }; + let mut nps_a_crd = nsu_crd.delta(0, 4); + if int.rd.tile_kinds.key(int.rd.tiles[&nps_a_crd].kind) == "NULL" { + *is_vnoc2_scan_offset = true; + nps_a_crd = nps_a_crd.delta(-1, 0); + } + let nmu_crd = nps_a_crd.delta(0, 7); + let scan_crd = nsu_crd.delta(1, 0); + naming.vnoc2.insert( + (col, reg), + VNoc2Naming { + nsu_xy: extract_site_xy(int.rd, &int.rd.tiles[&nsu_crd], "NOC2_NSU512").unwrap(), + nmu_xy: extract_site_xy(int.rd, &int.rd.tiles[&nmu_crd], "NOC2_NMU512").unwrap(), + nps_xy: extract_site_xy(int.rd, &int.rd.tiles[&nps_a_crd], "NOC2_NPS6X").unwrap(), + scan_xy: extract_site_xy(int.rd, &int.rd.tiles[&scan_crd], "NOC2_SCAN").unwrap(), + }, + ); + } } fn get_grid( die: DieId, int: &IntGrid<'_>, disabled: &mut BTreeSet, + is_vnoc2_scan_offset: &mut bool, ) -> (Grid, DieNaming) { let mut naming = DieNaming { hdio: BTreeMap::new(), @@ -373,6 +435,8 @@ fn get_grid( PsKind::Ps9 } else if !int.find_tiles(&["PSXL_CORE"]).is_empty() { PsKind::PsX + } else if !int.find_tiles(&["PSXC_TILE"]).is_empty() { + PsKind::PsXc } else { unreachable!() }; @@ -398,6 +462,7 @@ fn get_grid( } else { RightKind::Term }; + let is_vr = !int.find_tiles(&["CLE_W_VR_CORE"]).is_empty(); let grid = Grid { columns, cols_vbrk: get_cols_vbrk(int), @@ -408,11 +473,12 @@ fn get_grid( ps, cpm, has_xram_top, + is_vr, top: TopKind::Ssit, // XXX bottom: BotKind::Ssit, // XXX right, }; - get_vnoc_naming(int, &mut naming); + get_vnoc_naming(int, &mut naming, is_vnoc2_scan_offset); (grid, naming) } @@ -434,6 +500,7 @@ pub fn make_grids( }; let mut grids = EntityVec::new(); let mut namings = EntityVec::new(); + let mut is_vnoc2_scan_offset = false; if ikind == InterposerKind::Column { let mut rows_slr_split: BTreeSet<_> = find_rows(rd, &["NOC_TNOC_BRIDGE_BOT_CORE"]) .into_iter() @@ -445,7 +512,7 @@ pub fn make_grids( for (dieid, w) in rows_slr_split.windows(2).enumerate() { let int = extract_int_slr_column(rd, &["INT"], &[], *w[0], *w[1]); let die = DieId::from_idx(dieid); - let (grid, naming) = get_grid(die, &int, &mut disabled); + let (grid, naming) = get_grid(die, &int, &mut disabled, &mut is_vnoc2_scan_offset); grids.push(grid); namings.push(naming); } @@ -500,7 +567,7 @@ pub fn make_grids( .enumerate() { let die = DieId::from_idx(dieid); - let (grid, naming) = get_grid(die, &int, &mut disabled); + let (grid, naming) = get_grid(die, &int, &mut disabled, &mut is_vnoc2_scan_offset); grids.push(grid); namings.push(naming); } @@ -658,6 +725,7 @@ pub fn make_grids( DeviceNaming { die: namings, is_dsp_v2, + is_vnoc2_scan_offset, }, ) } diff --git a/prjcombine_versal_rd2db/src/int.rs b/prjcombine_versal_rd2db/src/int.rs index a2ea7643..d87f5516 100644 --- a/prjcombine_versal_rd2db/src/int.rs +++ b/prjcombine_versal_rd2db/src/int.rs @@ -486,6 +486,30 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { }, w, ); + builder.extra_name_tile( + match ew { + Dir::E => "CLE_W_VR_CORE", + Dir::W => "CLE_E_VR_CORE", + _ => unreachable!(), + }, + match i { + 0 => "CLE_SLICEL_VR_TOP_0_CLK", + 1 => "CLE_SLICEM_VR_TOP_1_CLK", + 2 => "CLE_SLICEL_VR_TOP_0_RST", + 3 => "CLE_SLICEM_VR_TOP_1_RST", + 4 => "CLE_SLICEL_VR_TOP_0_CKEN1", + 5 => "CLE_SLICEL_VR_TOP_0_CKEN2", + 6 => "CLE_SLICEL_VR_TOP_0_CKEN3", + 7 => "CLE_SLICEL_VR_TOP_0_CKEN4", + 8 => "CLE_SLICEM_VR_TOP_1_WE", + 9 => "CLE_SLICEM_VR_TOP_1_CKEN1", + 10 => "CLE_SLICEM_VR_TOP_1_CKEN2", + 11 => "CLE_SLICEM_VR_TOP_1_CKEN3", + 12 => "CLE_SLICEM_VR_TOP_1_CKEN4", + _ => unreachable!(), + }, + w, + ); } } @@ -783,7 +807,12 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { builder.extract_term_conn("TERM.S", Dir::S, "TERM_B_INT_TILE", &[]); builder.extract_term_conn("TERM.N", Dir::N, "TERM_T_INT_TILE", &[]); - for tkn in ["RCLK_INT_L_FT", "RCLK_INT_R_FT"] { + for tkn in [ + "RCLK_INT_L_FT", + "RCLK_INT_R_FT", + "RCLK_INT_L_VR_FT", + "RCLK_INT_R_VR_FT", + ] { for &xy in rd.tiles_by_kind_name(tkn) { let int_xy = builder.delta(xy, 0, 1); let mut int_xy_b = builder.delta(xy, 0, -1); @@ -802,9 +831,11 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { for (tkn, kind, key0, key1) in [ ("CLE_W_CORE", "CLE_R", "SLICE_L0", "SLICE_L1"), ("CLE_E_CORE", "CLE_L", "SLICE_R0", "SLICE_R1"), + ("CLE_W_VR_CORE", "CLE_R.VR", "SLICE_L0", "SLICE_L1"), + ("CLE_E_VR_CORE", "CLE_L.VR", "SLICE_R0", "SLICE_R1"), ] { if let Some(&xy) = rd.tiles_by_kind_name(tkn).iter().next() { - let int_xy = if kind == "CLE_R" { + let int_xy = if kind == "CLE_R" || kind == "CLE_R.VR" { builder.walk_to_int(xy, Dir::W, false).unwrap() } else { builder.walk_to_int(xy, Dir::E, false).unwrap() @@ -846,6 +877,8 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { for (dir, tkn) in [ (Dir::E, "BRAM_LOCF_BR_TILE"), (Dir::E, "BRAM_LOCF_TR_TILE"), + (Dir::W, "BRAM_LOCF_BL_TILE"), + (Dir::W, "BRAM_LOCF_TL_TILE"), (Dir::E, "BRAM_ROCF_BR_TILE"), (Dir::E, "BRAM_ROCF_TR_TILE"), (Dir::W, "BRAM_ROCF_BL_TILE"), @@ -971,7 +1004,12 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { } } - for tkn in ["DSP_ROCF_B_TILE", "DSP_ROCF_T_TILE"] { + for tkn in [ + "DSP_LOCF_B_TILE", + "DSP_LOCF_T_TILE", + "DSP_ROCF_B_TILE", + "DSP_ROCF_T_TILE", + ] { if let Some(&xy) = rd.tiles_by_kind_name(tkn).iter().next() { let mut bels = vec![]; for i in 0..2 { @@ -1075,6 +1113,9 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { ("PCIE5", "PCIEB5_TOP_TILE", "PCIE50", false), ("MRMAC", "MRMAC_BOT_TILE", "MRMAC", false), ("MRMAC", "MRMAC_TOP_TILE", "MRMAC", false), + ("DFE_CFC_BOT", "DFE_CFC_BOT_TILE", "DFE_CFC_BOT", false), + ("DFE_CFC_TOP", "DFE_CFC_TOP_TILE", "DFE_CFC_TOP", false), + ("SDFEC", "SDFECA_TOP_TILE", "SDFEC_A", false), ("DCMAC", "DCMAC_TILE", "DCMAC", true), ("ILKN", "ILKN_TILE", "ILKNF", true), ("HSC", "HSC_TILE", "HSC", true), @@ -1173,17 +1214,26 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { } } - for (tkn, naming_f, naming_h, swz) in [ + for (tkn, naming_f, naming_h, bkind, swz) in [ ( "RCLK_CLE_CORE", "RCLK_CLE", "RCLK_CLE.HALF", + "BUFDIV_LEAF", BUFDIV_LEAF_SWZ_A, ), + ( + "RCLK_CLE_VR_CORE", + "RCLK_CLE.VR", + "RCLK_CLE.HALF.VR", + "BUFDIV_LEAF_ULVT", + BUFDIV_LEAF_SWZ_B, + ), ( "RCLK_CLE_LAG_CORE", "RCLK_CLE.LAG", "RCLK_CLE.HALF.LAG", + "BUFDIV_LEAF", BUFDIV_LEAF_SWZ_B, ), ] { @@ -1191,7 +1241,10 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { let mut done_half = false; for &xy in rd.tiles_by_kind_name(tkn) { let td = &rd.tiles[&builder.delta(xy, 0, -1)]; - let is_full = rd.tile_kinds.key(td.kind) == "CLE_W_CORE"; + let is_full = matches!( + &rd.tile_kinds.key(td.kind)[..], + "CLE_W_CORE" | "CLE_W_VR_CORE" + ); if is_full { if done_full { continue; @@ -1206,7 +1259,7 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { let mut bels = vec![]; for (i, &y) in swz.iter().enumerate() { let mut bel = builder - .bel_xy(format!("BUFDIV_LEAF.CLE.{i}"), "BUFDIV_LEAF", 0, y as u8) + .bel_xy(format!("BUFDIV_LEAF.CLE.{i}"), bkind, 0, y as u8) .pin_name_only("I", 1) .pin_name_only("O_CASC", 1); if i != 0 { @@ -1253,31 +1306,147 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { } } - for (dir, naming, tkn, intf_dx, swz, has_dfx) in [ - (Dir::E, "DSP", "RCLK_DSP_CORE", 0, BUFDIV_LEAF_SWZ_A, false), - (Dir::W, "DSP", "RCLK_DSP_CORE", 3, BUFDIV_LEAF_SWZ_AH, true), - (Dir::E, "HB", "RCLK_HB_CORE", 0, BUFDIV_LEAF_SWZ_A, false), - (Dir::W, "HB", "RCLK_HB_CORE", 2, BUFDIV_LEAF_SWZ_AH, false), + for (dir, naming, tkn, bkind, intf_dx, swz, has_dfx) in [ + ( + Dir::E, + "DSP", + "RCLK_DSP_CORE", + "BUFDIV_LEAF", + 0, + BUFDIV_LEAF_SWZ_A, + false, + ), + ( + Dir::W, + "DSP", + "RCLK_DSP_CORE", + "BUFDIV_LEAF", + 3, + BUFDIV_LEAF_SWZ_AH, + true, + ), + ( + Dir::E, + "DSP.VR", + "RCLK_DSP_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), + ( + Dir::W, + "DSP.VR", + "RCLK_DSP_VR_CORE", + "BUFDIV_LEAF_ULVT", + 3, + BUFDIV_LEAF_SWZ_BH, + true, + ), + ( + Dir::E, + "HB", + "RCLK_HB_CORE", + "BUFDIV_LEAF", + 0, + BUFDIV_LEAF_SWZ_A, + false, + ), + ( + Dir::E, + "HB.VR", + "RCLK_HB_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), + ( + Dir::W, + "HB", + "RCLK_HB_CORE", + "BUFDIV_LEAF", + 2, + BUFDIV_LEAF_SWZ_AH, + false, + ), + ( + Dir::W, + "HB.VR", + "RCLK_HB_VR_CORE", + "BUFDIV_LEAF_ULVT", + 2, + BUFDIV_LEAF_SWZ_BH, + false, + ), + ( + Dir::E, + "SDFEC", + "RCLK_SDFEC_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), + ( + Dir::W, + "SDFEC", + "RCLK_SDFEC_CORE", + "BUFDIV_LEAF_ULVT", + 2, + BUFDIV_LEAF_SWZ_BH, + false, + ), ( Dir::E, "HDIO", "RCLK_HDIO_CORE", + "BUFDIV_LEAF", 0, BUFDIV_LEAF_SWZ_A, false, ), + ( + Dir::E, + "HDIO.VR", + "RCLK_HDIO_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), ( Dir::W, "HDIO", "RCLK_HDIO_CORE", + "BUFDIV_LEAF", 2, BUFDIV_LEAF_SWZ_AH, false, ), + ( + Dir::W, + "HDIO.VR", + "RCLK_HDIO_VR_CORE", + "BUFDIV_LEAF_ULVT", + 2, + BUFDIV_LEAF_SWZ_BH, + false, + ), ( Dir::E, "HB_HDIO", "RCLK_HB_HDIO_CORE", + "BUFDIV_LEAF", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), + ( + Dir::E, + "HB_HDIO.VR", + "RCLK_HB_HDIO_VR_CORE", + "BUFDIV_LEAF_ULVT", 0, BUFDIV_LEAF_SWZ_B, false, @@ -1286,6 +1455,16 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { Dir::W, "HB_HDIO", "RCLK_HB_HDIO_CORE", + "BUFDIV_LEAF", + 2, + BUFDIV_LEAF_SWZ_BH, + false, + ), + ( + Dir::W, + "HB_HDIO.VR", + "RCLK_HB_HDIO_VR_CORE", + "BUFDIV_LEAF_ULVT", 2, BUFDIV_LEAF_SWZ_BH, false, @@ -1294,6 +1473,16 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { Dir::W, "VNOC", "RCLK_INTF_L_CORE", + "BUFDIV_LEAF", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), + ( + Dir::W, + "VNOC.VR", + "RCLK_INTF_L_VR_CORE", + "BUFDIV_LEAF_ULVT", 0, BUFDIV_LEAF_SWZ_B, false, @@ -1302,6 +1491,16 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { Dir::E, "VNOC", "RCLK_INTF_R_CORE", + "BUFDIV_LEAF", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), + ( + Dir::E, + "VNOC.VR", + "RCLK_INTF_R_VR_CORE", + "BUFDIV_LEAF_ULVT", 0, BUFDIV_LEAF_SWZ_B, false, @@ -1310,30 +1509,61 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { Dir::W, "CFRM", "RCLK_INTF_OPT_CORE", + "BUFDIV_LEAF", 0, BUFDIV_LEAF_SWZ_A, false, ), + ( + Dir::W, + "CFRM.VR", + "RCLK_INTF_OPT_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), ( Dir::W, "GT", "RCLK_INTF_TERM_LEFT_CORE", + "BUFDIV_LEAF", 1, BUFDIV_LEAF_SWZ_A, false, ), + ( + Dir::W, + "GT.VR", + "RCLK_INTF_TERM_LEFT_VR_CORE", + "BUFDIV_LEAF_ULVT", + 1, + BUFDIV_LEAF_SWZ_B, + false, + ), ( Dir::E, "GT", "RCLK_INTF_TERM_RIGHT_CORE", + "BUFDIV_LEAF", 0, BUFDIV_LEAF_SWZ_A, false, ), + ( + Dir::E, + "GT.VR", + "RCLK_INTF_TERM_RIGHT_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + false, + ), ( Dir::E, "GT.ALT", "RCLK_INTF_TERM2_RIGHT_CORE", + "BUFDIV_LEAF", 0, BUFDIV_LEAF_SWZ_B, false, @@ -1342,39 +1572,97 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { Dir::W, "BRAM", "RCLK_BRAM_CORE_MY", + "BUFDIV_LEAF", 1, BUFDIV_LEAF_SWZ_A, true, ), + ( + Dir::W, + "BRAM.VR", + "RCLK_BRAM_VR_CORE_MY", + "BUFDIV_LEAF_ULVT", + 1, + BUFDIV_LEAF_SWZ_B, + true, + ), ( Dir::W, "URAM", "RCLK_URAM_CORE_MY", + "BUFDIV_LEAF", 1, BUFDIV_LEAF_SWZ_A, true, ), - (Dir::E, "BRAM", "RCLK_BRAM_CORE", 0, BUFDIV_LEAF_SWZ_A, true), + ( + Dir::W, + "URAM.VR", + "RCLK_URAM_VR_CORE_MY", + "BUFDIV_LEAF_ULVT", + 1, + BUFDIV_LEAF_SWZ_B, + true, + ), + ( + Dir::E, + "BRAM", + "RCLK_BRAM_CORE", + "BUFDIV_LEAF", + 0, + BUFDIV_LEAF_SWZ_A, + true, + ), + ( + Dir::E, + "BRAM.VR", + "RCLK_BRAM_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + true, + ), ( Dir::E, "BRAM.CLKBUF", "RCLK_BRAM_CLKBUF_CORE", + "BUFDIV_LEAF", 0, BUFDIV_LEAF_SWZ_A, true, ), + ( + Dir::E, + "BRAM.CLKBUF.VR", + "RCLK_BRAM_CLKBUF_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, + true, + ), ( Dir::E, "BRAM.CLKBUF.NOPD", "RCLK_BRAM_CLKBUF_NOPD_CORE", + "BUFDIV_LEAF", 0, - BUFDIV_LEAF_SWZ_A, + BUFDIV_LEAF_SWZ_B, + true, + ), + ( + Dir::E, + "BRAM.CLKBUF.NOPD.VR", + "RCLK_BRAM_CLKBUF_NOPD_VR_CORE", + "BUFDIV_LEAF_ULVT", + 0, + BUFDIV_LEAF_SWZ_B, true, ), ( Dir::W, "HB_FULL", "RCLK_HB_FULL_R_CORE", + "BUFDIV_LEAF", 0, BUFDIV_LEAF_SWZ_B, false, @@ -1383,6 +1671,7 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { Dir::E, "HB_FULL", "RCLK_HB_FULL_L_CORE", + "BUFDIV_LEAF", 0, BUFDIV_LEAF_SWZ_B, false, @@ -1424,7 +1713,7 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { let mut bels = vec![]; for (i, &y) in swz.iter().enumerate() { let mut bel = builder - .bel_xy(format!("BUFDIV_LEAF.{dir}.{i}"), "BUFDIV_LEAF", 0, y as u8) + .bel_xy(format!("BUFDIV_LEAF.{dir}.{i}"), bkind, 0, y as u8) .pin_name_only("I", 1) .pin_name_only("O_CASC", 1); if i != 0 { @@ -1485,104 +1774,156 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { } } - if let Some(&xy) = rd.tiles_by_kind_name("RCLK_HDIO_CORE").iter().next() { - let bel_dpll = builder - .bel_virtual("RCLK_HDIO_DPLL") - .extra_wire("OUT_S", &["IF_RCLK_BOT_CLK_TO_DPLL"]) - .extra_wire("OUT_N", &["IF_RCLK_TOP_CLK_TO_DPLL"]); - let mut bel_hdio = builder.bel_virtual("RCLK_HDIO"); - for i in 0..4 { - bel_hdio = bel_hdio - .extra_wire( - format!("BUFGCE_OUT_S{i}"), - &[format!("IF_RCLK_BOT_CLK_FROM_BUFG{i}")], - ) - .extra_wire( - format!("BUFGCE_OUT_N{i}"), - &[format!("IF_RCLK_TOP_CLK_FROM_BUFG{i}")], - ); - } - let swz = [ - 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 12, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 14, - ]; - for (i, si) in swz.into_iter().enumerate() { - bel_hdio = bel_hdio - .extra_wire(format!("HDISTR{i}"), &[format!("IF_HCLK_CLK_HDISTR{i}")]) - .extra_wire( - format!("HDISTR{i}_MUX"), - &[format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT")], - ); - } - for i in 0..12 { - bel_hdio = bel_hdio - .extra_wire(format!("HROUTE{i}"), &[format!("IF_HCLK_CLK_HROUTE{i}")]) - .extra_wire( - format!("HROUTE{i}_MUX"), - &[format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT", si = 24 + i)], - ); + for (tkn, naming) in [ + ("RCLK_HDIO_CORE", "RCLK_HDIO"), + ("RCLK_HDIO_VR_CORE", "RCLK_HDIO.VR"), + ] { + if let Some(&xy) = rd.tiles_by_kind_name(tkn).iter().next() { + let bel_dpll = builder + .bel_virtual("RCLK_HDIO_DPLL") + .extra_wire("OUT_S", &["IF_RCLK_BOT_CLK_TO_DPLL"]) + .extra_wire("OUT_N", &["IF_RCLK_TOP_CLK_TO_DPLL"]); + let mut bel_hdio = builder.bel_virtual("RCLK_HDIO"); + for i in 0..4 { + bel_hdio = bel_hdio + .extra_wire( + format!("BUFGCE_OUT_S{i}"), + &[format!("IF_RCLK_BOT_CLK_FROM_BUFG{i}")], + ) + .extra_wire( + format!("BUFGCE_OUT_N{i}"), + &[format!("IF_RCLK_TOP_CLK_FROM_BUFG{i}")], + ); + } + let swz = [ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 12, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, + 14, + ]; + for (i, si) in swz.into_iter().enumerate() { + bel_hdio = bel_hdio + .extra_wire( + format!("HDISTR{i}"), + &[ + format!("IF_HCLK_CLK_HDISTR{i}"), + match i { + 0..8 => format!("CLK_HDISTR_LSB{i}"), + 8..12 | 20..24 => format!("CLK_CMT_DRVR_TRI_ULVT_{si}_CLK_OUT_B"), + 12..20 => format!("CLK_HDISTR_MSB{ii}", ii = i - 12), + _ => unreachable!(), + }, + ], + ) + .extra_wire( + format!("HDISTR{i}_MUX"), + &[ + format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT"), + format!("CLK_CMT_MUX_8TO1_ULVT_{si}_CLK_OUT"), + ], + ); + } + for i in 0..12 { + bel_hdio = bel_hdio + .extra_wire(format!("HROUTE{i}"), &[format!("IF_HCLK_CLK_HROUTE{i}")]) + .extra_wire( + format!("HROUTE{i}_MUX"), + &[ + format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT", si = 24 + i), + format!("CLK_CMT_MUX_8TO1_ULVT_{si}_CLK_OUT", si = 24 + i), + ], + ); + } + builder + .xnode("RCLK_HDIO", naming, xy) + .num_tiles(0) + .bel(bel_hdio) + .bel(bel_dpll) + .extract(); } - builder - .xnode("RCLK_HDIO", "RCLK_HDIO", xy) - .num_tiles(0) - .bel(bel_hdio) - .bel(bel_dpll) - .extract(); } - if let Some(&xy) = rd.tiles_by_kind_name("RCLK_HB_HDIO_CORE").iter().next() { - let bel_dpll = builder - .bel_virtual("RCLK_HDIO_DPLL") - .extra_wire("OUT_S", &["IF_RCLK_BOT_CLK_TO_DPLL"]) - .extra_wire("OUT_N", &["CLK_CMT_MUX_24_ENC_1_CLK_OUT"]); - let mut bel_hdio = builder.bel_virtual("RCLK_HB_HDIO"); - for i in 0..4 { - bel_hdio = bel_hdio.extra_wire( - format!("BUFGCE_OUT_S{i}"), - &[format!("IF_RCLK_BOT_CLK_FROM_BUFG{i}")], - ); - } - let swz = [ - 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 12, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, 14, - ]; - for (i, si) in swz.into_iter().enumerate() { - bel_hdio = bel_hdio - .extra_wire(format!("HDISTR{i}"), &[format!("IF_HCLK_CLK_HDISTR{i}")]) + for (tkn, naming) in [ + ("RCLK_HB_HDIO_CORE", "RCLK_HB_HDIO"), + ("RCLK_HB_HDIO_VR_CORE", "RCLK_HB_HDIO.VR"), + ] { + if let Some(&xy) = rd.tiles_by_kind_name(tkn).iter().next() { + let bel_dpll = builder + .bel_virtual("RCLK_HDIO_DPLL") + .extra_wire("OUT_S", &["IF_RCLK_BOT_CLK_TO_DPLL"]) .extra_wire( - format!("HDISTR{i}_MUX"), - &[format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT")], + "OUT_N", + &[ + "CLK_CMT_MUX_24_ENC_1_CLK_OUT", + "CLK_CMT_MUX_24_ENC_ULVT_1_CLK_OUT", + ], ); - let b = [ - 0, 92, 120, 124, 128, 132, 136, 140, 8, 12, 4, 48, 16, 28, 32, 36, 40, 44, 52, 56, - 60, 64, 20, 24, - ][i]; - for j in 0..4 { + let mut bel_hdio = builder.bel_virtual("RCLK_HB_HDIO"); + for i in 0..4 { bel_hdio = bel_hdio.extra_wire( - format!("HDISTR{i}_MUX_DUMMY{j}"), - &[format!("GND_WIRE{k}", k = b + j)], + format!("BUFGCE_OUT_S{i}"), + &[format!("IF_RCLK_BOT_CLK_FROM_BUFG{i}")], ); } - } - for i in 0..12 { - bel_hdio = bel_hdio - .extra_wire(format!("HROUTE{i}"), &[format!("IF_HCLK_CLK_HROUTE{i}")]) - .extra_wire( - format!("HROUTE{i}_MUX"), - &[format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT", si = 24 + i)], - ); - let b = [68, 72, 76, 80, 84, 88, 96, 100, 104, 108, 112, 116][i]; - for j in 0..4 { - bel_hdio = bel_hdio.extra_wire( - format!("HROUTE{i}_MUX_DUMMY{j}"), - &[format!("GND_WIRE{k}", k = b + j)], - ); + let swz = [ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 12, 15, 16, 17, 18, 19, 20, 21, 22, 23, 13, + 14, + ]; + for (i, si) in swz.into_iter().enumerate() { + bel_hdio = bel_hdio + .extra_wire( + format!("HDISTR{i}"), + &[ + format!("IF_HCLK_CLK_HDISTR{i}"), + match i { + 0..8 => format!("CLK_HDISTR_LSB{i}"), + 8..12 | 20..24 => format!("CLK_CMT_DRVR_TRI_ULVT_{si}_CLK_OUT_B"), + 12..20 => format!("CLK_HDISTR_MSB{ii}", ii = i - 12), + _ => unreachable!(), + }, + ], + ) + .extra_wire( + format!("HDISTR{i}_MUX"), + &[ + format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT"), + format!("CLK_CMT_MUX_8TO1_ULVT_{si}_CLK_OUT"), + ], + ); + let b = [ + 0, 92, 120, 124, 128, 132, 136, 140, 8, 12, 4, 48, 16, 28, 32, 36, 40, 44, 52, + 56, 60, 64, 20, 24, + ][i]; + for j in 0..4 { + bel_hdio = bel_hdio.extra_wire( + format!("HDISTR{i}_MUX_DUMMY{j}"), + &[format!("GND_WIRE{k}", k = b + j)], + ); + } } + for i in 0..12 { + bel_hdio = bel_hdio + .extra_wire(format!("HROUTE{i}"), &[format!("IF_HCLK_CLK_HROUTE{i}")]) + .extra_wire( + format!("HROUTE{i}_MUX"), + &[ + format!("CLK_CMT_MUX_8TO1_{si}_CLK_OUT", si = 24 + i), + format!("CLK_CMT_MUX_8TO1_ULVT_{si}_CLK_OUT", si = 24 + i), + ], + ); + let b = [68, 72, 76, 80, 84, 88, 96, 100, 104, 108, 112, 116][i]; + for j in 0..4 { + bel_hdio = bel_hdio.extra_wire( + format!("HROUTE{i}_MUX_DUMMY{j}"), + &[format!("GND_WIRE{k}", k = b + j)], + ); + } + } + builder + .xnode("RCLK_HB_HDIO", naming, xy) + .num_tiles(0) + .bel(bel_hdio) + .bel(bel_dpll) + .extract(); } - builder - .xnode("RCLK_HB_HDIO", "RCLK_HB_HDIO", xy) - .num_tiles(0) - .bel(bel_hdio) - .bel(bel_dpll) - .extract(); } // XXX RCLK_CLKBUF @@ -1667,9 +2008,12 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { } if let Some(&nsu_xy) = rd.tiles_by_kind_name("NOC2_NSU512_VNOC_TILE").iter().next() { - let nps_a_xy = builder.delta(nsu_xy, 0, 4); - let nps_b_xy = builder.delta(nsu_xy, 0, 8); - let nmu_xy = builder.delta(nsu_xy, 0, 11); + let mut nps_a_xy = builder.delta(nsu_xy, 0, 4); + if rd.tile_kinds.key(rd.tiles[&nps_a_xy].kind) == "NULL" { + nps_a_xy = builder.delta(nps_a_xy, -1, 0); + } + let nps_b_xy = builder.delta(nps_a_xy, 0, 4); + let nmu_xy = builder.delta(nps_a_xy, 0, 7); let scan_xy = builder.delta(nsu_xy, 1, 0); let intf_l = builder.ndb.get_node_naming("INTF.E"); let intf_r = builder.ndb.get_node_naming("INTF.W"); @@ -1724,8 +2068,88 @@ pub fn make_int_db(rd: &Part, dev_naming: &DeviceNaming) -> (IntDb, NamingDb) { .raw_tile(nmu_xy) .raw_tile(scan_xy); for i in 0..48 { - let intf_l_xy = xn.builder.delta(nsu_xy, -1, -9 + (i + i / 4) as i32); - let intf_r_xy = xn.builder.delta(nsu_xy, 3, -9 + (i + i / 4) as i32); + let intf_l_xy = xn.builder.delta(nps_a_xy, -1, -13 + (i + i / 4) as i32); + let intf_r_xy = xn.builder.delta(nps_a_xy, 3, -13 + (i + i / 4) as i32); + + xn = xn + .ref_single(intf_l_xy, i, intf_l) + .ref_single(intf_r_xy, i + 48, intf_r) + } + xn.bels(bels).extract(); + } + + if let Some(&nsu_xy) = rd + .tiles_by_kind_name("NOC2_NSU512_VNOC4_TILE") + .iter() + .next() + { + let nps_a_xy = builder.delta(nsu_xy, -1, 4); + let nps_b_xy = builder.delta(nps_a_xy, 0, 4); + let nmu_xy = builder.delta(nps_a_xy, 0, 7); + let scan_xy = builder.delta(nsu_xy, 1, 0); + let intf_l = builder.ndb.get_node_naming("INTF.E"); + let intf_r = builder.ndb.get_node_naming("INTF.W"); + let mut bel_scan = builder.bel_xy("VNOC4_SCAN", "NOC2_SCAN", 0, 0).raw_tile(4); + for i in 7..15 { + bel_scan = bel_scan + .pin_name_only(&format!("NOC2_SCAN_CHNL_FROM_PL_{i}_"), 1) + .pin_name_only(&format!("NOC2_SCAN_CHNL_TO_PL_{i}_"), 1); + } + for i in 7..14 { + bel_scan = bel_scan.pin_name_only(&format!("NOC2_SCAN_CHNL_MASK_FROM_PL_{i}_"), 1); + } + let bels = [ + builder + .bel_xy("VNOC4_NSU512", "NOC2_NSU512", 0, 0) + .pin_name_only("TO_NOC", 1) + .pin_name_only("FROM_NOC", 1), + builder + .bel_xy("VNOC4_NPS_A", "NOC2_NPS6X", 0, 0) + .raw_tile(1) + .pin_name_only("IN_0", 1) + .pin_name_only("IN_1", 1) + .pin_name_only("IN_2", 1) + .pin_name_only("IN_3", 1) + .pin_name_only("IN_4", 1) + .pin_name_only("IN_5", 1) + .pin_name_only("OUT_0", 1) + .pin_name_only("OUT_1", 1) + .pin_name_only("OUT_2", 1) + .pin_name_only("OUT_3", 1) + .pin_name_only("OUT_4", 1) + .pin_name_only("OUT_5", 1), + builder + .bel_xy("VNOC4_NPS_B", "NOC2_NPS6X", 0, 0) + .raw_tile(2) + .pin_name_only("IN_0", 1) + .pin_name_only("IN_1", 1) + .pin_name_only("IN_2", 1) + .pin_name_only("IN_3", 1) + .pin_name_only("IN_4", 1) + .pin_name_only("IN_5", 1) + .pin_name_only("OUT_0", 1) + .pin_name_only("OUT_1", 1) + .pin_name_only("OUT_2", 1) + .pin_name_only("OUT_3", 1) + .pin_name_only("OUT_4", 1) + .pin_name_only("OUT_5", 1), + builder + .bel_xy("VNOC4_NMU512", "NOC2_NMU512", 0, 0) + .raw_tile(3) + .pin_name_only("TO_NOC", 1) + .pin_name_only("FROM_NOC", 1), + bel_scan, + ]; + let mut xn = builder + .xnode("VNOC4", "VNOC4", nsu_xy) + .num_tiles(96) + .raw_tile(nps_a_xy) + .raw_tile(nps_b_xy) + .raw_tile(nmu_xy) + .raw_tile(scan_xy); + for i in 0..48 { + let intf_l_xy = xn.builder.delta(nps_a_xy, -1, -13 + (i + i / 4) as i32); + let intf_r_xy = xn.builder.delta(nps_a_xy, 5, -13 + (i + i / 4) as i32); xn = xn .ref_single(intf_l_xy, i, intf_l) diff --git a/prjcombine_versal_rdverify/src/lib.rs b/prjcombine_versal_rdverify/src/lib.rs index 6ad85c49..0f017d25 100644 --- a/prjcombine_versal_rdverify/src/lib.rs +++ b/prjcombine_versal_rdverify/src/lib.rs @@ -351,7 +351,8 @@ fn verify_hardip( vrf.verify_bel(bel, kind, &[], &[]); } -fn verify_bufdiv_leaf(vrf: &mut Verifier, bel: &BelContext<'_>) { +fn verify_bufdiv_leaf(endev: &ExpandedNamedDevice, vrf: &mut Verifier, bel: &BelContext<'_>) { + let grid = endev.edev.grids[bel.die]; let mut pins = vec![("I", SitePinDir::In), ("O_CASC", SitePinDir::Out)]; if !bel.bel.pins.contains_key("O") { pins.push(("O", SitePinDir::Out)); @@ -367,7 +368,16 @@ fn verify_bufdiv_leaf(vrf: &mut Verifier, bel: &BelContext<'_>) { vrf.claim_node(&[bel.fwire("I_CASC")]); vrf.claim_pip(bel.crd(), bel.wire("I_CASC"), obel.wire_far("O_CASC")); } - vrf.verify_bel(bel, "BUFDIV_LEAF", &pins, &[]); + vrf.verify_bel( + bel, + if grid.is_vr { + "BUFDIV_LEAF_ULVT" + } else { + "BUFDIV_LEAF" + }, + &pins, + &[], + ); vrf.claim_node(&[bel.fwire("O_CASC")]); vrf.claim_node(&[bel.fwire_far("O_CASC")]); @@ -698,11 +708,13 @@ fn verify_rclk_hb_hdio(_endev: &ExpandedNamedDevice, vrf: &mut Verifier, bel: &B } fn verify_vnoc_nxu512(vrf: &mut Verifier, bel: &BelContext<'_>) { - let (kind, obel_key) = match bel.key { - "VNOC_NSU512" => ("NOC_NSU512", "VNOC_NPS_A"), - "VNOC_NMU512" => ("NOC_NMU512", "VNOC_NPS_B"), - "VNOC2_NSU512" => ("NOC2_NSU512", "VNOC2_NPS_A"), - "VNOC2_NMU512" => ("NOC2_NMU512", "VNOC2_NPS_B"), + let (kind, obel_key, obel_pin) = match bel.key { + "VNOC_NSU512" => ("NOC_NSU512", "VNOC_NPS_A", "OUT_3"), + "VNOC_NMU512" => ("NOC_NMU512", "VNOC_NPS_B", "OUT_3"), + "VNOC2_NSU512" => ("NOC2_NSU512", "VNOC2_NPS_A", "OUT_3"), + "VNOC2_NMU512" => ("NOC2_NMU512", "VNOC2_NPS_B", "OUT_3"), + "VNOC4_NSU512" => ("NOC2_NSU512", "VNOC4_NPS_A", "OUT_3"), + "VNOC4_NMU512" => ("NOC2_NMU512", "VNOC4_NPS_B", "OUT_0"), _ => unreachable!(), }; vrf.verify_bel( @@ -715,7 +727,7 @@ fn verify_vnoc_nxu512(vrf: &mut Verifier, bel: &BelContext<'_>) { vrf.claim_node(&[bel.fwire("FROM_NOC")]); vrf.claim_node(&[bel.fwire_far("TO_NOC")]); let obel = vrf.find_bel_sibling(bel, obel_key); - vrf.verify_node(&[bel.fwire_far("FROM_NOC"), obel.fwire_far("OUT_3")]); + vrf.verify_node(&[bel.fwire_far("FROM_NOC"), obel.fwire_far(obel_pin)]); vrf.claim_pip(bel.crd(), bel.wire_far("TO_NOC"), bel.wire("TO_NOC")); vrf.claim_pip(bel.crd(), bel.wire("FROM_NOC"), bel.wire_far("FROM_NOC")); } @@ -781,15 +793,81 @@ fn verify_vnoc_nps(vrf: &mut Verifier, bel: &BelContext<'_>) { } } +fn verify_vnoc_nps6x(vrf: &mut Verifier, bel: &BelContext<'_>) { + vrf.verify_bel( + bel, + "NOC2_NPS6X", + &[ + ("OUT_0", SitePinDir::Out), + ("OUT_1", SitePinDir::Out), + ("OUT_2", SitePinDir::Out), + ("OUT_3", SitePinDir::Out), + ("OUT_4", SitePinDir::Out), + ("OUT_5", SitePinDir::Out), + ("IN_0", SitePinDir::In), + ("IN_1", SitePinDir::In), + ("IN_2", SitePinDir::In), + ("IN_3", SitePinDir::In), + ("IN_4", SitePinDir::In), + ("IN_5", SitePinDir::In), + ], + &[], + ); + for pin in ["OUT_0", "OUT_1", "OUT_2", "OUT_3", "OUT_4", "OUT_5"] { + vrf.claim_node(&[bel.fwire(pin)]); + vrf.claim_node(&[bel.fwire_far(pin)]); + vrf.claim_pip(bel.crd(), bel.wire_far(pin), bel.wire(pin)); + } + for pin in ["IN_0", "IN_1", "IN_2", "IN_3", "IN_4", "IN_5"] { + vrf.claim_node(&[bel.fwire(pin)]); + vrf.claim_pip(bel.crd(), bel.wire(pin), bel.wire_far(pin)); + } + if bel.key == "VNOC4_NPS_A" { + let obel_nxu = vrf.find_bel_sibling(bel, "VNOC4_NSU512"); + let obel_nps = vrf.find_bel_sibling(bel, "VNOC4_NPS_B"); + vrf.verify_node(&[bel.fwire_far("IN_3"), obel_nxu.fwire_far("TO_NOC")]); + vrf.verify_node(&[bel.fwire_far("IN_0"), obel_nps.fwire_far("OUT_3")]); + } else { + let obel_nxu = vrf.find_bel_sibling(bel, "VNOC4_NMU512"); + let obel_nps = vrf.find_bel_sibling(bel, "VNOC4_NPS_A"); + vrf.verify_node(&[bel.fwire_far("IN_0"), obel_nxu.fwire_far("TO_NOC")]); + vrf.verify_node(&[bel.fwire_far("IN_3"), obel_nps.fwire_far("OUT_0")]); + } + if let Some(obel_s) = vrf.find_bel_delta(bel, 0, -48, bel.key) { + vrf.verify_node(&[bel.fwire_far("IN_4"), obel_s.fwire_far("OUT_2")]); + vrf.verify_node(&[bel.fwire_far("IN_5"), obel_s.fwire_far("OUT_1")]); + } else { + vrf.claim_node(&[bel.fwire_far("IN_4")]); + vrf.claim_node(&[bel.fwire_far("IN_5")]); + } + if let Some(obel_n) = vrf.find_bel_delta(bel, 0, 48, bel.key) { + vrf.verify_node(&[bel.fwire_far("IN_2"), obel_n.fwire_far("OUT_4")]); + vrf.verify_node(&[bel.fwire_far("IN_1"), obel_n.fwire_far("OUT_5")]); + } else { + vrf.claim_node(&[bel.fwire_far("IN_2")]); + vrf.claim_node(&[bel.fwire_far("IN_1")]); + } +} + fn verify_vnoc_scan(vrf: &mut Verifier, bel: &BelContext<'_>) { let mut outps = vec![]; let mut inps = vec![]; - for i in 6..15 { - outps.push(format!("NOC2_SCAN_CHNL_TO_PL_{i}_")); - inps.push(format!("NOC2_SCAN_CHNL_FROM_PL_{i}_")) - } - for i in 5..14 { - inps.push(format!("NOC2_SCAN_CHNL_MASK_FROM_PL_{i}_")); + if bel.key == "VNOC2_SCAN" { + for i in 6..15 { + outps.push(format!("NOC2_SCAN_CHNL_TO_PL_{i}_")); + inps.push(format!("NOC2_SCAN_CHNL_FROM_PL_{i}_")) + } + for i in 5..14 { + inps.push(format!("NOC2_SCAN_CHNL_MASK_FROM_PL_{i}_")); + } + } else { + for i in 7..15 { + outps.push(format!("NOC2_SCAN_CHNL_TO_PL_{i}_")); + inps.push(format!("NOC2_SCAN_CHNL_FROM_PL_{i}_")) + } + for i in 7..14 { + inps.push(format!("NOC2_SCAN_CHNL_MASK_FROM_PL_{i}_")); + } } let mut pins = vec![]; for ipin in &inps { @@ -824,23 +902,26 @@ fn verify_bel(endev: &ExpandedNamedDevice, vrf: &mut Verifier, bel: &BelContext< "DCMAC" => verify_hardip(endev, vrf, bel, "DCMAC"), "ILKN" => verify_hardip(endev, vrf, bel, "ILKNF"), "HSC" => verify_hardip(endev, vrf, bel, "HSC"), + "SDFEC" => verify_hardip(endev, vrf, bel, "SDFEC_A"), + "DFE_CFC_BOT" => verify_hardip(endev, vrf, bel, "DFE_CFC_BOT"), + "DFE_CFC_TOP" => verify_hardip(endev, vrf, bel, "DFE_CFC_TOP"), "RCLK_DFX_TEST.E" | "RCLK_DFX_TEST.W" => vrf.verify_bel(bel, "RCLK_DFX_TEST", &[], &[]), "SYSMON_SAT.VNOC" => vrf.verify_bel(bel, "SYSMON_SAT", &[], &[]), "DPLL.HDIO" => verify_dpll_hdio(endev, vrf, bel), "RCLK_HDIO_DPLL" => verify_rclk_hdio_dpll(vrf, bel), "RCLK_HDIO" => verify_rclk_hdio(endev, vrf, bel), "RCLK_HB_HDIO" => verify_rclk_hb_hdio(endev, vrf, bel), - "VNOC_NSU512" | "VNOC_NMU512" | "VNOC2_NSU512" | "VNOC2_NMU512" => { - verify_vnoc_nxu512(vrf, bel) - } + "VNOC_NSU512" | "VNOC_NMU512" | "VNOC2_NSU512" | "VNOC2_NMU512" | "VNOC4_NSU512" + | "VNOC4_NMU512" => verify_vnoc_nxu512(vrf, bel), "VNOC_NPS_A" | "VNOC_NPS_B" | "VNOC2_NPS_A" | "VNOC2_NPS_B" => verify_vnoc_nps(vrf, bel), - "VNOC2_SCAN" => verify_vnoc_scan(vrf, bel), + "VNOC4_NPS_A" | "VNOC4_NPS_B" => verify_vnoc_nps6x(vrf, bel), + "VNOC2_SCAN" | "VNOC4_SCAN" => verify_vnoc_scan(vrf, bel), "HDIO_BIAS" | "RPI_HD_APB" | "HDLOGIC_APB" | "MISR" => { vrf.verify_bel(bel, bel.key, &[], &[]) } _ if bel.key.starts_with("SLICE") => verify_slice(vrf, bel), - _ if bel.key.starts_with("BUFDIV_LEAF") => verify_bufdiv_leaf(vrf, bel), + _ if bel.key.starts_with("BUFDIV_LEAF") => verify_bufdiv_leaf(endev, vrf, bel), _ if bel.key.starts_with("RCLK_HDISTR_LOC") => verify_rclk_hdistr_loc(endev, vrf, bel), _ if bel.key.starts_with("HDIOB") => verify_hdiob(vrf, bel), _ if bel.key.starts_with("HDIOLOGIC") => verify_hdiologic(vrf, bel),