X-Git-Url: http://git.joshuawise.com/mandelfpga.git/blobdiff_plain/05c0805be5682a94d874a89f05f01d1830941a70..c3ed4329c4a2afcf90da4d9d26aae5b5af97c1e6:/Main.v diff --git a/Main.v b/Main.v index 2dd4764..40eac0b 100644 --- a/Main.v +++ b/Main.v @@ -1,4 +1,4 @@ -/* +/* * MandelFPGA * by Joshua Wise and Chris Lu * @@ -8,7 +8,7 @@ `define XRES 640 `define YRES 480 -`define WHIRRRRR 21 +`define WHIRRRRR 27 module SyncGen( input pixclk, @@ -89,9 +89,9 @@ endmodule module Multiplier( input clk, - input [11:0] x, y, + input [12:0] x, y, input xsign, ysign, - output wire [11:0] out, + output wire [12:0] out, output wire sign, output wire [1:0] overflow); @@ -103,16 +103,17 @@ module MandelUnit( input clk, input [12:0] x, y, input xsign, ysign, - input [13:0] r, i, + input [14: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 [14:0] rout, iout, output reg rsout, isout, output reg [7:0] obail, ocuriter); - wire [13:0] r2, i2, ri, diff; + wire [14:0] r2, i2, ri, diff; + wire [15:0] twocdiff; wire r2sign, i2sign, risign, dsign; wire [16:0] bigsum; wire bigsum_ovf, rin_ovf, iin_ovf, throwaway; @@ -124,16 +125,17 @@ module MandelUnit( 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); + Multiplier r2m(clk, r[12:0], r[12:0], rsign, rsign, r2[12:0], r2sign, r2[14:13]); + Multiplier i2m(clk, i[12:0], i[12:0], isign, isign, i2[12:0], i2sign, i2[14:13]); + Multiplier rim(clk, r[12:0], i[12:0], rsign, isign, ri[13:1], risign, {throwaway,ri[14]}); 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; + assign twocdiff = r2 - i2; + assign diff = twocdiff[15] ? -twocdiff : twocdiff; + assign dsign = twocdiff[15]; always @ (posedge clk) begin @@ -147,8 +149,8 @@ module MandelUnit( ysout <= ysd; ibaild <= ibail; curiterd <= icuriter; - rd <= r[13]; - id <= i[13]; + rd <= r[13] | r[14]; + id <= i[13] | i[14]; if (xsd ^ dsign) begin if (diff > xd) begin @@ -191,10 +193,12 @@ module Mandelbrot( input mclk, input pixclk, input [11:0] x, y, - input [12:0] xofs, yofs, + input [13:0] xofs, yofs, input [7:0] colorofs, input [2:0] scale, output reg [2:0] red, green, output reg [1:0] blue); + +`define MAXOUTN 11 wire [12:0] rx, ry; wire [13:0] nx, ny; @@ -208,62 +212,104 @@ module Mandelbrot( 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 [14:0] mr[`MAXOUTN:0], mi[`MAXOUTN:0]; + wire mrs[`MAXOUTN:0], mis[`MAXOUTN:0]; + wire [7:0] mb[`MAXOUTN:0]; + wire [12:0] xprop[`MAXOUTN:0], yprop[`MAXOUTN:0]; + wire xsprop[`MAXOUTN:0], ysprop[`MAXOUTN:0]; + wire [7:0] curiter[`MAXOUTN:0]; - wire [13:0] initx, inity, initr, initi; + wire [14: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; + // Values after the number of iterations denoted by the subscript. + reg [14:0] stagex [2:1], stagey [2:1], stager [2:1], stagei [2:1]; + reg [7:0] stageci [2:1], stageb [2:1]; + reg stagexs [2:1], stageys [2:1], stagers [2:1], stageis [2:1]; - // 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. + reg [2:0] state = 3'b001; // One-hot encoded state. - 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; + assign initx = state[0] ? rx : + state[1] ? stagex[1] : + stagex[2]; + assign inity = state[0] ? ry : + state[1] ? stagey[1] : + stagey[2]; + assign initr = state[0] ? rx : + state[1] ? stager[1] : + stager[2]; + assign initi = state[0] ? ry : + state[1] ? stagei[1] : + stagei[2]; + assign initxs = state[0] ? rxsign : + state[1] ? stagexs[1] : + stagexs[2]; + assign initys = state[0] ? rysign : + state[1] ? stageys[1] : + stageys[2]; + assign initrs = state[0] ? rxsign : + state[1] ? stagers[1] : + stagers[2]; + assign initis = state[0] ? rysign : + state[1] ? stageis[1] : + stageis[2]; + assign initb = state[0] ? 8'b11111111 : + state[1] ? stageb[1] : + stageb[2]; + assign initci = state[0] ? 8'b00000000 : + state[1] ? stageci[1] : + stageci[2]; reg [7:0] out; - reg pixclksync; + + // We detect when the state should be poked by a high negedge followed + // by a high posedge -- if tha thappens, then we're guaranteed that the + // state following the current state will be 100. + reg lastneg; always @(negedge mclk) - pixclksync <= ~pixclk; + lastneg <= pixclk; always @(posedge mclk) begin - if (!state) begin - out <= ~mb[9] + colorofs; - end else begin + if (lastneg && pixclk) // If a pixclk has happened, the state should be reset. + state <= 3'b100; + else // Otherwise, just poke it forward. + state <= {state[1], state[0], state[2]}; + + // Data output handling + if (state[0]) 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; + if (state[1]) begin + out <= ~mb[`MAXOUTN] + colorofs; + end + + if (state[0]) begin // PnR0 in, PnR2 out + stagex[2] <= xprop[`MAXOUTN]; + stagey[2] <= yprop[`MAXOUTN]; + stager[2] <= mr[`MAXOUTN]; + stagei[2] <= mi[`MAXOUTN]; + stagexs[2] <= xsprop[`MAXOUTN]; + stageys[2] <= ysprop[`MAXOUTN]; + stagers[2] <= mrs[`MAXOUTN]; + stageis[2] <= mis[`MAXOUTN]; + stageb[2] <= mb[`MAXOUTN]; + stageci[2] <= curiter[`MAXOUTN]; + end + + if (state[2]) begin // PnR2 in, PnR1 out + stagex[1] <= xprop[`MAXOUTN]; + stagey[1] <= yprop[`MAXOUTN]; + stager[1] <= mr[`MAXOUTN]; + stagei[1] <= mi[`MAXOUTN]; + stagexs[1] <= xsprop[`MAXOUTN]; + stageys[1] <= ysprop[`MAXOUTN]; + stagers[1] <= mrs[`MAXOUTN]; + stageis[1] <= mis[`MAXOUTN]; + stageb[1] <= mb[`MAXOUTN]; + stageci[1] <= curiter[`MAXOUTN]; + end end MandelUnit mu0( @@ -302,7 +348,13 @@ module Mandelbrot( 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]); - + MandelUnit mua(mclk, + xprop[9], yprop[9], xsprop[9], ysprop[9], mr[9], mi[9], mrs[9], mis[9], mb[9], curiter[9], + xprop[10], yprop[10], xsprop[10], ysprop[10], mr[10], mi[10], mrs[10], mis[10], mb[10], curiter[10]); + MandelUnit mub(mclk, + xprop[10], yprop[10], xsprop[10], ysprop[10], mr[10], mi[10], mrs[10], mis[10], mb[10], curiter[10], + xprop[11], yprop[11], xsprop[11], ysprop[11], mr[11], mi[11], mrs[11], mis[11], mb[11], curiter[11]); + endmodule module Logo( @@ -331,12 +383,28 @@ module MandelTop( input left, right, up, down, rst, cycle, logooff, input [2:0] scale); + + wire pixclk, mclk, gclk2, clk; + wire dcm1ok, dcm2ok; + assign dcmok = dcm1ok && dcm2ok; + + IBUFG typeA(.O(clk), .I(gclk)); + + pixDCM dcm( // CLKIN is 50MHz xtal, CLKFX_OUT is 25MHz + .CLKIN_IN(clk), + .CLKFX_OUT(pixclk), + .LOCKED_OUT(dcm1ok) + ); + + mandelDCM dcm2( + .CLKIN_IN(clk), + .CLKFX_OUT(mclk), + .LOCKED_OUT(dcm2ok) + ); + 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 [13:0] xofs = -`XRES/2, yofs = -`YRES/2; reg [5:0] slowctr = 0; reg [7:0] colorcycle = 0; wire [11:0] realx, realy; @@ -345,15 +413,10 @@ module MandelTop( 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); + Mandelbrot mandel(mclk, 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} =