6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Apr 28, 2024 10:52 pm

All times are UTC




Post new topic Reply to topic  [ 609 posts ]  Go to page Previous  1 ... 37, 38, 39, 40, 41  Next
Author Message
PostPosted: Wed Oct 09, 2013 2:43 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 09, 2013 6:27 pm 
Offline
User avatar

Joined: Sat Sep 29, 2012 10:15 pm
Posts: 899
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.

_________________
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 09, 2013 6:32 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
But do you only need to have the high drive strength for the clock ? Why not the other signals ?


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 09, 2013 7:13 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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?

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 13, 2013 11:59 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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.


Attachments:
4 boards.JPG
4 boards.JPG [ 101.77 KiB | Viewed 1135 times ]

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502
Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 13, 2013 1:30 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 13, 2013 1:45 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
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.


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 13, 2013 10:13 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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!

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 15, 2013 1:40 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Wed Oct 16, 2013 11:11 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 17, 2013 12:12 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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:
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


Attachments:
4 boards horizontal alignment.JPG
4 boards horizontal alignment.JPG [ 63.43 KiB | Viewed 1060 times ]

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502
Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 18, 2013 2:57 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Almost caught this slippery fish!
All vertical timing identical on all boards now:
Code:
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.


Attachments:
4 boards almost vertical alignment.JPG
4 boards almost vertical alignment.JPG [ 58.08 KiB | Viewed 1029 times ]

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502
Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 21, 2013 1:49 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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.


Attachments:
4 boards aligned.JPG
4 boards aligned.JPG [ 369.6 KiB | Viewed 1008 times ]

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502
Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 21, 2013 4:49 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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.


Attachments:
5 boards aligned.JPG
5 boards aligned.JPG [ 320.29 KiB | Viewed 1003 times ]
5 boards side.JPG
5 boards side.JPG [ 388.35 KiB | Viewed 1003 times ]

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502
Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 22, 2013 8:10 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
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.

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 609 posts ]  Go to page Previous  1 ... 37, 38, 39, 40, 41  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: