Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

RPA FLEX 10K problem with data bus

Hi All

This may well be the wrong place to ask this question. If so, I apologize in advance... just ignore my ignorance. On the off chance I am in the right place...

The project I am currently working on requires an on-device RAM block that can be written to and read from over the onboard data bus. The simulations all run OK, but when I install the solution onto the real hardware the RAM block does not function at all as expecting. Here is my VHDL code (and I believe all the ports are pinned correctly). I have reduced it down to the bear essentials... the full version routes many of the memory registers to various other blocks around the circuit.... but I can't even get the noddy version to function correctly.

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

---------------------------------------------------------

ENTITY basic_ram IS

PORT (

clock : IN STD_LOGIC;

addr : IN INTEGER RANGE 0 TO 30; -- Data port address

data : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data port

awr_n : IN STD_LOGIC; -- Date port write

ard_n : IN STD_LOGIC); -- Data port read

END basic_ram;

---------------------------------------------------------

ARCHITECTURE behavior OF basic_ram IS

TYPE vector_array IS ARRAY (0 TO 30) OF STD_LOGIC_VECTOR(7 DOWNTO 0);

SIGNAL memory : vector_array;

BEGIN

PROCESS(clock)

BEGIN

IF RISING_EDGE(clock) THEN

IF (awr_n='1') THEN

memory(addr) <= data;

ELSIF (ard_n='1') THEN

data <= memory(addr);

ELSE

data <= "ZZZZZZZZ";

END IF;

END IF;

END PROCESS;

END behavior;

I have also written a simple application that uses the altera_write and altera_read commands to poke and peek the various addresses. At present what I can do is write to memory address 0x0000 and the content will be stored correctly. However, when I read back 0x0004, 0x0008 (all addresses divisible by 4 - maybe the first two bits of the address bus are not useable) that all contain the value I poked into 0x0000. All other addresses return 0xFF.

I used the following fiocon command to get the ttf on to the device:

fiocon -ttf simple_ram.ttf -ca 20.0 -cb 10.0 -pca 1 -pcf 0

The card is from the RPA Flex 10K series and the device is the EPK10K100ARC240-1.

This is really bugging me as I would think that this would be a very trivial implementation but I'm utterly stuck, and yet again feeling like a fool for not being able to figure it out.

Many thanks in advance for any guidance you might be able to offer.

Kurt

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    Not sure how you are wr/rd to your ram but I don't see you are tristating your bidirectional data pins correctly. You better have two internal buses one for reading your ram and one for writing to your ram then mux them to the bidirectiona pins. You need to avoid bus contention with external drive. When you want to receive input from external device your pins must be tristated.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I wonder how you connected your integer type address port. The results seem to show, that it's connected incorrectly. Also it's not clear, how you tested the entity. If you connected it to a soft processor I/O, a chip select is probably missing.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks Kaz - before I added the "ELSE data <= "ZZZZZZZZ";" line I did get data contention errors with Quartus on compilation. Now it compiles without such errors so I had assumed that I had tri-stated correctly. I will take another look...

    Kindest regards, Kurt
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi FvM

    The entity was simulated using Quartus and then I loaded onto the Altera device which is on an RPA board (http://www.rpaelectronics.com/pdf/pci_fio.pdf). I have seen chip select used in other implementations, but did no understand its role, so I will look into that again. The address port is pinned directly to the 8-bit address bus on the RPA card. I'm wondering if it might be a simple case of not running the clock fast enough. I think the RPA data/address bus runs at 33Mhz, whereas I have the RAM block running at 20MHz... I don't quite see how this leads to the strange results, but worth a try I suppose.

    Many thanks for your suggestions... I'm hoping that I've just overlooked some small requirement related to the RPA board... fingers crossed!

    Kurt
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Guys

    This is what eventually seems to have worked - it ain't pretty but it does the job:

    IBRARY ieee;

    USE ieee.std_logic_1164.all;

    USE ieee.std_logic_arith.all;

    ---------------------------------------------------------

    ENTITY basic_ram IS

    PORT (

    clock : IN STD_LOGIC;

    addr : IN STD_LOGIC_VECTOR(4 DOWNTO 0); -- Data port address

    data : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data port

    awr_n : IN STD_LOGIC; -- Date port write

    ard_n : IN STD_LOGIC; -- Data port read

    acs_n : IN STD_LOGIC); -- Data port chip select

    END basic_ram;

    ---------------------------------------------------------

    ARCHITECTURE behavior OF basic_ram IS

    TYPE vector_array IS ARRAY (0 TO 31) OF STD_LOGIC_VECTOR(7 DOWNTO 0);

    SIGNAL memory : vector_array;

    BEGIN

    PROCESS(awr_n)

    BEGIN

    IF RISING_EDGE(awr_n) THEN

    IF acs_n='0' AND ard_n='1' THEN

    memory(CONV_INTEGER(UNSIGNED(addr))) <= data;

    END IF;

    END IF;

    END PROCESS;

    data <= memory(0) WHEN addr = "00000" ELSE

    memory(1) WHEN addr = "00001" ELSE

    memory(2) WHEN addr = "00010" ELSE

    memory(3) WHEN addr = "00011" ELSE

    memory(4) WHEN addr = "00100" ELSE

    memory(5) WHEN addr = "00101" ELSE

    memory(6) WHEN addr = "00110" ELSE

    memory(7) WHEN addr = "00111" ELSE

    memory(8) WHEN addr = "01000" ELSE

    memory(9) WHEN addr = "01001" ELSE

    memory(10) WHEN addr = "01010" ELSE

    memory(11) WHEN addr = "01011" ELSE

    memory(12) WHEN addr = "01100" ELSE

    memory(13) WHEN addr = "01101" ELSE

    memory(14) WHEN addr = "01110" ELSE

    memory(15) WHEN addr = "01111" ELSE

    memory(16) WHEN addr = "10001" ELSE

    memory(17) WHEN addr = "10010" ELSE

    memory(18) WHEN addr = "10011" ELSE

    memory(19) WHEN addr = "10100" ELSE

    memory(20) WHEN addr = "10101" ELSE

    memory(21) WHEN addr = "10110" ELSE

    memory(22) WHEN addr = "10111" ELSE

    memory(23) WHEN addr = "11000" ELSE

    memory(24) WHEN addr = "11001" ELSE

    memory(25) WHEN addr = "11010" ELSE

    memory(26) WHEN addr = "11011" ELSE

    memory(27) WHEN addr = "11100" ELSE

    memory(28) WHEN addr = "11101" ELSE

    memory(29) WHEN addr = "11110" ELSE

    memory(30) WHEN addr = "11111" ELSE

    (others => 'Z');

    END behavior;

    I'm assuming that the WHEN/ELSE stuff could be collapsed into the following line:

    data <= memory(CONV_INTEGER(UNSIGNED(addr)));

    Thanks for the tips! Kurt