Skip to content

Commit

Permalink
fix: magic exports are Y-axis mirrored
Browse files Browse the repository at this point in the history
  • Loading branch information
urish committed Nov 26, 2023
1 parent eac1141 commit fe339f3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/components/SpiceCodeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function SpiceCodeView() {

<Stack direction="row" spacing={1} sx={{ marginBottom: 1 }}>
<Button
onClick={() => downloadFile('siliwiz.mag', toMagic(layout))}
onClick={() => downloadFile('siliwiz.mag', toMagic(layout, { mirrorY: true }))}
startIcon={<AutoFixHigh />}
>
Download MAGIC
Expand Down
51 changes: 42 additions & 9 deletions src/model/magic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,27 @@ import type { Point2D } from '~/utils/geometry';

export const defaultTech = 'siliwiz';

function magicRect(rect: ILayoutRect) {
const x = Math.round(rect.x);
const y = Math.round(rect.y);
const width = Math.round(rect.x + rect.width);
const height = Math.round(rect.y + rect.height);
return `${x} ${y} ${width} ${height}`;
interface ITransform {
scaleX: number;
scaleY: number;
translateX: number;
translateY: number;
}

export const identityTransform: ITransform = {
scaleX: 1,
scaleY: 1,
translateX: 0,
translateY: 0,
};

function magicRect(rect: ILayoutRect, transform = identityTransform) {
const { scaleX, scaleY, translateX, translateY } = transform;
const x1 = Math.round((rect.x + translateX) * scaleX);
const y1 = Math.round((rect.y + translateY) * scaleY);
const x2 = Math.round((rect.x + rect.width + translateX) * scaleX);
const y2 = Math.round((rect.y + rect.height + translateY) * scaleY);
return `${Math.min(x1, x2)} ${Math.min(y1, y2)} ${Math.max(x1, x2)} ${Math.max(y1, y2)}`;
}

export function fromMagic(source: string, translate: Point2D = { x: 0, y: 0 }, scale = 1) {
Expand Down Expand Up @@ -68,7 +83,13 @@ export function fromMagic(source: string, translate: Point2D = { x: 0, y: 0 }, s
return result;
}

export function toMagic(layout: ILayout, tech = defaultTech) {
export interface IMagicOptions {
tech?: string;
mirrorY?: boolean;
}

export function toMagic(layout: ILayout, { tech = defaultTech, mirrorY = false }: IMagicOptions) {
const scale = 1;
const result = [
`magic`,
`tech ${tech}`,
Expand All @@ -77,6 +98,7 @@ export function toMagic(layout: ILayout, tech = defaultTech) {
];
const labels: Array<{ layerName: string; rect: ILayoutRect }> = [];
const layerRects = new Map<string, ILayoutRect[]>();
let maxY = 0;
for (const rect of layout.rects) {
const layer = rectViaLayer(layout, rect);
if (layer == null) {
Expand All @@ -85,11 +107,20 @@ export function toMagic(layout: ILayout, tech = defaultTech) {
const rects = layerRects.get(layer.magicName) ?? [];
rects.push(rect);
layerRects.set(layer.magicName, rects);
if (rect.y + rect.height > maxY) {
maxY = rect.y + rect.height;
}
}
const transform = {
scaleX: scale,
scaleY: mirrorY ? -scale : scale,
translateX: 0,
translateY: mirrorY ? -maxY : 0,
};
for (const [layerName, rects] of layerRects.entries()) {
result.push(`<< ${layerName} >>`);
for (const rect of rects) {
result.push(`rect ${magicRect(rect)}`);
result.push(`rect ${magicRect(rect, transform)}`);
if (rect.label != null) {
labels.push({ layerName, rect });
}
Expand All @@ -101,7 +132,9 @@ export function toMagic(layout: ILayout, tech = defaultTech) {
if (rect.label == null) {
continue;
}
result.push(`flabel ${layerName} s ${magicRect(rect)} 0 FreeSans 240 90 0 0 ${rect.label}`);
result.push(
`flabel ${layerName} s ${magicRect(rect, transform)} 0 FreeSans 240 90 0 0 ${rect.label}`,
);
result.push(`port ${portIndex} nsew signal output`);
portIndex++;
}
Expand Down
2 changes: 1 addition & 1 deletion src/model/runMagic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface IMagicResponse {

export async function runMagic(layout: ILayout) {
const start = new Date().getTime();
const magicInput = toMagic(layout, defaultTech);
const magicInput = toMagic(layout, { tech: defaultTech });
const res = await fetch(new URL('/magic', serverUrl), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
Expand Down

0 comments on commit fe339f3

Please sign in to comment.