Arlet, I think you're right. Everything seems jumbled now. I am dealing with code that I wrote when I first started learning Verilog. I had some early successes, but they weren't necessarily correct. I'm now having a problem generating a simple border using one video board!
I hate to realize this, but I may have to start from scratch...
But before I do I would like to ask you Verilog experts how to go about making a piece of code sleeker. It is the Line and circle hardware plotter...
I put delays in there to make the simulations look correct and in real life it works, but the code is not pretty. What is the simplest structural change I can make to make this more efficient?
Thanks for your input all!
Code:
`timescale 1ns / 1ps
module LineGen ( input clk,
input lineCS,
input [15:0] cpuDO,
input [3:0] cpuAB,
input countflag,
input [15:0] SRD,
output reg RAMWE,
output reg LGREADY,
output reg [aw:0] X,
output reg [aw:0] Y,
output reg [15:0] color,
output reg [15:0] border
);
parameter aw = 10; //2048
//blitter variables
reg [15:0] bXlen, bYlen;
reg [aw:0] bXc, bYc, bXp, bYp;
//linegen variables
reg [aw:0] x0, x1, dx, x0t, x1t, y0, y1, dy, y0t, y1t; //internal module registers
reg [aw+1:0] D; //error accumulator + carry bit. if D[aw+1] = 1, it is negative
reg [0:0] steep, //1 when dy>dx
dyneg, //1 when dy is negative
dxneg; //1 when dx is negative
//circle variables
reg [aw:0] xc, yc, rad, x, y = 0;
reg [aw+1:0] raderr;
reg [4:0] state;
parameter WAIT = 0, LOAD = 1, SLOPE = 2, DXDY = 3, CALC1 = 4, CALC2 = 5, PLOT = 6,
CALC3 = 7, CALC4 = 8, OCT1 = 9, OCT2 = 10, OCT3 = 11, OCT4 = 12, OCT5 = 13, OCT6 = 14, OCT7 = 15, OCT8 = 16,
DEL1 = 17, DEL2 = 18, DEL3 = 19, DEL4 = 20, DEL5= 21, DEL6 = 22, DEL7 = 23, DEL8 = 24;
always @(posedge clk) begin
if (lineCS && cpuAB == 4'b0000) //variables for line generator
x0t <= cpuDO;
if (lineCS && cpuAB == 4'b0001)
y0t <= cpuDO;
if (lineCS && cpuAB == 4'b0010)
x1t <= cpuDO;
if (lineCS && cpuAB == 4'b0011)
y1t <= cpuDO;
if (lineCS && cpuAB == 4'b0100) //variables for circle generator
xc <= cpuDO;
if (lineCS && cpuAB == 4'b0101)
yc <= cpuDO;
if (lineCS && cpuAB == 4'b0110)
rad <= cpuDO;
if (lineCS && cpuAB == 4'b0111) //color variable
color <= cpuDO;
if (lineCS && cpuAB == 4'b1000) //X length of blitter
bXlen <= cpuDO;
if (lineCS && cpuAB == 4'b1001) //Y length of blitter
bYlen <= cpuDO;
if (lineCS && cpuAB == 4'b1010) //X start copy
bXc <= cpuDO;
if (lineCS && cpuAB == 4'b1011) //Y start copy
bYc <= cpuDO;
if (lineCS && cpuAB == 4'b1100) //X start paste
bXp <= cpuDO;
if (lineCS && cpuAB == 4'b1101) //Y start paste
bYp <= cpuDO;
if (lineCS && cpuAB == 4'b1110) //border color
border <= cpuDO;
end
always @(posedge clk) begin
state <= WAIT;
case (state)
WAIT:
begin
if (lineCS && cpuAB == 3'b011) //draw a line
state <= LOAD;
else if (lineCS && cpuAB == 3'b110) //draw a circle
state <= CALC3;
else state <= WAIT;
end
LOAD:
state <= SLOPE;
SLOPE:
state <= DXDY;
DXDY:
state <= CALC1;
CALC1:
state <= CALC2;
CALC2:
state <= PLOT;
PLOT:
begin
if (!dyneg && steep) //e.g. (0,0) to (2,10)
if (y0 != y1)
state <= CALC2;
else state <= WAIT;
if (!dyneg && !steep) //e.g. (0,0) to (10,10)
if (x0 != x1)
state <= CALC2;
else state <= WAIT;
if (dyneg && !steep) //e.g. (0,10) to (10,0)
if (x0 != x1)
state <= CALC2;
else state <= WAIT;
if (dyneg && steep) //e.g. (0,20) to (2,0)
if (y0 != y1)
state <= CALC2;
else state <= WAIT;
end
CALC3:
state <= OCT1;
CALC4:
state <= OCT1;
OCT1:
if ( x >= y )
state <= DEL1;
else state <= WAIT;
DEL1:
state <= OCT2;
OCT2:
state <= DEL2;
DEL2:
state <= OCT3;
OCT3:
state <= DEL3;
DEL3:
state <= OCT4;
OCT4:
state <= DEL4;
DEL4:
state <= OCT5;
OCT5:
state <= DEL5;
DEL5:
state <= OCT6;
OCT6:
state <= DEL6;
DEL6:
state <= OCT7;
OCT7:
state <= DEL7;
DEL7:
state <= OCT8;
OCT8:
state <= DEL8;
DEL8:
state <= CALC4;
endcase
end
always @(posedge clk) begin
case (state)
WAIT:
begin
RAMWE <= 0;
LGREADY <= 1;
if (x0t > x1t)
dxneg <= 1;
else dxneg <= 0;
end
LOAD:
begin
LGREADY <= 0;
if (dxneg)
begin
x0 <= x1t;
y0 <= y1t;
x1 <= x0t;
y1 <= y0t;
end
else begin
x0 <= x0t;
y0 <= y0t;
x1 <= x1t;
y1 <= y1t;
end
end
SLOPE:
if (y0 > y1)
dyneg <= 1;
else dyneg <= 0;
DXDY:
begin
dx <= x1 - x0;
RAMWE <= 1;
X <= x0;
Y <= y0;
if (dyneg)
dy <= y0 - y1;
else dy <= y1 - y0;
end
CALC1:
begin
RAMWE <= 0;
if (dx >= dy) begin
steep <= 0;
D <= (dy*2 - dx);
end
else begin
steep <= 1;
D <= (dx*2 - dy);
end
end
CALC2:
begin
RAMWE <= 0;
if (steep) begin
if ( D[10] == 0 ) begin
x0 <= x0 + 1;
y0 <= dyneg ? y0 - 1:
y0 + 1;
D <= D + (dx*2 - dy*2);
end
else begin
y0 <= dyneg ? y0 - 1:
y0 + 1;
D <= D + dx*2;
end
end
else if ( D[10] == 0 ) begin
x0 <= x0 + 1;
y0 <= dyneg ? y0 - 1:
y0 + 1;
D <= D + (dy*2 - dx*2);
end
else begin
x0 <= x0 + 1;
D <= D + dy*2;
end
end
PLOT:
begin
RAMWE <= 1;
X <= x0;
Y <= y0;
end
CALC3:
begin
x <= rad;
y <= 0;
raderr <= 1 - x;
LGREADY <= 0;
RAMWE <= 0;
end
CALC4:
begin
RAMWE <= 0;
y <= y + 1;
if ( raderr[10] )
raderr <= raderr + (y+1);
else begin
x <= x - 1;
raderr <= raderr + (y-x)+1;
end
end
OCT1: // |
begin // |
RAMWE <= 1; // -------
X <= xc + (x); // | Oct1
Y <= yc + y; // |
end
OCT2:
begin // |
RAMWE <= 1; // |
X <= xc + (y); // -------
Y <= yc + (x); // |
end // | Oct2
OCT3: // |
begin // |
RAMWE <= 1; // -------
X <= xc - x; // Oct3 |
Y <= yc + y; // |
end
OCT4: // |
begin // |
RAMWE <= 1; // -------
X <= xc - (y); // |
Y <= yc + (x); // Oct4 |
end
OCT5: // |
begin // Oct5 |
RAMWE <= 1; // -------
X <= xc - (x); // |
Y <= yc - y; // |
end
OCT6: // Oct6 |
begin // |
RAMWE <= 1; // -------
X <= xc - (y); // |
Y <= yc - x; // |
end
OCT7: // |
begin // | Oct7
RAMWE <= 1; // -------
X <= xc + (x); // |
Y <= yc - y; // |
end
OCT8: // | Oct8
begin // |
RAMWE <= 1; // -------
X <= xc + (y); // |
Y <= yc - (x); // |
end
DEL1:
RAMWE <= 1;
//DEL2:
// RAMWE <= 1;
//DEL3:
// RAMWE <= 1;
//DEL4:
// RAMWE <= 1;
//DEL5:
// RAMWE <= 1;
//DEL6:
// RAMWE <= 1;
//DEL7:
// RAMWE <= 1;
//DEL8:
// RAMWE <= 1;
endcase
end
endmodule