Author Topic: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock  (Read 4683 times)

0 Members and 1 Guest are viewing this topic.

Offline garvind25Topic starter

  • Regular Contributor
  • *
  • Posts: 59
  • Country: in
Hi all,

  I was planning to implement a VGA controller using the code as below:

https://eewiki.net/pages/viewpage.action?pageId=15925278

 As per the appendix, if I want to implement a VGA controller for 640X480 resolution (60 Hz), I will need a pixel clock of 25.125 MHz. My kit has a 25.0 MHz clock. My queries are;

1. How has this number (25.125M) come in existence.
2. Can I generate this clock through an on-board 25.0 MHz source (Spartan 3 XC3S400; ISE 10.1)
3. What happens if I implement the same using the 25.0 MHz. clock instead of 25.125 MHz clock. I will prefer asking before trying it out to avoid any possible damage to
    the only board I have access to.

Thanks,
Arvind Gupta.


 
 

Offline Buriedcode

  • Super Contributor
  • ***
  • Posts: 1610
  • Country: gb
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #1 on: September 15, 2017, 05:51:52 pm »
On that page, scroll down to:

https://eewiki.net/pages/viewpage.action?pageId=15925278#VGAController(VHDL)-SignalTiming

That table shows how the pixel clock value is derived based on resolution, refresh rate, front porch, back porch etc..  Essentially, the horizontal front porch, sync, and back porch are in terms of pixel clocks.. so a line may be 640 pixels wide, but.. there are extra pixel periods off-screen (in CRT monitors, this is to give the beam a chance to "fly back" to the start of the next line) so for 16, 96, and 48  pixel clocks for front, sync, and back, thats an extra 160 off-screen "pixels", making each line 800 pixels. 

Similarly, for the vertical front porch, sync and back porch, these are added as extra 'lines'.    10,2,33 gives an extra 45 lines, with 480 display lines, that's 525. 

800 pixels * 525 lines * 60Hz refresh = 25200000 Hz. Or 25.2MHz.

I believe you can vary the front and back porch times to suit your needs.  However, I'm sure the spartan 3 has on-board PLL's which will allow you to generate almost any clock you need.

I don't see how you can damage your board.. unless you provide it with over voltage on its IO's, or start desoldering things..
 
The following users thanked this post: garvind25

Offline Scrts

  • Frequent Contributor
  • **
  • Posts: 797
  • Country: lt
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #2 on: September 15, 2017, 06:31:39 pm »
If the clock is 25MHz, you will just have a slower frame rate. Otherwise, play with the blanking periods. I've used 800x480 display with 27MHz clock, which is easily achievable by any PLL using 27 multiply and 25 division in your case.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #3 on: September 15, 2017, 07:18:08 pm »
Quote
1. How has this number (25.125M) come in existence.
No idea, most likely a lot of historical choices that no longer apply

Quote
2. Can I generate this clock through an on-board 25.0 MHz source (Spartan 3 XC3S400; ISE 10.1)
Using 25MHz will work just fine.

Quote
3. What happens if I implement the same using the 25.0 MHz. clock instead of 25.125 MHz clock.
It will work just fine. If you are using an old CRT monitor I would check the timing with a scope or logic analyzer, as driving very old CRTs with an out-of-spec video signal can break them. If the monitor has an On Screen Display (e.g. shows "No Signal") it will check the signal specs before it displays it.

If frame rate is vitally important to you, reduce the total horizontal count from 800 to 796 (by 0.5%) to balance out the clock being about 0.5% slower.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: jancumps

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9886
  • Country: us
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #4 on: September 15, 2017, 07:46:30 pm »
For the original Spartan 3 Starter Board, VGA is discussed beginning on page 21:
https://www.xilinx.com/support/documentation/boards_and_kits/ug130.pdf

They use 25 MHz...
 

Online BrianHG

  • Super Contributor
  • ***
  • Posts: 7661
  • Country: ca
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #5 on: September 16, 2017, 04:43:30 am »
If frame rate is vitally important to you, reduce the total horizontal count from 800 to 796 (by 0.5%) to balance out the clock being about 0.5% slower.
***Make the horizontal count 794...
LCD screens will need an 'auto adjust' to clean up the pixels if you are using analog RGB VGA.
You shouldn't have a problem with 800 anyways, 59.5hz should still lock, but, when playing a video file, you will occasionally drop a frame.
« Last Edit: September 16, 2017, 04:49:04 am by BrianHG »
 

Offline garvind25Topic starter

  • Regular Contributor
  • *
  • Posts: 59
  • Country: in
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #6 on: September 16, 2017, 06:28:38 am »
Thanks... One more thing. Is there a way to generate 25.2 MHz clock in Xilinx CPLD (say XC2C128/256).

Thanks again,
Arvind Gupta
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #7 on: September 16, 2017, 09:21:43 am »
AFAIK Most CPLDs do not have PLLs, DCMs or other things that allow you to generate new clocks, however I am sure somebody will correct me....

If you use two DCM blocks on the Spartan 3E, you can get pretty close - 25.1241MHz

First block:
Input 25.0 MHz
multiply by 30, Divide by 31
Output 24.193,548MHz

Second block:
Input 24.193,548 MHz
multiply by 27, Divide by 26
Output 25.124 069 MHz

That is off by only 0.004%


Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: jancumps, garvind25

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #8 on: September 16, 2017, 10:00:54 am »
Oh, and here is some code to convert a 25.0 MHz clock to a approximately 25.125 clock

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity make25_125 is
    Port ( c_in : in  STD_LOGIC;
           c_out : out  STD_LOGIC;
  locked : out STD_LOGIC);
end make25_125;

architecture Behavioral of make25_125 is
signal c_middle : std_logic;
signal locked_first : std_logic;
signal clkfb_1 : std_logic;
signal clkfb_2 : std_logic;
signal reset_2nd : std_logic_vector(4 downto 0) := (others => '1');
begin

DCM_SP_1 : DCM_SP generic map (
      CLKDV_DIVIDE => 2.0,
      CLKFX_DIVIDE => 31,   
      CLKFX_MULTIPLY => 30,
      CLKIN_DIVIDE_BY_2 => FALSE,
      CLKIN_PERIOD => 0.0,
      CLKOUT_PHASE_SHIFT => "NONE",
      CLK_FEEDBACK => "1X",
      DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
      DLL_FREQUENCY_MODE => "LOW",
      DUTY_CYCLE_CORRECTION => TRUE,
      PHASE_SHIFT => 0,
      STARTUP_WAIT => FALSE)
   port map (
      CLK0 => clkfb_1,
      CLK180 => open,
      CLK270 => open,
      CLK2X => open,
      CLK2X180 => open,
      CLK90 => open,
      CLKDV => open,
      CLKFX => c_middle,
      CLKFX180 => open,
      LOCKED => locked_first,
      PSDONE => open,
      STATUS => open,
      CLKFB => clkfb_1,
      CLKIN => c_in,
      PSCLK => '0',
      PSEN => '0',
      PSINCDEC => '0',
      RST => '0'
   );

process(c_middle)
begin
if rising_edge(c_middle) then
-- hold the reset on the second DCM a few cycles after the first one locks
reset_2nd <= '0' & reset_2nd(reset_2nd'high downto 1);
end if;
end process;


DCM_SP_2 : DCM_SP generic map (
      CLKDV_DIVIDE => 2.0,
      CLKFX_DIVIDE => 26,
      CLKFX_MULTIPLY => 27,
      CLKIN_DIVIDE_BY_2 => FALSE,
      CLKIN_PERIOD => 0.0,
      CLKOUT_PHASE_SHIFT => "NONE",
      CLK_FEEDBACK => "1X",
      DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
      DLL_FREQUENCY_MODE => "LOW",
      DUTY_CYCLE_CORRECTION => TRUE,
      PHASE_SHIFT => 0,
      STARTUP_WAIT => FALSE)
   port map (
      CLK0 => clkfb_2,
      CLK180 => open,
      CLK270 => open,
      CLK2X => open,
      CLK2X180 => open,
      CLK90 => open,
      CLKDV => open,
      CLKFX => c_out,
      CLKFX180 => open,
      LOCKED => locked,
      PSDONE => open,
      STATUS => open,
      CLKFB => clkfb_2,
      CLKIN => c_middle,
      PSCLK => '0',
      PSEN => '0',
      PSINCDEC => '0',
      RST      => reset_2nd(0));
end Behavioral;

(I am relying on the tools to infer any required clock buffers, which ISE does, usually  :D).
« Last Edit: September 16, 2017, 10:18:38 am by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: jancumps

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #9 on: September 16, 2017, 04:41:09 pm »





In this project I have divided by 2 the physical clock (50Mhz)
and everything is fine  :D

 
The following users thanked this post: garvind25

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9886
  • Country: us
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #10 on: September 16, 2017, 05:21:16 pm »
Thanks... One more thing. Is there a way to generate 25.2 MHz clock in Xilinx CPLD (say XC2C128/256).

Thanks again,
Arvind Gupta

No

There is nothing in the datasheet that leads me to believe there is a PLL or DCM in a CPLD.

https://www.xilinx.com/support/documentation/data_sheets/ds094.pdf
 

Offline garvind25Topic starter

  • Regular Contributor
  • *
  • Posts: 59
  • Country: in
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #11 on: November 06, 2017, 08:47:27 am »
Will it be possible for you to share your VGA controller code pls? I have got a Spartan 3 board from a friend and wanted to check if its VGA port works OK. I downloaded a few codes from the internet but no luck. I have a suspicion that these codes from the internet actually don't work

Thanks and Regards,
Arvind Gupta
« Last Edit: November 06, 2017, 08:49:07 am by garvind25 »
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9886
  • Country: us
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #12 on: November 06, 2017, 05:32:06 pm »
Here is code from John Kent down under.  I used if for a console on a CPU project.

http://www.volkerschatz.com/hardware/vhdocl-example/sources/vdu8.html

Not shown is the fact that you need to populate 'vdu_char_rom' using whatever scheme you wish.

Here is my VHDL version of the character ROM:
Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity char_rom is
    Port (
       clk   : in  std_logic;
       rst   : in  std_logic;
       cs    : in  std_logic;
       rw    : in  std_logic;
       addr  : in  std_logic_vector (9 downto 0);
       wdata : in  std_logic_vector (7 downto 0);
       rdata : out std_logic_vector (7 downto 0)
    );
end char_rom;

architecture rtl of char_rom is

signal Raddr : std_logic_vector(10 downto 0);

begin

Raddr <= "0" & addr;

CharRom: RAMB16_S9
   generic map (
      INIT => "000000000", --  Value of output RAM registers at startup
      SRVAL => "000000000", --  Ouput value upon SSR assertion
      WRITE_MODE => "WRITE_FIRST", --  WRITE_FIRST, READ_FIRST or NO_CHANGE

INIT_00 => x"000000FF0000001010101010101010003E1C7F7F3E1C08000000FF0000000000", -- 00..03
INIT_01 => x"202020202020200000FF0000000000000000000000FF000000000000FF000000", -- 04..07
INIT_02 => x"0000E0100808080000000304080808080810E000000000040404040404040420", -- 08..0B
INIT_03 => x"808080808080FF80402010080402010102040810204080FF8080808080808000", -- 0C..0F
INIT_04 => x"081C3E7F7F7F3600FF000000000000003C7E7E7E7E3C0001010101010101FF80", -- 10..13
INIT_05 => x"003C424242423C00814224181824428108080403000000004040404040404040", -- 14..17
INIT_06 => x"0808FF0808080800081C3E7F3E1C0802020202020202020008082A772A1C0800", -- 18..1B
INIT_07 => x"03070F1F3F7FFF001414543E010000080808080808080850A050A050A050A008", -- 1C..1F
INIT_08 => x"0024247E247E2424000000000024242400080000080808080000000000000000", -- 20..23
INIT_09 => x"0000000000100804003A444A30484830004626100864620000083C0A1C281E08", -- 24..27
INIT_0A => x"000008083E08080000082A1C3E1C2A0800201008080810200004081010100804", -- 28..2B
INIT_0B => x"00402010080402000018180000000000000000007E0000001008080000000000", -- 2C..2F
INIT_0C => x"003C42021C02423C007E40300C02423C003E080808281808003C42625A46423C", -- 30..33
INIT_0D => x"001010100804427E003C42427C40201C003844020478407E0004047E24140C04", -- 34..37
INIT_0E => x"00080800000800000000080000080000003804023E42423C003C42423C42423C", -- 38..3B
INIT_0F => x"001000100C02423C0070180C060C18700000007E007E0000000E18306030180E", -- 3C..3F
INIT_10 => x"001C22404040221C007C22223C22227C004242427E422418001E204C564A221C",
INIT_11 => x"001C22424E40221C004040407840407E007E40407840407E0078242222222478",
INIT_12 => x"0042444870484442003844040404040E001C08080808081C004242427E424242",
INIT_13 => x"0018244242422418004242464A526242004242425A5A6642007E404040404040",
INIT_14 => x"003C42023C40423C004244487C42427C001A244A42422418004040407C42427C",
INIT_15 => x"0042665A5A4242420018182424424242003C424242424242000808080808083E",
INIT_16 => x"003C20202020203C007E40201804027E000808081C2222220042422418244242",
INIT_17 => x"007E0000000000000000000000221408003C04040404043C0001020408102040",
INIT_18 => x"003C4240423C0000005C6242625C4040003A443C04380000001E204C564A221C",
INIT_19 => x"3C023A46463A0000001010107C10120C003C407E423C0000003A4642463A0202",
INIT_1A => x"004468504844404038440404040C0004001C08080818000800424242625C4040",
INIT_1B => x"003C4242423C000000424242625C00000049494949760000001C080808080818",
INIT_1C => x"007C023C403E000000404040625C000002023A46463A000040405C62625C0000",
INIT_1D => x"00364949494100000018244242420000003A464242420000000C1210107C1010",
INIT_1E => x"000C18183018180C007E2018047E00003C023A46424200000042241824420000",
INIT_1F => x"00522A522A522A520000060948300000003018180c1818300018181800181818"
)
   port map (
      DO => rdata,      -- 8-bit Data Output
      DOP => open,    -- 1-bit parity Output
      ADDR => Raddr,  -- 11-bit Address Input
      CLK => clk,    -- Clock
      DI => wdata,      -- 8-bit Data Input
      DIP => "0",    -- 1-bit parity Input
      EN => cs,      -- RAM Enable Input
      SSR => rst,    -- Synchronous Set/Reset Input
      WE => not rw       -- Write Enable Input
   );
end;


All of this works under ISE.

ETA:  This generates a text display of 25 lines of 80 chars.  It is NOT a graphics display.  Nevertheless, the timing is fully shown and it is just a matter of laying the right bits down at the right time.  The memory scheme is all wrong for graphics.  There is no pixel memory, just an 80x25 array of ASCII codes and a character ROM containing the bits for the various characters.  There is also an 80x25 array of attribute codes.

ETA:  25 MHz (even) works well.  Note that in the vdu code above, the vertical refresh rate is slightly over 70 Hz.  Most monitors can handle this easily.  I know that it works on a standard 4:3 1024x768 LCD monitor.

Absolute timing accuracy may matter for broadcast TV but not for digital monitors.
« Last Edit: November 06, 2017, 07:10:27 pm by rstofer »
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #13 on: November 06, 2017, 09:16:58 pm »
The real first big problem with a graphics display is the video ram! It's requested to be very big, so big that you can't use fpga's bram because too limited in size. Therefore you need to implement a dram controller to interface external dram, and the design goes more complex.

The second problem is: how to access it? Of course it still needs to be dual-port-ram but with dual-buffering? Yup, fine! Good! You will want it, but it needs more video memory and here it is an other step.
« Last Edit: November 06, 2017, 09:22:17 pm by legacy »
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #14 on: November 06, 2017, 09:29:51 pm »
The real first big problem with a graphics display is the video ram! It's requested to be very big, so big that you can't use fpga's bram because too limited in size. Therefore you need to implement a dram controller to interface external dram, and the design goes more complex.

The second problem is: how to access it? Of course it still needs to be dual-port-ram but with dual-buffering? Yup, fine! Good! You will want it, but it needs more video memory and here it is an other step.

The easiest way I've found to deal with this issue is to time-slice - esp with page-mode DRAM:

- a few cycles to read some data for display (open a line, read words into display shift register, close the line)
- a few cycles to process frame buffer read or writes or on a fixed schedule (e.g. once every N times) replace with a refresh cycle.

It isn't optimal, but that way you can ensure that you never stave the display of data.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9886
  • Country: us
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #15 on: November 06, 2017, 10:08:43 pm »
The Digilent Nexys 4 DDR board uses DDR2 memory.  The important thing is that Digilent provides a component that allows the memory to be treated as static ram.  Nice simple reads and writes.

I haven't used the component so I don't know how fast it is but I would try to work it out such that memory accesses could be interleaved.

The component documentation says 210 ns Read Cycle and 260 ns Write Cycle while using a 350 MHz clock.  The data width is 16 bits (which helps!).
https://reference.digilentinc.com/learn/programmable-logic/tutorials/nexys-4-ddr-sram-to-ddr-component/start

Here's a project using the Nexys 4 DDR board for graphics and mouse:
https://reference.digilentinc.com/learn/programmable-logic/tutorials/nexys-4-ddr-vga-test-pattern-with-mouse-overlay/start

 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9886
  • Country: us
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #16 on: November 07, 2017, 12:42:07 am »
The real first big problem with a graphics display is the video ram! It's requested to be very big, so big that you can't use fpga's bram because too limited in size. Therefore you need to implement a dram controller to interface external dram, and the design goes more complex.

The second problem is: how to access it? Of course it still needs to be dual-port-ram but with dual-buffering? Yup, fine! Good! You will want it, but it needs more video memory and here it is an other step.

I'm not sure the resolution was ever stated.  Further, color depth just keeps increasing word width.
640x480 with 256 colors would require 307,200 bytes of memory.  So, 512k bytes would cover it.

It is possible to get a 512kx8 10 ns SRAM for about $4
https://www.mouser.com/Semiconductors/Memory/SRAM/_/N-4bzpt

Interleave access!

 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #17 on: November 07, 2017, 08:09:38 am »
1024x768x 24bit_color x2(double buffer) => you need an external DDR controller
and a nice dram chip: already done! I am happy, just the complexity has doubled.
 

Offline simmconn

  • Regular Contributor
  • *
  • Posts: 55
Re: Implementing a VGA controller on Spartan 3 board with 25.0 MHz clock
« Reply #18 on: November 09, 2017, 12:41:20 am »
Using 25MHz for VGA pixel clock is perfectly fine. I've been using it for years. A CRT monitor is almost guaranteed to lock due to their wide frequency tolerance. I haven't have problems with LCD monitors, either. Changing the frame structure to make up for the H/V timing differences could be tricky, as you are creating a non-standard frame structure. Most likely the LCD monitor will lock to the non-standard frame structure, but the video ADC sampling points will be approximate and won't be dot-for-dot accurate. Not a big deal as today's monitor would have to scale the picture up and the artifacts of imperfect sampling would not be that obvious.

Using cascaded DCM to do clock syntheses is generally not recommended due to the resulting clock jitter, especially with large M and N values. I think Xilinx removed this configuration in the ISE core gen. Although you can still cascade them manually, you are pretty much on your own wrt jitter performance.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf