Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,29 @@ foundry via open PDKs and shuttle services like

## Devices

### Aegis Luna 1

A compact Aegis device targeting GF180MCU via [wafer.space](https://wafer.space)
(1x1 Full slot, 3.93 x 5.12mm die).

| Resource | Count |
|-------------------|---------------|
| LUT4 | ~760 |
| BRAM (128x8) | 40 tiles |
| DSP18 (18x18 MAC) | 40 tiles |
| I/O pads | 118 |
| SerDes | 1 |
| Clock tiles | 1 (4 outputs) |
| Routing tracks | 1 per edge |

```bash
nix build .#luna-1 # Generate IP (SV, JSON, chipdb, techmap)
nix build .#luna-1-tapeout # Full RTL-to-GDS for fab submission
```

### Aegis Terra 1

The first Aegis device, targeting GF180MCU via [wafer.space](https://wafer.space).
A larger Aegis device targeting Sky130.

| Resource | Count |
|-------------------|---------------|
Expand Down
42 changes: 42 additions & 0 deletions devices.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
aegis-ip-tools,
gf180mcu-pdk,
sky130-pdk,
}:
{
terra-1 = {
ip = aegis-ip-tools.mkIp {
deviceName = "terra_1";
width = 48;
height = 64;
tracks = 4;
serdesCount = 4;
bramColumnInterval = 16;
dspColumnInterval = 24;
clockTileCount = 2;
};
tapeout = {
pdk = sky130-pdk;
clockPeriodNs = 20;
};
};
luna-1 = {
ip = aegis-ip-tools.mkIp {
deviceName = "luna_1";
width = 19;
height = 40;
tracks = 1;
serdesCount = 1;
bramColumnInterval = 9;
dspColumnInterval = 10;
clockTileCount = 1;
};
tapeout = {
pdk = gf180mcu-pdk;
clockPeriodNs = 20;
dieWidthUm = 3930;
dieHeightUm = 5120;
tilePlacementDensities.SerDesTile = 0.5;
};
};
}
151 changes: 88 additions & 63 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -80,74 +80,99 @@
sky130-pdk = pkgs.callPackage ./pkgs/sky130-pdk { };
};

packages = {
default = pkgs.aegis-ip-tools;
ip-tools = pkgs.aegis-ip-tools;
terra-1 = pkgs.aegis-ip-tools.mkIp {
deviceName = "terra_1";
width = 48;
height = 64;
tracks = 4;
serdesCount = 4;
bramColumnInterval = 16;
dspColumnInterval = 24;
clockTileCount = 2;
};
terra-1-tapeout = self.packages.${system}.terra-1.mkTapeout {
pdk = pkgs.gf180mcu-pdk;
clockPeriodNs = 20;
};
terra-1-deb = self.packages.${system}.terra-1.deb;
terra-1-docker = self.packages.${system}.terra-1.docker;
};
packages =
let
devices = import ./devices.nix {
inherit (pkgs) aegis-ip-tools gf180mcu-pdk sky130-pdk;
};

mkDevicePackages = name: cfg: {
"${name}" = cfg.ip;
"${name}-tapeout" = cfg.ip.mkTapeout cfg.tapeout;
"${name}-deb" = cfg.ip.deb;
"${name}-docker" = cfg.ip.docker;
};
in
{
default = pkgs.aegis-ip-tools;
ip-tools = pkgs.aegis-ip-tools;
}
// lib.foldl' (acc: name: acc // mkDevicePackages name devices.${name}) { } (
builtins.attrNames devices
);

checks =
let
terra-1 = self.packages.${system}.terra-1;
devices = builtins.filter (
name:
let
pkg = self.packages.${system}.${name};
in
pkg ? deviceName && !(pkg ? tileMacros)
) (builtins.attrNames self.packages.${system});
mkDeviceChecks =
name:
let
ip = self.packages.${system}.${name};
tapeout = self.packages.${system}."${name}-tapeout";
in
{
"${name}-blinky" = pkgs.callPackage ./examples/blinky {
aegis-ip = ip;
};
"${name}-blinky-sim" = pkgs.callPackage ./tests/blinky-sim {
aegis-ip = ip;
};
"${name}-counter" = pkgs.callPackage ./tests/counter-verify {
aegis-ip = ip;
};
"${name}-shift-register" = pkgs.callPackage ./tests/shift-register {
aegis-ip = ip;
};
"${name}-logic-gates" = pkgs.callPackage ./tests/logic-gates {
aegis-ip = ip;
};
"${name}-tile-bits" = pkgs.callPackage ./tests/tile-bits-consistency {
aegis-ip = ip;
};
"${name}-synth-equiv-comb" = pkgs.callPackage ./tests/synth-equiv {
aegis-ip = ip;
design = "comb";
};
"${name}-synth-equiv-counter" = pkgs.callPackage ./tests/synth-equiv {
aegis-ip = ip;
design = "counter";
};
"${name}-formal-ip" = pkgs.callPackage ./tests/formal-ip {
aegis-ip = ip;
};
"${name}-gds-verify" = pkgs.callPackage ./tests/gds-verify {
aegis-tapeout = tapeout;
};
};
in
{
terra-1-blinky = pkgs.callPackage ./examples/blinky {
aegis-ip = terra-1;
};
terra-1-blinky-sim = pkgs.callPackage ./tests/blinky-sim {
aegis-ip = terra-1;
};
terra-1-counter = pkgs.callPackage ./tests/counter-verify {
aegis-ip = terra-1;
};
terra-1-shift-register = pkgs.callPackage ./tests/shift-register {
aegis-ip = terra-1;
};
terra-1-logic-gates = pkgs.callPackage ./tests/logic-gates {
aegis-ip = terra-1;
};
# Formal verification checks
terra-1-tile-bits = pkgs.callPackage ./tests/tile-bits-consistency {
aegis-ip = terra-1;
};
terra-1-synth-equiv-comb = pkgs.callPackage ./tests/synth-equiv {
aegis-ip = terra-1;
design = "comb";
};
terra-1-synth-equiv-counter = pkgs.callPackage ./tests/synth-equiv {
aegis-ip = terra-1;
design = "counter";
};
terra-1-formal-ip = pkgs.callPackage ./tests/formal-ip {
aegis-ip = terra-1;
};
terra-1-gds-verify = pkgs.callPackage ./tests/gds-verify {
aegis-tapeout = self.packages.${system}.terra-1-tapeout;
};
};
lib.foldl' (acc: name: acc // mkDeviceChecks name) { } devices;

devShells = {
default = pkgs.aegis-ip-tools.shell;
ip-tools = pkgs.aegis-ip-tools.shell;
terra-1 = self.packages.${system}.terra-1.shell;
terra-1-tapeout = self.packages.${system}.terra-1-tapeout.shell;
terra-1-blinky = self.checks.${system}.terra-1-blinky.shell;
};
devShells =
let
devices = builtins.filter (
name:
let
pkg = self.packages.${system}.${name};
in
pkg ? deviceName && !(pkg ? tileMacros)
) (builtins.attrNames self.packages.${system});
mkDeviceShells = name: {
"${name}" = self.packages.${system}.${name}.shell;
"${name}-tapeout" = self.packages.${system}."${name}-tapeout".shell;
"${name}-blinky" = self.checks.${system}."${name}-blinky".shell;
};
in
{
default = pkgs.aegis-ip-tools.shell;
ip-tools = pkgs.aegis-ip-tools.shell;
}
// lib.foldl' (acc: name: acc // mkDeviceShells name) { } devices;
};
};
}
10 changes: 8 additions & 2 deletions ip/lib/src/openroad/tcl_emitter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,10 @@ class OpenroadTclEmitter {

// Then place remaining standard cells (glue logic)
buf.writeln('# Place remaining standard cells');
buf.writeln('global_placement -density \$UTILIZATION');
buf.writeln(
'if {![info exists PLACEMENT_DENSITY]} { set PLACEMENT_DENSITY 0.1 }',
);
buf.writeln('global_placement -density \$PLACEMENT_DENSITY');
buf.writeln('detailed_placement');
buf.writeln();
}
Expand Down Expand Up @@ -642,7 +645,10 @@ class OpenroadTclEmitter {
'# Detailed route may fail on offgrid pin shapes from place_pins.',
);
buf.writeln('# If it fails, we still have the global-routed DEF.');
buf.writeln('detailed_route');
buf.writeln(
'if {![info exists DROUTE_END_ITER]} { set DROUTE_END_ITER 8 }',
);
buf.writeln('detailed_route -droute_end_iter \$DROUTE_END_ITER');
buf.writeln();
}

Expand Down
6 changes: 5 additions & 1 deletion ip/lib/src/openroad/tile_tcl_emitter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ class OpenroadTileTclEmitter {
buf.writeln();

// Placement
buf.writeln('global_placement -density \$TILE_UTIL');
buf.writeln(
'if {![info exists TILE_PLACEMENT_DENSITY]} '
'{ set TILE_PLACEMENT_DENSITY \$TILE_UTIL }',
);
buf.writeln('global_placement -density \$TILE_PLACEMENT_DENSITY');
buf.writeln('detailed_placement');
buf.writeln();

Expand Down
17 changes: 17 additions & 0 deletions pkgs/aegis-tapeout/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ lib.extendMkDerivation {
"gridMarginUm"
"tileUtilization"
"tileDieSizes"
"tilePlacementDensities"
"topPlacementDensity"
"topDetailedRouteIter"
];

extendDrvArgs =
Expand All @@ -42,6 +45,9 @@ lib.extendMkDerivation {
gridMarginUm ? 20,
tileUtilization ? 0.85,
tileDieSizes ? { },
tilePlacementDensities ? { },
topPlacementDensity ? 0.1,
topDetailedRouteIter ? 8,
...
}@args:

Expand Down Expand Up @@ -186,6 +192,9 @@ lib.extendMkDerivation {
set TILE_DIE_W ${toString effectiveTileDieSizes.${tileModule}.w}
set TILE_DIE_H ${toString effectiveTileDieSizes.${tileModule}.h}
''}
${lib.optionalString (builtins.hasAttr tileModule tilePlacementDensities) ''
set TILE_PLACEMENT_DENSITY ${toString tilePlacementDensities.${tileModule}}
''}
source ${aegis-ip}/${deviceName}-openroad-${tileModule}.tcl
EOF
openroad -threads $NIX_BUILD_CORES -exit pnr.tcl 2>&1 | tee openroad.log
Expand Down Expand Up @@ -318,6 +327,8 @@ lib.extendMkDerivation {
set CELL_LIB "${cellLib}"
set MACRO_HALO ${toString macroHaloUm}
set GRID_MARGIN ${toString gridMarginUm}
set PLACEMENT_DENSITY ${toString topPlacementDensity}
set DROUTE_END_ITER ${toString topDetailedRouteIter}
${lib.optionalString (dieWidthUm != null && dieHeightUm != null) ''
set DIE_AREA "0 0 ${toString dieWidthUm} ${toString dieHeightUm}"
''}
Expand Down Expand Up @@ -352,6 +363,9 @@ lib.extendMkDerivation {
"gridMarginUm"
"tileUtilization"
"tileDieSizes"
"tilePlacementDensities"
"topPlacementDensity"
"topDetailedRouteIter"
]
// {
inherit name;
Expand Down Expand Up @@ -461,6 +475,9 @@ lib.extendMkDerivation {
gridMarginUm
tileUtilization
tileDieSizes
tilePlacementDensities
topPlacementDensity
topDetailedRouteIter
tileMacros
topSynth
topPnr
Expand Down
Loading