Forum Discussion

kwiorek's avatar
kwiorek
Icon for New Contributor rankNew Contributor
5 years ago
Solved

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: 2046

One 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;
endmodule
  • Hi,

    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

12 Replies

  • kwiorek's avatar
    kwiorek
    Icon for New Contributor rankNew Contributor

    Thanks very much for your help! This fixed it!

    Now it says that

    Error (170048): Selected device has 30 RAM location(s) of type M9K.  However, the current design needs more than 30 to successfully fit

    Does this mean that this amount of ram will never fit inside a Cyclone IV? Is there a way to optimize it? There is about 14K left and the fitter lists 32 RAM cells.

    Sorry, I replied this late, I didn't have time to test this before.