5
\$\begingroup\$

How do I access the PCM flash ram on a Nexys3 FPGA board?

I've got a simple T80 (Z80) CPU core project working with a Core Generator ROM module, but not having any luck with the flash ram. The Nexys 3 Reference Manual suggests using the Reference Designs from the Digilent website, but there isn't actually one for the Nexys 3 board - I've asked Digilent and they say there's only one for the Nexys 2, which I've been through. I've also read most of the data sheet for the flash chip - Micron NP8P128A13T1760E but can't get it working.

So I've put together the most minimal project I can think of: a simple state machine that attempts to read the first word from the flash ram and display the lower byte on the 8 leds on the board. See the VHDL below. I'm loading up the flash ram using the Adept memory utility, but all I ever seem to get its 0xFF displayed.

(Update, I've just found that if I press the button I've got wired to reset it displays 0x06, but that's not what's been put into flash)

My understanding of how it should work is:

  1. Set FlashRP = 1, FlashCS = 1, MemOE = 1, MemWR = 1,
  2. Set address to MemAdr (I've hard coded to 0)
  3. Enable flash - FlashCS = 0
  4. Enable out - FlashOE = 0
  5. Read from MemDB

My test project runs these steps on a 3.375Mhz clock (since that's what the T80 will run at).

One thing I'm not sure about is the Nexys3 Reference Manual refers to some other signals that are common to the RAM and the Flash - namely CLK, ADV and WAIT - but I've not been able to correlate these to the data sheet for the flash chip.

What am I missing?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity Top is
    Port ( clock : in  STD_LOGIC;
           reset : in  STD_LOGIC;
              led : out STD_LOGIC_VECTOR (7 downto 0);
              MemOE : out STD_LOGIC;
              MemWR : out STD_LOGIC;
              FlashCS : out STD_LOGIC;
              FlashRP : out STD_LOGIC;
              MemAdr : out STD_LOGIC_VECTOR(26 downto 1);
              MemDB : inout STD_LOGIC_VECTOR(15 downto 0)
              );
end Top;

architecture Behavioral of Top is
    signal slow_clock : STD_LOGIC;
    signal led_reg : STD_LOGIC_VECTOR(7 downto 0);
    signal state : unsigned(3 downto 0) := "0000";
    signal state_next : unsigned(3 downto 0);
begin

    led <= led_reg;

    -- Clock Generation
    clock_core : entity work.ClockCore
        PORT MAP 
        (
            clock => clock,
            clock_3375 => slow_clock,       -- 3.375 Mhz clock
            RESET  => reset
        );

    process (slow_clock, reset)
    begin
        if (reset='1') then
            state <= "0000";
            led_reg <= "00000000";
        elsif (slow_clock'event and slow_clock='1') then
            state <= state_next;
            if (state = "1110") then
                led_reg <= MemDB(7 downto 0);
            end if;
        end if;
    end process;

    MemAdr <= "00000000000000000000000000";
    MemDB <= "ZZZZZZZZZZZZZZZZ";
    MemWR <= '1';
    FlashRP <= NOT reset;

    process (state)
    begin
        case state is
            when "0000" =>
                -- initialize
                FlashCS <= '1';
                MemOE <= '1';
            when "0001" =>
                -- enable flash
                FlashCS <= '0';
                MemOE <= '1';
            when "0010" =>
                -- enable flash output
                FlashCS <= '0';
                MemOE <= '0';   
            when others =>
                -- hold steady
                FlashCS <= '0';
                MemOE <= '0';   
        end case;
    end process;

    state_next <= "1111" when (state="1111") else state + 1;

end Behavioral;

Here's the reference material I've been using:

\$\endgroup\$
7
  • \$\begingroup\$ what value are you expecting instead of 06? \$\endgroup\$ Commented Jul 2, 2012 at 14:32
  • \$\begingroup\$ Well, whatever's stored in the first byte of the flash which is my case is 0x20, but could be anything. Certainly I'm not expecting 0x06. \$\endgroup\$ Commented Jul 2, 2012 at 14:38
  • \$\begingroup\$ Clutching at straws, maybe the bits/nibbles were swapped :) More constructively, is the timing within spec (as measured by an oscilloscope)? Have you resynchronised the data to your internal clock - can you show the code where you capture the data? Have you checked the pinout file to be sure the pins are the right ones? \$\endgroup\$ Commented Jul 2, 2012 at 15:07
  • \$\begingroup\$ I'll check the bit swap thing but doubt it. Don't have oscilloscope so that's hard to check but is the reason for the extra delay cycles. The data isn't captured - its just written there by the board's pc utility ( adept) and it reads back correctly using the same util. I've even written something to ram and the two flash chips just to make sure I'm not reading from the wrong chip. The printouts I'm using are from the master UFC file as supplied by digilent but I'll double check them. \$\endgroup\$ Commented Jul 2, 2012 at 22:21
  • \$\begingroup\$ By "printouts" I actually mean "pinouts". :) \$\endgroup\$ Commented Jul 3, 2012 at 0:38

3 Answers 3

3
\$\begingroup\$

I finally figured this out... and it was nothing wrong with the VHDL which works perfectly. The problem was exactly as suggested by Martin Thompson's comment, a pin-out problem.

Although I checked the UCF file pin connections many times, I was only checking the correct pin labels - not that they were all present and I had missed the MemOE pin, which of course is essential for this to work at all.

Some notes:

  1. The Xilinx tool chain doesn't provide any warning messages for an unconnected output pin as in this case.
  2. Reading from the MemDB was appearing to provide consistent but incorrect data depending on what mode I set the flash chip to. In read array mode, it always returned 0xFF in the low byte. In read identifier, 0x86. Totally meaningless data but the consistency fooled me into thinking I had the correct pinouts.

Lesson learned.

\$\endgroup\$
0
\$\begingroup\$

check this Nexys 3 project It have some good things for starting a project and writing to cellular RAM of the Nexys 3. It doesn't contain pcm code though.

\$\endgroup\$
0
+100
\$\begingroup\$

Some things to check:

  • are the bits/bytes/nibbles swapped somewhere?
  • is the timing within spec (as measured by an oscilloscope)?
  • have you resynchronised the data to your internal clock - can you show the code where you capture the data?
  • have you checked the pinout file to be sure the pins are the right ones?
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.