Code: Select all
module LineGen ( input clk,
output reg [9:0] X = 0, //LSB of RAM address
output reg [8:0] Y = 0 //MSB of RAM address
);
reg [9:0] x0, x1, dx; //internal module registers
reg [8:0] y0, y1, dy;
reg [16:0] D; //error accumulator + carry bit. if D[16] = 1, it is negative
reg steep; //this will be a '1' when dy>dx
reg [3:0] state;
parameter LOAD = 0, DXDY = 1, CALC1 = 2, CALC2 = 3, PLOT = 4;
always @(posedge clk) begin
state <= LOAD;
case (state)
LOAD: //load register values
state <= DXDY; //go on to the next state
DXDY: //calculate dx & dy and plot initial (x0,y0) coordinates
state <= CALC1; //go on to the next state
CALC1: //calculate 'D' for dy>dx and dx>=dy
state <= CALC2; //go on to next state
CALC2: //use 'steep' to determine if dx/dy swapping is necessary
state <= PLOT; //go on to next state
PLOT:
if (steep) begin
if (y0 + 1 <= y1)
state <= CALC2;
else state <= LOAD;
end
else begin
if (x0 + 1 <= x1)
state <= CALC2;
else state <= LOAD;
end
endcase
end
always @(posedge clk) begin
case (state)
LOAD: //1st clk: load values into (x0,y0) & (x1,y1)
begin
x0 <= 0;
y0 <= 0;
x1 <= 10;
y1 <= 0;
end
DXDY: //2nd clk: figure dx & dy, output initial coordinates: (x0,y0)
begin
dx <= x1 - x0;
dy <= y1 - y0;
X <= x0;
Y <= y0; //plot first coordinate before changing x0 & y0.
end
CALC1: //3rd clk: based on dx and dy, start swapping dx and dy within the error accumulator
if (dx >= dy) begin //if dy>dx, swap dx and dy
steep <= 0;
D <= (dy*2 - dx); //calculate the initial error value when x is the greater axis
end
else begin
steep <= 1;
D <= (dx*2 - dy); //calculate the initial error value when y is the greater axis
end
CALC2: //4th clk: after error is calculated, perform the x,y advance based on the error accumulator
if (steep) begin //if dy>dx, swap dx and dy
if ( D[16] == 0 ) begin //test for when error accumulator is negative value
x0 <= x0 + 1; //then
y0 <= y0 + 1; //go diagonal
D <= D + (dx*2 - dy*2); //accumulate the error
end
else begin
y0 <= y0 + 1; //increment on the greater axis
D <= D + dx*2;
end
end
else if ( D[16] == 0 ) begin //dx>dy here: test for when error accumulator is negative value
x0 <= x0 + 1; //then
y0 <= y0 + 1; //go diagonal
D <= D + (dy*2 - dx*2); //accumulate the error
end
else begin
x0 <= x0 + 1; //increment on the greater axis
D <= D + dy*2;
end
PLOT: //5th clk: output values
begin
X <= x0;
Y <= y0;
end
endcase
end
endmodule