Page 40 of 41

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Wed Oct 09, 2013 2:43 pm
by ElEctric_EyE
I did have to raise the drive strength to 16mA to successfully drive the main clock to 3 other boards. So maybe 24mA for 5 boards? I don't like the idea of stressing 1 pin to it's max, especially for a high speed clock...
Also, with a common clock originating from one board, there is a problem at startup when all the boards are programmed at the same speed. While this could be fixed by programming the slave boards slower. Something isn't right with that IMO.

A few more experiments and I will submit the block diagram. I would like to further investigate the operation when each of the 4 boards is running off of it's own oscillator and trying to sync to the incoming HSYNC and VSYNC.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Wed Oct 09, 2013 6:27 pm
by enso
Just as a thought, if it becomes necessary, you could probably gang up 2 (or more) adjacent pins to increase drive power.

There is an issue of contention. I would verify (in FPGA editor) that the connection between the output pin drivers is direct and reasonably identical. It may be necessary to put a resistor on the output to avoid contention if there is a timing mismatch, although it may mess up the clock depending on how fast it is going.

I am assuming you are driving DCMs, which should square up the clock anyway...

You could also put a fast switching transistor on a pin output.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Wed Oct 09, 2013 6:32 pm
by Arlet
But do you only need to have the high drive strength for the clock ? Why not the other signals ?

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Wed Oct 09, 2013 7:13 pm
by ElEctric_EyE
I really need to finish the block diagram. But look at the backplane which connects the 4 boards presently. The main clock in the center, in green (under the board), is common to all the PVB's. It was meant to be used so that oscillators would not be needed on the pass-thru boards. However, I am starting to rethink that...

Right now I have 4 boards running each with their own oscillators, but I think I am having metastability issues? The circles outputted by each board are not steady horizontally. Do I need to put each HSYNCin & VSYNCin through a 2 or 3 stage shift register?

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Sun Oct 13, 2013 11:59 am
by ElEctric_EyE
ElEctric_EyE wrote:
...Right now I have 4 boards running each with their own oscillators, but I think I am having metastability issues? The circles outputted by each board are not steady horizontally. Do I need to put each HSYNCin & VSYNCin through a 2 or 3 stage shift register?
I don't think it's a metastibility issue as I have tried to eliminate the jitter by adding a 3-stage shift to HSYNCin and VSYNCin to each of the boards, with no noticeable difference.
So I think it's time to solder in the bypass caps for the power supply and FPGA on the 2 newest boards.

I tried to capture the jitter in this pic, but it doesn't seem to show. I haven't tried to make any adjustments to align the pic's. Each board is programmed as such:
PVB1 outputs a Red circle @(319,239) radius=174
PVB2 outputs a Green circle @(319,239), radius=176
PVB3 outputs a Blue circle @(319,239), radius=178
PVB4 outputs a Yellow circle @(319,239), radius=180

Observations:
Jitter is worst on PVB1. Holding PVB1 in a reset state does not improve PVB2 jitter.
Holding PVB2 in a reset state does improve PVB3 and eliminates PVB4 jitter.

The red and green are the 1st and 2nd PVB's using the faster 4.0ns GSI RAM's. The blue and yellow are the 3rd and 4th PVB's using the slower 6.5ns Cypress RAM's. The 4th board is the output board. Each boards delay shifts the alignment to the left.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Sun Oct 13, 2013 1:30 pm
by MichaelM
EEyE:

I don't think that clock jitter is the issue. I think the issue is caused by using separate oscillators for each card. There's very little chance that they are all on the same frequency. That fact alone is enough to induce the jitter-like effects that you seem to be tracking down.

Because you have used multi-stage synchronizers on your critical timing signals, you have reduce the possibility that metastability, which can arise in systems simply because of clock drift, is a likely culprit. All signals passing between the cards at the pixel rate need to be synchronized. Thus, in addition to the timing signals, you may require that data input and output be synchronized. I doubt that will be required because your oscillators would need to have substantially larger relative frequency differences than you can expect in a lot of standard 50 ppm or 100 ppm oscillators.

One experiment that you can conduct is to use a gated counter on three of your boards. This counter is gated on the video field, and counts the number of clock cycles between two points in the video. I suggest that the counter count the number of clock cycles between consecutive vertical synch pulses. This gives a large window over which the frequency of three of the oscillators can be measured.

My suspicion is that one oscillator, say the oscillator on PVB1, is 50 MHz ±0 Hz, but relative to that frequency, the frequencies of the oscillators on PVB2, PVB3, and PVB4 are different. I expect them to be within the tolerances specified by the manufacturer, but I also expect them not to be equal to frequency of PVB1, or 50 MHz ±0 Hz.

Say that PVB2 is 10ppm faster, PVB3 is 25ppm faster, and PVB4 is 12.5 ppm slower than PVB1. That would mean that PVB2 would have an operating frequency of 50.0005 MHz, and PVB3 would have an operating frequency of 50.00125 MHz, and PVB4 would have an operating frequency of 49.999375 MHz. In a 60 Hz field, the number of clock cycles that these boards would have relative to PVB1 would be PVB2: 833,341.6667; PVB3: 833,354.1667; PVB4: 833,322.9167.

The differences relative to PVB1 are relatively small, but across a single line of video, they can cause a slight shift in the alignment of one pixel to another when compared to a reference signal. I expect those differences to manifest themselves as regular or irregular horizontal shifts in the images of the three boards relative to the fourth.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Sun Oct 13, 2013 1:45 pm
by Arlet
Metastability is rarely an issue, especially with fast logic and comparatively low clock speeds. A much more common problem is that one input gets routed to two flip flops, and due to threshold differences and delays, one flip flop reads a '0' while the other reads a '1'. Another common problem is with parallel buses. You can use 2-flop synchronizers on all incoming wires, but that could still introduce timing differences. If two incoming signals go from '0' to '1' at the same time, and you grab them both during the transition, one could be sampled as '0' and the other as '1'.

My recommendation would be to send a pixel clock with the pixel/sync data, so that all incoming data can be sampled on the edge of this pixel clock, guaranteeing none of the issues above. Once inside the FPGA you have two choices: use the same pixel clock for the rest of your circuit, or stick the pixel/sync data into asynchronous FIFO, and take it out using the other clock. The first option is simpler, so I'd start with that first.

With 3 FPGAs in a row, the first one generates the pixel clock, sends it to second board, and the second board sends its own pixel clock with the outgoing data.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Sun Oct 13, 2013 10:13 pm
by ElEctric_EyE
MichaelM wrote:
...One experiment that you can conduct is to use a gated counter on three of your boards. This counter is gated on the video field, and counts the number of clock cycles between two points in the video. I suggest that the counter count the number of clock cycles between consecutive vertical synch pulses. This gives a large window over which the frequency of three of the oscillators can be measured...
Excellent suggestion! I will give priority to this idea. I imagine a pixel counter that spans multiple 1024x768 PVB's, which suggests some new possibilities IMO. Either overlay, or a contiguous graphic space with each board having it's assigned area. This will require a register that is readable by all PVB's and/or the cpu controlling them. I think this is the solution I was looking for.
Arlet wrote:
...My recommendation would be to send a pixel clock with the pixel/sync data, so that all incoming data can be sampled on the edge of this pixel clock, guaranteeing none of the issues... Once inside the FPGA... use the same pixel clock for the rest of your circuit...
With 3 FPGAs in a row, the first one generates the pixel clock, sends it to second board, and the second board sends its own pixel clock with the outgoing data.
A few weeks ago, when I had 3 boards running successfully, this was exactly how it ran. I ran into a problem in the way I was aligning the boards with a multiple many thousands of cycle shift registers. So with 4 boards, I basically lost the attempt to align and just get good data through. But I went errant it seems.
The backplane was designed so each PVB could receive a pixel clock and send a pixel clock, along with receiving and sending the RGB data. No doubt thanks to your input way back then.
So I will reprogram the 4 boards to do this tonight, and delay the soldering of the bypass cap's. :lol:

Thanks for the suggestions/observations!

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Tue Oct 15, 2013 1:40 am
by ElEctric_EyE
Arlet wrote:
...With 3 FPGAs in a row, the first one generates the pixel clock, sends it to second board, and the second board sends its own pixel clock with the outgoing data.
The only thing I don't like about this setup is that if any 1 board is reprogrammed, the final picture is always blanked during programming

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Wed Oct 16, 2013 11:11 am
by ElEctric_EyE
Also, I'm thinking that each board reset after PVB1, which is done in Verilog after initial powerup, should be staggered by some cycles.

Working on PVB5.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Thu Oct 17, 2013 12:12 am
by ElEctric_EyE
Not so much luck with PVB5. ISE sees the PROMs but no action from the board. I tried to modify my SOP for soldering... Will figure it out later.

Had some luck re-routing some signals to center 4 outputs horizontally. The last output board PVB6 now outputs its primary pixel clock back through to the PVB5's videoDAC and pixel clock in. Then PVB5 countflag is delayed some cycles using a 1-bit shift register. Countflag triggers 1 cycle after hstart. Same concept for PVB5 into PVB4, etc. Now resetting any board (except PVB6) does not take out the whole picture.

Before, PVB6 was the output board but PVB3 was the master pixel clock generator passing it's pixel clock through it's videoDAC onto PVB4, etc.
Now PVB6 is still the output board but outputs its pixel clock to its videoDAC and PVB5's videoDAC (used to be pixel clock out, now pixel clock in). Still working on the block diag!

PVB6 no delay. Output board. 6.5ns SyncRAM.
For PVB5 a countflag delay of 6. 6.5ns SyncRAM.
For PVB4 a countflag delay of 15. 4.0ns SyncRAM.
For PVB3 a countflag delay of 23. 4.0ns SyncRAM.

The next challenge is to delay vertically. I've not had much luck there yet for some reason.


Here is my modified version of Arlet's vga.v controller for PVB3.

Code: Select all

module vga( input clk,
				input [10:0] OACCout,	// vertical offset register
				input [10:0] NACCout,	// horizontal offset register
				input CB0,					// 1 = bank 1, 0 = bank 0
				input CB1,					// 1 = scroll, 0 = bank switch
				input CB2,					// 1 = horizontal scroll, 0 = vertical scroll
				input CB3,					// 1 = arrange memory for vertical scroll and allow offscreen plotting in Y direction
				output reg hsync,			// horizontal sync out
			   output reg vsync,			// vertical sync out
			   output reg hstart,		// line start on next clock
			   output reg vstart,		// field starts on next clock
			   output reg hblank = 1,	// hblank on next clock
			   output reg vblank = 0,	// vblank on next clock
				output reg [20:0] Vaddr,// to SyncRAM
				output reg countflag,	// to VDACdata module
				input HSYNCin,				// horizontal sync input
				input VSYNCin				// vertical sync input
				);
				
// timing parameters
parameter
	 HFRONT  = 3,			// front porch (+right border)
    HVIDEO  = 1024,		// active video area 
    HSYNC   = 3,			// hsync 
    HBACK   = 316;		// back porch  (+left border)  :1346 horizontal pixels total 356

parameter
    VFRONT  = 3,			// front porch (+bottom border)
    VVIDEO  = 768,		// active video area
    VSYNC   = 6,			// vsync
    VBACK   = 30;  		// back porch  (+top border)

// states (used for both H and V state machines)
parameter
    VIDEO  = 2'd0,
    FRONT  = 2'd1,
    SYNC   = 2'd2,
    BACK   = 2'd3;

// horizontal counters and state
reg [10:0] hcount = 0;				// down counter for horizontal state 
reg [9:0] hload;						// next load value
reg [1:0] hstate = FRONT;			// horizontal state
wire hcount_done = hcount[10];	// done when count < 0

// vertical counters and state
reg [10:0] vcount = 0;				// down counter for vertical state
reg [9:0] vload;						// next load value
reg [1:0] vstate = FRONT;			// horizontal state
wire vcount_done = vcount[10];	// done when count < 0

// enable signal for V state machine
wire venable = (hstate == FRONT) & hcount_done;
	
// preload next timer value depending on state
// subtract 2 from timing value to compensate for pipeline delays
// This should be synthesized as a small LUT ROM, so it's quite
// efficient.
always @(posedge clk)
	hload <= (hstate == BACK)  ? HVIDEO - 2:
	         (hstate == VIDEO) ? HFRONT - 2:
		 (hstate == FRONT) ? HSYNC - 2:
		  		     HBACK - 2;

// do the same for vertical 
always @(posedge clk)
	vload <= (vstate == BACK)  ? VVIDEO - 2:
	         (vstate == VIDEO) ? VFRONT - 2:
		 (vstate == FRONT) ? VSYNC  - 2:
		  		     VBACK  - 2;

// adjust down counter. Reload when it's done.
always @(posedge clk) 
	     if( HSYNCin | hcount_done )
		  hcount <= { 1'b0, hload };
	     else
		  hcount <= hcount - 1;

// when down counter is done, go to next state
always @(posedge clk)
	if( hcount_done ) 
	    case( hstate )
		    VIDEO : hstate <= FRONT;
		    FRONT : hstate <= SYNC;
		    SYNC  : hstate <= BACK;
		    BACK  : hstate <= VIDEO;
	    endcase
		 else if (HSYNCin)
			hstate <= VIDEO;

// start of active line
always @(posedge clk)
	    hstart <= (hstate == BACK) & hcount_done & ~vblank;

// vstart pulse to signal end of vertical blanking
always @(posedge clk)
	    vstart <= (vstate == BACK) & venable & vcount_done;
	
// adjust down counter. Reload when it's done.
always @(posedge clk) 
	if( venable ) begin
	     if( VSYNCin | vcount_done )
		  vcount <= { 1'b0, vload };
	     else
		  vcount <= vcount - 1;
	end

// when down counter is done, go to next state
always @(posedge clk) 
	if( venable & vcount_done ) 
	    case( vstate )
		    VIDEO : vstate <= FRONT;
		    FRONT : vstate <= SYNC;
		    SYNC  : vstate <= BACK;
		    BACK  : vstate <= VIDEO;
	    endcase
		 else if (VSYNCin)
			vstate <= VIDEO;
		 
// update registered outputs
always @(posedge clk) begin
	    hsync  <= hstate == SYNC;		
	    vsync  <= vstate == SYNC;		
	    hblank <= (vstate == VIDEO) & (hstate == VIDEO) & hcount_done;
	    vblank <= vstate != VIDEO;
	end

//delay countflag using a single bit shift register	
parameter hvd = 23;		
reg [hvd:0] s;
wire q = s[hvd];

always @(posedge clk)
   s <= { s[hvd-1:0], countflag };
	
//pixel counters & video address
always @(posedge clk) 
	if ( hstart )
		countflag <= 1;
	else if ( hblank )
		countflag <= 0;

//X & Y pixel counters
reg [9:0] X = 0;
reg [10:0] Y = 0;

always @(posedge clk) begin
		if ( vstart | ( X == 1023 & Y == 767 )) begin
			X <= 0;
			Y <= 0;
		end
		if ( X == 1023 ) begin
			Y <= Y + 1;
			X <= 0;
		end
			else if ( q ) 
				X <= X + 1;
end
	
//X & Y addressing using pixel counters	
always @*
	if (!CB3) begin																		//CB3 = 1 to allow offscreen plotting in Y direction
		if (CB1) begin																		//CB1 = 1 to scroll, 0 to bank switch
			if (CB2)	Vaddr [20:0] <= { X + NACCout, 10'd768 - Y [9:0]};		//CB2 = 1 to scroll horizontal
				else  Vaddr [20:0] <= { Y [9:0] + OACCout, X }; 				//scrolling vertical
		end
		else 	   Vaddr [20:0] <= { CB0, Y [9:0], X };  			 				//bank switching
	end
		else Vaddr [20:0] <= { Y, X };
 
endmodule

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Fri Oct 18, 2013 2:57 am
by ElEctric_EyE
Almost caught this slippery fish!
All vertical timing identical on all boards now:

Code: Select all

parameter
    VFRONT  = 2,			// front porch (+bottom border)
    VVIDEO  = 768,		// active video area
    VSYNC   = 2,			// vsync
    VBACK   = 35;  		// back porch  (+top border) (807 total)
Red & Green (PVB1 & 2) seems be off horizontally by 1 pixel. I can easily fix that later.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Mon Oct 21, 2013 1:49 pm
by ElEctric_EyE
A bittersweet moment. I got them lined up vertically using my inefficient method of delaying 'countflag', which is like a display enable signal, by a great many cycles. It's inefficient because each successive board uses up an additional ~4% of slice LUTs, and ~14% of slice LUTs used as memory. The 1st output board with no delay uses 55% and 1% respectively and the 4th board uses 66% and 43% respectively. But it still fits and I need to move on, lest I go insane. With 2 more boards to go, it should all be able to still fit. This is still including the 65Org16.b to control things. When I attain more Verilog skills I will go back and deal with this issue.
Not sure what to go on to next, maybe having the cpu draw in block RAM first instead of video RAM and then transfer on non display periods. Anyway progress should be much quicker, and the efforts reaped 4x, since programming 4 boards simultaneously to get up to par was very time consuming.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Mon Oct 21, 2013 4:49 pm
by ElEctric_EyE
Got board 5 running. There was initially a noise issue after touching up the board 4 times with the soldering iron and finally seeing signs of life. I thought the noise issue was low supply voltage, because I read 2.5V on the 3.3V rail. I realized PVB2 was set to output 6mA. I changed it to 12mA and the issue cleared up.
Still there are 2 curiosities:
1) These boards are running fine @2.5V when all are set to LVCMOS33. ?
2) PVB2 is the main current hog for some reason, but appears to be fully functional. The RAM runs about 10degF hotter.

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Posted: Tue Oct 22, 2013 8:10 pm
by ElEctric_EyE
Today I refined a few things. Like the ISE JTAG programming speed of all the boards are now identical @22. Also the low drive current @6mA setting in the .ucf file for boards 3,4,5 had propagated in from PVB2. What a discovery and the realization that while it may be easy to copy and paste chunks of code across the boards or even entire project files, a simple oversight can become a huge problem in the end.

Anyway, I just wanted to say I am observing an interesting phenomenon: When the boards are cold, I see all the circles 'shimmering' horizontally. After about an hour of no power this can take about 10 seconds before the effect dies down. After they're warm, when I power-down then power-up, it only happens for about 1 sec. It's very interesting and sort of cool to think that all the sync's are locking-on despite external variables like temperature. I can tolerate this.