Skip to content

Commit

Permalink
fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
rohanku committed Dec 31, 2023
2 parents d89177a + 4019d4d commit 5e73c56
Show file tree
Hide file tree
Showing 12 changed files with 506 additions and 118 deletions.
151 changes: 81 additions & 70 deletions libs/atoll/src/abs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ use substrate::geometry::bbox::Bbox;
use substrate::geometry::transform::{Transformation, Translate, TranslateMut};
use substrate::layout::element::Text;

use substrate::context::PdkContext;
use substrate::geometry::dir::Dir;
use substrate::geometry::point::Point;
use substrate::geometry::rect::Rect;
use substrate::io::layout::Builder;
use substrate::layout::bbox::LayerBbox;
use substrate::layout::element::Shape;
use substrate::layout::element::{CellId, Element, RawCell};
use substrate::layout::{CellBuilder, Draw, DrawReceiver, ExportsLayoutData, Layout};
use substrate::pdk::layers::HasPin;
use substrate::pdk::layers::{HasPin, Layer};
use substrate::pdk::Pdk;
use substrate::schematic::ExportsNestedData;
use substrate::{arcstr, layout};
Expand All @@ -43,7 +45,7 @@ pub struct GridCoord {
///
/// There are three coordinate systems used within the abstract view.
/// * Physical coordinates: the raw physical coordinate system of the cell, expressed in PDK database units.
/// * Track coordinates: track indices indexing the ATOLL [`LayerStack`]. Track is 0 is typically centered at the origin, or immediately to the upper left of the origin.
/// * Track coordinates: track indices indexing the ATOLL [`LayerStack`]. Track 0 is typically centered at the origin, or immediately to the upper left of the origin.
/// * Grid coordinates: these have the same spacing as track coordinates, but are shifted so that (0, 0) is always at the lower left. These are used to index [`LayerAbstract`]s.
///
/// ATOLL provides the following utilities for converting between these coordinate systems:
Expand Down Expand Up @@ -171,6 +173,83 @@ impl Abstract {
pub fn physical_origin(&self) -> Point {
self.lcm_bounds.lower_left() * self.slice().lcm_units()
}

/// Generates an abstract view of a layout cell.
pub fn generate<PDK: Pdk, T: ExportsNestedData + ExportsLayoutData>(
ctx: &PdkContext<PDK>,
layout: &layout::Cell<T>,
) -> Abstract {
let stack = ctx
.get_installation::<LayerStack<PdkLayer>>()
.expect("must install ATOLL layer stack");
let virtual_layers = ctx.install_layers::<crate::VirtualLayers>();

let cell = layout.raw();
let bbox = cell
.layer_bbox(virtual_layers.outline.id())
.expect("cell must provide an outline on ATOLL virtual layer");

let top = top_layer(cell, &stack)
.expect("cell did not have any ATOLL routing layers; cannot produce an abstract");
let top = if top == 0 { 1 } else { top };

let slice = stack.slice(0..top + 1);

let xmin = div_floor(bbox.left(), slice.lcm_unit_width());
let xmax = div_ceil(bbox.right(), slice.lcm_unit_width());
let ymin = div_floor(bbox.bot(), slice.lcm_unit_height());
let ymax = div_ceil(bbox.top(), slice.lcm_unit_height());
let lcm_bounds = Rect::from_sides(xmin, ymin, xmax, ymax);

let nx = lcm_bounds.width();
let ny = lcm_bounds.height();

let grid = RoutingGrid::new((*stack).clone(), 0..top + 1);
let mut state = RoutingState::new((*stack).clone(), top, nx, ny);
let mut ports = Vec::new();
for (i, (_name, geom)) in cell.ports().enumerate() {
let net = NetId(i);
ports.push(net);
if let Some(layer) = stack.layer_idx(geom.primary.layer().drawing()) {
let rect = match geom.primary.shape() {
substrate::geometry::shape::Shape::Rect(r) => *r,
substrate::geometry::shape::Shape::Polygon(p) => {
p.bbox().expect("empty polygons are unsupported")
}
};
println!("source rect = {rect:?}");
if let Some(rect) = grid.shrink_to_grid(rect, layer) {
println!("grid rect = {rect:?}");
for x in rect.left()..=rect.right() {
for y in rect.bot()..=rect.top() {
let xofs = xmin * slice.lcm_unit_width() / grid.xpitch(layer);
let yofs = ymin * slice.lcm_unit_height() / grid.ypitch(layer);
state.layer_mut(layer)[((x - xofs) as usize, (y - yofs) as usize)] =
PointState::Routed {
net,
via_down: false,
via_up: false,
};
}
}
}
}
}

let layers = state
.layers
.into_iter()
.map(|states| LayerAbstract::Detailed { states })
.collect();

Abstract {
top_layer: top,
lcm_bounds,
grid: RoutingGrid::new((*stack).clone(), 0..top + 1),
ports,
layers,
}
}
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
Expand Down Expand Up @@ -375,74 +454,6 @@ fn top_layer_inner(
top
}

/// Generates an abstract view of a layout cell.
pub fn generate_abstract<T: ExportsNestedData + ExportsLayoutData>(
layout: &layout::Cell<T>,
stack: &LayerStack<PdkLayer>,
) -> Abstract {
let cell = layout.raw();
let bbox = cell.bbox().unwrap();

let top = top_layer(cell, stack)
.expect("cell did not have any ATOLL routing layers; cannot produce an abstract");
let top = if top == 0 { 1 } else { top };

let slice = stack.slice(0..top + 1);

let xmin = div_floor(bbox.left(), slice.lcm_unit_width());
let xmax = div_ceil(bbox.right(), slice.lcm_unit_width());
let ymin = div_floor(bbox.bot(), slice.lcm_unit_height());
let ymax = div_ceil(bbox.top(), slice.lcm_unit_height());
let lcm_bounds = Rect::from_sides(xmin, ymin, xmax, ymax);

let nx = lcm_bounds.width();
let ny = lcm_bounds.height();

let grid = RoutingGrid::new(stack.clone(), 0..top + 1);
let mut state = RoutingState::new(stack.clone(), top, nx, ny);
let mut ports = Vec::new();
for (i, (name, geom)) in cell.ports().enumerate() {
let net = NetId(i);
ports.push(net);
if let Some(layer) = stack.layer_idx(geom.primary.layer().drawing()) {
let rect = match geom.primary.shape() {
substrate::geometry::shape::Shape::Rect(r) => *r,
substrate::geometry::shape::Shape::Polygon(p) => {
p.bbox().expect("empty polygons are unsupported")
}
};
if let Some(rect) = grid.shrink_to_grid(rect, layer) {
for x in rect.left()..=rect.right() {
for y in rect.bot()..=rect.top() {
let xofs = xmin * slice.lcm_unit_width() / grid.xpitch(layer);
let yofs = ymin * slice.lcm_unit_height() / grid.ypitch(layer);
state.layer_mut(layer)[((x - xofs) as usize, (y - yofs) as usize)] =
PointState::Routed {
net,
via_down: false,
via_up: false,
};
}
}
}
}
}

let layers = state
.layers
.into_iter()
.map(|states| LayerAbstract::Detailed { states })
.collect();

Abstract {
top_layer: top,
lcm_bounds,
grid: RoutingGrid::new(stack.clone(), 0..top + 1),
ports,
layers,
}
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct DebugAbstract {
pub abs: Abstract,
Expand Down
25 changes: 22 additions & 3 deletions libs/atoll/src/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use grid::Grid;
use num::integer::{div_ceil, div_floor};
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Range};

use std::ops::Range;
use substrate::context::{ContextBuilder, Installation};
use substrate::geometry::corner::Corner;
use substrate::geometry::dims::Dims;
Expand Down Expand Up @@ -365,6 +364,26 @@ impl<L: AtollLayer> RoutingGrid<L> {
tracks.track(track)
}

/// The tracks on the given layer.
pub fn tracks(&self, layer: usize) -> UniformTracks {
self.stack.tracks(layer)
}

/// Returns the track grid for the given layer.
///
/// Returns a tuple containing the vertical going tracks followed by the horizontal going tracks.
/// In other words, the first element of the tuple is indexed by an x-coordinate,
/// and the second element of the tuple is indexed by a y-coordinate.
pub fn track_grid(&self, layer: usize) -> (UniformTracks, UniformTracks) {
let tracks = self.tracks(layer);
let adj_tracks = self.stack.tracks(self.grid_defining_layer(layer));

match self.stack.layer(layer).dir().track_dir() {
Dir::Horiz => (adj_tracks, tracks),
Dir::Vert => (tracks, adj_tracks),
}
}

/// Calculates the bounds of a particular track on the given layer.
///
/// The start and end coordinates are with respect to tracks on the grid defining layer.
Expand Down
21 changes: 17 additions & 4 deletions libs/atoll/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,15 @@ pub mod abs;
pub mod grid;
pub mod route;

use crate::abs::{generate_abstract, Abstract, DebugAbstract, InstanceAbstract};
use crate::abs::{Abstract, DebugAbstract, InstanceAbstract};
use crate::grid::{AtollLayer, LayerStack, PdkLayer};
use crate::route::Router;
use ena::unify::UnifyKey;
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::collections::HashMap;
use std::ops::Deref;

use std::sync::Arc;
use substrate::arcstr::ArcStr;
use substrate::block::Block;
Expand All @@ -166,8 +167,9 @@ use substrate::io::layout::{Builder, PortGeometry};
use substrate::io::schematic::{Bundle, Connect, Node, TerminalView};
use substrate::io::{FlatLen, Flatten};
use substrate::layout::element::Shape;

use substrate::layout::{ExportsLayoutData, Layout};
use substrate::pdk::layers::HasPin;
use substrate::pdk::layers::{HasPin, Layers};
use substrate::pdk::Pdk;
use substrate::schematic::schema::Schema;
use substrate::schematic::{CellId, ExportsNestedData, Schematic};
Expand All @@ -177,6 +179,16 @@ use substrate::{geometry, io, layout, schematic};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
pub struct NetId(pub(crate) usize);

/// Virtual layers for use in ATOLL.
#[derive(Layers)]
pub struct VirtualLayers {
/// The layer indicating the outline of an ATOLL tile.
///
/// Must be aligned to the LCM grid of the cell's top layer or,
/// if the cell's top layer is layer 0, layer 1.
pub outline: Outline,
}

/// The state of a point on a routing grid.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum PointState {
Expand Down Expand Up @@ -421,7 +433,8 @@ impl<'a, PDK: Pdk + Schema> TileBuilder<'a, PDK> {
let layout = self.layout.generate(block.clone());
let schematic = self.schematic.instantiate(block);
self.register_bundle(schematic.io());
let abs = generate_abstract(layout.raw_cell(), self.layer_stack.as_ref());
let abs = Abstract::generate(&self.layout.ctx, layout.raw_cell());

Instance {
layout,
schematic,
Expand All @@ -438,7 +451,7 @@ impl<'a, PDK: Pdk + Schema> TileBuilder<'a, PDK> {
let schematic = self.schematic.instantiate(wrapper);
self.register_bundle(schematic.io());
// todo: generate abstract from AtollTile trait directly
let abs = generate_abstract(layout.raw_cell(), self.layer_stack.as_ref());
let abs = Abstract::generate(&self.layout.ctx, layout.raw_cell());
Instance {
layout,
schematic,
Expand Down
2 changes: 1 addition & 1 deletion libs/geometry/src/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Shape {
}
}

/// If this shape is a rectangle, returns the contained polygon.
/// If this shape is a polygon, returns the contained polygon.
/// Otherwise, returns [`None`].
pub fn polygon(&self) -> Option<&Polygon> {
match self {
Expand Down
2 changes: 0 additions & 2 deletions libs/geometry/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,6 @@ impl<T: HasTransformedView> HasTransformedView for Vec<T> {

#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use approx::assert_relative_eq;

Expand Down
Loading

0 comments on commit 5e73c56

Please sign in to comment.