1 package edu.berkeley.obits.gui;
3 import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
4 import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
5 import edu.berkeley.obits.*;
6 import edu.berkeley.obits.device.atmel.*;
8 import java.awt.geom.*;
9 import java.awt.event.*;
10 import java.awt.color.*;
11 import org.ibex.util.*;
16 public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListener {
21 public static int SIZE = 92;
22 public static int RINGS = 3;
23 public static int BEVEL = 5;
24 public static int CORE_SIZE = 64;
25 public static int CORE_OFFSET = 10;
26 public static int HOFF = 52;
28 public static int RED = 0xff0000;
29 public static int BLUE = 0x0000ff;
31 public static final P YLUT_OUTPUT_POINT = new P(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + 41 - 3);
32 public static final P XLUT_OUTPUT_POINT = new P(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + 41 - 3);
36 private HashSet<Cell> cells = new HashSet<Cell>();
37 private Cell[][] ca = new Cell[128][];
39 public static final Color nonselectedcell = new Color(0xcc, 0xcc, 0xcc);
40 public static final Color selectedcell = new Color(0x44, 0x44, 0xff);
42 public Gui(At40k at40k) {
44 for(int i=0; i<ca.length; i++)
45 ca[i] = new Cell[128];
46 for(int x=0; x<7; x++)
47 for(int y=0; y<7; y++)
48 new Cell(x,y, at40k.cell(x+7, y+7));
56 public Cell(int x, int y, At40k.Cell cell) {
64 gg.color(in ? selectedcell : nonselectedcell);
65 g.fillRect(0, 0, SIZE, SIZE);
71 AffineTransform t = g.getTransform();
72 g.transform(rotateInnerTransform());
75 drawInternalRouting();
82 public void drawBuffer() {
83 if (!cell.out_relevant()) return;
84 gg.color(Color.black);
85 gg.line(21, 64, 28, 60);
86 gg.line(21, 64, 28, 68);
87 gg.line(28, 60, 28, 68);
89 gg.color(Color.magenta);
90 if (cell.oe() == V4) {
91 gg.line(16, 53, 25, 53);
92 gg.line(25, 53, 25, 62);
93 } else if (cell.oe() == H4) {
94 gg.line(25, 76, 25, 67);
98 public void drawHwires() {
99 gg.color(Color.magenta);
100 for(int i=0; i<5; i++)
101 if (cell.hwire(i).isDriven())
102 gg.line(0, SIZE-(2*(1+RINGS)+2*i), SIZE, SIZE-(2*(1+RINGS)+2*i));
103 int plane = cell.zi();
104 if (plane >= L0 && plane <= L4 && cell.hx(plane)) {
105 P p1 = new P(38, 18);
106 p1 = rotateInner(p1);
107 if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
108 route(new P(84, 84 - 2*(plane-L0)), p1, 3);
110 p1 = rotateInner(p1);
111 if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
112 route(new P(84, 84 - 2*(plane-L0)), p1, 3);
115 if (plane >= L0 && plane <= L4 && cell.hx(plane)) {
116 P p1 = new P(38, 18);
117 p1 = rotateInner(p1);
118 if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
119 route(new P(84, 84 - 2*(plane-L0)), p1, 3);
120 p1 = rotateInner(new P(64, 18));
121 if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
122 route(new P(84, 84 - 2*(plane-L0)), p1, 3);
125 public void drawVwires() {
126 gg.color(Color.magenta);
127 for(int i=0; i<5; i++)
128 if (cell.vwire(i).isDriven())
129 gg.line(2*(1+RINGS)+2*i, 0, 2*(1+RINGS)+2*i, SIZE);
130 int plane = cell.zi();
131 if (plane >= L0 && plane <= L4 && cell.vx(plane)) {
132 P p1 = new P(38, 18);
133 p1 = rotateInner(p1);
134 if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
135 route(new P(17 - 2*(plane-L0), 8), p1, 3);
137 p1 = rotateInner(p1);
138 if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
139 route(new P(17 - 2*(plane-L0), 8), p1, 3);
142 if (plane >= L0 && plane <= L4 && cell.vx(plane)) {
143 P p1 = new P(38, 18);
144 p1 = rotateInner(p1);
145 if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
146 route(new P(17 - 2*(plane-L0), 8), p1, 3);
148 p1 = rotateInner(p1);
149 if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
150 route(new P(17 - 2*(plane-L0), 8), p1, 3);
153 public P corner(int corner, int ring) {
155 case NW: return new P(0 +2*ring, SIZE -2*xring);
156 case SW: return new P(0 +2*ring, 0 +2*xring);
157 case NE: return new P(SIZE -2*ring, SIZE -2*xring);
158 case SE: return new P(SIZE -2*ring, 0 +2*xring);
159 default: return null;
163 public void drawInternalRouting() {
164 gg.color(new Color(0, 107, 51));
165 if (cell.fb_relevant()) {
167 gg.line(51, 74, 37, 74);
168 gg.line(37, 74, 50, 12);
169 } else if (cell.c() == XLUT) {
170 gg.line(32, 52, 50, 52);
171 gg.line(50, 52, 50, 12);
172 } else if (cell.c() == YLUT) {
173 gg.line(68, 52, 50, 52);
174 gg.line(50, 52, 50, 12);
176 gg.line(50, 56, 41, 56);
177 gg.line(41, 56, 50, 12);
179 if (cell.xlut_relevant()) {
180 gg.line(52, 12, XLUT_OUTPUT_POINT.getX(), 12);
181 gg.line(XLUT_OUTPUT_POINT.getX(), 12, XLUT_OUTPUT_POINT.getX(), 32);
183 if (cell.ylut_relevant()) {
184 gg.line(52, 12, YLUT_OUTPUT_POINT.getX(), 12);
185 gg.line(YLUT_OUTPUT_POINT.getX(), 12, YLUT_OUTPUT_POINT.getX(), 32);
190 public void drawLocal() {
191 if (!cell.ylut_relevant() && !cell.xlut_relevant()) return;
192 P in = new P(HOFF, 0);
193 P join = new P(HOFF, CORE_OFFSET);
194 in = rotateOuter(in);
195 join = rotateInner(join);
199 join = new P(in.getX(), join.getY());
202 join = new P(join.getX(), in.getY());
206 P xi = corner(cell.xi(), xring);
208 gg.color(new Color(0xff, 0x00, 0x00));
210 if (cell.xi_relevant() && cell.xlut_relevant())
213 xi2 = new P(-BEVEL, SIZE+BEVEL);
214 xi = translate(xi, 0, -3);
215 xi2 = translate(xi2, 0, -3);
220 xi2 = new P(-BEVEL, -BEVEL);
221 xi = translate(xi, 0, 3);
222 xi2 = translate(xi2, 0, 3);
227 xi2 = new P(SIZE+BEVEL, SIZE+BEVEL);
228 xi = translate(xi, 0, -3);
229 xi2 = translate(xi2, 0, -3);
234 xi2 = new P(SIZE+BEVEL, -BEVEL);
235 xi = translate(xi, 0, 3);
236 xi2 = translate(xi2, 0, 3);
241 if (cell.xlut_relevant()) {
244 if (cell.yi_to_xlut_relevant())
245 route(in, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 6, 20)), 5);
248 if (cell.xi_to_xlut_relevant() && xi != null)
249 route(xi, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 3, 20)), 4);
251 P xo = XLUT_OUTPUT_POINT;
252 P xout = new P(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + CORE_SIZE - 3);
253 xo = rotateInner(xo);
254 xout = rotateInner(xout);
255 gg.color(new Color(0xff, 0xcc, 0xcc));
257 if (cell.ne() != null && cell.ne().xi()==SW && cell.ne().xi_relevant() && cell.ne().xlut_relevant()) {
259 P xoo = new P(SIZE-2*xring, SIZE-2*xring);
260 P xoo2 = new P(SIZE, SIZE);
261 xoo = translate(xoo, -3, 0);
262 xoo2 = translate(xoo2, -3, 0);
264 route(xout, xoo, xring);
266 if (cell.nw() != null && cell.nw().xi()==SE && cell.nw().xi_relevant() && cell.nw().xlut_relevant()) {
268 P xoo = new P(0+2*xring, SIZE-2*xring);
269 P xoo2 = new P(0, SIZE);
270 xoo = translate(xoo, 3, 0);
271 xoo2 = translate(xoo2, 3, 0);
273 route(xout, xoo, xring);
275 if (cell.se() != null && cell.se().xi()==NW && cell.se().xi_relevant() && cell.se().xlut_relevant()) {
277 P xoo = new P(SIZE-2*xring, 0+2*xring);
278 P xoo2 = new P(SIZE, 0);
279 xoo = translate(xoo, -3, 0);
280 xoo2 = translate(xoo2, -3, 0);
282 route(xout, xoo, xring);
284 if (cell.sw() != null && cell.sw().xi()==NE && cell.sw().xi_relevant() && cell.sw().xlut_relevant()) {
286 P xoo = new P(0+2*xring, 0+2*xring);
287 P xoo2 = new P(0, 0);
288 xoo = translate(xoo, 3, 0);
289 xoo2 = translate(xoo2, 3, 0);
291 route(xout, xoo, xring);
295 if (cell.ylut_relevant()) {
296 gg.color(new Color(0x00, 0x00, 0xff));
298 if (cell.yi_to_ylut_relevant()) {
299 c = new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 6, 20);
303 gg.color(new Color(0xff, 0x00, 0x00));
304 if (cell.xi_to_ylut_relevant()) {
305 c = rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 3, 20));
310 P yo = rotateInner(YLUT_OUTPUT_POINT);
311 P yout = rotateInner(new P(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + CORE_SIZE - 3));
313 if (cell.north() != null && cell.north().yi()==SOUTH && cell.north().yi_relevant() && cell.north().ylut_relevant()) {
315 route(yout, new P(SIZE-40, SIZE+ 0), 2);
317 if (cell.east() != null && cell.east().yi()==WEST && cell.east().yi_relevant() && cell.east().ylut_relevant()) {
319 route(yout, new P(SIZE+ 0, 40), 2);
321 if (cell.south() != null && cell.south().yi()==NORTH && cell.south().yi_relevant() && cell.south().ylut_relevant()) {
323 route(yout, new P( 40, 0), 2);
325 if (cell.west() != null && cell.west().yi()==EAST && cell.west().yi_relevant() && cell.west().ylut_relevant()) {
327 route(yout, new P( 0, SIZE-40), 2);
334 private AffineTransform rotateOuterTransform() {
336 AffineTransform a = new AffineTransform();
337 a.rotate((Math.PI/2) * rot);
340 case 1: a.translate(0, -SIZE); break;
341 case 2: a.translate(-SIZE, -SIZE); break;
342 case 3: a.translate(-SIZE, 0); break;
347 private P rotateOuter(P p) { return p.transform(rotateOuterTransform()); }
348 private P rotateInner(P p) { return p.transform(rotateInnerTransform()); }
350 private AffineTransform rotateInnerTransform() {
352 AffineTransform a = new AffineTransform();
353 a.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
354 a.rotate((Math.PI/2) * rot);
357 case 1: a.translate(0, -CORE_SIZE); break;
358 case 2: a.translate(-CORE_SIZE, -CORE_SIZE); break;
359 case 3: a.translate(-CORE_SIZE, 0); break;
361 a.translate(-1 * (SIZE-CORE_SIZE-CORE_OFFSET), -CORE_OFFSET);
366 private P project(P p1, int ring) {
367 double north = Math.abs( (SIZE-(ring*2)) - p1.getY() );
368 double south = Math.abs( ( (ring*2)) - p1.getY() );
369 double east = Math.abs( (SIZE-(ring*2)) - p1.getX() );
370 double west = Math.abs( ( (ring*2)) - p1.getX() );
371 if (north < south && north < east && north < west) return new P(p1.x, SIZE-ring*2);
372 else if (south < east && south < west) return new P(p1.x, ring*2);
373 else if (east < west) return new P(SIZE-ring*2, p1.y);
374 else return new P(ring*2, p1.y);
378 private void route(P p1, P p2, int ring) {
379 int ringpos = ring * 2;
380 P projected = project(p1, ring);
381 gg.line(p1, projected);
384 projected = project(p2, ring);
385 gg.line(p2, projected);
388 double x1 = p1.getX();
389 double y1 = p1.getY();
390 double x2 = p2.getX();
391 double y2 = p2.getY();
393 if (x1==x2 || y1==y2) {
398 if ((x1==SIZE-ring*2 || x1==ring*2) && !(y1==SIZE-ring*2 || y1==ring*2)) {
399 P p3 = new P(x1, y2 > SIZE/2 ? SIZE-ring*2 : ring*2);
402 } else if ((y1==SIZE-ring*2 || y1==ring*2) && !(x1==SIZE-ring*2 || x1==ring*2)) {
403 P p3 = new P(x2 > SIZE/2 ? SIZE-ring*2 : ring*2, y1);
414 case SOUTH: rot = 0; break;
415 case NORTH: rot = 2; break;
416 case EAST: rot = 1; break;
417 case WEST: rot = 3; break;
419 // FIXME: choose based on xin
420 if (cell.north() != null && cell.north().yi()==SOUTH) { rot = 0; break; }
421 if (cell.south() != null && cell.south().yi()==NORTH) { rot = 2; break; }
422 if (cell.east() != null && cell.east().yi()==WEST) { rot = 3; break; }
423 if (cell.west() != null && cell.west().yi()==EAST) { rot = 1; break; }
429 public void drawGates() {
430 AffineTransform t = g.getTransform();
432 g.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
435 g.rotate((Math.PI/2) * rot);
438 case 1: g.translate(0, -CORE_SIZE); break;
439 case 2: g.translate(-CORE_SIZE, -CORE_SIZE); break;
440 case 3: g.translate(-CORE_SIZE, 0); break;
443 //gg.color(Color.gray);
444 //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE);
447 GeneralPath p = new GeneralPath();
448 p.moveTo(29.141f, 36.301f);
449 p.lineTo(29.141f, 36.301f-7.161f);
450 p.curveTo(27.71f, 11.24f, 23.413f, 9.45f, 14.82f, 0.5f);
451 p.curveTo(6.229f, 9.45f, 1.932f, 11.24f, 0.5f, 29.141f);
452 p.lineTo(0.5f, 29.141f+7.161f);
454 float y = 29.141f+7.161f;
455 p.curveTo(5.729f+x, -1.789f+y,
458 p.curveTo(22.697f, 33.616f, 23.413f, 34.512f, 29.141f, 36.301f);
459 g.translate(0, -40f);
460 if (cell.xlut_relevant()) {
461 gg.color(Color.white);
466 g.translate(34f, 0f);
467 if (cell.ylut_relevant()) {
468 gg.color(Color.white);
470 gg.color(Color.blue);
477 public void drawMux() {
478 if (!cell.c_relevant()) return;
479 gg.color(Color.black);
480 if (cell.xlut_relevant() && (cell.c() == ZMUX || cell.c() == XLUT)) {
481 gg.color(new Color(0xff, 0xbb, 0xbb));
482 gg.line(XLUT_OUTPUT_POINT, new P(XLUT_OUTPUT_POINT.getX(), 52));
483 gg.line(new P(XLUT_OUTPUT_POINT.getX(), 52), new P(51, 52));
485 if (cell.ylut_relevant() && (cell.c() == ZMUX || cell.c() == YLUT)) {
486 gg.color(new Color(0xbb, 0xbb, 0xff));
487 gg.line(YLUT_OUTPUT_POINT, new P(YLUT_OUTPUT_POINT.getX(), 52));
488 gg.line(new P(YLUT_OUTPUT_POINT.getX(), 52), new P(51, 52));
490 gg.line(51, 52, 51, 51+25);
491 if (cell.c() == ZMUX) {
492 gg.color(Color.black);
493 gg.line(51, 52, 51, 51+25);
494 gg.line(46, 54, 46+2, 54+5);
495 gg.line(46+2, 54+5, 60-2, 54+5);
496 gg.line(60-2, 54+5, 60, 54);
497 gg.line(60, 54, 46, 54);
500 public void drawRegister() {
501 if (!cell.register_relevant()) return;
502 gg.color(Color.white);
503 g.fillRect(48, 58, 10, 14);
504 gg.color(Color.black);
505 g.drawRect(48, 58, 10, 14);
506 gg.line(57, 70, 54, 68);
507 gg.line(54, 68, 57, 66);
509 public void drawBorder() {
510 gg.color(Color.gray);
511 //gg.line(0, BEVEL, BEVEL, 0);
512 gg.line(BEVEL, 0, SIZE-BEVEL, 0);
513 //gg.line(SIZE-BEVEL, 0, SIZE, BEVEL);
514 gg.line(SIZE, BEVEL, SIZE, SIZE-BEVEL);
515 //gg.line(SIZE, SIZE-BEVEL, SIZE-BEVEL, SIZE);
516 gg.line(SIZE-BEVEL, SIZE, BEVEL, SIZE);
517 //gg.line(BEVEL, SIZE, 0, SIZE-BEVEL);
518 gg.line(0, SIZE-BEVEL, 0, BEVEL);
522 public void _paint(Graphics2D g) {
526 g.setStroke(new BasicStroke((float)0.5));
528 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
529 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
531 AffineTransform t = g.getTransform();
532 for(Cell c : cells) {
534 g.translate( c._x * SIZE/* + (10 * (c._x/4))*/, c._y * SIZE/* + (10 * (c._y/4))*/);
539 g.setTransform(new AffineTransform());
541 gg.color(selectedcell);
542 g.fillRect(getWidth() - 200, 0, 200, 100);
543 gg.color(Color.white);
544 g.drawRect(getWidth() - 200, 0, 200, 100);
546 Cell newcell = whichCell(mousex, mousey);
548 if (newcell != null && newcell.cell != null) {
549 g.drawString("selected: " + newcell._x + ","+newcell._y,
550 getWidth() - 200 + 10, (line += 15));
551 g.drawString(" xlut: " + AtmelSerial.bin8(newcell.cell.xlut()),
552 getWidth() - 200 + 10, (line += 15));
553 g.drawString(" ylut: " + AtmelSerial.bin8(newcell.cell.ylut()),
554 getWidth() - 200 + 10, (line += 15));
556 switch(newcell.cell.xi()) {
557 case NW : xi = "NW"; break;
558 case NE : xi = "NE"; break;
559 case SW : xi = "SW"; break;
560 case SE : xi = "SE"; break;
562 g.drawString(" xi: " + xi, getWidth() - 200 + 10, (line += 15));
564 switch(newcell.cell.yi()) {
565 case NORTH : yi = "NORTH"; break;
566 case SOUTH : yi = "SOUTH"; break;
567 case EAST : yi = "EAST"; break;
568 case WEST : yi = "WEST"; break;
570 g.drawString(" yi: " + yi, getWidth() - 200 + 10, (line += 15));
577 public void clear() {
578 Graphics2D g = (Graphics2D)getGraphics();
579 //gg.color(Color.black);
580 //gg.color(Color.lightGray);
581 g.clearRect(0, 0, getWidth(), getHeight());
584 public static final P translate(P p, int dx, int dy) {
585 return new P(p.getX()+dx, p.getY()+dy);
588 public Cell whichCell(int x, int y) {
591 p = p.inverseTransform(transform);
592 } catch (Exception e) {
595 int col = ((int)p.getX()) / (SIZE + BEVEL);
596 int row = ((int)p.getY()) / (SIZE + BEVEL);
598 if (c._x == col && c._y == row)