Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Getting Around Bus Contention Issue with SRAM Model

Status
Not open for further replies.

BlackHelicopter

Full Member level 2
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
    SRAM.png
    152.1 KB · Views: 81
  • Memory Content.png
    Memory Content.png
    7.1 KB · Views: 79

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
    sram_write.png
    26.3 KB · Views: 77
  • sram_data.png
    sram_data.png
    31.9 KB · Views: 75
  • sram_waveform.png
    sram_waveform.png
    41.1 KB · Views: 74

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top