Problem with indexing a large register.
For some time I have been trying to make a simple CGA to VGA converter. I don't need it to be very complicated - it just has to display black and white text.
It is supposed to deinterlace the video signal by storing the whole frame in the first half of the RAM, while the other half is read with a different clock speed and send it to the output. VGA and CGA have completely different pixel clock speeds, so I'm using two PLLs to generate the clock cycles - ~6MHz and ~25MHz
The converter should only be displaying and reading pixels only when it is in a specific part of the frame.
To my knowledge I'm using a Dual Clock RAM, so It should be possible to fit two 128 Kb frames into the block RAM of a Cyclone IV. Hovewer when I try to compile it, it uses a lot more logic elements than it is supposed to. The compilation often hangs for a couple of hours and then crashes. The error I frequently get is:
Sub-system: OPT, File: /quartus/synth/opt/opt_op_decsel.cpp, Line: 2046One time it finished synthesizing after 1.5 h, it made 218 000 logic elements apart from using the 130Kb of RAM. One time I also got a quartus_map.exe out of memory error as it tried to use 12GB.
I tried using the template of a Simple Dual Port RAM (dual clock), but the problem was the same.
I am quite new to FPGA programming, and I have no idea what might cause this problem as the compiler doesn't show any errors, it just crashes.
Here is the code:
module CGA2VGA2(
input clk,
input rgb,
input cgaVsync,
input cgaHsync,
output reg val,
output reg vgaHsync,
output reg vgaVsync
);
wire cgapxclk;
wire vgapxclk;
reg [8:0] cgahcnt;
reg [8:0] cgavcnt;
reg [9:0] vgahcnt;
reg [9:0] vgavcnt;
reg [6:0] hsyncnt;
reg [1:0] vsyncnt;
reg [16:0] cgafpxcnt;
reg [17:0] vgafpxcnt;
reg f1pxdat [127999:0];
reg f2pxdat [127999:0];
reg parity;
reg frame;
reg vsync, hsync;
reg [1:0] test;
pll PLL (.inclk0(clk), .c0(cgapxclk), .c1(vgapxclk));
always @(posedge cgapxclk) begin
if(cgaHsync && cgahcnt > 320) begin
cgahcnt = 0;
cgavcnt = cgavcnt + 1;
hsync = 1;
end
else begin
cgahcnt = cgahcnt + 1;
hsync = 0;
end
if(!cgaVsync && cgavcnt > 200) begin
cgavcnt = 0;
vsync = 1;
end
else vsync = 0;
if(cgahcnt >=56 && cgahcnt < 376 && cgavcnt >=39 && cgavcnt <239) begin
cgafpxcnt = (cgahcnt-56)*2*(cgavcnt-39);
if(frame) begin
if(parity) f1pxdat[cgafpxcnt] <= rgb;
else f1pxdat[cgafpxcnt+1] <= rgb;
end
else begin
if(parity) f2pxdat[cgafpxcnt] = rgb;
else f2pxdat[cgafpxcnt+1] = rgb;
end
end
end
always @(posedge vgapxclk) begin
if (hsync) begin
vgaHsync = 0;
test = test + 1;
end
if (!vgaHsync && hsyncnt < 96) hsyncnt = hsyncnt + 1;
else begin
vgaHsync = 1;
hsyncnt = 0;
end
if((!vgaHsync && vgahcnt > 320) || vgahcnt >=799) begin
vgahcnt = 0;
vgavcnt = vgavcnt + 1;
if (test[1]) begin
vgaHsync = 0;
end
test = test + 1;
end
else vgahcnt = vgahcnt + 1;
if (vsync) vgaVsync = 0;
if (!vgaVsync && vsyncnt < 2) vsyncnt = vsyncnt + 1;
else begin
vgaVsync = 1;
vsyncnt = 0;
end
if(!vgaVsync && vgavcnt > 200) vgavcnt = 0;
if(vgahcnt >=144 && vgahcnt < 784 && vgavcnt >=75 && vgavcnt <475) begin
vgafpxcnt = (vgahcnt-144)*(vgavcnt-75);
if(!frame) val = f1pxdat[vgafpxcnt[17:1]];
else val = f2pxdat[vgafpxcnt[17:1]];
end
else val = 0;
end
always @(negedge cgaVsync) parity = ~parity;
always @(posedge parity) frame = ~frame;
endmoduleHi,
I received the reply from our developer today, you have to add the below setting in the QSF file. If the RAM inference is off, the 128K RAM is not fit for generic logic implementation.
set_global_assignment -name AUTO_RAM_RECOGNITION ON
Thanks.
Best regards,
KhaiY