Notes
Here you may find the sourcecode for the line drawing unit whose output is shown on the homepage. Many (but not all) of the compiler's features are exploited in the example. For a stripped-down version that will compile under most other compilers, click here.
// // this is the structural version of the line-drawing algorithm as described // in the proposal. note that a fsm may be grafted on top of this so that // "mode" may be replaced by a reset which initializes the fsm to its initial // state. // // fsm would look as follows: // // m0 --> m1 --> m2 --> m3 --+ // ^ | // +----+ // // with reset asserted at any time causing a cycle back to state m0. // note that this may be encapsulated on top of the package module to // save work and enhance modularity. // // m0: load x1, x2 // m1: load y1, y2 // m2: delay cycle // m3: work cycle. continue until eoln is high. // // 12jan98ajb // behavioral extension modifications 14aug99, 09sep99ajb // module package(in1, in2, clk, eoln, mode, xout, yout); input [7:0] in1; input [7:0] in2; input clk; output eoln; input [1:0] mode; output [7:0] xout, yout; wire [15:0] rc; wire vectored [15:0] rcr7,rcr8; wire vectored [1:0] r5out,r6out; wire [1:0] r5bus,r6bus; wire vectored [7:0] x2x1,y2y1,x1out,x1r5,x2out,x1x2,y1y2; wire vectored [7:0] r7out,r8out,y1out,y2out,y1r6; assign xout=x1out; assign yout=y1out; // // decode fsm position (00 01 10 11) to discrete m-control bits // assign m0 = mode==2'd0; assign m1 = mode==2'd1; assign m2 = mode==2'd2; assign m3 = mode==2'd3; // // left half of diagram // assign x1r5 = x1out + {{7{r5bus[1]}},r5bus[0]}; assign r5bus = r5out & {2{eolnbar}}; f3 modx1(x1out, in1, x1r5, x1out, m3, m0, rc[15],clk); f0 modx2(x2out, in2, m0,clk); subtractor88 modx2x1(zerox2x1, x2x1, x2out, x1out,cox0), modx1x2(zerox1x2, x1x2, x1out, x2out,cox); killstep modr5(r5out, cox, m1, clk); f7 modr7(r7out, x2x1, x1x2, m1, cox,clk); // // right half of diagram // assign y1r6 = y1out + {{7{r6bus[1]}},r6bus[0]}; assign r6bus = r6out & {2{eolnbar}}; f4 mody1(y1out, in1, y1r6, y1out, m3, m2, m1, rc[15],clk); f0 mody2(y2out, in2, m1, clk); subtractor88 mody2y1(zeroy2y1, y2y1, y2out, y1out,coy0),mody1y2(zeroy1y2, y1y2, y1out, y2out,coy); killstep modr6(r6out, coy, m2, clk); f7 modr8(r8out, y2y1, y1y2, m2, coy,clk); // // bottom part // assign rcr8 = rc - {8'h00, r8out}; assign rcr7 = rc + {8'h00, r7out}; f5 modrc(rc, zerox1x2 , rcr7, rcr8, m3, rc[15],clk); // // eoln part // assign eolnbar = ~eoln; assign eoln = zerox1x2 & zeroy2y1; endmodule // // subtract one eight bit number from another // use not(co) to input of r7/r8 muxes to make unsigned comparison // module subtractor88(z, o, i1, i2, co); output z,co; output [7:0] o; input [7:0] i1; input [7:0] i2; wire [1:8]zer,car; assign z=zer[8], co=car[8]; bsub b[1:8](car[1:8],o[0:7],i1[0:7],i2[0:7],{1'b1,car[1:7]},zer[1:8],{1'b1,zer[1:7]}); endmodule // // single cell "full subtractor" // module bsub(co, sum, a, b, ci, zo, zi); output co,sum,zo; input a,b,ci,zi; not (tb,b); xor (t1,a,tb), (sum,t1,ci); or (co,a&tb,tb&ci,a&ci); not (zdet,sum); and (zo,zi,zdet); endmodule // // muxed register that accepts new input only on an m1 cycle // module f0(o, i, m, ck); input [7:0] i; input m, ck; output [7:0] o; reg [7:0] o; always @(posedge ck) if(m) o=i; endmodule // // muxed register for x1 that only accepts as follows: // m0 in1 // m3 & rc:15==0 in2 // else in3 // module f3(o,i1,i2,i3,m3,m0,s,ck); input [7:0] i1,i2,i3; input m3,m0,s,ck; output [7:0] o; reg [7:0] o; always @(posedge ck) if(m0) o=i1; else if(m3&~s) o=i2; else o=i3; endmodule // // muxed register for y1 that only accepts as follows: // m1 in1 // m3 & rc:15 == 1 in2 // (m3 & rc:15 == 0) in3 // | (m2) // else old y1 // module f4(o,i1,i2,i3,m3,m2,m1,s,ck); input [7:0] i1,i2,i3; input m3,m2,m1,s,ck; output [7:0] o; reg [7:0] o; always @(posedge ck) if (m1) o=i1; else if(m3) begin if(s) o=i2; else o=i3; end else if(m2) o=i3; endmodule // // muxed register for rc that only accepts as following: // m3 & rc:15 == 1 in2 // m3 & rc:15 == 0 in3 // else in1 ($0000 or $8000) // module f5(o,i1,i2,i3,m3,s,ck); input i1; input [15:0] i2,i3; input m3,s,ck; output [15:0] o; reg[15:0] o; always @(posedge ck) if(m3) begin if(s) o=i2; else o=i3; end else o={i1,{15{1'b0}}}; endmodule // // muxed register for r7 and r8 that only accepts as following: // m & s==0 i1 // m & s==1 i2 // else previous contents // module f7(o, i1, i2, m, s, ck); output [7:0]o; reg [7:0]o; input m,s,ck; input [7:0] i1; input [7:0] i2; always @(posedge ck) if(m) if(s) o=i2; else o=i1; endmodule // // stores either a +1 or -1 depending on whether zero out (i) is true // // module killstep(o,i,m,ck); input m, i, ck; output [1:0] o; wire [1:0] o; reg w; assign {o[0],o[1]}= {1'b1,w}; always @(posedge ck) if(m) w=i; endmodule