Skip to content

Commit

Permalink
add untested bscan order code to xc2000, virtex, virtex2, spartan6.
Browse files Browse the repository at this point in the history
  • Loading branch information
wanda-phi committed Dec 21, 2024
1 parent eaf2f64 commit a418b4f
Show file tree
Hide file tree
Showing 22 changed files with 606 additions and 68 deletions.
90 changes: 90 additions & 0 deletions prjcombine_spartan6/src/bscan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use std::collections::BTreeMap;

use prjcombine_int::grid::{EdgeIoCoord, TileIobId};
use prjcombine_types::bscan::{BScanBuilder, BScanPin};
use unnamed_entity::EntityId;

use crate::{
bond::CfgPin,
grid::{ColumnIoKind, Grid},
};

#[derive(Debug)]
pub struct BScan {
pub bits: usize,
pub io: BTreeMap<EdgeIoCoord, BScanPin>,
pub cfg: BTreeMap<CfgPin, BScanPin>,
}

impl Grid {
pub fn get_bscan(&self) -> BScan {
let mut io = BTreeMap::new();
let mut cfg = BTreeMap::new();
let mut builder = BScanBuilder::new();
// TIO
for (col, &cd) in self.columns.iter().rev() {
if cd.tio == ColumnIoKind::None {
continue;
}
for (iob, unused) in [
// inner
(0, cd.tio == ColumnIoKind::Outer),
(1, cd.tio == ColumnIoKind::Outer),
// outer
(2, cd.tio == ColumnIoKind::Inner),
(3, cd.tio == ColumnIoKind::Inner),
] {
if !unused {
let crd = EdgeIoCoord::T(col, TileIobId::from_idx(iob));
io.insert(crd, builder.get_toi());
}
}
}
// LIO
for (row, &rd) in self.rows.iter().rev() {
if rd.lio {
for iob in [0, 1] {
let crd = EdgeIoCoord::L(row, TileIobId::from_idx(iob));
io.insert(crd, builder.get_toi());
}
}
}
cfg.insert(CfgPin::ProgB, builder.get_toi());
// BIO
for (col, &cd) in &self.columns {
if cd.bio == ColumnIoKind::None {
continue;
}
for (iob, unused) in [
// inner
(0, cd.bio == ColumnIoKind::Outer),
(1, cd.bio == ColumnIoKind::Outer),
// outer
(2, cd.bio == ColumnIoKind::Inner),
(3, cd.bio == ColumnIoKind::Inner),
] {
if !unused {
let crd = EdgeIoCoord::B(col, TileIobId::from_idx(iob));
io.insert(crd, builder.get_toi());
}
}
}
cfg.insert(CfgPin::Done, builder.get_toi());
cfg.insert(CfgPin::CmpCsB, builder.get_toi());
cfg.insert(CfgPin::Suspend, builder.get_toi());
// RIO
for (row, &rd) in &self.rows {
if rd.rio {
for iob in [0, 1] {
let crd = EdgeIoCoord::R(row, TileIobId::from_idx(iob));
io.insert(crd, builder.get_toi());
}
}
}
BScan {
bits: builder.bits,
io,
cfg,
}
}
}
55 changes: 5 additions & 50 deletions prjcombine_spartan6/src/expand.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use enum_map::EnumMap;
use prjcombine_int::db::{Dir, IntDb};
use prjcombine_int::grid::{
ColId, Coord, EdgeIoCoord, ExpandedDieRefMut, ExpandedGrid, Rect, RowId, TileIobId,
};
use prjcombine_int::grid::{ColId, Coord, ExpandedDieRefMut, ExpandedGrid, Rect, RowId};
use prjcombine_virtex_bitstream::{
BitstreamGeom, DeviceKind, DieBitstreamGeom, FrameAddr, FrameInfo,
};
Expand All @@ -22,7 +20,6 @@ struct Expander<'a, 'b> {
frame_info: Vec<FrameInfo>,
bram_frame_info: Vec<FrameInfo>,
iob_frame_len: usize,
io: Vec<EdgeIoCoord>,
col_frame: EntityVec<RegId, EntityVec<ColId, usize>>,
col_width: EntityVec<ColId, usize>,
spine_frame: EntityVec<RegId, usize>,
Expand Down Expand Up @@ -203,7 +200,7 @@ impl Expander<'_, '_> {
for (row, &rd) in &self.grid.rows {
if rd.lio {
self.fill_ioi((col, row));
self.fill_iob((col, row));
self.die.add_xnode((col, row), "IOB", &[]);
} else {
self.die.add_xnode((col, row), "INTF", &[(col, row)]);
if row == self.grid.row_bio_outer() {
Expand Down Expand Up @@ -245,7 +242,7 @@ impl Expander<'_, '_> {
for (row, &rd) in self.grid.rows.iter().rev() {
if rd.rio {
self.fill_ioi((col, row));
self.fill_iob((col, row));
self.die.add_xnode((col, row), "IOB", &[]);
} else {
self.die.add_xnode((col, row), "INTF", &[(col, row)]);
if row == self.grid.row_bio_outer() {
Expand Down Expand Up @@ -301,7 +298,7 @@ impl Expander<'_, '_> {
] {
self.fill_ioi((col, row));
if !unused {
self.fill_iob((col, row));
self.die.add_xnode((col, row), "IOB", &[]);
}
}
let row = self.grid.row_tio_outer();
Expand Down Expand Up @@ -331,7 +328,7 @@ impl Expander<'_, '_> {
] {
self.fill_ioi((col, row));
if !unused {
self.fill_iob((col, row));
self.die.add_xnode((col, row), "IOB", &[]);
}
}
let row = self.grid.row_bio_outer();
Expand Down Expand Up @@ -816,44 +813,6 @@ impl Expander<'_, '_> {
self.die.add_xnode(crd, kind, &[crd]);
}

fn fill_iob(&mut self, crd: Coord) {
self.die.add_xnode(crd, "IOB", &[]);
let (crd_p, crd_n) = if crd.0 == self.grid.col_lio() {
(
EdgeIoCoord::L(crd.1, TileIobId::from_idx(1)),
EdgeIoCoord::L(crd.1, TileIobId::from_idx(0)),
)
} else if crd.0 == self.grid.col_rio() {
(
EdgeIoCoord::R(crd.1, TileIobId::from_idx(1)),
EdgeIoCoord::R(crd.1, TileIobId::from_idx(0)),
)
} else if crd.1 == self.grid.row_bio_outer() {
(
EdgeIoCoord::B(crd.0, TileIobId::from_idx(3)),
EdgeIoCoord::B(crd.0, TileIobId::from_idx(2)),
)
} else if crd.1 == self.grid.row_bio_inner() {
(
EdgeIoCoord::B(crd.0, TileIobId::from_idx(1)),
EdgeIoCoord::B(crd.0, TileIobId::from_idx(0)),
)
} else if crd.1 == self.grid.row_tio_outer() {
(
EdgeIoCoord::T(crd.0, TileIobId::from_idx(3)),
EdgeIoCoord::T(crd.0, TileIobId::from_idx(2)),
)
} else if crd.1 == self.grid.row_tio_inner() {
(
EdgeIoCoord::T(crd.0, TileIobId::from_idx(1)),
EdgeIoCoord::T(crd.0, TileIobId::from_idx(0)),
)
} else {
unreachable!()
};
self.io.extend([crd_p, crd_n]);
}

fn fill_intf_rterm(&mut self, crd: Coord) {
self.die.fill_term(crd, "TERM.E");
self.die.add_xnode(crd, "INTF", &[crd]);
Expand Down Expand Up @@ -1019,7 +978,6 @@ impl Grid {
frame_info: vec![],
bram_frame_info: vec![],
iob_frame_len: 0,
io: vec![],
col_frame: EntityVec::new(),
col_width: EntityVec::new(),
spine_frame: EntityVec::new(),
Expand Down Expand Up @@ -1050,8 +1008,6 @@ impl Grid {
expander.fill_frame_info();
expander.fill_iob_frame_info();

let io = expander.io;

let die_bs_geom = DieBitstreamGeom {
frame_len: 1040,
frame_info: expander.frame_info,
Expand Down Expand Up @@ -1081,7 +1037,6 @@ impl Grid {
egrid,
site_holes,
bs_geom,
io,
col_frame,
col_width,
spine_frame,
Expand Down
3 changes: 1 addition & 2 deletions prjcombine_spartan6/src/expanded.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use enum_map::EnumMap;
use prjcombine_int::{
db::Dir,
grid::{ColId, DieId, EdgeIoCoord, ExpandedGrid, Rect, RowId},
grid::{ColId, DieId, ExpandedGrid, Rect, RowId},
};
use prjcombine_virtex_bitstream::{BitTile, BitstreamGeom};
use std::collections::{BTreeSet, HashMap};
Expand All @@ -15,7 +15,6 @@ pub struct ExpandedDevice<'a> {
pub egrid: ExpandedGrid<'a>,
pub site_holes: Vec<Rect>,
pub bs_geom: BitstreamGeom,
pub io: Vec<EdgeIoCoord>,
pub col_frame: EntityVec<RegId, EntityVec<ColId, usize>>,
pub col_width: EntityVec<ColId, usize>,
pub spine_frame: EntityVec<RegId, usize>,
Expand Down
57 changes: 57 additions & 0 deletions prjcombine_spartan6/src/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,63 @@ impl Grid {
}
}

pub fn get_bonded_ios(&self) -> Vec<EdgeIoCoord> {
let mut res = vec![];
// TIO
for (col, &cd) in &self.columns {
if cd.tio == ColumnIoKind::None {
continue;
}
for (iob, unused) in [
// outer
(3, cd.tio == ColumnIoKind::Inner),
(2, cd.tio == ColumnIoKind::Inner),
// inner
(1, cd.tio == ColumnIoKind::Outer),
(0, cd.tio == ColumnIoKind::Outer),
] {
if !unused {
res.push(EdgeIoCoord::T(col, TileIobId::from_idx(iob)));
}
}
}
// RIO
for (row, &rd) in self.rows.iter().rev() {
if rd.rio {
for iob in [1, 0] {
res.push(EdgeIoCoord::R(row, TileIobId::from_idx(iob)));
}
}
}
// BIO
for (col, &cd) in self.columns.iter().rev() {
if cd.bio == ColumnIoKind::None {
continue;
}
for (iob, unused) in [
// outer
(3, cd.bio == ColumnIoKind::Inner),
(2, cd.bio == ColumnIoKind::Inner),
// inner
(1, cd.bio == ColumnIoKind::Outer),
(0, cd.bio == ColumnIoKind::Outer),
] {
if !unused {
res.push(EdgeIoCoord::B(col, TileIobId::from_idx(iob)));
}
}
}
// LIO
for (row, &rd) in &self.rows {
if rd.lio {
for iob in [1, 0] {
res.push(EdgeIoCoord::L(row, TileIobId::from_idx(iob)));
}
}
}
res
}

pub fn to_json(&self) -> serde_json::Value {
json!({
"columns": Vec::from_iter(self.columns.values().map(|column| {
Expand Down
1 change: 1 addition & 0 deletions prjcombine_spartan6/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod bond;
pub mod bscan;
pub mod db;
mod expand;
pub mod expanded;
Expand Down
2 changes: 1 addition & 1 deletion prjcombine_spartan6_naming/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ pub fn name_device<'a>(edev: &'a ExpandedDevice<'a>, ndb: &'a NamingDb) -> Expan
}

let mut pad_cnt = 1;
for &io in &edev.io {
for io in edev.grid.get_bonded_ios() {
let (col, row, bel) = grid.get_io_loc(io);
let layer = edev
.egrid
Expand Down
8 changes: 4 additions & 4 deletions prjcombine_spartan6_rd2db/src/bond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ pub fn make_bond(endev: &ExpandedNamedDevice, pins: &[PkgPin]) -> Bond {
let mut io_banks = BTreeMap::new();
let mut vref = BTreeSet::new();
let io_lookup: HashMap<_, _> = endev
.edev
.io
.iter()
.map(|&io| (endev.get_io_name(io), io))
.grid
.get_bonded_ios()
.into_iter()
.map(|io| (endev.get_io_name(io), io))
.collect();
let mut gt_lookup: HashMap<_, (String, u32, GtPin)> = HashMap::new();
for gt in endev.get_gts() {
Expand Down
46 changes: 46 additions & 0 deletions prjcombine_types/src/bscan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum BScanPin {
Input(usize),
Output(usize),
OutputTristate(usize, usize),
OutputEnable(usize, usize),
InputOutputTristate(usize, usize, usize),
InputOutputEnable(usize, usize, usize),
}

#[derive(Debug, Default)]
pub struct BScanBuilder {
pub bits: usize,
}

impl BScanBuilder {
pub fn new() -> Self {
Self { bits: 0 }
}

pub fn get_toi(&mut self) -> BScanPin {
let res = BScanPin::InputOutputTristate(self.bits + 2, self.bits + 1, self.bits);
self.bits += 3;
res
}

pub fn get_to(&mut self) -> BScanPin {
let res = BScanPin::OutputTristate(self.bits + 1, self.bits);
self.bits += 2;
res
}

pub fn get_o(&mut self) -> BScanPin {
let res = BScanPin::Output(self.bits);
self.bits += 1;
res
}

pub fn get_i(&mut self) -> BScanPin {
let res = BScanPin::Input(self.bits);
self.bits += 1;
res
}
}
1 change: 1 addition & 0 deletions prjcombine_types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use core::fmt::Debug;
use serde::{Deserialize, Serialize};
use unnamed_entity::entity_id;

pub mod bscan;
pub mod tiledb;

entity_id! {
Expand Down
Loading

0 comments on commit a418b4f

Please sign in to comment.