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 void drawInternalRouting() {
154 gg.color(new Color(0, 107, 51));
155 if (cell.fb_relevant()) {
157 gg.line(51, 74, 37, 74);
158 gg.line(37, 74, 50, 12);
159 } else if (cell.c() == XLUT) {
160 gg.line(32, 52, 50, 52);
161 gg.line(50, 52, 50, 12);
162 } else if (cell.c() == YLUT) {
163 gg.line(68, 52, 50, 52);
164 gg.line(50, 52, 50, 12);
166 gg.line(50, 56, 41, 56);
167 gg.line(41, 56, 50, 12);
169 if (cell.xlut_relevant()) {
170 gg.line(52, 12, XLUT_OUTPUT_POINT.getX(), 12);
171 gg.line(XLUT_OUTPUT_POINT.getX(), 12, XLUT_OUTPUT_POINT.getX(), 32);
173 if (cell.ylut_relevant()) {
174 gg.line(52, 12, YLUT_OUTPUT_POINT.getX(), 12);
175 gg.line(YLUT_OUTPUT_POINT.getX(), 12, YLUT_OUTPUT_POINT.getX(), 32);
180 public void drawLocal() {
181 if (!cell.ylut_relevant() && !cell.xlut_relevant()) return;
182 P in = new P(HOFF, 0);
183 P join = new P(HOFF, CORE_OFFSET);
184 in = rotateOuter(in);
185 join = rotateInner(join);
189 join = new P(in.getX(), join.getY());
192 join = new P(join.getX(), in.getY());
198 gg.color(new Color(0xff, 0x00, 0x00));
200 if (cell.xi_relevant() && cell.xlut_relevant())
203 xi = new P(0+2*xring, SIZE-2*xring);
204 xi2 = new P(-BEVEL, SIZE+BEVEL);
205 xi = translate(xi, 0, -3);
206 xi2 = translate(xi2, 0, -3);
211 xi = new P(0+2*xring, 0+2*xring);
212 xi2 = new P(-BEVEL, -BEVEL);
213 xi = translate(xi, 0, 3);
214 xi2 = translate(xi2, 0, 3);
219 xi = new P(SIZE-2*xring, SIZE-2*xring);
220 xi2 = new P(SIZE+BEVEL, SIZE+BEVEL);
221 xi = translate(xi, 0, -3);
222 xi2 = translate(xi2, 0, -3);
227 xi = new P(SIZE-2*xring, 0+2*xring);
228 xi2 = new P(SIZE+BEVEL, -BEVEL);
229 xi = translate(xi, 0, 3);
230 xi2 = translate(xi2, 0, 3);
235 if (cell.xlut_relevant()) {
238 if (cell.yi_to_xlut_relevant())
239 route(in, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 6, 20)), 5);
242 if (cell.xi_to_xlut_relevant() && xi != null)
243 route(xi, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 3, 20)), 4);
245 P xo = XLUT_OUTPUT_POINT;
246 P xout = new P(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + CORE_SIZE - 3);
247 xo = rotateInner(xo);
248 xout = rotateInner(xout);
249 gg.color(new Color(0xff, 0xcc, 0xcc));
251 if (cell.ne() != null && cell.ne().xi()==SW && cell.ne().xi_relevant() && cell.ne().xlut_relevant()) {
253 P xoo = new P(SIZE-2*xring, SIZE-2*xring);
254 P xoo2 = new P(SIZE, SIZE);
255 xoo = translate(xoo, -3, 0);
256 xoo2 = translate(xoo2, -3, 0);
258 route(xout, xoo, xring);
260 if (cell.nw() != null && cell.nw().xi()==SE && cell.nw().xi_relevant() && cell.nw().xlut_relevant()) {
262 P xoo = new P(0+2*xring, SIZE-2*xring);
263 P xoo2 = new P(0, SIZE);
264 xoo = translate(xoo, 3, 0);
265 xoo2 = translate(xoo2, 3, 0);
267 route(xout, xoo, xring);
269 if (cell.se() != null && cell.se().xi()==NW && cell.se().xi_relevant() && cell.se().xlut_relevant()) {
271 P xoo = new P(SIZE-2*xring, 0+2*xring);
272 P xoo2 = new P(SIZE, 0);
273 xoo = translate(xoo, -3, 0);
274 xoo2 = translate(xoo2, -3, 0);
276 route(xout, xoo, xring);
278 if (cell.sw() != null && cell.sw().xi()==NE && cell.sw().xi_relevant() && cell.sw().xlut_relevant()) {
280 P xoo = new P(0+2*xring, 0+2*xring);
281 P xoo2 = new P(0, 0);
282 xoo = translate(xoo, 3, 0);
283 xoo2 = translate(xoo2, 3, 0);
285 route(xout, xoo, xring);
289 if (cell.ylut_relevant()) {
290 gg.color(new Color(0x00, 0x00, 0xff));
292 if (cell.yi_to_ylut_relevant()) {
293 c = new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 6, 20);
297 gg.color(new Color(0xff, 0x00, 0x00));
298 if (cell.xi_to_ylut_relevant()) {
299 c = rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 3, 20));
304 P yo = rotateInner(YLUT_OUTPUT_POINT);
305 P yout = rotateInner(new P(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + CORE_SIZE - 3));
307 if (cell.north() != null && cell.north().yi()==SOUTH && cell.north().yi_relevant() && cell.north().ylut_relevant()) {
309 route(yout, new P(SIZE-40, SIZE+ 0), 2);
311 if (cell.east() != null && cell.east().yi()==WEST && cell.east().yi_relevant() && cell.east().ylut_relevant()) {
313 route(yout, new P(SIZE+ 0, 40), 2);
315 if (cell.south() != null && cell.south().yi()==NORTH && cell.south().yi_relevant() && cell.south().ylut_relevant()) {
317 route(yout, new P( 40, 0), 2);
319 if (cell.west() != null && cell.west().yi()==EAST && cell.west().yi_relevant() && cell.west().ylut_relevant()) {
321 route(yout, new P( 0, SIZE-40), 2);
328 private AffineTransform rotateOuterTransform() {
330 AffineTransform a = new AffineTransform();
331 a.rotate((Math.PI/2) * rot);
334 case 1: a.translate(0, -SIZE); break;
335 case 2: a.translate(-SIZE, -SIZE); break;
336 case 3: a.translate(-SIZE, 0); break;
341 private P rotateOuter(P p) { return p.transform(rotateOuterTransform()); }
342 private P rotateInner(P p) { return p.transform(rotateInnerTransform()); }
344 private AffineTransform rotateInnerTransform() {
346 AffineTransform a = new AffineTransform();
347 a.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
348 a.rotate((Math.PI/2) * rot);
351 case 1: a.translate(0, -CORE_SIZE); break;
352 case 2: a.translate(-CORE_SIZE, -CORE_SIZE); break;
353 case 3: a.translate(-CORE_SIZE, 0); break;
355 a.translate(-1 * (SIZE-CORE_SIZE-CORE_OFFSET), -CORE_OFFSET);
360 private P project(P p1, int ring) {
361 double north = Math.abs( (SIZE-(ring*2)) - p1.getY() );
362 double south = Math.abs( ( (ring*2)) - p1.getY() );
363 double east = Math.abs( (SIZE-(ring*2)) - p1.getX() );
364 double west = Math.abs( ( (ring*2)) - p1.getX() );
365 if (north < south && north < east && north < west) return new P(p1.x, SIZE-ring*2);
366 else if (south < east && south < west) return new P(p1.x, ring*2);
367 else if (east < west) return new P(SIZE-ring*2, p1.y);
368 else return new P(ring*2, p1.y);
372 private void route(P p1, P p2, int ring) {
373 int ringpos = ring * 2;
374 P projected = project(p1, ring);
375 gg.line(p1, projected);
378 projected = project(p2, ring);
379 gg.line(p2, projected);
382 double x1 = p1.getX();
383 double y1 = p1.getY();
384 double x2 = p2.getX();
385 double y2 = p2.getY();
387 if (x1==x2 || y1==y2) {
392 if ((x1==SIZE-ring*2 || x1==ring*2) && !(y1==SIZE-ring*2 || y1==ring*2)) {
393 P p3 = new P(x1, y2 > SIZE/2 ? SIZE-ring*2 : ring*2);
396 } else if ((y1==SIZE-ring*2 || y1==ring*2) && !(x1==SIZE-ring*2 || x1==ring*2)) {
397 P p3 = new P(x2 > SIZE/2 ? SIZE-ring*2 : ring*2, y1);
408 case SOUTH: rot = 0; break;
409 case NORTH: rot = 2; break;
410 case EAST: rot = 1; break;
411 case WEST: rot = 3; break;
413 // FIXME: choose based on xin
414 if (cell.north() != null && cell.north().yi()==SOUTH) { rot = 0; break; }
415 if (cell.south() != null && cell.south().yi()==NORTH) { rot = 2; break; }
416 if (cell.east() != null && cell.east().yi()==WEST) { rot = 3; break; }
417 if (cell.west() != null && cell.west().yi()==EAST) { rot = 1; break; }
423 public void drawGates() {
424 AffineTransform t = g.getTransform();
426 g.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
429 g.rotate((Math.PI/2) * rot);
432 case 1: g.translate(0, -CORE_SIZE); break;
433 case 2: g.translate(-CORE_SIZE, -CORE_SIZE); break;
434 case 3: g.translate(-CORE_SIZE, 0); break;
437 //gg.color(Color.gray);
438 //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE);
441 GeneralPath p = new GeneralPath();
442 p.moveTo(29.141f, 36.301f);
443 p.lineTo(29.141f, 36.301f-7.161f);
444 p.curveTo(27.71f, 11.24f, 23.413f, 9.45f, 14.82f, 0.5f);
445 p.curveTo(6.229f, 9.45f, 1.932f, 11.24f, 0.5f, 29.141f);
446 p.lineTo(0.5f, 29.141f+7.161f);
448 float y = 29.141f+7.161f;
449 p.curveTo(5.729f+x, -1.789f+y,
452 p.curveTo(22.697f, 33.616f, 23.413f, 34.512f, 29.141f, 36.301f);
453 g.translate(0, -40f);
454 if (cell.xlut_relevant()) {
455 gg.color(Color.white);
460 g.translate(34f, 0f);
461 if (cell.ylut_relevant()) {
462 gg.color(Color.white);
464 gg.color(Color.blue);
471 public void drawMux() {
472 if (!cell.c_relevant()) return;
473 gg.color(Color.black);
474 if (cell.xlut_relevant() && (cell.c() == ZMUX || cell.c() == XLUT)) {
475 gg.color(new Color(0xff, 0xbb, 0xbb));
476 gg.line(XLUT_OUTPUT_POINT, new P(XLUT_OUTPUT_POINT.getX(), 52));
477 gg.line(new P(XLUT_OUTPUT_POINT.getX(), 52), new P(51, 52));
479 if (cell.ylut_relevant() && (cell.c() == ZMUX || cell.c() == YLUT)) {
480 gg.color(new Color(0xbb, 0xbb, 0xff));
481 gg.line(YLUT_OUTPUT_POINT, new P(YLUT_OUTPUT_POINT.getX(), 52));
482 gg.line(new P(YLUT_OUTPUT_POINT.getX(), 52), new P(51, 52));
484 gg.line(51, 52, 51, 51+25);
485 if (cell.c() == ZMUX) {
486 gg.color(Color.black);
487 gg.line(51, 52, 51, 51+25);
488 gg.line(46, 54, 46+2, 54+5);
489 gg.line(46+2, 54+5, 60-2, 54+5);
490 gg.line(60-2, 54+5, 60, 54);
491 gg.line(60, 54, 46, 54);
494 public void drawRegister() {
495 if (!cell.register_relevant()) return;
496 gg.color(Color.white);
497 g.fillRect(48, 58, 10, 14);
498 gg.color(Color.black);
499 g.drawRect(48, 58, 10, 14);
500 gg.line(57, 70, 54, 68);
501 gg.line(54, 68, 57, 66);
503 public void drawBorder() {
504 gg.color(Color.gray);
505 //gg.line(0, BEVEL, BEVEL, 0);
506 gg.line(BEVEL, 0, SIZE-BEVEL, 0);
507 //gg.line(SIZE-BEVEL, 0, SIZE, BEVEL);
508 gg.line(SIZE, BEVEL, SIZE, SIZE-BEVEL);
509 //gg.line(SIZE, SIZE-BEVEL, SIZE-BEVEL, SIZE);
510 gg.line(SIZE-BEVEL, SIZE, BEVEL, SIZE);
511 //gg.line(BEVEL, SIZE, 0, SIZE-BEVEL);
512 gg.line(0, SIZE-BEVEL, 0, BEVEL);
516 public void _paint(Graphics2D g) {
520 g.setStroke(new BasicStroke((float)0.5));
522 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
523 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
525 AffineTransform t = g.getTransform();
526 for(Cell c : cells) {
528 g.translate( c._x * SIZE/* + (10 * (c._x/4))*/, c._y * SIZE/* + (10 * (c._y/4))*/);
533 g.setTransform(new AffineTransform());
535 gg.color(selectedcell);
536 g.fillRect(getWidth() - 200, 0, 200, 100);
537 gg.color(Color.white);
538 g.drawRect(getWidth() - 200, 0, 200, 100);
540 Cell newcell = whichCell(mousex, mousey);
542 if (newcell != null && newcell.cell != null) {
543 g.drawString("selected: " + newcell._x + ","+newcell._y,
544 getWidth() - 200 + 10, (line += 15));
545 g.drawString(" xlut: " + AtmelSerial.bin8(newcell.cell.xlut()),
546 getWidth() - 200 + 10, (line += 15));
547 g.drawString(" ylut: " + AtmelSerial.bin8(newcell.cell.ylut()),
548 getWidth() - 200 + 10, (line += 15));
550 switch(newcell.cell.xi()) {
551 case NW : xi = "NW"; break;
552 case NE : xi = "NE"; break;
553 case SW : xi = "SW"; break;
554 case SE : xi = "SE"; break;
556 g.drawString(" xi: " + xi, getWidth() - 200 + 10, (line += 15));
558 switch(newcell.cell.yi()) {
559 case NORTH : yi = "NORTH"; break;
560 case SOUTH : yi = "SOUTH"; break;
561 case EAST : yi = "EAST"; break;
562 case WEST : yi = "WEST"; break;
564 g.drawString(" yi: " + yi, getWidth() - 200 + 10, (line += 15));
571 public void clear() {
572 Graphics2D g = (Graphics2D)getGraphics();
573 //gg.color(Color.black);
574 //gg.color(Color.lightGray);
575 g.clearRect(0, 0, getWidth(), getHeight());
578 public static final P translate(P p, int dx, int dy) {
579 return new P(p.getX()+dx, p.getY()+dy);
582 public Cell whichCell(int x, int y) {
585 p = p.inverseTransform(transform);
586 } catch (Exception e) {
589 int col = ((int)p.getX()) / (SIZE + BEVEL);
590 int row = ((int)p.getY()) / (SIZE + BEVEL);
592 if (c._x == col && c._y == row)