Getting Around Bus Contention Issue with SRAM Model

Status
Not open for further replies.

BlackHelicopter

Full Member level 2
Joined
Jun 3, 2010
Messages
137
Helped
13
Reputation
26
Reaction score
16
Trophy points
1,298
Visit site
Activity points
2,207
Not sure what's going on here but I believe I'm encountering a bus contention issue while trying to simulate SRAM. When I look at the memory content section in ModelSim it shows address 1 = "XX00", when it should be "A500". Here's the VHDL code I'm using to model SRAM. I've also posted a waveform from the simulation as well.

The only conclusion I can draw is that I think it's because OE_F goes high at the same time WE_F goes low. Does this seem like a valid reason why memory would show up as "XX00"? To me it seems like everything should be working fine?


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
entity tb_sram_model is
    port (
        sram_addr : in std_logic_vector(18 downto 0);
        sram_oe   : in std_logic;
        sram_we   : in std_logic;
        sram_data : inout std_logic_vector(15 downto 0);
        sram_ce   : in std_logic
    );
end tb_sram_model;
 
architecture arch of tb_sram_model is
  type memory is array(0 to 2**sram_addr'length) of std_logic_vector(sram_data'range);
  signal sram : memory := (others => (others => '1'));
  signal address : integer range 0 to 2**sram_addr'length;
 
begin
 
    address <= to_integer(unsigned(sram_addr));
    sram_data <= sram(address) when sram_oe = '0' else (others => 'Z');
    
    -- write to sram on rising egde of WE
    process (sram_we)
    begin
       if rising_edge(sram_we) then
          sram(address) <= sram_data;
        end if;
    end process;
    
end arch;

 

Attachments

  • SRAM.png
    152.1 KB · Views: 84
  • Memory Content.png
    7.1 KB · Views: 82

Now I'm completely stumped. I changed around the model to try to add upper/lower enable signals, it appears I've made things worse. Now in my simulation, during an SRAM write, my data which should be "00A5" is "00XX" (actually "000000001X1XX1X1), I haven no idea why. I've added a screenshot of the waveform and the code during debug which shows what I'm referring to.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity tb_sram_model is
    port (
        sram_addr : in    std_logic_vector(17 downto 0);
        sram_oe   : in    std_logic;
        sram_ue   : in    std_logic;
        sram_le   : in    std_logic;
        sram_we   : in    std_logic;
        sram_data : inout std_logic_vector(15 downto 0);
        sram_ce   : in    std_logic
        );
end tb_sram_model;
 
architecture arch of tb_sram_model is
    type memory is array(0 to 524287) of std_logic_vector(7 downto 0);
    signal sram          : memory := (others => (others => '1'));
    signal address       : integer range 0 to 524287;
    signal sram_addr_lsb : std_logic;
    signal sram_uef_lef  : std_logic_vector(1 downto 0);
--      constant Tdoe  : time :=  4 ns;
--      constant THZOE : time :=  4 ns;
 
begin
 
    sram_uef_lef <= sram_ue & sram_le;
    
    sram_addr_lsb <= '1' when (sram_uef_lef = "01") else '0';
 
    address <= to_integer(unsigned(sram_addr & sram_addr_lsb));
 
    -- read sram
    process (sram_oe, sram_uef_lef) is
    begin  -- process
        if sram_oe = '1' then
            sram_data <= (others => 'Z');
        else
            case sram_uef_lef is
                when "00" =>
                    sram_data <= "ZZZZZZZZ" & sram(address);
                when "01" =>
                    sram_data <= sram(address) & "ZZZZZZZZ";
                when "10" =>
                    sram_data <= "ZZZZZZZZ" & sram(address);
                when "11" =>
                    sram_data <= "XXXXXXXXXXXXXXXX";
                when others => null;
            end case;
        end if;
    end process;
    
    -- write to sram on rising egde of WE
    process (sram_we, sram_uef_lef)
    begin
        if rising_edge(sram_we) then
            if sram_uef_lef = "01" then
                sram(address) <= sram_data(15 downto 8);
            else
                sram(address) <= sram_data(7 downto 0);
            end if;
        end if;
    end process;
    
end arch;



- - - Updated - - -

Well it's getting better, I realized I screwed up the sensitivity lists. It still doesn't appear to be working 100% correct but it's better. Now I'm back to the same problem as in my first post though even with this model.:shock:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
sram_uef_lef <= sram_ue & sram_le;
    
    sram_addr_lsb <= '1' when (sram_uef_lef = "01") else '0';
 
    address <= to_integer(unsigned(sram_addr & sram_addr_lsb));
 
    -- read sram
    process (sram_oe, sram_uef_lef, sram) is
    begin  -- process
        if sram_oe = '1' then
            sram_data <= (others => 'Z');
        else
            case sram_uef_lef is
                when "00" =>
                    sram_data <= "ZZZZZZZZ" & sram(address);
                when "01" =>
                    sram_data <= sram(address) & "ZZZZZZZZ";
                when "10" =>
                    sram_data <= "ZZZZZZZZ" & sram(address);
                when "11" =>
                    sram_data <= "XXXXXXXXXXXXXXXX";
                when others => null;
            end case;
        end if;
    end process;
    
    -- write to sram on rising egde of WE
    process (sram_we)
    begin
        if rising_edge(sram_we) then
            if sram_uef_lef = "01" then
                sram(address) <= sram_data(15 downto 8);
            else
                sram(address) <= sram_data(7 downto 0);
            end if;
        end if;
    end process;



- - - Updated - - -

UPDATE:

Finally figured out my problem, it wasn't in my model after all. I was pulling invalid data from a fifo due to a ready signal occurring at the wrong time. Guess this is what happens when you code like a reckless madman...
 

Attachments

  • sram_write.png
    26.3 KB · Views: 80
  • sram_data.png
    31.9 KB · Views: 77
  • sram_waveform.png
    41.1 KB · Views: 76

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…