Notes
This version compiles under InterHDL's Verilogger. Note that vectored nets as well as arrays of instantiations are not supported in that compiler, hence the necessity of this version. A simple little testbench has been provided as the top module.
// // 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 top(eoln, xout, yout); output eoln; output [7:0] xout, yout; reg [7:0] in1; reg [7:0] in2; reg [1:0] mode; reg [15:0] i; reg clk; package p1(in1, in2, clk, eoln, mode, xout, yout); initial for(i=0;i<1;i=i+1) begin #10 mode=0; clk=0; in1=0; in2=255; #10 clk=1; #10 $display("xout: %d yout: %d (x-loader cycle) ",xout,yout); #10 mode=1; clk=0; in1=0; in2=255; #10 clk=1; #10 $display("xout: %d yout: %d (y-loader cycle)",xout,yout); #10 mode=2; clk=0; #10 clk=1; #10 $display("xout: %d yout: %d (delay cycle)",xout,yout); while(eoln==0) begin #10 mode=3; clk=0; #10 clk=1; #10 $display("xout: %d yout: %d",xout,yout); end end endmodule 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 [15:0] rcr7,rcr8; wire [1:0] r5out,r6out; wire [1:0] r5bus,r6bus; wire [7:0] x2x1,y2y1,x1out,x1r5,x2out,x1x2,y1y2; wire [7:0] r7out,r8out,y1out,y2out,y1r6; wire m0, m1, m2, m3, eolnbar; 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]}); bsub b0(car[1],o[0],i1[0],i2[0],1'b1, zer[1],1'b1 ); bsub b1(car[2],o[1],i1[1],i2[1],car[1],zer[2],zer[1]); bsub b2(car[3],o[2],i1[2],i2[2],car[2],zer[3],zer[2]); bsub b3(car[4],o[3],i1[3],i2[3],car[3],zer[4],zer[3]); bsub b4(car[5],o[4],i1[4],i2[4],car[4],zer[5],zer[4]); bsub b5(car[6],o[5],i1[5],i2[5],car[5],zer[6],zer[5]); bsub b6(car[7],o[6],i1[6],i2[6],car[6],zer[7],zer[6]); bsub b7(car[8],o[7],i1[7],i2[7],car[7],zer[8],zer[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