From 8df4a74879d368bc4e4bc4aa1bc5089e265d6eff Mon Sep 17 00:00:00 2001 From: Wanda Date: Wed, 29 May 2024 07:34:22 +0000 Subject: [PATCH] ise_hammer: 2v ppc. --- prjcombine_ise_hammer/src/fgen.rs | 26 ++++++++ prjcombine_ise_hammer/src/main.rs | 9 ++- prjcombine_ise_hammer/src/ppc.rs | 1 + prjcombine_ise_hammer/src/ppc/virtex2.rs | 83 ++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 prjcombine_ise_hammer/src/ppc.rs create mode 100644 prjcombine_ise_hammer/src/ppc/virtex2.rs diff --git a/prjcombine_ise_hammer/src/fgen.rs b/prjcombine_ise_hammer/src/fgen.rs index 5a04888e..3eeb943f 100644 --- a/prjcombine_ise_hammer/src/fgen.rs +++ b/prjcombine_ise_hammer/src/fgen.rs @@ -557,6 +557,8 @@ pub enum TileBits { BTSpine, #[allow(clippy::upper_case_acronyms)] LLV, + #[allow(clippy::upper_case_acronyms)] + PPC, } impl TileBits { @@ -688,6 +690,30 @@ impl TileBits { vec![edev.btile_llv(col)] } } + TileBits::PPC => match backend.edev { + ExpandedDevice::Virtex2(edev) => { + let mut res = vec![]; + for i in 0..16 { + res.push(edev.btile_main(col, row + i)); + } + for i in 0..16 { + res.push(edev.btile_main(col + 9, row + i)); + } + for i in 1..9 { + res.push(edev.btile_main(col + i, row)); + } + for i in 1..9 { + res.push(edev.btile_main(col + i, row + 15)); + } + res + } + ExpandedDevice::Virtex4(edev) => match edev.kind { + prjcombine_virtex4::grid::GridKind::Virtex4 => todo!(), + prjcombine_virtex4::grid::GridKind::Virtex5 => todo!(), + _ => unreachable!(), + }, + _ => unreachable!(), + }, } } } diff --git a/prjcombine_ise_hammer/src/main.rs b/prjcombine_ise_hammer/src/main.rs index 8d8ec337..ba7477f2 100644 --- a/prjcombine_ise_hammer/src/main.rs +++ b/prjcombine_ise_hammer/src/main.rs @@ -15,6 +15,7 @@ mod dsp; mod fgen; mod fuzz; mod int; +mod ppc; mod tiledb; use backend::IseBackend; @@ -64,6 +65,9 @@ fn main() -> Result<(), Box> { if edev.grid.kind == prjcombine_virtex2::grid::GridKind::Spartan3ADsp { dsp::spartan3adsp::add_fuzzers(&mut hammer, &backend); } + if edev.grid.kind.is_virtex2p() { + ppc::virtex2::add_fuzzers(&mut hammer, &backend); + } } ExpandedDevice::Spartan6(_) => { clb::virtex5::add_fuzzers(&mut hammer, &backend); @@ -110,7 +114,10 @@ fn main() -> Result<(), Box> { clb::virtex2::collect_fuzzers(&mut ctx); bram::virtex2::collect_fuzzers(&mut ctx); if edev.grid.kind == prjcombine_virtex2::grid::GridKind::Spartan3ADsp { - dsp::spartan3adsp::collect_fuzzers(&mut ctx) + dsp::spartan3adsp::collect_fuzzers(&mut ctx); + } + if edev.grid.kind.is_virtex2p() { + ppc::virtex2::collect_fuzzers(&mut ctx); } } ExpandedDevice::Spartan6(_) => { diff --git a/prjcombine_ise_hammer/src/ppc.rs b/prjcombine_ise_hammer/src/ppc.rs new file mode 100644 index 00000000..9d90a457 --- /dev/null +++ b/prjcombine_ise_hammer/src/ppc.rs @@ -0,0 +1 @@ +pub mod virtex2; \ No newline at end of file diff --git a/prjcombine_ise_hammer/src/ppc/virtex2.rs b/prjcombine_ise_hammer/src/ppc/virtex2.rs new file mode 100644 index 00000000..0040509b --- /dev/null +++ b/prjcombine_ise_hammer/src/ppc/virtex2.rs @@ -0,0 +1,83 @@ +use prjcombine_hammer::Session; +use prjcombine_int::db::{BelId, PinDir}; +use unnamed_entity::EntityId; + +use crate::{ + backend::IseBackend, diff::CollectorCtx, fgen::TileBits, fuzz::FuzzCtx, fuzz_enum, fuzz_one, +}; + +pub fn add_fuzzers<'a>(session: &mut Session>, backend: &IseBackend<'a>) { + let intdb = backend.egrid.db; + for tile in ["RBPPC", "LBPPC"] { + let node_kind = intdb.get_node(tile); + if backend.egrid.node_index[node_kind].is_empty() { + continue; + } + let bel = BelId::from_idx(0); + let ctx = FuzzCtx { + session, + node_kind, + bits: TileBits::PPC, + tile_name: tile, + bel, + bel_name: "PPC405", + }; + fuzz_one!(ctx, "PRESENT", "1", [], [(mode "PPC405")]); + let bel_data = &intdb.nodes[node_kind].bels[bel]; + for (pin, pin_data) in &bel_data.pins { + if pin_data.dir != PinDir::Input { + continue; + } + assert_eq!(pin_data.wires.len(), 1); + let wire = *pin_data.wires.first().unwrap(); + if intdb.wires.key(wire.1).starts_with("IMUX.G") { + continue; + } + let pininv = format!("{pin}INV").leak(); + let pin_b = &*format!("{pin}_B").leak(); + fuzz_enum!(ctx, pininv, [pin, pin_b], [(mode "PPC405"), (pin pin)]); + } + fuzz_enum!(ctx, "PPC405_TEST_MODE", ["CORE_TEST", "GASKET_TEST"], [(mode "PPC405")]); + } +} + +pub fn collect_fuzzers(ctx: &mut CollectorCtx) { + let egrid = ctx.edev.egrid(); + for tile in ["RBPPC", "LBPPC"] { + let node_kind = egrid.db.get_node(tile); + if egrid.node_index[node_kind].is_empty() { + continue; + } + let bel = "PPC405"; + ctx.state.get_diff(tile, bel, "PRESENT", "1").assert_empty(); + let bel_data = &egrid.db.nodes[node_kind].bels[BelId::from_idx(0)]; + for (pin, pin_data) in &bel_data.pins { + if pin_data.dir != PinDir::Input { + continue; + } + assert_eq!(pin_data.wires.len(), 1); + let wire = *pin_data.wires.first().unwrap(); + if egrid.db.wires.key(wire.1).starts_with("IMUX.G") { + continue; + } + let int_tiles = &["INT.PPC"; 48]; + if egrid.db.wires.key(wire.1).starts_with("IMUX.CE") + || egrid.db.wires.key(wire.1).starts_with("IMUX.TI") + { + // yup. inverted polarity. + let pininv = format!("{pin}INV").leak(); + let pin_b = format!("{pin}_B").leak(); + let item = ctx.extract_enum_bool(tile, bel, pininv, pin_b, pin); + ctx.insert_int_inv(int_tiles, tile, bel, pin, item); + } else { + ctx.collect_int_inv(int_tiles, tile, bel, pin); + } + } + ctx.state + .get_diff(tile, bel, "PPC405_TEST_MODE", "CORE_TEST") + .assert_empty(); + ctx.state + .get_diff(tile, bel, "PPC405_TEST_MODE", "GASKET_TEST") + .assert_empty(); + } +}