ElEctric_EyE wrote:
Code:
NFO:Xst:1767 - HDL ADVISOR - Resource sharing has identified that some arithmetic operations in this design can share the same physical resources for reduced device utilization. For improved clock frequency you may try to disable resource sharing.
Yesterday I tried disabling the 'resource sharing' as was suggested by the programmer(s) of ISE and max speed shot up to 220+MHz just for the module...
So, with confidence I could maintain 100MHz cpu speed, I applied this setting to my current project in the midst of adding in the LineGen module and was able to keep the cpu and all the other modules 4x speed above the 640x480 25MHz video generator module!
I have successfully drawn 4 lines using my LineGen state machine running @100MHz alongside the .b core. I have it set up so that it immediately starts plotting each time after the cpu has sent the last coordinate, i.e. 'y1'. The software sends x0, y0, x1, finally y1. I put a software delay in after sending the final y1 coordinate as I have not yet added in a DONE state to LineGen and it takes 2 cycles for each pixel to be plotted + another 4 cycles for each line total.
Just as I have tried to route the stack page and zero page pointers off cpu, I tried to do the same with the B accumulator, which I want dedicated to the pixel color. This part is not yet correct as the FPGA is writing '0's to the external SyncRAM instead of the B accumulator value that I can see in ISim correctly as a yellow value 'FFE4' (although it looks blue in the pic). More work is needed, but I am very pleased with the progress, and the Spartan6 product.
The 4 line coordinates are (swapping is still needed as not all coordinates functioned correctly):
Code:
(0,0) to (320,240)
(320,240) to (639,0)
(320,240) to (639,479)
(0,479) to (320,240)
So in the name of the projects' progress I think I should post the LineGen, especially since it will be the last post on this page:
Code:
`timescale 1ns / 1ps
module LineGen ( input clk,
input lineCS,
input [15:0] cpuDO,
input [1:0] cpuAB,
output reg RAMWE,
output reg [9:0] X,
output reg [8:0] Y
);
reg [9:0] x0, x1, dx, x0t, x1t; //internal module registers
reg [8:0] y0, y1, dy, y0t, y1t;
reg [16:0] D; //error accumulator + carry bit. if D[16] = 1, it is negative
reg steep; //1 when dy>dx
reg dyneg; //1 when dy is negative
reg [2:0] state;
parameter WAIT = 0, LOAD = 1, SLOPE = 2, DXDY = 3, CALC1 = 4, CALC2 = 5, PLOT = 6;
always @(posedge clk) begin
if (lineCS && cpuAB == 2'b00)
x0t <= cpuDO;
if (lineCS && cpuAB == 2'b01)
y0t <= cpuDO;
if (lineCS && cpuAB == 2'b10)
x1t <= cpuDO;
if (lineCS && cpuAB == 2'b11)
y1t <= cpuDO;
end
always @(posedge clk) begin
state <= WAIT;
case (state)
WAIT:
if (lineCS && cpuAB == 2'b11)
state <= LOAD;
else state <= WAIT;
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
endcase
end
always @(posedge clk) begin
case (state)
WAIT:
RAMWE <= 0;
LOAD:
begin
x0 <= x0t;
y0 <= y0t;
x1 <= x1t;
y1 <= y1t;
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:
if (dx >= dy) begin
steep <= 0;
D <= (dy*2 - dx);
end
else begin
steep <= 1;
D <= (dx*2 - dy);
end
CALC2:
begin
RAMWE <= 0;
if (steep) begin
if ( D[16] == 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[16] == 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
endcase
end
endmodule