AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
fifo66X512.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 09:04:40 06/08/2014
6 -- Design Name:
7 -- Module Name: fifo66X512 - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 library IEEE;
21 use IEEE.STD_LOGIC_1164.ALL;
22 use IEEE.STD_LOGIC_ARITH.ALL;
23 use IEEE.STD_LOGIC_UNSIGNED.ALL;
24 use IEEE.std_logic_misc.all;
25 
26 -- Uncomment the following library declaration if using
27 -- arithmetic functions with Signed or Unsigned values
28 --use IEEE.NUMERIC_STD.ALL;
29 
30 -- Uncomment the following library declaration if instantiating
31 -- any Xilinx primitives in this code.
32 library UNISIM;
33 use UNISIM.VComponents.all;
34 Library UNIMACRO;
35 use UNIMACRO.vcomponents.all;
36 
37 entity fifo66X512 is
38  generic (ALMOST_FULL_OFFSET : STD_LOGIC_VECTOR (15 downto 0) := x"0004";
39  ALMOST_EMPTY_OFFSET : STD_LOGIC_VECTOR (15 downto 0) := x"0004");
40  Port ( wclk : in STD_LOGIC;
41  rclk : in STD_LOGIC;
42  reset : in STD_LOGIC;
43  Di : in STD_LOGIC_VECTOR (65 downto 0);
44  we : in STD_LOGIC;
45  re : in STD_LOGIC;
46  Do : out STD_LOGIC_VECTOR (65 downto 0);
47  almostfull : out STD_LOGIC;
48  almostempty : out STD_LOGIC;
49  full : out STD_LOGIC;
50  empty : out STD_LOGIC);
51 end fifo66X512;
52 
53 architecture Behavioral of fifo66X512 is
54 constant N : integer := 9;
55 signal ce_ra: std_logic := '0';
56 signal RDEN: std_logic := '0';
57 signal REGCE: std_logic := '0';
58 signal RAM_dav: std_logic := '0';
59 signal RAM_Do_vld: std_logic := '0';
60 signal Do_vld: std_logic := '0';
61 signal wa_g: std_logic_vector(3 downto 0) := (others => '0');
62 signal wa_g_sync: std_logic_vector(3 downto 0) := (others => '0');
63 signal wa_g_sync1: std_logic_vector(3 downto 0) := (others => '0');
64 signal wa_g_sync2: std_logic_vector(3 downto 0) := (others => '0');
65 signal wc_w: std_logic_vector(N downto 0) := (others => '0');
66 signal wc_r: std_logic_vector(N downto 0) := (others => '0');
67 signal wa: std_logic_vector(N downto 0) := (others => '0');
68 signal wap: std_logic_vector(N downto 0) := (others => '0');
69 signal ra_g: std_logic_vector(3 downto 0) := (others => '0');
70 signal ra_g_sync: std_logic_vector(3 downto 0) := (others => '0');
71 signal ra_g_sync1: std_logic_vector(3 downto 0) := (others => '0');
72 signal ra_g_sync2: std_logic_vector(3 downto 0) := (others => '0');
73 signal ra: std_logic_vector(N downto 0) := (others => '0');
74 signal rap: std_logic_vector(N downto 0) := (others => '0');
75 attribute ASYNC_REG : string;
76 attribute ASYNC_REG of wa_g_sync : signal is "TRUE";
77 attribute ASYNC_REG of wa_g_sync1 : signal is "TRUE";
78 attribute ASYNC_REG of wa_g_sync2 : signal is "TRUE";
79 attribute ASYNC_REG of ra_g_sync : signal is "TRUE";
80 attribute ASYNC_REG of ra_g_sync1 : signal is "TRUE";
81 attribute ASYNC_REG of ra_g_sync2 : signal is "TRUE";
82 attribute shreg_extract : string;
83 attribute shreg_extract of wa_g_sync : signal is "TRUE";
84 attribute shreg_extract of wa_g_sync1 : signal is "TRUE";
85 attribute shreg_extract of wa_g_sync2 : signal is "TRUE";
86 attribute shreg_extract of ra_g_sync : signal is "TRUE";
87 attribute shreg_extract of ra_g_sync1 : signal is "TRUE";
88 attribute shreg_extract of ra_g_sync2 : signal is "TRUE";
89 
90 begin
91 empty <= not Do_vld;
92 process(wclk,reset)
93 variable full_th: std_logic_vector(N downto 0);
94 begin
95  full_th := '0' & not ALMOST_FULL_OFFSET(N-1 downto 0);
96  if(reset = '1')then
97  wa_g <= (others => '0');
98  wa <= (others => '0');
99  ra_g_sync <= (others => '0');
100  ra_g_sync1 <= (others => '0');
101  ra_g_sync2 <= (others => '0');
102  rap <= (others => '0');
103  wc_w <= (others => '0');
104  almostfull <= '0';
105  full <= '0';
106  elsif(wclk'event and wclk = '1')then
107  if(we = '1')then
108  case wa_g is
109  when x"0" => wa_g <= x"1";
110  when x"1" => wa_g <= x"3";
111  when x"3" => wa_g <= x"2";
112  when x"2" => wa_g <= x"6";
113  when x"6" => wa_g <= x"7";
114  when x"7" => wa_g <= x"5";
115  when x"5" => wa_g <= x"4";
116  when x"4" => wa_g <= x"c";
117  when x"c" => wa_g <= x"d";
118  when x"d" => wa_g <= x"f";
119  when x"f" => wa_g <= x"e";
120  when x"e" => wa_g <= x"a";
121  when x"a" => wa_g <= x"b";
122  when x"b" => wa_g <= x"9";
123  when x"9" => wa_g <= x"8";
124  when others => wa_g <= x"0";
125  end case;
126  wa <= wa + 1;
127  end if;
128  ra_g_sync <= ra_g;
129  ra_g_sync1 <= ra_g_sync;
130  ra_g_sync2 <= ra_g_sync1;
131  rap(3) <= ra_g_sync2(3);
132  rap(2) <= ra_g_sync2(3) xor ra_g_sync2(2);
133  rap(1) <= ra_g_sync2(3) xor ra_g_sync2(2) xor ra_g_sync2(1);
134  rap(0) <= ra_g_sync2(3) xor ra_g_sync2(2) xor ra_g_sync2(1) xor ra_g_sync2(0);
135  if(rap(3) = '1' and ra_g_sync2(3) = '0')then
136  rap(N downto 4) <= rap(N downto 4) + 1;
137  end if;
138  wc_w <= wa - rap + we;
139  if(wc_w >= full_th)then
140  almostfull <= '1';
141  else
142  almostfull <= '0';
143  end if;
144  if(wc_w(N) = '1' or (and_reduce(wc_w(N-1 downto 0)) = '1' and we = '1'))then
145  full <= '1';
146  else
147  full <= '0';
148  end if;
149  end if;
150 end process;
151 process(rclk,reset)
152 begin
153  if(reset = '1')then
154  ra_g <= (others => '0');
155  ra <= (others => '0');
156  wa_g_sync <= (others => '0');
157  wa_g_sync1 <= (others => '0');
158  wa_g_sync2 <= (others => '0');
159  wap <= (others => '0');
160  wc_r <= (others => '0');
161  RAM_dav <= '0';
162  RAM_Do_vld <= '0';
163  Do_vld <= '0';
164  almostempty <= '1';
165  elsif(rclk'event and rclk = '1')then
166  if(ce_ra = '1')then
167  case ra_g is
168  when x"0" => ra_g <= x"1";
169  when x"1" => ra_g <= x"3";
170  when x"3" => ra_g <= x"2";
171  when x"2" => ra_g <= x"6";
172  when x"6" => ra_g <= x"7";
173  when x"7" => ra_g <= x"5";
174  when x"5" => ra_g <= x"4";
175  when x"4" => ra_g <= x"c";
176  when x"c" => ra_g <= x"d";
177  when x"d" => ra_g <= x"f";
178  when x"f" => ra_g <= x"e";
179  when x"e" => ra_g <= x"a";
180  when x"a" => ra_g <= x"b";
181  when x"b" => ra_g <= x"9";
182  when x"9" => ra_g <= x"8";
183  when others => ra_g <= x"0";
184  end case;
185  ra <= ra + 1;
186  end if;
187  wa_g_sync <= wa_g;
188  wa_g_sync1 <= wa_g_sync;
189  wa_g_sync2 <= wa_g_sync1;
190  wap(3) <= wa_g_sync2(3);
191  wap(2) <= wa_g_sync2(3) xor wa_g_sync2(2);
192  wap(1) <= wa_g_sync2(3) xor wa_g_sync2(2) xor wa_g_sync2(1);
193  wap(0) <= wa_g_sync2(3) xor wa_g_sync2(2) xor wa_g_sync2(1) xor wa_g_sync2(0);
194  if(wap(3) = '1' and wa_g_sync2(3) = '0')then
195  wap(N downto 4) <= wap(N downto 4) + 1;
196  end if;
197  if(ce_ra = '1')then
198  wc_r <= wap - ra - 1;
199  else
200  wc_r <= wap - ra;
201  end if;
202  if(or_reduce(wc_r(N downto 1)) = '1' or (wc_r(0) = '1' and (RAM_dav = '0' or (re = '0' and RAM_Do_vld = '1' and Do_vld = '1'))))then
203  RAM_dav <= '1';
204  else
205  RAM_dav <= '0';
206  end if;
207  if(RAM_dav = '1')then
208  RAM_Do_vld <= '1';
209  elsif(re = '1' or Do_vld = '0')then
210  RAM_Do_vld <= '0';
211  end if;
212  if(RAM_Do_vld = '1')then
213  Do_vld <= '1';
214  elsif(re = '1')then
215  Do_vld <= '0';
216  end if;
217  if(wc_r < ALMOST_EMPTY_OFFSET(N downto 0))then
218  almostempty <= '1';
219  else
220  almostempty <= '0';
221  end if;
222  end if;
223 end process;
224 i_BRAM_SDP_MACRO : BRAM_SDP_MACRO
225  generic map (
226  BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
227  DEVICE => "VIRTEX6", -- Target device: "VIRTEX5", "VIRTEX6", "SPARTAN6"
228  WRITE_WIDTH => 66, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb")
229  READ_WIDTH => 66, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb")
230  DO_REG => 1, -- Optional output register (0 or 1)
231  INIT_FILE => "NONE",
232  SIM_COLLISION_CHECK => "ALL", -- Collision check enable "ALL", "WARNING_ONLY",
233  -- "GENERATE_X_ONLY" or "NONE"
234  SRVAL => X"000000000000000000", -- Set/Reset value for port output
235  INIT => X"000000000000000000", -- Initial values on output port
236  WRITE_MODE => "WRITE_FIRST") -- Specify "READ_FIRST" for same clock or synchronous clocks
237  port map (
238  DO => Do, -- Output read data port, width defined by READ_WIDTH parameter
239  DI => Di, -- Input write data port, width defined by WRITE_WIDTH parameter
240  RDADDR => ra(N-1 downto 0), -- Input read address, width defined by read port depth
241  RDCLK => rclk, -- 1-bit input read clock
242  RDEN => RDEN, -- 1-bit input read port enable
243  REGCE => REGCE, -- 1-bit input read output register enable
244  RST => '0', -- 1-bit input reset
245  WE => x"ff", -- Input write enable, width defined by write port depth
246  WRADDR => wa(N-1 downto 0), -- Input write address, width defined by write port depth
247  WRCLK => wclk, -- 1-bit input write clock
248  WREN => we -- 1-bit input write port enable
249  );
250 REGCE <= '1' when re = '1' or Do_vld = '0' else '0';
251 RDEN <= '1' when re = '1' or Do_vld = '0' or RAM_Do_vld = '0' else '0';
252 ce_ra <= '1' when RAM_dav = '1' and (re = '1' or Do_vld = '0' or RAM_Do_vld = '0') else '0';
253 end Behavioral;
254