Trying to get blockram to work reliably


Guest John W

Recommended Posts

Guest John W

Hi all,

I am trying to get a block memory to work properly using the AVR8.  I have something that appears to be writing correctly, but when reading back I get invalid values.  More specifically, it looks like I'm getting the value from the previous read attempt.

Here is my modifications to the template code:



library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity papilio_core_template is
    Port (
            -- begin Signals required by AVR8 for this core, do not modify.
            nReset        : in  STD_LOGIC;
            clk            : in  STD_LOGIC;
            adr            : in  STD_LOGIC_VECTOR (15 downto 0);
            dbus_in        : in  STD_LOGIC_VECTOR (7 downto 0);
            dbus_out    : out STD_LOGIC_VECTOR (7 downto 0);
            iore            : in  STD_LOGIC;
            iowe            : in  STD_LOGIC;
            out_en        : out STD_LOGIC
            -- end Signals required by AVR8 for this core, do not modify.
    );
end papilio_core_template;

architecture Behavioral of papilio_core_template is

    COMPONENT test_ram
      PORT (
        clka : IN STD_LOGIC;
        ena : IN STD_LOGIC;
        wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
        addra : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
        dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
        douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
      );
    END COMPONENT;

    signal text_en : std_logic;
    signal text_we : std_logic_vector(0 downto 0);

begin

    -- text memory
    ram: test_ram port map (
        clka  => clk,
        ena  => text_en,
        dina  => dbus_in,
        addra => adr(11 downto 0),
        wea  => text_we,
        douta => dbus_out
        );

    text_en <= '1' when adr >= x"1000" and adr <= x"1FFF" else '0'; -- 0x1020 - 0x201F
    text_we <= (others => iowe);
    out_en <= '1' when (text_en = '1' and iore = '1') else '0';

end Behavioral;

Here is the code running on the soft processor:


volatile uint8_t* m_TextBuffer = (volatile uint8_t*)0x1020;

void setup()
{
  Serial.begin(9600);
  Serial.println("Console Test");
  for (int i = 0; i < 1000; i++)
    m_TextBuffer[i] = (uint8_t)(i + 10);
  Serial.print("Value in frame buffer location 0: ");
  Serial.println((int)m_TextBuffer[0]);
  Serial.print("Value in frame buffer location 0: ");
  Serial.println((int)m_TextBuffer[0]);
}

int pass = 0;
int errors = 0;
void loop()
{
  pass++;
  for (int i = 0; i < 1000; i++)
  {
    int value = m_TextBuffer[i];
    int expected = (uint8_t)(i + 10);
    if (value != expected)
    {
      Serial.print("Invalid value: ");
      Serial.print(value);
      Serial.print(", expected: ");
      Serial.print(expected);
      Serial.print(" at location ");
      Serial.print(i);
      Serial.print(" (pass ");
      Serial.print(pass);
      Serial.println(")");
      if (errors++ >= 10)
      {
        for (;;
      }
    }
  }
}

This is what I get when running it:

Console Test
Value in frame buffer location 0: 241
Value in frame buffer location 0: 10
Invalid value: 10, expected: 11 at location 1 (pass 1)
Invalid value: 11, expected: 12 at location 2 (pass 1)
Invalid value: 12, expected: 13 at location 3 (pass 1)
Invalid value: 13, expected: 14 at location 4 (pass 1)
Invalid value: 14, expected: 15 at location 5 (pass 1)
Invalid value: 15, expected: 16 at location 6 (pass 1)
Invalid value: 16, expected: 17 at location 7 (pass 1)
Invalid value: 17, expected: 18 at location 8 (pass 1)
Invalid value: 18, expected: 19 at location 9 (pass 1)
Invalid value: 19, expected: 20 at location 10 (pass 1)
Invalid value: 20, expected: 21 at location 11 (pass 1)

Has anybody seen anything like this?  Any ideas on what I could be doing incorrectly?

Thanks,

John

Link to comment
Share on other sites

Guest John W

OK, it looks like I just figured it out.  The clk to the BRAM needs to be negated.  I changed the template to the following and now it appears to work.


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity papilio_core_template is
    Port (
            -- begin Signals required by AVR8 for this core, do not modify.
            nReset        : in  STD_LOGIC;
            clk            : in  STD_LOGIC;
            adr            : in  STD_LOGIC_VECTOR (15 downto 0);
            dbus_in        : in  STD_LOGIC_VECTOR (7 downto 0);
            dbus_out    : out STD_LOGIC_VECTOR (7 downto 0);
            iore            : in  STD_LOGIC;
            iowe            : in  STD_LOGIC;
            out_en        : out STD_LOGIC
            -- end Signals required by AVR8 for this core, do not modify.
    );
end papilio_core_template;

architecture Behavioral of papilio_core_template is

    COMPONENT test_ram
      PORT (
        clka : IN STD_LOGIC;
        ena : IN STD_LOGIC;
        wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
        addra : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
        dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
        douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
      );
    END COMPONENT;

    signal clkn : std_logic;
    signal text_en : std_logic;
    signal text_we : std_logic_vector(0 downto 0);

begin

    -- text memory
    ram: test_ram port map (
        clka  => clkn,
        ena  => text_en,
        dina  => dbus_in,
        addra => adr(11 downto 0),
        wea  => text_we,
        douta => dbus_out
        );

    clkn <= not clk;
    text_en <= '1' when adr >= x"1000" and adr <= x"1FFF" else '0'; -- 0x1020 - 0x201F
    text_we(0) <= iowe;
    out_en <= '1' when (text_en = '1' and iore = '1') else '0';

end Behavioral;

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.