Reply by pete...@alarmip.com December 30, 20052005-12-30
Dear Symon,

Today I rewrote the entire module using procedural code and now
everything is working perfectly!!!

It is odd how the code would work for a bit and then stop for another
bit...

Anyhow, this is how one learns to make things work...

Many thanks to you and to all who offered help.

Regards,
Peter

PS. It is p-ing down here in torrents!!! Corfu is the greenest island
in Greece for a very good reason!!!

Reply by Jon Elson December 30, 20052005-12-30

peter.halford@alarmip.com wrote:

>Dear All, > >Many thanks for all your suggestions... > >I have tried dividing my incoming 25MHz clock by 2 and voilla! >everything works, albeit 50% slower... > >So now I guess I will have to divide the incoming clock by 2, multiply >it and re-divide it. > >Any ideas why this could be happening? > >
Doesn't completely fit the symptoms, but is it possible there are reflections on the clock input? What you are doing is not only dividing the clock, but providing a clean clock from WITHIN the FPGA. Of course, you also could have an extremely slow path in the design somewhere, but that would have to be a huge amount of combinatorial logic or maybe some very slow external path like a RAM, to make it work at 12.5 MHz but fail at 25. Jon
Reply by Symon December 30, 20052005-12-30
Hi Peter,
It would appear from your VHDL code that you're sending sync signals out of 
your entity that are generated from combinational logic. I would suggest 
that this is BAD.
Look at this line:-

IHSync_x <= LO when hCount_r = (tHP-1) else HI when hCount_r = (tWH-1) else 
IHSync_r; -- Hor. sync generation

The signal IHSync_x is the signal that gets propagated out of the design. 
The problem is that not all of the wires that make up signal hCount_r change 
at exactly the same time. There will be some skew on them. This means that 
IHSync_x could have glitches on it. Not good for a sync signal! Move the 
VHDL line inside the clocked update process. That way, IHSync_x will come 
straight from a FF and will be glitch free.

HTH, Syms.

p.s. I hope the wine is still flowing in Greece? Wish I was there myself, 
it's p-ing down here in Plymouth.


Reply by pete...@alarmip.com December 29, 20052005-12-29
Dear Group,

I know how annoying it is when one posts blocks of HDL, but I would
really appreciate someone telling me why this code does not work -- or
at least, a pointer to my stupidity!!!

This HDL is supposed to generate standard -ve syncs plus an early
'newline' signal to a specialised SDRAM controller which writes a
complete line of octets into alternate block-RAMs in my Spartan-3
device.

It then attempts to display them by generating alternate read enables
(based on the current vertical line).

Tomorrow I am going to rewrite the code using discrete processes (one
for each sync signal etc...).


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;

entity VidCont is
  generic(
    DATA_WIDTH           :     natural := 16;      -- video data width
    VADDR_WIDTH          :     natural := 10       -- Video FIFO
(blockRAM) address width
    );
  port(
    -- Interface
    clk                 : in  std_logic;    -- Master clock @25MHz
    rst                 : in  std_logic;    -- Reset
    -- Video blockRAM side
    VIAddr              : out std_logic_vector(VADDR_WIDTH-1 downto 0);
-- Video line buffer address
    VADIn               : in  std_logic_vector(DATA_WIDTH-1 downto 0);
-- Data from 'A' block RAM
    VEnA                : out std_logic;    -- Enable 'A' FIFO
    VBDIn               : in  std_logic_vector(DATA_WIDTH-1 downto 0);
-- Data from 'B' block RAM
    VEnB                : out std_logic;    -- Enable 'B' FIFO
    NewLine             : out std_logic;    -- Initiate line read burst
    -- TFT interface
    VRed                : out std_logic_vector(5 downto 0); -- 6-bit
red
    VGreen              : out std_logic_vector(5 downto 0); -- 6-bit
green
    VBlue               : out std_logic_Vector(5 downto 0); -- 6-bit
blue
    VDE                 : out std_logic;    -- Data-enable
    VVSync              : out std_logic;    -- Vertical synch.
    VHSync              : out std_logic;    -- Horizontal synch.
    -- Debug signal...
    Debug               : out std_logic
    );
end VidCont;

architecture arch of VidCont is

  constant YES                :    std_logic := '1';
  constant NO                 :    std_logic := '0';
  constant HI                 :    std_logic := '1';
  constant LO                 :    std_logic := '0';
  constant ONE                :    std_logic := '1';
  constant ZERO               :    std_logic := '0';

  -- TFT timing parameters...
  constant tHP   : natural := 800;      -- Horizontal sync. period
  constant tWH   : natural := 96;       -- Horizontal sync. width
  constant tVP   : natural := 525;      -- Vertical sync. period
  constant tWV   : natural := 2;        -- Vertical sync. width
  constant tHV   : natural := 640;      -- Active horizontal period
  constant tHBP  : natural := tWH+40;   -- End of H back porch (start
of active area)
  constant tHFP  : natural := tHBP+tHV; -- Start of H front porch (end
of active area)
  constant tVV   : natural := 480;      -- Active vertical period
  constant tVBP  : natural := tWV+33;   -- End of V back porch (start
of active area)
  constant tVFP  : natural := tVBP+tVV; -- Start of V front porch (end
of active area)

    -- Horizontal & vertical counters...
    signal hCount_x, hCount_r               : natural range 0 to tHP+1;
 -- Horizontal column count
    signal vCount_x, vCount_r               : natural range 0 to tVP+1;
    -- Address counters...
    signal hAddr_x, hAddr_r                 :
std_logic_vector(VIAddr'range); -- Horizontal address
    -- Data enable flags...
    signal hDEm3_x, hDEm3_r                 : std_logic; -- Early (-3)
horizontal data enable
    signal hDEm2_r                          : std_logic; -- Early (-2)
latched horizontal data enable
    signal hDEm1_r                          : std_logic; -- Early (-1)
latched horizontal data enable
    signal hDE_r                            : std_logic; -- Horizontal
data enable
    signal vDEm2_x, vDEm2_r                 : std_logic; -- Early (-2)
vertical data enable
    signal vDEm1_r                          : std_logic; -- Early (-1)
vertical data enable
    signal vDE_r                            : std_logic; -- Vertical
data enable
    signal nlBurst_x, nlBurst_r             : std_logic; -- Newline
burst strobe
    signal IVEnA_x, IVEnA_r                 : std_logic; -- Block RAM
'A' read enable
    signal IVEnB_x, IVEnB_r                 : std_logic; -- Block RAM
'B' read enable
    -- Syncs...
    signal IVSync_x, IVSync_r               : std_logic; -- Vertical
sync
    signal IHSync_x, IHSync_r               : std_logic; -- Horizontal
sync
    signal AltLine_x, AltLine_r             : std_logic; -- Source
flipper
    -- RGB data...
    signal RGB_x, RGB_r                     :
std_logic_vector(VADIn'range); -- Demultiplexed and latched RGB data

 begin

  -- Attach signals to outputs...
  VIAddr <= hAddr_r; -- Horizontal address = block RAM address
  VDE <= hDE_r; -- Display enable...
  VRed(5 downto 1) <= RGB_r(15 downto 11);
  VRed(0) <= RGB_r(15);
  VGreen(5 downto 0) <= RGB_r(10 downto 5);
  VBlue(5 downto 1) <= RGB_r(4 downto 0);
  VBlue(0) <= RGB_r(4);
  VHSync <= IHSync_r;
  VVSync <= IVSync_r;
  VEnA <= IVEnA_r;
  VEnB <= IVEnB_r;
  NewLine <= nlBurst_r;
  Debug <= IHSync_r;

  -- Determine next state...
  RGB_x <= VBDIn when AltLine_r = '0' else VADIn; -- Video input mux
  IHSync_x <= LO when hCount_r = (tHP-1) else HI when hCount_r =
(tWH-1) else IHSync_r; -- Hor. sync generation
  IVSync_x <= LO when vCount_r = (tVP-1) else HI when vCount_r =
(tWV-1) else IVSync_r; -- Vert. sync generation
  hCount_x <= 0 when hCount_r = (tHP-1) else hCount_r + 1; -- Hor.
counter
  vCount_x <= 0 when vCount_r = (tVP-1) else vCount_r + 1 when hCount_r
= (tHP-1) else vCount_r; -- Vert. counter
  AltLine_x <= LO when vCount_r = (tVP-1) else not AltLine_r when
hCount_r = (tHP-1) else AltLine_r; -- Alternate line generation
  hDEm3_x <= HI when (hCount_r = (tHBP-1)) and (vDEm2_r = HI) else LO
when hCount_r = (tHFP-1) else hDEm3_r; -- Early horizontal DE
  vDEm2_x <= HI when vCount_r = (tVBP-1) else LO when vCount_r =
(tVFP-1) else vDEm2_r; -- Early vertical DE
  nlBurst_x <= HI when (vDEm1_r = '1') and (hCount_r = (tWH-1)) else
LO; -- BlockRAM fill strobe
  hAddr_x <= hAddr_r + 1 when hDEm2_r = '1' else (others => '0'); --
Keep advancing blockRAM address during active window, else reset
  IVEnA_x <= HI when AltLine_r = '1' else LO;
  IVEnB_x <= HI when AltLine_r = '0' else LO;

  update : process(rst, clk)
  begin

    if rst=YES then
       -- Asynchronous reset...
       hAddr_r      <= (others => '0');
       hDEm3_r      <= '0';
       hDEm2_r      <= '0';
       hDEm1_r      <= '0';
       hDE_r        <= '0';
       vDEm1_r      <= '0';
       vDEm2_r      <= '0';
       vDE_r        <= '0';
       nlBurst_r    <= '0';
       IVEnA_r      <= '0';
       IVEnB_r      <= '0';
       IVSync_r     <= '1';
       IHSync_r     <= '1';
       hCount_r     <= 0;
       vCount_r     <= 0;
       AltLine_r    <= '0';
       RGB_r        <= (others => '0');
--    elsif rising_edge(clk) then
    elsif clk'event and clk='1' then
       -- Ripple pipline display enable bits...
       hDEm3_r      <= hDEm3_x;
       hDEm2_r      <= hDEm3_r;
       hDEm1_r      <= hDEm2_r;
       hDE_r        <= hDEm1_r;
       vDEm2_r      <= vDEm2_x;
       vDEm1_r      <= vDEm2_r;
       vDE_r        <= vDEm1_r;
       nlBurst_r    <= nlBurst_x;
       IVEnA_r      <= IVEnA_x;
       IVEnB_r      <= IVEnB_x;
       -- Syncs...
       IHSync_r     <= IHSync_x;
       IVSync_r     <= IVSync_x;
       -- Video data/address...
       hAddr_r      <= hAddr_x; -- Update video RAM address
       RGB_r        <= RGB_x; -- Latch video data
       -- Counters...
       hCount_r     <= hCount_x;
       vCount_r     <= vCount_x;
       AltLine_r    <= AltLine_x;
    end if;

  end process update;

end arch;

Thanks for your patience.

Regards,
Peter

Reply by Phil Hays December 29, 20052005-12-29
peter halford wrote:


>I have tried dividing my incoming 25MHz clock by 2 and voilla! >everything works, albeit 50% slower... > >So now I guess I will have to divide the incoming clock by 2, multiply >it and re-divide it. > >Any ideas why this could be happening?
If you can run the clock at a slower speed and everything works, then you might have one of several problems. My first suspection would be: There is a logic path longer than the normal time between clocks. I assume you have a period constrant. Yes? Do you have all FFs in the IOBs? And/or checking setup time on all inputs? Do you have any asynchronous sets or resets? -- Phil Hays
Reply by pete...@alarmip.com December 28, 20052005-12-28
Dear All,

Many thanks for all your suggestions...

I have tried dividing my incoming 25MHz clock by 2 and voilla!
everything works, albeit 50% slower...

So now I guess I will have to divide the incoming clock by 2, multiply
it and re-divide it.

Any ideas why this could be happening?

Regards to all,
Peter

Reply by dp December 22, 20052005-12-22
> However, all I can think is that somehow the BlackFin is resetting the > array. Unfortunately, I didn't write any of the code nor UBOOT, so I > guess tomorrow (they're very small legs and too much CAIR) I will look > at all of the FPGA control signals...
Could there be some sort of COP (watchdog) circuit which resets things periodically (because it does not get some service it expects, that is)? Dimiter ------------------------------------------------------ Dimiter Popoff Transgalactic Instruments http://www.tgi-sci.com ------------------------------------------------------
Reply by bh December 22, 20052005-12-22
<peter.halford@alarmip.com> wrote in message
news:1135270697.315589.100480@g44g2000cwa.googlegroups.com...
> Dear Group, > > I am designing an LCD controller, straight VGA using a 6.5" TFT (60Hz > and a 25MHz dot clock) with a 32MBit SDRAM frame buffer (using two > Xilinx block RAMs as alternate line buffers).
I'm not so sure about LCDs, but one thing I found surprising with a VGA display was that the HSYNC and VSYNC were not sufficient to keep the display active... I needed to drive the blanking controls as well. (You might think that it just wouldn't blank, but it appears as if the SYNC signals are ignored if blanking is not active.) Probably not your problem, but if you're at a complete loss for something to look at, you might give it a try. Good luck. Let us know what it turns out to be.
Reply by Sylvain Munaut December 22, 20052005-12-22
peter.halford@alarmip.com wrote:
> Dear Group, > > I am designing an LCD controller, straight VGA using a 6.5" TFT (60Hz > and a 25MHz dot clock) with a 32MBit SDRAM frame buffer (using two > Xilinx block RAMs as alternate line buffers).
Is the SDRAM connected directly on the SP3 ? Could you provide a little more on how things are connected, dataflow, ...
> Come on now... Just how difficult can it be? Or so I thought. > > Well, everything works just fine for about 200ms (correct syncs etc...) > and then things go dead for 800ms -- no syncs, nothing. And then things > spring back to life for another 200ms ad nauseam...
What in your design can make the sync not happen ? For examples, what if pixel are not fetched in time ? would that stop sync ? For e.g., I know in the last VGA controller I made, nothing excepted reset or a unlocked DCM could make the sync go away ... But that's dependent on how you do things, you should know your design to know what condition can make it stop produce sync. Sylvain
Reply by Jim Granville December 22, 20052005-12-22
peter.halford@alarmip.com wrote:
> Dear Group, > > I am designing an LCD controller, straight VGA using a 6.5" TFT (60Hz > and a 25MHz dot clock) with a 32MBit SDRAM frame buffer (using two > Xilinx block RAMs as alternate line buffers). > > Xilinx ISE 7.1 development environment. > > I also designed the hardware: a BlackFin BF532 CPU/ROM/SDRAM with a > Xilinx Spartan-3 (XC3S400-4PQ208C) handling the general I/F > requirements and VGA display. It is a 4-layer PCB with a 25MHz master > clock. > > Until now, all my coding has been with VHDL and everything has > simulated correctly. > > Come on now... Just how difficult can it be? Or so I thought. > > Well, everything works just fine for about 200ms (correct syncs etc...) > and then things go dead for 800ms -- no syncs, nothing. And then things > spring back to life for another 200ms ad nauseam... > > The internal clocks are running fine (I have some spare signals on the > FPGA to which I can bind some debug signals). > > Since I am pretty much a newbie to VHDL, I figured I would design a > replacement VGA module using gate-level logic (counters, comparators > and so on) but it generates exactly the same results. > > The power supplies appear to be clean. The BlackFin continues to work > with a command-line UBOOT serial link. > > This project has taken 6-weeks longer than it needed to. I look an > idiot (which I probably am) and only the thought of how much pleasure > it would give my mother-in-law stops me from 'doing myself in'... > > Any kind or informative suggestions would be very much appreciated. > > Regards & seasonal greetings to all.
As you seem to have a behaving system some of the time, lock onto that, and expand on what you DO know - viz: try and be get better values for the 200ms and 800ms - things like how many frames, exactly; and is it a precise 1 second repeat. and how dead is dead.. Syncs gone, or changed, ? (etc) Are the syncs precisely correct ? - it's not something like the montior just not quite being able to hold-onto things ? That's many, many frames, so sounds unlike a gate level issue. Then look around at what it is in the system that changes at precisely those times.... -jg