cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
dpAsymRam.vhd
Go to the documentation of this file.
1 -- *******************************************************************************
2 -- * Copyright 2016 -- 2021 IBM Corporation
3 -- *
4 -- * Licensed under the Apache License, Version 2.0 (the "License");
5 -- * you may not use this file except in compliance with the License.
6 -- * You may obtain a copy of the License at
7 -- *
8 -- * http://www.apache.org/licenses/LICENSE-2.0
9 -- *
10 -- * Unless required by applicable law or agreed to in writing, software
11 -- * distributed under the License is distributed on an "AS IS" BASIS,
12 -- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 -- * See the License for the specific language governing permissions and
14 -- * limitations under the License.
15 -- *******************************************************************************
16 
17 
18 -- ******************************************************************************
19 -- *
20 -- * cloudFPGA
21 -- *
22 -- *-----------------------------------------------------------------------------
23 -- *
24 -- * Title : Dual port asymmetric RAM.
25 -- * File : dpAsymRam.vhd
26 -- *
27 -- * Created : Mar. 2018
28 -- * Authors : Francois Abel <fab@zurich.ibm.com>
29 -- *
30 -- * Devices : xcku060-ffva1156-2-i
31 -- * Tools : Vivado v2016.4 (64-bit)
32 -- * Depends : None
33 -- *
34 -- * Description : True dual port RAM with different port widths and read first
35 -- * priority (cf ug901).
36 -- *
37 -- * Generics:
38 -- *
39 -- *
40 -- ******************************************************************************
41 
42 library IEEE;
43 use IEEE.std_logic_1164.all;
44 use IEEE.std_logic_unsigned.all;
45 use IEEE.std_logic_arith.all;
46 
47 
48 --*************************************************************************
49 --** ENTITY
50 --*************************************************************************
52  generic (
53  gDataWidth_A : integer := 8;
54  gSize_A : integer := 1024;
55  gAddrWidth_A : integer := 10;
56  gDataWidth_B : integer := 64;
57  gSize_B : integer := 128;
58  gAddrWidth_B : integer := 7
59  );
60  port (
61  -- Port A ------------------------------------
62  piClkA : in std_logic;
63  piEnA : in std_logic;
64  piWenA : in std_logic;
65  piAddrA : in std_logic_vector(gAddrWidth_A - 1 downto 0);
66  piDataA : in std_logic_vector(gDataWidth_A - 1 downto 0);
67  poDataA : out std_logic_vector(gDataWidth_A - 1 downto 0);
68  -- Port B ------------------------------------
69  piClkB : in std_logic;
70  piEnB : in std_logic;
71  piWenB : in std_logic;
72  piAddrB : in std_logic_vector(gAddrWidth_B - 1 downto 0);
73  piDataB : in std_logic_vector(gDataWidth_B - 1 downto 0);
74  poDataB : out std_logic_vector(gDataWidth_B - 1 downto 0)
75  );
77 
78 
79 --*************************************************************************
80 --** ARCHITECTURE
81 --*************************************************************************
82 architecture Behavioral of DualPortAsymmetricRam is
83 
84  -----------------------------------------------------------------
85  -- Function Definitions: fMAx, fMin and fLog2
86  -----------------------------------------------------------------
87  function fMax(L, R : integer) return integer is
88  begin
89  if L > R then
90  return L;
91  else
92  return R;
93  end if;
94  end function fMax;
95  --
96  function fMin(L, R : integer) return integer is
97  begin
98  if L < R then
99  return L;
100  else
101  return R;
102  end if;
103  end function fMin;
104  --
105  function fLog2(val : INTEGER) return natural is
106  variable res : natural;
107  begin
108  for i in 0 to 31 loop
109  if (val <= (2 ** i)) then
110  res := i;
111  exit;
112  end if;
113  end loop;
114  return res;
115  end function FLog2;
116  --
117  constant cMinWidth : integer := fMin(gDataWidth_A, gDataWidth_B);
118  constant cMaxWidth : integer := fMax(gDataWidth_A, gDataWidth_B);
119  constant cMaxSize : integer := fMax(gSize_A, gSize_B);
120  constant cRatio : integer := cMaxWidth / cMinWidth;
121 
122  -- An asymmetric RAM is modeled in a similar way as a symmetric RAM, with an
123  -- array of array object. Its aspect ratio corresponds to the port with the
124  -- lower data width (respectvely larger depth)
125  type tRAM is array (0 to cMaxSize - 1) of std_logic_vector(cMinWidth - 1 downto 0);
126 
127  -- You need to declare RAM as a shared variable when :
128  -- - the RAM has two write ports,
129  shared variable vRAM : tRAM := (others => (others => '0'));
130 
131  signal sRAM_DataA : std_logic_vector(gDataWidth_A - 1 downto 0) := (others => '0');
132  signal sRAM_DataB : std_logic_vector(gDataWidth_B - 1 downto 0) := (others => '0');
133  signal sRAM_DataAReg : std_logic_vector(gDataWidth_A - 1 downto 0) := (others => '0');
134  signal sRAM_DataBReg : std_logic_vector(gDataWidth_B - 1 downto 0) := (others => '0');
135 
136 begin -- architecture Behavioral
137 
138  -----------------------------------------------------------------
139  -- PROC: Port A
140  -----------------------------------------------------------------
141  pPortA : process (piClkA)
142  begin
143  if rising_edge(piClkA) then
144  if (piEnA = '1') then
145  sRAM_DataA <= vRAM(conv_integer(piAddrA));
146  if (piWenA = '1') then
147  vRAM(conv_integer(piAddrA)) := piDataA;
148  end if;
149  end if;
150  end if;
151  end process pPortA;
152 
153  ---------------------------------------------------------------
154  -- PROC: Port B
155  ---------------------------------------------------------------
156  pPortB : process (piClkB)
157  begin
158  if rising_edge(piClkB) then
159  for i in 0 to cRatio - 1 loop
160  if (piEnB = '1') then
161  sRAM_DataB((i + 1) * cMinWidth - 1 downto i * cMinWidth) <=
162  vRAM(conv_integer(piAddrB & conv_std_logic_vector(i, fLog2(cRatio))));
163  if (piWenB = '1') then
164  vRAM(conv_integer(piAddrB & conv_std_logic_vector(i, fLog2(cRatio)))) :=
165  piDataB((i + 1) * cMinWidth - 1 downto i * cMinWidth);
166  end if;
167  end if;
168  end loop;
169  end if;
170  end process pPortB;
171 
172  ----------------------------------------------------------
173  -- Output Ports Assignment
174  ----------------------------------------------------------
175  poDataA <= sRAM_DataA;
176  poDataB <= sRAM_DataB;
177 
178 end Behavioral;
in piWenBstd_logic
Definition: dpAsymRam.vhd:71
gDataWidth_Binteger :=64
Definition: dpAsymRam.vhd:56
gDataWidth_Ainteger :=8
Definition: dpAsymRam.vhd:53
in piWenAstd_logic
Definition: dpAsymRam.vhd:64
in piAddrAstd_logic_vector( gAddrWidth_A- 1 downto 0)
Definition: dpAsymRam.vhd:65
gSize_Binteger :=128
Definition: dpAsymRam.vhd:57
in piEnBstd_logic
Definition: dpAsymRam.vhd:70
out poDataAstd_logic_vector( gDataWidth_A- 1 downto 0)
Definition: dpAsymRam.vhd:67
in piClkAstd_logic
Definition: dpAsymRam.vhd:62
gSize_Ainteger :=1024
Definition: dpAsymRam.vhd:54
in piClkBstd_logic
Definition: dpAsymRam.vhd:69
in piEnAstd_logic
Definition: dpAsymRam.vhd:63
in piDataAstd_logic_vector( gDataWidth_A- 1 downto 0)
Definition: dpAsymRam.vhd:66
out poDataBstd_logic_vector( gDataWidth_B- 1 downto 0)
Definition: dpAsymRam.vhd:75
in piAddrBstd_logic_vector( gAddrWidth_B- 1 downto 0)
Definition: dpAsymRam.vhd:72
in piDataBstd_logic_vector( gDataWidth_B- 1 downto 0)
Definition: dpAsymRam.vhd:73
gAddrWidth_Ainteger :=10
Definition: dpAsymRam.vhd:55
gAddrWidth_Binteger :=7
Definition: dpAsymRam.vhd:59