aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/synth/issue2023/async_dpram.vhd
blob: 6a35eced021eb9e9177dea0f97d613f317620926 (plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
--
-- Dual-Port Block RAM with Two Write Ports
-- Correct Modelization with a Shared Variable
--
-- Download: ftp://ftp.xilinx.com/pub/documentation/misc/xstug_examples.zip
-- File: HDL_Coding_Techniques/rams/rams_16b.vhd
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity async_dpram is
  generic
  (
    ADDR_BITS  : natural := 9;
    DATA_BITS  : natural := 16;
    OUTPUT_REG : boolean := true
  );
  port
  (
    clka  : in  std_logic;
    clkb  : in  std_logic;
    ena   : in  std_logic := '1';
    enb   : in  std_logic := '1';
    wea   : in  std_logic;
    web   : in  std_logic;
    addra : in  std_logic_vector(ADDR_BITS-1 downto 0);
    addrb : in  std_logic_vector(ADDR_BITS-1 downto 0);
    dia   : in  std_logic_vector(DATA_BITS-1 downto 0);
    dib   : in  std_logic_vector(DATA_BITS-1 downto 0) := (others => '0');
    doa   : out std_logic_vector(DATA_BITS-1 downto 0);
    dob   : out std_logic_vector(DATA_BITS-1 downto 0)
  );
end async_dpram;

architecture rtl of async_dpram is
  type ram_type is array (2**ADDR_BITS-1 downto 0) of std_logic_vector(DATA_BITS-1 downto 0);
  shared variable RAM : ram_type;

  signal ram_out_a : std_logic_vector(DATA_BITS-1 downto 0);
  signal ram_out_b : std_logic_vector(DATA_BITS-1 downto 0);
begin

  process (CLKA) begin
    if rising_edge(CLKA) then
      if ENA = '1' then
        ram_out_a <= RAM(conv_integer(ADDRA));
        if WEA = '1' then
          RAM(conv_integer(ADDRA)) := DIA;
        end if;
      end if;
    end if;
  end process;

  process (CLKB) begin
    if rising_edge(CLKB) then
      if ENB = '1' then
        ram_out_b <= RAM(conv_integer(ADDRB));
        if WEB = '1' then
          RAM(conv_integer(ADDRB)) := DIB;
        end if;
      end if;
    end if;
  end process;

  gen_output_reg : if OUTPUT_REG generate
    process (CLKA) begin
      if rising_edge(CLKA) then
        doa <= ram_out_a;
      end if;
    end process;

    process (CLKB) begin
      if rising_edge(CLKB) then
        dob <= ram_out_b;
      end if;
    end process;
  end generate;

  no_output_reg : if OUTPUT_REG = false generate
    doa <= ram_out_a;
    dob <= ram_out_b;
  end generate;

end;