Page 2 of 5

Re: n00b Verilog Questions

Posted: Wed Sep 25, 2013 6:30 pm
by ElEctric_EyE
Great insight gentlemen! Thank you both.

What is likely to be synthesized with a very high value like the following?

Code: Select all

// timing parameters
parameter 
    HFRONT  = 2,			// front porch (+right border)
    HVIDEO  = 1024,		// active video area 
    HSYNC   = 2,			// hsync 
    HBACK   = 318;		// back porch  (+left border)  :1346 horizontal pixels total 356

......

//horizontal & vertical delay using a multi-stage single bit shift register
parameter hvd = ((HFRONT + HVIDEO + HSYNC + HBACK) * 22) + 11;		//22 scanlines + 11 pixel delay
	
reg [hvd:0] s;

wire q = s[hvd];

always @(posedge clk)
   s <= { s[hvd-1:0], countflag }

......
......

//X & Y pixel counters
reg [9:0] X = 0;
reg [9: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;
Will the tools really string 29,623 FFs in sequential order? Is this a big waste of resources?

EDIT: Functionally this works, but is adding to occupied slices and takes forever to synthesize. I guess I am on the wrong track here.

Re: n00b Verilog Questions

Posted: Wed Sep 25, 2013 8:01 pm
by Arlet
Yeah, that's probably the wrong track.

It may be a reasonable way to delay a random signal by a certain amount, but in this case, the sync pulses have a well known behavior that can be optimized.

What exactly are you trying to accomplish in the end ?

Re: n00b Verilog Questions

Posted: Wed Sep 25, 2013 8:24 pm
by ElEctric_EyE
Arlet, thanks for responding!

The code above is for PVB4, the first in line originating the HSYNC, VSYNC and RGB data.
I'm trying to center 3 pixel streams from 3 video boards each with their own HSYNC and VSYNC and pixel clock outputs/inputs.

Video board 6 is the last in line and outputs to the monitor. It receives HSYNC, VSYNC & RGB data from video board 5. It outputs its pixel clock to video board 5.
Video board 5 receives its HSYNC, VSYNC & RGB data from video board 4. It outputs its pixel clock to video board 4.
Video board 4 is the origin and outputs HSYNC, VSYNC & RGB data. It receives the pixel clock from video board 5.

I have tried to delay HSYNC in the same manner. A small delay results in shifting the picture to the left. Logically I could shift it a large delay to center it horizontally. BUT, trying to delay VSYNC only shifts the picture horizontally, not vertically. So I abandoned this approach and chose to delay the total number of pixels.

As I mentioned, I presently have all 3 boards sync'd horizontally and vertically but there must be a better method. I have tried many previous attempts that have failed.

I can draw a diagram which might be easier on the eyes.

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 5:04 pm
by ElEctric_EyE
Arlet wrote:
...What exactly are you trying to accomplish in the end ?
To put it simpler, I need to delay a certain clock signal by many thousands of cycles.
I have time to work on it today. I'm not lazy and I know it's very trivial and can do it on my own, but I like to try to learn from others as well.
This is the code I've started to work on, in the process of testing.

Code: Select all

//delay countflag
parameter hd = ((HFRONT + HVIDEO + HSYNC + HBACK) * 11) + 4;		//11 scanlines + 4 pixel = 1346 cycle horizontal delay
	
reg [11:0] s = hd;			//delay down counter
wire hd_done = s[11];		//delay count done
reg q;							//delayed output

always @(posedge clk) begin
   if (countflag)
		s <= s - 1;
	if (hd_done) begin
		q <= !q;
		s <= hd;
	end
	if (!countflag)
		s <= s - 1;
end

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 5:21 pm
by Arlet
You can't really just delay the hsync/vsync signal by so many cycles, because the pixel data needs to be sync'ed too.

What you should do is have two VGA timing generators like you have, but provide a way to delay the second one until it is in sync with the first one, or set the internal state of the second one to be in sync with the first one at some point in time. For instance, detect rising or falling edge of incoming vsync, and use that to set the 2nd state machine in the same state.

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 5:26 pm
by ElEctric_EyE
Thanks, but it's not the sync signals I'm attempting to delay. Just delaying the 'countflag' signal that enables the horizontal counter to start counting pixels for the X/Y RAM address generator.

The sync signals are locked on with this code for vsync (same for hsync):

Code: Select all

// 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;

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 5:30 pm
by Arlet
In your code you have 3 assignments to 's'. That's not going to work. You can only have 1 assignment.

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 5:52 pm
by ElEctric_EyE
I see that now, thanks. My main mental problem with this circuit is that I shouldn't have to have 2 delay counters for when the signal, to be delayed, is high or low should I? or maybe I should because it is not a 50/50 square wave.

Code: Select all

//delay countflag
parameter hd = ((HFRONT + HVIDEO + HSYNC + HBACK) * 11) + 4;		//11 scanlines + 4 pixels = 1346 cycle horizontal delay
	
reg [11:0] s = hd;			//delay down counter
wire hd_done = s[11];		//delay count done
reg q;							//delayed output

always @(posedge clk) begin
   if (hd_done) begin
		q <= !q;
		s <= hd;
	end
		else if (countflag | !countflag)
			s <= s - 1;
end
The signal 'countflag' is not 50/50 due to this code:

Code: Select all

//pixel counters & video address
always @(posedge clk) 
	if ( hstart )
		countflag <= 1;
	else if ( hblank )
		countflag <= 0;

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 5:59 pm
by Arlet
Taking a step back... What I would do is : 1) synchronize 2nd VGA timing generator to first. 2) Use each timing generator to derive the signals for the RAM address generator. So, even if you disconnect first video card, the 2nd will just generate a standalone image.

But, back to your code, basically you want to delay incoming 'countflag' signal by 'hd' cycles ? And I assume that countflag stays in same state for > hd cycles, which allows use of simple counter, correct ?

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 6:07 pm
by ElEctric_EyE
Arlet wrote:
... basically you want to delay incoming 'countflag' signal by 'hd' cycles ? And I assume that countflag stays in same state for > hd cycles, which allows use of simple counter, correct ?
Yes, when 'countflag' goes high, the output 'q' goes high after 'hd' cycles. When 'countflag' goes low, the output 'q' goes low after 'hd' cycles.
Arlet wrote:
Taking a step back... What I would do is : 1) synchronize 2nd VGA timing generator to first. 2) Use each timing generator to derive the signals for the RAM address generator. So, even if you disconnect first video card, the 2nd will just generate a standalone image...
Right now I have the boards set up like that. If you reset the 1st board, only that image disappears. If you reset the 2nd board, boards 1 & 2 image disappears. Only if you reset the last output board does the screen go blank.

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 6:21 pm
by Arlet
If I understand it correctly, countflag toggles per line, but you want to delay it by 11 lines. This means that using a counter isn't going to work.

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 6:28 pm
by ElEctric_EyE
Ok, I see that now. Would you recommend delaying each boards' 'countflag' signal by 'hd' amount after hstart, and the same for 'hblank'?

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 6:41 pm
by MichaelM
Coming into this kind of late. Understand you want to build a one-shot delay circuit. Can you provide a timing diagram. A picture of a napkin drawing should be sufficient instead of a nice and pretty diagram. It may clear up your requirements.

I did notice one thing in your code that I don't think you intended:

Code: Select all

//delay countflag
parameter hd = ((HFRONT + HVIDEO + HSYNC + HBACK) * 11) + 4;      //11 scanlines + 4 pixels = 1346 cycle horizontal delay
   
reg [11:0] s = hd;         //delay down counter
wire hd_done = s[11];      //delay count done
reg q;                     //delayed output

always @(posedge clk) begin
   if (hd_done) begin
      q <= !q;
      s <= hd;
   end
      else if (countflag | !countflag)
         s <= s - 1;
end
I think your intent is to count s down on the falling edge of countflag. However, the construction in the if() is always true because the operator should be an AND (&) instead of an OR (|). However, even if you change it to an AND as I recommend, it still won't work as I think you'd like. The problem is that you need to store countflag in a register so that the falling edge can be determined as a change in the state of countflag.

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 6:56 pm
by ElEctric_EyE
Michael, thanks for your input.
I'm thinking maybe I may need something like:

Code: Select all

always @(posedge countflag)
.....delayed output reg will go high after many cycles
.....
always @(negedge countflag)
.....delayed output reg will go low after same amount of cycles
.....
But I am unfamiliar with this type of coding.

Re: n00b Verilog Questions

Posted: Wed Oct 02, 2013 7:03 pm
by Arlet
The problem remains that your input signal toggles a number of times within the delay period, which means there's no simple way to do this.