Initial revision -- unknown as to whether it works, post-precision increment.
authorJoshua Wise <joshua@rebirth.joshuawise.com>
Sat, 15 Mar 2008 22:17:46 +0000 (18:17 -0400)
committerJoshua Wise <joshua@rebirth.joshuawise.com>
Sat, 15 Mar 2008 22:17:46 +0000 (18:17 -0400)
FPGA.pal [new file with mode: 0644]
Main.v [new file with mode: 0644]
ctoreadmemb.c [new file with mode: 0644]
makepal.c [new file with mode: 0644]
mandelfpga.xcf [new file with mode: 0644]
shnasto.cmd [new file with mode: 0644]

diff --git a/FPGA.pal b/FPGA.pal
new file mode 100644 (file)
index 0000000..fa8bb6f
--- /dev/null
+++ b/FPGA.pal
@@ -0,0 +1,258 @@
+GIMP Palette
+Name: FPGA
+0 0 0
+0 0 85
+0 0 170
+0 0 255
+0 36 0
+0 36 85
+0 36 170
+0 36 255
+0 72 0
+0 72 85
+0 72 170
+0 72 255
+0 109 0
+0 109 85
+0 109 170
+0 109 255
+0 145 0
+0 145 85
+0 145 170
+0 145 255
+0 182 0
+0 182 85
+0 182 170
+0 182 255
+0 218 0
+0 218 85
+0 218 170
+0 218 255
+0 255 0
+0 255 85
+0 255 170
+0 255 255
+36 0 0
+36 0 85
+36 0 170
+36 0 255
+36 36 0
+36 36 85
+36 36 170
+36 36 255
+36 72 0
+36 72 85
+36 72 170
+36 72 255
+36 109 0
+36 109 85
+36 109 170
+36 109 255
+36 145 0
+36 145 85
+36 145 170
+36 145 255
+36 182 0
+36 182 85
+36 182 170
+36 182 255
+36 218 0
+36 218 85
+36 218 170
+36 218 255
+36 255 0
+36 255 85
+36 255 170
+36 255 255
+72 0 0
+72 0 85
+72 0 170
+72 0 255
+72 36 0
+72 36 85
+72 36 170
+72 36 255
+72 72 0
+72 72 85
+72 72 170
+72 72 255
+72 109 0
+72 109 85
+72 109 170
+72 109 255
+72 145 0
+72 145 85
+72 145 170
+72 145 255
+72 182 0
+72 182 85
+72 182 170
+72 182 255
+72 218 0
+72 218 85
+72 218 170
+72 218 255
+72 255 0
+72 255 85
+72 255 170
+72 255 255
+109 0 0
+109 0 85
+109 0 170
+109 0 255
+109 36 0
+109 36 85
+109 36 170
+109 36 255
+109 72 0
+109 72 85
+109 72 170
+109 72 255
+109 109 0
+109 109 85
+109 109 170
+109 109 255
+109 145 0
+109 145 85
+109 145 170
+109 145 255
+109 182 0
+109 182 85
+109 182 170
+109 182 255
+109 218 0
+109 218 85
+109 218 170
+109 218 255
+109 255 0
+109 255 85
+109 255 170
+109 255 255
+145 0 0
+145 0 85
+145 0 170
+145 0 255
+145 36 0
+145 36 85
+145 36 170
+145 36 255
+145 72 0
+145 72 85
+145 72 170
+145 72 255
+145 109 0
+145 109 85
+145 109 170
+145 109 255
+145 145 0
+145 145 85
+145 145 170
+145 145 255
+145 182 0
+145 182 85
+145 182 170
+145 182 255
+145 218 0
+145 218 85
+145 218 170
+145 218 255
+145 255 0
+145 255 85
+145 255 170
+145 255 255
+182 0 0
+182 0 85
+182 0 170
+182 0 255
+182 36 0
+182 36 85
+182 36 170
+182 36 255
+182 72 0
+182 72 85
+182 72 170
+182 72 255
+182 109 0
+182 109 85
+182 109 170
+182 109 255
+182 145 0
+182 145 85
+182 145 170
+182 145 255
+182 182 0
+182 182 85
+182 182 170
+182 182 255
+182 218 0
+182 218 85
+182 218 170
+182 218 255
+182 255 0
+182 255 85
+182 255 170
+182 255 255
+218 0 0
+218 0 85
+218 0 170
+218 0 255
+218 36 0
+218 36 85
+218 36 170
+218 36 255
+218 72 0
+218 72 85
+218 72 170
+218 72 255
+218 109 0
+218 109 85
+218 109 170
+218 109 255
+218 145 0
+218 145 85
+218 145 170
+218 145 255
+218 182 0
+218 182 85
+218 182 170
+218 182 255
+218 218 0
+218 218 85
+218 218 170
+218 218 255
+218 255 0
+218 255 85
+218 255 170
+218 255 255
+255 0 0
+255 0 85
+255 0 170
+255 0 255
+255 36 0
+255 36 85
+255 36 170
+255 36 255
+255 72 0
+255 72 85
+255 72 170
+255 72 255
+255 109 0
+255 109 85
+255 109 170
+255 109 255
+255 145 0
+255 145 85
+255 145 170
+255 145 255
+255 182 0
+255 182 85
+255 182 170
+255 182 255
+255 218 0
+255 218 85
+255 218 170
+255 218 255
+255 255 0
+255 255 85
+255 255 170
+255 255 255
diff --git a/Main.v b/Main.v
new file mode 100644 (file)
index 0000000..2dd4764
--- /dev/null
+++ b/Main.v
@@ -0,0 +1,386 @@
+/*
+ * MandelFPGA
+ * by Joshua Wise and Chris Lu
+ * 
+ * An implementation of a pipelined algorithm to calculate the Mandelbrot set
+ * in real time on an FPGA.
+ */
+
+`define XRES 640
+`define YRES 480
+`define WHIRRRRR 21
+
+module SyncGen(
+       input pixclk,
+       output reg vs, hs,
+       output reg [11:0] xout = `WHIRRRRR, yout = 0,
+       output wire [11:0] xoutreal, youtreal,
+       output reg border);
+       
+       reg [11:0] x = 0, y = 0;        // Used for generating border and timing.
+       assign xoutreal = x;
+       assign youtreal = y;
+       
+       parameter XFPORCH = 16;
+       parameter XSYNC = 96;
+       parameter XBPORCH = 48;
+       
+       parameter YFPORCH = 10;
+       parameter YSYNC = 2;
+       parameter YBPORCH = 29;
+
+       always @(posedge pixclk)
+       begin
+               if (x >= (`XRES + XFPORCH + XSYNC + XBPORCH))
+               begin
+                       if (y >= (`YRES + YFPORCH + YSYNC + YBPORCH))
+                               y <= 0;
+                       else
+                               y <= y + 1;
+                       x <= 0;
+               end else
+                       x <= x + 1;
+                       
+               if (xout >= (`XRES + XFPORCH + XSYNC + XBPORCH))
+               begin
+                       if (yout >= (`YRES + YFPORCH + YSYNC + YBPORCH))
+                               yout <= 0;
+                       else
+                               yout <= yout + 1;
+                       xout <= 0;
+               end else
+                       xout <= xout + 1;
+               hs <= (x >= (`XRES + XFPORCH)) && (x < (`XRES + XFPORCH + XSYNC));
+               vs <= (y >= (`YRES + YFPORCH)) && (y < (`YRES + YFPORCH + YSYNC));
+               border <= (x > `XRES) || (y > `YRES);
+       end
+endmodule
+
+// bits: 1.12
+
+module NaiveMultiplier(
+       input clk,
+       input [12:0] x, y,
+       input xsign, ysign,
+       output reg [12:0] out,
+       output reg sign,
+       output reg [1:0] ovf);
+
+       always @(posedge clk)
+       begin
+               {ovf,out} <=
+                       (((y[12] ? (x     ) : 0)  +
+                         (y[11] ? (x >> 1) : 0)  +
+                         (y[10] ? (x >> 2) : 0)  +
+                         (y[9]  ? (x >> 3) : 0)) +
+                        ((y[8]  ? (x >> 4) : 0)  +
+                         (y[7]  ? (x >> 5) : 0)  +
+                         (y[6]  ? (x >> 6) : 0)))+
+                       (((y[5]  ? (x >> 7) : 0)  +
+                         (y[4]  ? (x >> 8) : 0)  +
+                         (y[3]  ? (x >> 9) : 0)) +
+                        ((y[2]  ? (x >> 10): 0)  +
+                         (y[1]  ? (x >> 11): 0)  +
+                         (y[0]  ? (x >> 12): 0)));
+               sign <= xsign ^ ysign;
+       end
+
+endmodule
+
+module Multiplier(
+       input clk,
+       input [11:0] x, y,
+       input xsign, ysign,
+       output wire [11:0] out,
+       output wire sign,
+       output wire [1:0] overflow);
+
+       NaiveMultiplier nm(clk, x, y, xsign, ysign, out, sign, overflow);
+
+endmodule
+
+module MandelUnit(
+       input clk,
+       input [12:0] x, y,
+       input xsign, ysign,
+       input [13:0] r, i,
+       input rsign, isign,
+       input [7:0] ibail, icuriter,
+       output reg [12:0] xout, yout,
+       output reg xsout, ysout,
+       output reg [13:0] rout, iout,
+       output reg rsout, isout,
+       output reg [7:0] obail, ocuriter);
+
+       wire [13:0] r2, i2, ri, diff;
+       wire r2sign, i2sign, risign, dsign;
+       wire [16:0] bigsum;
+       wire bigsum_ovf, rin_ovf, iin_ovf, throwaway;
+
+       reg [12:0] xd, yd;
+       reg rd, id;
+       reg xsd, ysd;
+       reg [7:0] ibaild, curiterd;
+
+       assign ri[0] = 0;
+
+       Multiplier r2m(clk, r[12:0], r[12:0], rsign, rsign, r2[12:0], r2sign, r2[13]);
+       Multiplier i2m(clk, i[12:0], i[12:0], isign, isign, i2[12:0], i2sign, i2[13]);
+       Multiplier rim(clk, r[12:0], i[12:0], rsign, isign, ri[13:1], risign, throwaway);
+
+       assign bigsum = r2 + i2;
+       assign bigsum_ovf = bigsum[16] | bigsum[15] | bigsum[14];
+       assign rin_ovf = rd;
+       assign iin_ovf = id;
+       assign diff = (r2 > i2) ? r2 - i2 : i2 - r2;
+       assign dsign = (r2 > i2) ? 0 : 1;
+
+       always @ (posedge clk)
+       begin
+               xd <= x;
+               yd <= y;
+               xsd <= xsign;
+               ysd <= ysign;
+               xout <= xd;
+               yout <= yd;
+               xsout <= xsd;
+               ysout <= ysd;
+               ibaild <= ibail;
+               curiterd <= icuriter;
+               rd <= r[13];
+               id <= i[13];
+
+               if (xsd ^ dsign) begin
+                       if (diff > xd) begin
+                               rout <= diff - xd;
+                               rsout <= dsign;
+                       end else begin
+                               rout <= xd - diff;
+                               rsout <= xsd;
+                       end
+               end else begin
+                       rout <= diff + xd;
+                       rsout <= xsd;
+               end
+               
+               if (ysd ^ risign) begin
+                       if (ri > yd) begin
+                               iout <= ri - yd;
+                               isout <= risign;
+                       end else begin
+                               iout <= yd - ri;
+                               isout <= ysd;
+                       end
+               end else begin
+                       iout <= ri + yd;
+                       isout <= ysd;
+               end
+               
+               // If we haven't bailed out, and we meet any of the bailout conditions,
+               // bail out now.  Otherwise, leave the bailout at whatever it was before.
+               if ((ibaild == 255) && (bigsum_ovf | rin_ovf | iin_ovf))
+                       obail <= curiterd;
+               else
+                       obail <= ibaild;
+               ocuriter <= curiterd + 8'b1;
+       end
+
+endmodule
+
+module Mandelbrot(
+       input mclk,
+       input pixclk,
+       input [11:0] x, y,
+       input [12:0] xofs, yofs,
+       input [7:0] colorofs,
+       input [2:0] scale,
+       output reg [2:0] red, green, output reg [1:0] blue);
+       
+       wire [12:0] rx, ry;
+       wire [13:0] nx, ny;
+       wire rxsign, rysign;
+       
+       assign nx = x + xofs;
+       assign ny = y + yofs;
+       assign rx = (nx[13] ? -nx[12:0] : nx[12:0]) << scale;
+       assign rxsign = nx[13];
+       assign ry = (ny[13] ? -ny[12:0] : ny[12:0]) << scale;
+       assign rysign = ny[13];
+       
+
+       wire [13:0] mr[9:0], mi[9:0];
+       wire mrs[9:0], mis[9:0];
+       wire [7:0] mb[9:0];
+       wire [12:0] xprop[9:0], yprop[9:0];
+       wire xsprop[9:0], ysprop[9:0];
+       wire [7:0] curiter[9:0];
+       
+       wire [13:0] initx, inity, initr, initi;
+       wire [7:0] initci, initb;
+       wire initxs, initys, initrs, initis;
+       
+       reg [13:0] loopx, loopy, loopr, loopi;
+       reg [7:0] loopci, loopb;
+       reg loopxs, loopys, looprs, loopis;
+       
+       reg state = 0;
+       
+       // On pixclk = 1,
+       //    A new value to be loaded comes in, and a value in need of loopback comes out.
+       // On pixclk = 0,
+       //    A new value in need of loopback comes in, and a completed value comes out.
+       
+       assign initx = state ? rx : loopx;
+       assign inity = state ? ry : loopy;
+       assign initr = state ? rx : loopr;
+       assign initi = state ? ry : loopi;
+       assign initxs = state ? rxsign : loopxs;
+       assign initys = state ? rysign : loopys;
+       assign initrs = state ? rxsign : looprs;
+       assign initis = state ? rysign : loopis;
+       assign initb = state ? 8'b11111111 : loopb;
+       assign initci = state ? 8'b00000000 : loopci;
+       
+       reg [7:0] out;
+       reg pixclksync;
+       always @(negedge mclk)
+               pixclksync <= ~pixclk;
+       
+       always @(posedge mclk)
+       begin
+               if (!state) begin
+                       out <= ~mb[9] + colorofs;
+               end else begin
+                       {red, green, blue} <= {out[0],out[3],out[6],out[1],out[4],out[7],out[2],out[5]};
+                       loopx <= xprop[9];
+                       loopy <= yprop[9];
+                       loopr <= mr[9];
+                       loopi <= mi[9];
+                       loopxs <= xsprop[9];
+                       loopys <= ysprop[9];
+                       looprs <= mrs[9];
+                       loopis <= mis[9];
+                       loopb <= mb[9];
+                       loopci <= curiter[9];
+               end
+               state <= ~pixclksync;
+       end
+
+       MandelUnit mu0(
+               mclk,
+               initx, inity, initxs, initys,
+               initr, initi, initrs, initis,
+               initb, initci,
+               xprop[0], yprop[0], xsprop[0], ysprop[0],
+               mr[0], mi[0], mrs[0], mis[0],
+               mb[0], curiter[0]);
+
+       MandelUnit mu1(mclk,
+               xprop[0], yprop[0], xsprop[0], ysprop[0], mr[0], mi[0], mrs[0], mis[0], mb[0], curiter[0],
+               xprop[1], yprop[1], xsprop[1], ysprop[1], mr[1], mi[1], mrs[1], mis[1], mb[1], curiter[1]);
+       MandelUnit mu2(mclk,
+               xprop[1], yprop[1], xsprop[1], ysprop[1], mr[1], mi[1], mrs[1], mis[1], mb[1], curiter[1],
+               xprop[2], yprop[2], xsprop[2], ysprop[2], mr[2], mi[2], mrs[2], mis[2], mb[2], curiter[2]);
+       MandelUnit mu3(mclk,
+               xprop[2], yprop[2], xsprop[2], ysprop[2], mr[2], mi[2], mrs[2], mis[2], mb[2], curiter[2],
+               xprop[3], yprop[3], xsprop[3], ysprop[3], mr[3], mi[3], mrs[3], mis[3], mb[3], curiter[3]);
+       MandelUnit mu4(mclk,
+               xprop[3], yprop[3], xsprop[3], ysprop[3], mr[3], mi[3], mrs[3], mis[3], mb[3], curiter[3],
+               xprop[4], yprop[4], xsprop[4], ysprop[4], mr[4], mi[4], mrs[4], mis[4], mb[4], curiter[4]);
+       MandelUnit mu5(mclk,
+               xprop[4], yprop[4], xsprop[4], ysprop[4], mr[4], mi[4], mrs[4], mis[4], mb[4], curiter[4],
+               xprop[5], yprop[5], xsprop[5], ysprop[5], mr[5], mi[5], mrs[5], mis[5], mb[5], curiter[5]);
+       MandelUnit mu6(mclk,
+               xprop[5], yprop[5], xsprop[5], ysprop[5], mr[5], mi[5], mrs[5], mis[5], mb[5], curiter[5],
+               xprop[6], yprop[6], xsprop[6], ysprop[6], mr[6], mi[6], mrs[6], mis[6], mb[6], curiter[6]);
+       MandelUnit mu7(mclk,
+               xprop[6], yprop[6], xsprop[6], ysprop[6], mr[6], mi[6], mrs[6], mis[6], mb[6], curiter[6],
+               xprop[7], yprop[7], xsprop[7], ysprop[7], mr[7], mi[7], mrs[7], mis[7], mb[7], curiter[7]);
+       MandelUnit mu8(mclk,
+               xprop[7], yprop[7], xsprop[7], ysprop[7], mr[7], mi[7], mrs[7], mis[7], mb[7], curiter[7],
+               xprop[8], yprop[8], xsprop[8], ysprop[8], mr[8], mi[8], mrs[8], mis[8], mb[8], curiter[8]);
+       MandelUnit mu9(mclk,
+               xprop[8], yprop[8], xsprop[8], ysprop[8], mr[8], mi[8], mrs[8], mis[8], mb[8], curiter[8],
+               xprop[9], yprop[9], xsprop[9], ysprop[9], mr[9], mi[9], mrs[9], mis[9], mb[9], curiter[9]);
+       
+endmodule
+
+module Logo(
+       input pixclk,
+       input [11:0] x, y,
+       output wire enb,
+       output wire [2:0] red, green, output wire [1:0] blue);
+       
+       reg [1:0] logo[8191:0];
+       initial $readmemb("logo.readmemb", logo);
+       
+       assign enb = (x < 96) && (y < 64);
+       wire [12:0] addr = {y[5:0], x[6:0]};
+       wire [1:0] data = logo[addr];
+       assign {red, green, blue} = 
+                (data == 2'b00) ? 8'b00000000 :
+               ((data == 2'b01) ? 8'b00011100 :
+               ((data == 2'b10) ? 8'b11100000 :
+                                   8'b11111111));
+endmodule
+
+module MandelTop(
+       input gclk, output wire dcmok,
+       output wire vs, hs,
+       output wire [2:0] red, green, output [1:0] blue,
+       input left, right, up, down, rst, cycle, logooff,
+       input [2:0] scale);
+
+       wire border;
+       wire pixclk;
+       wire [7:0] zero = 8'b0;
+       wire clk;
+       wire [11:0] x, y;
+       reg [12:0] xofs = -`XRES/2, yofs = -`YRES/2;
+       reg [5:0] slowctr = 0;
+       reg [7:0] colorcycle = 0;
+       wire [11:0] realx, realy;
+       
+       wire logoenb;
+       wire [2:0] mandelr, mandelg, logor, logog;
+       wire [1:0] mandelb, logob;
+       
+       pixDCM dcm(                                     // CLKIN is 50MHz xtal, CLKFX_OUT is 25MHz
+               .CLKIN_IN(gclk), 
+               .CLKFX_OUT(pixclk),
+               .CLKIN_IBUFG_OUT(clk),
+               .LOCKED_OUT(dcmok)
+               );
+
+       SyncGen sync(pixclk, vs, hs, x, y, realx, realy, border);
+       Mandelbrot mandel(clk, pixclk, x, y, xofs, yofs, cycle ? colorcycle : 0, scale, mandelr, mandelg, mandelb);
+       Logo logo(pixclk, realx, realy, logoenb, logor, logog, logob);
+       
+       assign {red,green,blue} =
+               border ? 8'b00000000 :
+               (!logooff && logoenb) ? {logor, logog, logob} : {mandelr, mandelg, mandelb};
+       
+       always @(posedge vs)
+       begin
+               if (rst)
+               begin
+                       xofs <= -`XRES/2;
+                       yofs <= -`YRES/2;
+                       colorcycle <= 0;
+               end else begin
+                       if (up) yofs <= yofs + 1;
+                       else if (down) yofs <= yofs - 1;
+                       
+                       if (left) xofs <= xofs + 1;
+                       else if (right) xofs <= xofs - 1;
+                       
+                       if (slowctr == 0)
+                               colorcycle <= colorcycle + 1;
+               end
+               
+               if (slowctr == 12)
+                       slowctr <= 0;
+               else
+                       slowctr <= slowctr + 1;
+       end
+endmodule
diff --git a/ctoreadmemb.c b/ctoreadmemb.c
new file mode 100644 (file)
index 0000000..330cb6d
--- /dev/null
@@ -0,0 +1,29 @@
+#include "mandelfpga.c"
+#include <stdio.h>
+
+// w t f, the data is inverted somehow :psyduck:
+void main()
+{
+  int y,x;
+  
+  for (y=MANDELFPGA_HEIGHT-1; y >= 0; y--)
+  {
+    for (x = MANDELFPGA_WIDTH; x < 128; x++)
+      printf("00\n");  // XST can't take don't cares there. sad face
+    for (x=MANDELFPGA_WIDTH-1; x >= 0; x--)
+    {
+      unsigned char *p = &MANDELFPGA_PIXEL_DATA[MANDELFPGA_BYTES_PER_PIXEL*(MANDELFPGA_WIDTH*y+x)];
+      if (p[0] == 0 && p[1] == 0 && p[2] == 0)
+        printf("00\n");
+      else if (p[0] == 255 && p[1] == 0 && p[2] == 0)
+        printf("10\n");
+      else if (p[0] == 0 && p[1] == 255 && ((p[2] == 0) || (p[2] == 36)))
+        printf("01\n");
+      else if (p[0] == 255 && p[1] == 255 && p[2] == 255)
+        printf("11\n");
+      else
+        fprintf(stderr, "o shi, what is %d %d %d\n", p[0], p[1], p[2]);
+    }
+    
+  }
+}
\ No newline at end of file
diff --git a/makepal.c b/makepal.c
new file mode 100644 (file)
index 0000000..915e15b
--- /dev/null
+++ b/makepal.c
@@ -0,0 +1,14 @@
+void main()
+{
+  unsigned char c = 0;
+  printf("GIMP Palette\n");
+  printf("Name: FPGA\n");
+  do
+  {
+    printf("%d %d %d\n",
+      (int)(255 * ((float)(c >> 5)) / 7.0),
+      (int)(255 * ((float)((c >> 2) & 0x7) / 7.0)),
+      (int)(255 * ((float)(c & 0x3) / 3.0)));
+    c++;
+  } while (c != 0);
+}
\ No newline at end of file
diff --git a/mandelfpga.xcf b/mandelfpga.xcf
new file mode 100644 (file)
index 0000000..e1a1419
Binary files /dev/null and b/mandelfpga.xcf differ
diff --git a/shnasto.cmd b/shnasto.cmd
new file mode 100644 (file)
index 0000000..cda4be7
--- /dev/null
@@ -0,0 +1,7 @@
+setMode -bs
+setCable -port svf -file "/home/joshua/projects/fpga/MandelFPGA/test.svf"
+addDevice -p 1 -file "/home/joshua/projects/fpga/MandelFPGA/MandelTop.bit"
+addDevice -p 2 -part xcf04s
+Program -p 1 -defaultVersion 0
+quit
+
This page took 0.037576 seconds and 4 git commands to generate.