OpenCores
URL https://opencores.org/ocsvn/copyblaze/copyblaze/trunk

Subversion Repositories copyblaze

[/] [copyblaze/] [trunk/] [copyblaze/] [rtl/] [vhdl/] [ip/] [wb_3p_spram_wrapper/] [wb_Np_ram.vhd] - Blame information for rev 65

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 65 ameziti
----------------------------------------------------------------------------------
2
-- Company:       VISENGI S.L. (www.visengi.com)
3
-- Engineer:      Victor Lopez Lorenzo (victor.lopez (at) visengi (dot) com)
4
-- 
5
-- Create Date:    23:44:13 22/August/2008 
6
-- Project Name:   Triple Port WISHBONE SPRAM Wrapper
7
-- Tool versions:  Xilinx ISE 9.2i
8
-- Description: 
9
--
10
-- Description: This is a wrapper for an inferred single port RAM, that converts it
11
--              into a Three-port RAM with one WISHBONE slave interface for each port. 
12
--
13
--
14
-- LICENSE TERMS: GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
15
--     That is you may use it in ANY project (commercial or not) without paying a cent.
16
--     You are only required to include in the copyrights/about section of accompanying 
17
--     software and manuals of use that your system contains a "3P WB SPRAM Wrapper
18
--     (C) VISENGI S.L. under LGPL license"
19
--     This holds also in the case where you modify the core, as the resulting core
20
--     would be a derived work.
21
--     Also, we would like to know if you use this core in a project of yours, just an email will do.
22
--
23
--    Please take good note of the disclaimer section of the LPGL license, as we don't
24
--    take any responsability for anything that this core does.
25
----------------------------------------------------------------------------------
26
 
27
library IEEE;
28
use IEEE.STD_LOGIC_1164.ALL;
29
use IEEE.STD_LOGIC_ARITH.ALL;
30
use IEEE.STD_LOGIC_UNSIGNED.ALL;
31
 
32
entity wb_Np_ram is
33
      generic (data_width : integer := 32;
34
                                        addr_width : integer := 8);
35
      port (
36
                        wb_clk_i: in std_logic;
37
         wb_rst_i: in std_logic;
38
 
39
         wb1_cyc_i : in std_logic;
40
         wb1_stb_i : in std_logic;
41
         wb1_we_i : in std_logic;
42
         wb1_adr_i : in std_logic_vector(addr_width-1 downto 0);
43
         wb1_dat_i : in std_logic_vector(data_width-1 downto 0);
44
                        wb1_dat_o : out std_logic_vector(data_width-1 downto 0);
45
         wb1_ack_o : out std_logic;
46
 
47
         wb2_cyc_i : in std_logic;
48
         wb2_stb_i : in std_logic;
49
         wb2_we_i : in std_logic;
50
         wb2_adr_i : in std_logic_vector(addr_width-1 downto 0);
51
         wb2_dat_i : in std_logic_vector(data_width-1 downto 0);
52
                        wb2_dat_o : out std_logic_vector(data_width-1 downto 0);
53
         wb2_ack_o : out std_logic;
54
 
55
         wb3_cyc_i : in std_logic;
56
         wb3_stb_i : in std_logic;
57
         wb3_we_i : in std_logic;
58
         wb3_adr_i : in std_logic_vector(addr_width-1 downto 0);
59
         wb3_dat_i : in std_logic_vector(data_width-1 downto 0);
60
                        wb3_dat_o : out std_logic_vector(data_width-1 downto 0);
61
         wb3_ack_o : out std_logic);
62
end wb_Np_ram;
63
 
64
architecture Behavioral of wb_Np_ram is
65
   component sp_ram is --uncomment to use an inferred spram
66
                generic (data_width : integer := 32;
67
                                        addr_width : integer := 8);
68
   --component sp_ram_core is --uncomment to use the coregen spram
69
                port (
70
                        clka: IN std_logic;
71
                        wea: IN std_logic_vector(0 downto 0);
72
                        addra: IN std_logic_vector(addr_width-1 downto 0);
73
                        dina: IN std_logic_vector(data_width-1 downto 0);
74
                        douta: OUT std_logic_vector(data_width-1 downto 0));
75
   end component;
76
 
77
   signal we: std_logic_vector(0 downto 0);
78
   signal a : std_logic_vector(addr_width-1 downto 0);
79
   signal d,q : std_logic_vector(data_width-1 downto 0);
80
begin
81
 
82
 
83
        u_sp_ram : sp_ram --uncomment to use an inferred spram
84
                generic map (data_width,addr_width)
85
   --u_sp_ram : sp_ram_core  --uncomment to use the coregen spram
86
                port map (
87
                        clka => wb_clk_i,
88
                        wea => we,
89
                        addra => a,
90
                        dina => d,
91
                        douta => q);
92
 
93
   wb1_dat_o <= q;
94
   wb2_dat_o <= q;
95
   wb3_dat_o <= q;
96
 
97
   WB_interconnect: process (wb_clk_i, wb_rst_i)
98
      variable ack1, ack2, ack3 : std_logic;
99
      variable lock : integer;
100
      variable State : integer;
101
   begin
102
      if (wb_rst_i = '1') then
103
         we(0) <= '0';
104
         a <= (others => '0');
105
         d <= (others => '0');
106
         ack1 := '0';
107
         wb1_ack_o <= '0';
108
         ack2 := '0';
109
         wb2_ack_o <= '0';
110
         ack3 := '0';
111
         wb3_ack_o <= '0';
112
 
113
         lock := 0;
114
         State := 0;
115
      elsif (wb_clk_i = '1' and wb_clk_i'event) then
116
         --defaults (unless overriden afterwards)
117
         we(0) <= '0';
118
 
119
         case State is
120
            when 0 => --priority for wb1
121
               --unlockers
122
               if (lock = 1 and wb1_cyc_i = '0') then lock := 0; end if;
123
               if (lock = 2 and wb2_cyc_i = '0') then lock := 0; end if;
124
               if (lock = 3 and wb3_cyc_i = '0') then lock := 0; end if;
125
 
126
               if (wb1_cyc_i = '1' and (lock = 0 or lock=1)) then --lock request (grant if lock is available)
127
                  ack2 := '0';
128
                  ack3 := '0';
129
                  lock := 1;
130
                  if (wb1_stb_i = '1' and ack1 = '0') then --operation request
131
                     we(0) <= wb1_we_i;
132
                     a <= wb1_adr_i;
133
                     d <= wb1_dat_i;
134
                     if (wb1_we_i = '1') then
135
                        ack1 := '1'; --ack now and stay in this state waiting for new ops
136
                        State := 1;
137
                     else
138
                        State := 11; --wait one cycle for operation to end
139
                     end if;
140
                  else
141
                     ack1 := '0'; --force one cycle wait between operations
142
                     --or else the wb master could issue a write, then receive two acks (first legal ack and then
143
                     --a spurious one due to being in the cycle where the master is still reading the first ack)
144
                     --followed by a read and misinterpret the spurious ack as an ack for the read
145
                  end if;
146
               elsif (wb2_cyc_i = '1' and (lock = 0 or lock=2)) then --lock request (grant if lock is available)
147
                  ack1 := '0';
148
                  ack3 := '0';
149
                  lock := 2;
150
                  if (wb2_stb_i = '1' and ack2 = '0') then --operation request
151
                     we(0) <= wb2_we_i;
152
                     a <= wb2_adr_i;
153
                     d <= wb2_dat_i;
154
                     if (wb2_we_i = '1') then
155
                        ack2 := '1'; --ack now and stay in this state waiting for new ops
156
                        State := 2;
157
                     else
158
                        State := 12; --wait one cycle for operation to end
159
                     end if;
160
                  else
161
                     ack2 := '0'; --force one cycle wait between operations
162
                  end if;
163
               elsif (wb3_cyc_i = '1' and (lock = 0 or lock=3)) then --lock request (grant if lock is available)
164
                  ack1 := '0';
165
                  ack2 := '0';
166
                  lock := 3;
167
                  if (wb3_stb_i = '1' and ack3 = '0') then --operation request
168
                     we(0) <= wb3_we_i;
169
                     a <= wb3_adr_i;
170
                     d <= wb3_dat_i;
171
                     if (wb3_we_i = '1') then
172
                        ack3 := '1'; --ack now and stay in this state waiting for new ops
173
                        State := 0;
174
                     else
175
                        State := 13; --wait one cycle for operation to end
176
                     end if;
177
                  else
178
                     ack3 := '0'; --force one cycle wait between operations
179
                  end if;
180
               end if;
181
 
182
            when 1 => --priority for wb2 (same code as previous State but changing the order of the if...elsifs)
183
               --unlockers
184
               if (lock = 1 and wb1_cyc_i = '0') then lock := 0; end if;
185
               if (lock = 2 and wb2_cyc_i = '0') then lock := 0; end if;
186
               if (lock = 3 and wb3_cyc_i = '0') then lock := 0; end if;
187
 
188
               if (wb2_cyc_i = '1' and (lock = 0 or lock=2)) then --lock request (grant if lock is available)
189
                  ack1 := '0';
190
                  ack3 := '0';
191
                  lock := 2;
192
                  if (wb2_stb_i = '1' and ack2 = '0') then --operation request
193
                     we(0) <= wb2_we_i;
194
                     a <= wb2_adr_i;
195
                     d <= wb2_dat_i;
196
                     if (wb2_we_i = '1') then
197
                        ack2 := '1'; --ack now and stay in this state waiting for new ops
198
                        State := 2;
199
                     else
200
                        State := 12; --wait one cycle for operation to end
201
                     end if;
202
                  else
203
                     ack2 := '0'; --force one cycle wait between operations
204
                  end if;
205
               elsif (wb3_cyc_i = '1' and (lock = 0 or lock=3)) then --lock request (grant if lock is available)
206
                  ack1 := '0';
207
                  ack2 := '0';
208
                  lock := 3;
209
                  if (wb3_stb_i = '1' and ack3 = '0') then --operation request
210
                     we(0) <= wb3_we_i;
211
                     a <= wb3_adr_i;
212
                     d <= wb3_dat_i;
213
                     if (wb3_we_i = '1') then
214
                        ack3 := '1'; --ack now and stay in this state waiting for new ops
215
                        State := 0;
216
                     else
217
                        State := 13; --wait one cycle for operation to end
218
                     end if;
219
                  else
220
                     ack3 := '0'; --force one cycle wait between operations
221
                  end if;
222
               elsif (wb1_cyc_i = '1' and (lock = 0 or lock=1)) then --lock request (grant if lock is available)
223
                  ack2 := '0';
224
                  ack3 := '0';
225
                  lock := 1;
226
                  if (wb1_stb_i = '1' and ack1 = '0') then --operation request
227
                     we(0) <= wb1_we_i;
228
                     a <= wb1_adr_i;
229
                     d <= wb1_dat_i;
230
                     if (wb1_we_i = '1') then
231
                        ack1 := '1'; --ack now and stay in this state waiting for new ops
232
                        State := 1;
233
                     else
234
                        State := 11; --wait one cycle for operation to end
235
                     end if;
236
                  else
237
                     ack1 := '0'; --force one cycle wait between operations
238
                  end if;
239
               end if;
240
 
241
            when 2 => --priority for wb3 (same code as previous State but changing the order of the if...elsifs)
242
               --unlockers
243
               if (lock = 1 and wb1_cyc_i = '0') then lock := 0; end if;
244
               if (lock = 2 and wb2_cyc_i = '0') then lock := 0; end if;
245
               if (lock = 3 and wb3_cyc_i = '0') then lock := 0; end if;
246
 
247
               if (wb3_cyc_i = '1' and (lock = 0 or lock=3)) then --lock request (grant if lock is available)
248
                  ack1 := '0';
249
                  ack2 := '0';
250
                  lock := 3;
251
                  if (wb3_stb_i = '1' and ack3 = '0') then --operation request
252
                     we(0) <= wb3_we_i;
253
                     a <= wb3_adr_i;
254
                     d <= wb3_dat_i;
255
                     if (wb3_we_i = '1') then
256
                        ack3 := '1'; --ack now and stay in this state waiting for new ops
257
                        State := 0;
258
                     else
259
                        State := 13; --wait one cycle for operation to end
260
                     end if;
261
                  else
262
                     ack3 := '0'; --force one cycle wait between operations
263
                  end if;
264
               elsif (wb1_cyc_i = '1' and (lock = 0 or lock=1)) then --lock request (grant if lock is available)
265
                  ack2 := '0';
266
                  ack3 := '0';
267
                  lock := 1;
268
                  if (wb1_stb_i = '1' and ack1 = '0') then --operation request
269
                     we(0) <= wb1_we_i;
270
                     a <= wb1_adr_i;
271
                     d <= wb1_dat_i;
272
                     if (wb1_we_i = '1') then
273
                        ack1 := '1'; --ack now and stay in this state waiting for new ops
274
                        State := 1;
275
                     else
276
                        State := 11; --wait one cycle for operation to end
277
                     end if;
278
                  else
279
                     ack1 := '0'; --force one cycle wait between operations
280
                  end if;
281
               elsif (wb2_cyc_i = '1' and (lock = 0 or lock=2)) then --lock request (grant if lock is available)
282
                  ack1 := '0';
283
                  ack3 := '0';
284
                  lock := 2;
285
                  if (wb2_stb_i = '1' and ack2 = '0') then --operation request
286
                     we(0) <= wb2_we_i;
287
                     a <= wb2_adr_i;
288
                     d <= wb2_dat_i;
289
                     if (wb2_we_i = '1') then
290
                        ack2 := '1'; --ack now and stay in this state waiting for new ops
291
                        State := 2;
292
                     else
293
                        State := 12; --wait one cycle for operation to end
294
                     end if;
295
                  else
296
                     ack2 := '0'; --force one cycle wait between operations
297
                  end if;
298
               end if;
299
 
300
            when 11 =>
301
               ack1 := '1'; --ack operation
302
               ack2 := '0';
303
               ack3 := '0';
304
               State := 1;
305
            when 12 =>
306
               ack1 := '0';
307
               ack2 := '1'; --ack operation
308
               ack3 := '0';
309
               State := 2;
310
            when 13 =>
311
               ack1 := '0';
312
               ack2 := '0';
313
               ack3 := '1'; --ack operation
314
               State := 0;
315
 
316
            when others => --sanity
317
               ack1 := '0';
318
               ack2 := '0';
319
               ack3 := '0';
320
               State := 0;
321
         end case;
322
 
323
         wb1_ack_o <= (ack1 and wb1_stb_i and wb1_cyc_i); --to don't ack aborted operations
324
         wb2_ack_o <= (ack2 and wb2_stb_i and wb2_cyc_i); --to don't ack aborted operations
325
         wb3_ack_o <= (ack3 and wb3_stb_i and wb3_cyc_i); --to don't ack aborted operations
326
      end if;
327
   end process WB_interconnect;
328
end Behavioral;
329
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.