1 package edu.berkeley.obits;
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.device.atmel.*;
7 import java.awt.geom.*;
8 import java.awt.event.*;
9 import java.awt.color.*;
10 import org.ibex.util.*;
15 public class Visual extends JFrame implements KeyListener {
17 public static int SIZE = 92;
18 public static int RINGS = 3;
19 public static int BEVEL = 5;
20 public static int CORE_SIZE = 64;
21 public static int CORE_OFFSET = 10;
23 public static int HOFF = 52;
26 public static void main(String[] s) {
27 Visual v = new Visual();
35 public Visual(At40k at40k) {
37 for(int x=0; x<7; x++)
38 for(int y=0; y<7; y++)
39 new Cell(x,y, at40k.cell(x+7, y+7));
43 private HashSet<Cell> cells = new HashSet<Cell>();
49 public Cell(int x, int y, At40k.Cell cell) {
58 drawInternalRouting();
65 public void drawHwires() {
66 g.setColor(Color.magenta);
67 for(int i=0; i<5; i++)
68 if (cell.hwire(i).isDriven())
69 g.drawLine(0, SIZE-(2*(1+RINGS)+2*i), SIZE, SIZE-(2*(1+RINGS)+2*i));
71 public void drawVwires() {
72 g.setColor(Color.magenta);
73 for(int i=0; i<5; i++)
74 if (cell.vwire(i).isDriven())
75 g.drawLine(2*(1+RINGS)+2*i, 0, 2*(1+RINGS)+2*i, SIZE);
77 public void drawInternalRouting() {
80 public void drawLocal() {
81 if (!cell.ylut_relevant() && !cell.ylut_relevant()) return;
82 Point2D in = new Point2D.Double(HOFF, 0);
83 Point2D join = new Point2D.Double(HOFF, CORE_OFFSET);
89 join.setLocation(in.getX(), join.getY());
92 join.setLocation(join.getX(), in.getY());
97 g.setColor(new Color(0xff, 0x00, 0x00));
101 xi = new Point2D.Double(0+2*xring, SIZE-2*xring);
102 g.draw(new Line2D.Double(new Point2D.Double(0, SIZE), xi));
106 xi = new Point2D.Double(0+2*xring, 0+2*xring);
107 g.draw(new Line2D.Double(new Point2D.Double(0, 0), xi));
111 xi = new Point2D.Double(SIZE-2*xring, SIZE-2*xring);
112 g.draw(new Line2D.Double(new Point2D.Double(SIZE, SIZE), xi));
116 xi = new Point2D.Double(SIZE-2*xring, 0+2*xring);
117 g.draw(new Line2D.Double(new Point2D.Double(SIZE, 0), xi));
122 if (cell.xlut_relevant()) {
123 g.setColor(new Color(0x00, 0x00, 0xff));
124 Point2D c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 6, 20);
128 g.setColor(new Color(0xff, 0x00, 0x00));
129 c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 3, 20);
134 Point2D xo = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + 41 - 3);
135 Point2D xout = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + CORE_SIZE - 3);
138 g.setColor(new Color(0xff, 0xcc, 0xcc));
139 g.draw(new Line2D.Double(xo, xout));
140 if (cell.ne() != null && cell.ne().xi()==SW) {
141 Point2D xoo = new Point2D.Double(SIZE-2*xring, SIZE-2*xring);
142 g.draw(new Line2D.Double(new Point2D.Double(SIZE, SIZE), xoo));
143 route(xout, xoo, xring);
145 if (cell.nw() != null && cell.nw().xi()==SE) {
146 Point2D xoo = new Point2D.Double(0+2*xring, SIZE-2*xring);
147 g.draw(new Line2D.Double(new Point2D.Double(0, SIZE), xoo));
148 route(xout, xoo, xring);
150 if (cell.se() != null && cell.se().xi()==NW) {
151 Point2D xoo = new Point2D.Double(SIZE-2*xring, 0+2*xring);
152 g.draw(new Line2D.Double(new Point2D.Double(SIZE, 0), xoo));
153 route(xout, xoo, xring);
155 if (cell.sw() != null && cell.sw().xi()==NE) {
156 Point2D xoo = new Point2D.Double(0+2*xring, 0+2*xring);
157 g.draw(new Line2D.Double(new Point2D.Double(0, 0), xoo));
158 route(xout, xoo, xring);
162 if (cell.ylut_relevant()) {
163 g.setColor(new Color(0x00, 0x00, 0xff));
164 Point2D c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 6, 20);
168 g.setColor(new Color(0xff, 0x00, 0x00));
169 c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 3, 20);
174 Point2D yo = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + 41 - 3);
175 Point2D yout = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + CORE_SIZE - 3);
178 g.setColor(new Color(0xbb, 0xbb, 0xff));
179 //g.setColor(new Color(0x00, 0x00, 0xff));
180 g.draw(new Line2D.Double(yo, yout));
181 if (cell.north() != null && cell.north().yi()==SOUTH) route(yout, new Point2D.Double(SIZE-40, SIZE+ 0), 2);
182 if (cell.east() != null && cell.east().yi()==WEST) route(yout, new Point2D.Double(SIZE+ 0, 40), 2);
183 if (cell.south() != null && cell.south().yi()==NORTH) route(yout, new Point2D.Double( 40, 0), 2);
184 if (cell.west() != null && cell.west().yi()==EAST) route(yout, new Point2D.Double( 0, SIZE-40), 2);
189 private void rotateOuter(Point2D p) {
191 AffineTransform a = new AffineTransform();
192 a.rotate((Math.PI/2) * rot);
195 case 1: a.translate(0, -SIZE); break;
196 case 2: a.translate(-SIZE, -SIZE); break;
197 case 3: a.translate(-SIZE, 0); break;
202 private void rotateInner(Point2D p) {
204 AffineTransform a = new AffineTransform();
205 a.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
206 a.rotate((Math.PI/2) * rot);
209 case 1: a.translate(0, -CORE_SIZE); break;
210 case 2: a.translate(-CORE_SIZE, -CORE_SIZE); break;
211 case 3: a.translate(-CORE_SIZE, 0); break;
213 a.translate(-1 * (SIZE-CORE_SIZE-CORE_OFFSET), -CORE_OFFSET);
217 private Point2D project(Point2D p1, int ring) {
218 double north = Math.abs( (SIZE-(ring*2)) - p1.getY() );
219 double south = Math.abs( ( (ring*2)) - p1.getY() );
220 double east = Math.abs( (SIZE-(ring*2)) - p1.getX() );
221 double west = Math.abs( ( (ring*2)) - p1.getX() );
222 if (north < south && north < east && north < west) {
223 return new Point2D.Double(p1.getX(), SIZE-ring*2);
224 } else if (south < east && south < west) {
225 return new Point2D.Double(p1.getX(), ring*2);
226 } else if (east < west) {
227 return new Point2D.Double(SIZE-ring*2, p1.getY());
229 return new Point2D.Double(ring*2, p1.getY());
233 private void route(Point2D p1, Point2D p2, int ring) {
234 int ringpos = ring * 2;
235 Point2D projected = project(p1, ring);
236 g.draw(new Line2D.Double(p1, projected));
239 projected = project(p2, ring);
240 g.draw(new Line2D.Double(p2, projected));
243 double x1 = p1.getX();
244 double y1 = p1.getY();
245 double x2 = p2.getX();
246 double y2 = p2.getY();
248 if (x1==x2 || y1==y2) {
249 g.draw(new Line2D.Double(p1, p2));
253 if ((x1==SIZE-ring*2 || x1==ring*2) && !(y1==SIZE-ring*2 || y1==ring*2)) {
254 Point2D p3 = new Point2D.Double(x1, y2 > SIZE/2 ? SIZE-ring*2 : ring*2);
255 g.draw(new Line2D.Double(p1, p3));
259 if (y1==SIZE-ring*2 || y1==ring*2) {
260 Point2D p3 = new Point2D.Double(x2 > SIZE/2 ? SIZE-ring*2 : ring*2, y1);
261 g.draw(new Line2D.Double(p1, p3));
270 case SOUTH: rot = 0; break;
271 case NORTH: rot = 2; break;
272 case EAST: rot = 1; break;
273 case WEST: rot = 3; break;
275 // FIXME: choose based on xin
276 if (cell.north() != null && cell.north().yi()==SOUTH) { rot = 0; break; }
277 if (cell.south() != null && cell.south().yi()==NORTH) { rot = 2; break; }
278 if (cell.east() != null && cell.east().yi()==WEST) { rot = 3; break; }
279 if (cell.west() != null && cell.west().yi()==EAST) { rot = 1; break; }
285 public void drawGates() {
286 AffineTransform t = g.getTransform();
288 g.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
291 g.rotate((Math.PI/2) * rot);
294 case 1: g.translate(0, -CORE_SIZE); break;
295 case 2: g.translate(-CORE_SIZE, -CORE_SIZE); break;
296 case 3: g.translate(-CORE_SIZE, 0); break;
299 //g.setColor(Color.gray);
300 //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE);
303 GeneralPath p = new GeneralPath();
304 p.moveTo(29.141f, 36.301f);
305 p.lineTo(29.141f, 36.301f-7.161f);
306 p.curveTo(27.71f, 11.24f, 23.413f, 9.45f, 14.82f, 0.5f);
307 p.curveTo(6.229f, 9.45f, 1.932f, 11.24f, 0.5f, 29.141f);
308 p.lineTo(0.5f, 29.141f+7.161f);
310 float y = 29.141f+7.161f;
311 p.curveTo(5.729f+x, -1.789f+y,
314 p.curveTo(22.697f, 33.616f, 23.413f, 34.512f, 29.141f, 36.301f);
315 g.translate(0, -40f);
316 if (cell.xlut_relevant()) {
317 g.setColor(Color.white);
319 g.setColor(Color.red);
322 g.translate(34f, 0f);
323 if (cell.ylut_relevant()) {
324 g.setColor(Color.white);
326 g.setColor(Color.blue);
333 public void drawMux() {
334 if (cell.c() != ZMUX) return;
335 g.setColor(Color.black);
336 g.drawLine(46, 54, 46+2, 54+5);
337 g.drawLine(46+2, 54+5, 60-2, 54+5);
338 g.drawLine(60-2, 54+5, 60, 54);
339 g.drawLine(60, 54, 46, 54);
341 public void drawRegister() {
343 public void drawBorder() {
344 g.setColor(Color.gray);
345 //g.drawLine(0, BEVEL, BEVEL, 0);
346 g.drawLine(BEVEL, 0, SIZE-BEVEL, 0);
347 //g.drawLine(SIZE-BEVEL, 0, SIZE, BEVEL);
348 g.drawLine(SIZE, BEVEL, SIZE, SIZE-BEVEL);
349 //g.drawLine(SIZE, SIZE-BEVEL, SIZE-BEVEL, SIZE);
350 g.drawLine(SIZE-BEVEL, SIZE, BEVEL, SIZE);
351 //g.drawLine(BEVEL, SIZE, 0, SIZE-BEVEL);
352 g.drawLine(0, SIZE-BEVEL, 0, BEVEL);
356 public void paint(Graphics _g) {
357 Graphics2D g = (Graphics2D)_g;
358 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
359 g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
360 g.setStroke(new BasicStroke((float)0.5));
363 g.translate(5, -1 * getHeight() + 10);
364 g.scale(scale,scale);
365 for(Cell c : cells) {
366 AffineTransform t = g.getTransform();
367 g.translate( c._x * SIZE/* + (10 * (c._x/4))*/, c._y * SIZE/* + (10 * (c._y/4))*/);
377 public void clear() {
378 Graphics2D g = (Graphics2D)getGraphics();
379 //g.setColor(Color.black);
380 //g.setColor(Color.lightGray);
381 g.clearRect(0, 0, getWidth(), getHeight());
384 public void keyTyped(KeyEvent k) {
386 public void keyReleased(KeyEvent k) {
388 public void keyPressed(KeyEvent keyevent) {
389 char c = keyevent.getKeyChar();
391 case '+': scale += 0.1; clear(); paint(getGraphics()); return;
392 case '-': scale -= 0.1; clear(); paint(getGraphics()); return;