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

Subversion Repositories the_wizardry_project

[/] [the_wizardry_project/] [trunk/] [Wizardry/] [VHDL/] [Wizardry Top Level/] [Address Generation/] [JOP/] [stack.vhd] - Blame information for rev 22

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 mcwaccent
--
2
--
3
--  This file is a part of JOP, the Java Optimized Processor
4
--
5
--  Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com)
6
--
7
--  This program is free software: you can redistribute it and/or modify
8
--  it under the terms of the GNU General Public License as published by
9
--  the Free Software Foundation, either version 3 of the License, or
10
--  (at your option) any later version.
11
--
12
--  This program is distributed in the hope that it will be useful,
13
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
--  GNU General Public License for more details.
16
--
17
--  You should have received a copy of the GNU General Public License
18
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
 
21
 
22
--
23
--      stack.vhd
24
--
25
--      Stack/Alu for JOP3
26
--
27
--      resources on ACEX1K30-3
28
--
29
--
30
--      2001-06-30      first version (adapted from alu.vhd)
31
--      2001-07-18      components add, sub in own file for Xilinx
32
--      2001-10-28      ldjpc, stjpc
33
--      2001-10-31      init cp and vp with 0
34
--      2001-12-04      cp removed
35
--      2001-12-06      sp is 0 after reset, must be set in sw
36
--      2001-12-07      removed imm. values
37
--      2002-03-24      barrel shifter
38
--      2003-02-12      added mux for 8 and 16 bit unsigned bytecode operand
39
--      2004-10-07      new alu selection with sel_sub, sel_amux and ena_a
40
--      2006-01-12      new ar for local memory addressing, sp and vp MSB fix at '1'
41
--      2007-08-31      change stack addressing without wrapping, generate sp_ov on max_stack-8
42
--      2007-09-01      use ram_width from jop_config instead of parameter
43
--      2007-11-21      use 33 bit for the comparison (compare bug for diff > 2^31 corrected)
44
--
45
 
46
 
47
library ieee;
48
use ieee.std_logic_1164.all;
49
use ieee.numeric_std.all;
50
 
51
use work.jop_config.all;
52
 
53
entity stack is
54
 
55
generic (
56
        width           : integer := 32;        -- one data word
57
        jpc_width       : integer := 10         -- address bits of java byte code pc
58
);
59
port (
60
        clk, reset      : in std_logic;
61
 
62
        din                     : in std_logic_vector(width-1 downto 0);
63
        dir                     : in std_logic_vector(ram_width-1 downto 0);
64
        opd                     : in std_logic_vector(15 downto 0);              -- index for vp load opd
65
        jpc                     : in std_logic_vector(jpc_width downto 0);       -- jpc read
66
 
67
        sel_sub         : in std_logic;                                                 -- 0..add, 1..sub
68
        sel_amux        : in std_logic;                                                 -- 0..sum, 1..lmux
69
        ena_a           : in std_logic;                                                 -- 1..store new value
70
        sel_bmux        : in std_logic;                                                 -- 0..a, 1..mem
71
        sel_log         : in std_logic_vector(1 downto 0);               -- pop/st, and, or, xor
72
        sel_shf         : in std_logic_vector(1 downto 0);               -- sr, sl, sra, (sr)
73
        sel_lmux        : in std_logic_vector(2 downto 0);               -- log, shift, mem, din, reg
74
        sel_imux        : in std_logic_vector(1 downto 0);               -- java opds
75
        sel_rmux        : in std_logic_vector(1 downto 0);               -- sp, vp, jpc
76
        sel_smux        : in std_logic_vector(1 downto 0);               -- sp, a, sp-1, sp+1
77
 
78
        sel_mmux        : in std_logic;                                                 -- 0..a, 1..b
79
        sel_rda         : in std_logic_vector(2 downto 0);               -- 
80
        sel_wra         : in std_logic_vector(2 downto 0);               -- 
81
 
82
        wr_ena          : in std_logic;
83
 
84
        ena_b           : in std_logic;
85
        ena_vp          : in std_logic;
86
        ena_ar          : in std_logic;
87
 
88
        sp_ov           : out std_logic;
89
 
90
        zf                      : out std_logic;
91
        nf                      : out std_logic;
92
        eq                      : out std_logic;
93
        lt                      : out std_logic;
94
        aout            : out std_logic_vector(width-1 downto 0);
95
        bout            : out std_logic_vector(width-1 downto 0)
96
);
97
end stack;
98
 
99
architecture rtl of stack is
100
 
101
component shift is
102
generic (width : integer);
103
port (
104
        din                     : in std_logic_vector(width-1 downto 0);
105
        off                     : in std_logic_vector(4 downto 0);
106
        shtyp           : in std_logic_vector(1 downto 0);
107
        dout            : out std_logic_vector(width-1 downto 0)
108
);
109
end component shift;
110
 
111
--
112
--      ram component (use technology specific vhdl-file (aram/xram))
113
--
114
--      registered  and delayed wraddress, wren
115
--      registered din
116
--      registered rdaddress
117
--      unregistered dout
118
--
119
--              => read during write on same address
120
--
121
component ram is
122
generic (width : integer; addr_width : integer);
123
port (
124
        data            : in std_logic_vector(width-1 downto 0);
125
        wraddress       : in std_logic_vector(ram_width-1 downto 0);
126
        rdaddress       : in std_logic_vector(ram_width-1 downto 0);
127
        wren            : in std_logic;
128
        clock           : in std_logic;
129
        reset           : in std_logic;
130
 
131
        q                       : out std_logic_vector(width-1 downto 0)
132
);
133
end component;
134
 
135
        signal a, b                     : std_logic_vector(width-1 downto 0);
136
        signal ram_dout         : std_logic_vector(width-1 downto 0);
137
 
138
        signal sp, spp, spm     : std_logic_vector(ram_width-1 downto 0);
139
        signal vp0, vp1, vp2, vp3
140
                                                : std_logic_vector(ram_width-1 downto 0);
141
        signal ar                       : std_logic_vector(ram_width-1 downto 0);
142
 
143
        signal sum                      : std_logic_vector(32 downto 0);
144
        signal sout                     : std_logic_vector(width-1 downto 0);
145
        signal log                      : std_logic_vector(width-1 downto 0);
146
        signal immval           : std_logic_vector(width-1 downto 0);
147
        signal opddly           : std_logic_vector(15 downto 0);
148
 
149
        signal amux             : std_logic_vector(width-1 downto 0);
150
        signal lmux             : std_logic_vector(width-1 downto 0);
151
        signal imux             : std_logic_vector(width-1 downto 0);
152
        signal mmux             : std_logic_vector(width-1 downto 0);
153
 
154
        signal rmux             : std_logic_vector(jpc_width downto 0);
155
        signal smux             : std_logic_vector(ram_width-1 downto 0);
156
        signal vpadd    : std_logic_vector(ram_width-1 downto 0);
157
        signal wraddr   : std_logic_vector(ram_width-1 downto 0);
158
        signal rdaddr   : std_logic_vector(ram_width-1 downto 0);
159
        signal ci : std_logic_vector(width-1 downto 0);
160
begin
161
 
162
        cmp_shf: shift generic map (width) port map (b, a(4 downto 0), sel_shf, sout);
163
 
164
        cmp_ram: ram generic map(width, ram_width)
165
                        port map(mmux, wraddr, rdaddr, wr_ena, clk, reset, ram_dout);
166
 
167
 
168
-- a version that 'could' be better in Spartan
169
--process(a, b, sel_sub)
170
--begin
171
--
172
--      if sel_sub='0' then
173
--              temp <= a;
174
--              ci <= X"00000000";
175
--      else
176
--              temp <= not a;
177
--              ci <= X"00000001";
178
--      end if;
179
--      sum <= std_logic_vector(signed(b) + signed(temp)+ signed(ci));
180
--
181
--end process;
182
 
183
 
184
-- this add/sub, the sum/lmux mux and the enable should fit into
185
-- a single LE.
186
-- But it doesn't! A synthesizer problem in Quartus.
187
--
188
process(a, b, sel_sub)
189
begin
190
 
191
        -- subtract with 33 bits to get the correct carry
192
        if sel_sub='1' then
193
                sum <= std_logic_vector(signed(b(31) & b) - signed(a(31) & a));
194
        else
195
                sum <= std_logic_vector(signed(b(31) & b) + signed(a(31) & a));
196
        end if;
197
 
198
end process;
199
 
200
        lt <= sum(32);          -- default is subtract
201
 
202
-- shift version from Flavius?
203
 
204
--
205
--      mux for stack register, alu
206
--
207
process(ram_dout, opddly, immval, sout, din, lmux, rmux, sp, vp0, jpc, sum, log, a, b,
208
                sel_log, sel_shf, sel_rmux, sel_lmux, sel_imux, sel_mmux, sel_amux)
209
 
210
begin
211
 
212
        case sel_log is
213
                when "00" =>
214
                        log <= b;
215
                when "01" =>
216
                        log <= a and b;
217
                when "10" =>
218
                        log <= a or b;
219
                when "11" =>
220
                        log <= a xor b;
221
                when others =>
222
                        null;
223
        end case;
224
 
225
        case sel_rmux is
226
                when "00" =>
227
--                      rmux <= "00" & sp;
228
                        rmux <= std_logic_vector(to_signed(to_integer(unsigned(sp)), jpc_width+1));
229
                when "01" =>
230
--                      rmux <= "00" & vp0;
231
                        rmux <= std_logic_vector(to_signed(to_integer(unsigned(vp0)), jpc_width+1));
232
                when others =>
233
                        rmux <= jpc;
234
        end case;
235
 
236
--
237
--      this is worse than the shift component
238
--
239
--      case sel_shf is
240
--              when "00" =>
241
--                      sout <= std_logic_vector(shift_right(unsigned(b),to_integer(unsigned(a(4 downto 0)))));
242
--              when "01" =>
243
--                      sout <= std_logic_vector(shift_left(signed(b),to_integer(unsigned(a(4 downto 0)))));
244
--              when "10" =>
245
--                      sout <= std_logic_vector(shift_right(signed(b),to_integer(unsigned(a(4 downto 0)))));
246
--              when "11" =>
247
--                      sout <= std_logic_vector(shift_right(unsigned(b),to_integer(unsigned(a(4 downto 0)))));
248
--              when others =>
249
--                      null;
250
--      end case;
251
 
252
        case sel_lmux(2 downto 0) is
253
                when "000" =>
254
                        lmux <= log;
255
                when "001" =>
256
                        lmux <= sout;
257
                when "010" =>
258
                        lmux <= ram_dout;
259
                when "011" =>
260
                        lmux <= immval;
261
                when "100" =>
262
                        lmux <= din;
263
                when others =>
264
                        lmux <= std_logic_vector(to_signed(to_integer(unsigned(rmux)), width));
265
        end case;
266
 
267
        case sel_imux is
268
                when "00" =>
269
                        imux <= "000000000000000000000000" & opddly(7 downto 0);
270
                when "01" =>
271
                        imux <= std_logic_vector(to_signed(to_integer(signed(opddly(7 downto 0))), width));
272
                when "10" =>
273
                        imux <= "0000000000000000" & opddly;
274
                when others =>
275
                        imux <= std_logic_vector(to_signed(to_integer(signed(opddly)), width));
276
        end case;
277
 
278
        if sel_mmux='0' then
279
                mmux <= a;
280
        else
281
                mmux <= b;
282
        end if;
283
 
284
        if sel_amux='0' then
285
                amux <= sum(31 downto 0);
286
        else
287
                amux <= lmux;
288
        end if;
289
 
290
--      if (a = (a'range => '0'))  then         -- Xilinx ISE has problems
291
        if (a=std_logic_vector(to_unsigned(0, width))) then
292
                zf <= '1';
293
        else
294
                zf <= '0';
295
        end if;
296
        nf <= a(width-1);
297
        if (a=b) then
298
                eq <= '1';
299
        else
300
                eq <= '0';
301
        end if;
302
 
303
end process;
304
 
305
process(clk, reset) begin
306
 
307
        if (reset='1') then
308
                a <= (others => '0');
309
                b <= (others => '0');
310
        elsif rising_edge(clk) then
311
 
312
                if ena_a='1' then
313
                        a <= amux;
314
                end if;
315
 
316
                if ena_b = '1' then
317
                        if sel_bmux = '0' then
318
                                b <= a;
319
                        else
320
                                b <= ram_dout;
321
                        end if;
322
                end if;
323
 
324
        end if;
325
end process;
326
 
327
        aout <= a;
328
        bout <= b;
329
 
330
--
331
--      stack pointer and vp register
332
--
333
process(a, sp, spm, spp, sel_smux)
334
 
335
begin
336
 
337
        case sel_smux is
338
                when "00" =>
339
                        smux <= sp;
340
                when "01" =>
341
                        smux <= spm;
342
                when "10" =>
343
                        smux <= spp;
344
                when "11" =>
345
                        smux <= a(ram_width-1 downto 0);
346
                when others =>
347
                        null;
348
        end case;
349
 
350
end process;
351
 
352
 
353
--
354
--      address mux for ram
355
--
356
process(sp, spp, vp0, vp1, vp2, vp3, vpadd, ar, dir, sel_rda, sel_wra)
357
 
358
begin
359
 
360
 
361
        case sel_rda is
362
                when "000" =>
363
                        rdaddr <= vp0;
364
                when "001" =>
365
                        rdaddr <= vp1;
366
                when "010" =>
367
                        rdaddr <= vp2;
368
                when "011" =>
369
                        rdaddr <= vp3;
370
                when "100" =>
371
                        rdaddr <= vpadd;
372
                when "101" =>
373
                        rdaddr <= ar;
374
                when "110" =>
375
                        rdaddr <= sp;
376
                when others =>
377
                        rdaddr <= dir;
378
        end case;
379
 
380
        case sel_wra is
381
                when "000" =>
382
                        wraddr <= vp0;
383
                when "001" =>
384
                        wraddr <= vp1;
385
                when "010" =>
386
                        wraddr <= vp2;
387
                when "011" =>
388
                        wraddr <= vp3;
389
                when "100" =>
390
                        wraddr <= vpadd;
391
                when "101" =>
392
                        wraddr <= ar;
393
                when "110" =>
394
                        wraddr <= spp;
395
                when others =>
396
                        wraddr <= dir;
397
        end case;
398
 
399
end process;
400
 
401
process(clk, reset)
402
 
403
begin
404
        if (reset='1') then
405
                -- a reasonable start value for the stack addressing
406
                -- will be overwritten by the first microcode instructions
407
                sp <= std_logic_vector(to_unsigned(128, ram_width));
408
                spp <= std_logic_vector(to_unsigned(129, ram_width));
409
                spm <= std_logic_vector(to_unsigned(127, ram_width));
410
                sp_ov <= '0';
411
                vp0 <= std_logic_vector(to_unsigned(0, ram_width));
412
                vp1 <= std_logic_vector(to_unsigned(0, ram_width));
413
                vp2 <= std_logic_vector(to_unsigned(0, ram_width));
414
                vp3 <= std_logic_vector(to_unsigned(0, ram_width));
415
                ar <= (others => '0');
416
                vpadd <= std_logic_vector(to_unsigned(0, ram_width));
417
                immval <= std_logic_vector(to_unsigned(0, width));
418
                opddly <= std_logic_vector(to_unsigned(0, 16));
419
        elsif rising_edge(clk) then
420
                spp <= std_logic_vector(unsigned(smux) + 1);
421
                spm <= std_logic_vector(unsigned(smux) - 1);
422
                sp <= smux;
423
                -- Value depends on code in JVMHelp.exception() and how much
424
                -- usefull information can be printed out
425
                -- -8 was ok with just a plain print...
426
                -- -10 (or -12) should be ok for a stack trace?
427
                if sp=std_logic_vector(to_unsigned(2**ram_width-1-16, ram_width)) then
428
                        sp_ov <= '1';
429
                end if;
430
                if (ena_vp = '1') then
431
                        vp0 <= a(ram_width-1 downto 0);
432
                        vp1 <= std_logic_vector(unsigned(a(ram_width-1 downto 0)) + 1);
433
                        vp2 <= std_logic_vector(unsigned(a(ram_width-1 downto 0)) + 2);
434
                        vp3 <= std_logic_vector(unsigned(a(ram_width-1 downto 0)) + 3);
435
                end if;
436
                if ena_ar = '1' then
437
                        ar <= a(ram_width-1 downto 0);
438
                end if;
439
                vpadd <= std_logic_vector(unsigned(vp0(ram_width-1 downto 0)) + unsigned(opd(6 downto 0)));
440
                opddly <= opd;
441
                immval <= imux;
442
        end if;
443
end process;
444
 
445
end rtl;

powered by: WebSVN 2.1.0

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