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

Subversion Repositories rise

[/] [rise/] [trunk/] [vhdl/] [id_stage.vhd] - Blame information for rev 148

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jlechner
-- File: id_stage.vhd
2
-- Author: Jakob Lechner, Urban Stadler, Harald Trinkl, Christian Walter
3
-- Created: 2006-11-29
4
-- Last updated: 2006-11-29
5
 
6
-- Description:
7
-- Instruction decode stage
8
-------------------------------------------------------------------------------
9
 
10
library IEEE;
11 11 cwalter
use IEEE.std_logic_1164.all;
12
use IEEE.numeric_std.all;
13 2 jlechner
use WORK.RISE_PACK.all;
14 72 jlechner
use work.RISE_PACK_SPECIFIC.all;
15 2 jlechner
 
16
entity id_stage is
17
 
18
  port (
19 15 cwalter
    clk   : in std_logic;
20
    reset : in std_logic;
21 2 jlechner
 
22 15 cwalter
    if_id_register : in  IF_ID_REGISTER_T;
23 2 jlechner
    id_ex_register : out ID_EX_REGISTER_T;
24
 
25 15 cwalter
    rx_addr : out REGISTER_ADDR_T;
26
    ry_addr : out REGISTER_ADDR_T;
27
    rz_addr : out REGISTER_ADDR_T;
28 2 jlechner
 
29 15 cwalter
    rx : in REGISTER_T;
30
    ry : in REGISTER_T;
31
    rz : in REGISTER_T;
32
    sr : in SR_REGISTER_T;
33 2 jlechner
 
34 15 cwalter
    lock_register  : in  LOCK_REGISTER_T;
35
    set_reg_lock0  : out std_logic;
36
    lock_reg_addr0 : out REGISTER_ADDR_T;
37
    set_reg_lock1  : out std_logic;
38
    lock_reg_addr1 : out REGISTER_ADDR_T;
39 2 jlechner
 
40 15 cwalter
    stall_in  : in  std_logic;
41
    stall_out : out std_logic;
42
    clear_in  : in  std_logic);
43 2 jlechner
 
44 15 cwalter
 
45 2 jlechner
end id_stage;
46
 
47
architecture id_stage_rtl of id_stage is
48
 
49 15 cwalter
  signal rx_addr_int         : REGISTER_ADDR_T;
50
  signal ry_addr_int         : REGISTER_ADDR_T;
51
  signal rz_addr_int         : REGISTER_ADDR_T;
52
  signal id_ex_register_int  : ID_EX_REGISTER_T;
53
  signal id_ex_register_next : ID_EX_REGISTER_T;
54 32 cwalter
  signal stall_out_int       : std_logic;
55 15 cwalter
 
56
  function opcode_modifies_sr(opcode : in OPCODE_T) return std_logic is
57 4 cwalter
    variable modifies : std_logic;
58
  begin
59
    case opcode is
60 15 cwalter
      when OPCODE_NOP        => modifies := '0';
61
      when OPCODE_JMP        => modifies := '0';
62
      when OPCODE_LD_DISP_MS => modifies := '0';
63
      when others            => modifies := '1';
64
    end case;
65
    return modifies;
66
  end;
67
 
68
  function opcode_modifies_rx(opcode : in OPCODE_T) return std_logic is
69
    variable modifies : std_logic;
70
  begin
71
    case opcode is
72
      when OPCODE_JMP     => modifies := '0';
73
      when OPCODE_TST     => modifies := '0';
74
      when OPCODE_NOP     => modifies := '0';
75 11 cwalter
      when OPCODE_ST_DISP => modifies := '0';
76 15 cwalter
      when others         => modifies := '1';
77 4 cwalter
    end case;
78
    return modifies;
79
  end;
80
 
81 2 jlechner
begin  -- id_stage_rtl
82
 
83 15 cwalter
  rx_addr        <= rx_addr_int;
84
  ry_addr        <= ry_addr_int;
85
  rz_addr        <= rz_addr_int;
86
  id_ex_register <= id_ex_register_int;
87 32 cwalter
  stall_out      <= stall_out_int;
88 2 jlechner
--  process (clk, reset)
89
--  begin  -- process
90
--    if reset = '0' then                 -- asynchronous reset (active low)
91
--      id_ex_register_int        <= (others => (others => '0'));
92
--      id_ex_register_next       <= (others => (others => '0'));
93
--    elsif clk'event and clk = '1' then  -- rising clock edge
94
--      id_ex_register_int        <= id_ex_register_next;
95
--    end if;
96
--  end process;  
97
 
98 92 jlechner
  process (clk, reset, stall_in, clear_in)
99 4 cwalter
  begin
100 92 jlechner
    if reset = '0' or clear_in = '1' then
101 15 cwalter
      id_ex_register_int.sr        <= RESET_SR_VALUE;
102
      id_ex_register_int.pc        <= RESET_PC_VALUE;
103
      id_ex_register_int.opcode    <= OPCODE_NOP;
104 51 cwalter
      id_ex_register_int.cond      <= COND_UNCONDITIONAL;
105 15 cwalter
      id_ex_register_int.rX_addr   <= (others => '0');
106
      id_ex_register_int.rX        <= (others => '0');
107
      id_ex_register_int.rY        <= (others => '0');
108
      id_ex_register_int.rZ        <= (others => '0');
109
      id_ex_register_int.immediate <= (others => '0');
110 32 cwalter
    elsif clk'event and clk = '1' then
111
      if stall_in = '0' then
112 51 cwalter
        if stall_out_int = '0' then
113
          id_ex_register_int <= id_ex_register_next;
114
        else
115
          id_ex_register_int.sr        <= RESET_SR_VALUE;
116
          id_ex_register_int.pc        <= RESET_PC_VALUE;
117
          id_ex_register_int.opcode    <= OPCODE_NOP;
118
          id_ex_register_int.cond      <= COND_UNCONDITIONAL;
119
          id_ex_register_int.rX_addr   <= (others => '0');
120
          id_ex_register_int.rX        <= (others => '0');
121
          id_ex_register_int.rY        <= (others => '0');
122
          id_ex_register_int.rZ        <= (others => '0');
123
          id_ex_register_int.immediate <= (others => '0');
124
        end if;
125 32 cwalter
      end if;
126 4 cwalter
    end if;
127
  end process;
128 15 cwalter
 
129 9 cwalter
  -- The opc_extender decodes the two different formats used for the opcodes
130
  -- in the instruction set into a single 5-bit opcode format.
131 111 cwalter
  opc_extender : process (clk, reset, if_id_register)
132 15 cwalter
  begin
133 51 cwalter
    if reset = '0' then
134 4 cwalter
      id_ex_register_next.opcode <= OPCODE_NOP;
135 9 cwalter
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
136 15 cwalter
    elsif if_id_register.ir(15 downto 13) = "100" then
137 72 jlechner
      id_ex_register_next.opcode <= svector2opcode(if_id_register.ir(15 downto 13) & if_id_register.ir(12) & "0");
138 9 cwalter
      -- decodes: OPCODE_LD_DISP, OPCODE_LD_DISP_MS, OPCODE_ST_DISP
139 4 cwalter
    elsif if_id_register.ir(15) = '1' then
140 72 jlechner
      id_ex_register_next.opcode <= svector2opcode(if_id_register.ir(15 downto 13) & "00");
141 9 cwalter
      -- decodes: OPCODE_XXX
142 4 cwalter
    else
143 72 jlechner
      id_ex_register_next.opcode <= svector2opcode(if_id_register.ir(15 downto 11));
144 4 cwalter
    end if;
145
  end process;
146 15 cwalter
 
147 111 cwalter
  cond_decode : process (clk, reset, if_id_register)
148 4 cwalter
  begin
149 51 cwalter
    if reset = '0' then
150
      id_ex_register_next.cond <= COND_UNCONDITIONAL;
151 9 cwalter
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
152 15 cwalter
    elsif if_id_register.ir(15 downto 13) = "100" then
153 9 cwalter
      id_ex_register_next.cond <= COND_UNCONDITIONAL;
154
      -- decodes: OPCODE_LD_DISP, OPCODE_LD_DISP_MS, OPCODE_ST_DISP      
155 4 cwalter
    elsif if_id_register.ir(15) = '1' then
156 72 jlechner
      id_ex_register_next.cond <= svector2cond(if_id_register.ir(12 downto 10));
157 9 cwalter
      -- decodes: OPCODE_XXX
158 4 cwalter
    else
159 72 jlechner
      id_ex_register_next.cond <= svector2cond(if_id_register.ir(10 downto 8));
160 4 cwalter
    end if;
161
  end process;
162 15 cwalter
 
163 111 cwalter
  pc : process(reset, if_id_register)
164 4 cwalter
  begin
165 51 cwalter
    if reset = '0' then
166 6 cwalter
      id_ex_register_next.pc <= RESET_PC_VALUE;
167
    else
168
      id_ex_register_next.pc <= if_id_register.pc;
169
    end if;
170 4 cwalter
  end process;
171 15 cwalter
 
172
  -- The SR fetch process read the value of the SR registers and passes it to
173
  -- the execute pipeline. In addition it checks if the opcode modifies the
174
  -- SR register and if yes locks the register.
175 111 cwalter
  sr_fetch : process (reset, sr, id_ex_register_next, stall_out_int, clear_in)
176 4 cwalter
  begin
177 51 cwalter
    if reset = '0' then
178 15 cwalter
      id_ex_register_next.sr <= RESET_SR_VALUE;
179
    else
180
      id_ex_register_next.sr <= sr;
181
    end if;
182
 
183 92 jlechner
    if opcode_modifies_sr(id_ex_register_next.opcode) = '1' and stall_out_int = '0' and clear_in = '0' then
184 20 cwalter
      lock_reg_addr1 <= SR_REGISTER_ADDR;
185 15 cwalter
      set_reg_lock1  <= '1';
186
    else
187
      lock_reg_addr1 <= (others => '-');
188
      set_reg_lock1  <= '0';
189
    end if;
190
  end process;
191
 
192 111 cwalter
  rx_decode_and_fetch : process (reset, if_id_register, id_ex_register_next, rx, stall_out_int, clear_in)
193 15 cwalter
  begin
194 4 cwalter
    -- make sure we don't synthesize a latch for rx_addr
195 15 cwalter
    rx_addr_int <= (others => '0');
196
 
197 51 cwalter
    if reset = '0' then
198 15 cwalter
      id_ex_register_next.rX      <= (others => '0');
199
      id_ex_register_next.rX_addr <= (others => '0');
200
    elsif id_ex_register_next.opcode = OPCODE_LD_IMM or
201 9 cwalter
      id_ex_register_next.opcode = OPCODE_LD_IMM_HB then
202 15 cwalter
      rx_addr_int                 <= if_id_register.ir(11 downto 8);
203
      id_ex_register_next.rX      <= rx;
204
      id_ex_register_next.rX_addr <= if_id_register.ir(11 downto 8);
205 4 cwalter
    else
206 15 cwalter
      rx_addr_int                 <= if_id_register.ir(7 downto 4);
207
      id_ex_register_next.rX      <= rx;
208
      id_ex_register_next.rX_addr <= if_id_register.ir(7 downto 4);
209 4 cwalter
    end if;
210 15 cwalter
 
211 92 jlechner
    if opcode_modifies_rx(id_ex_register_next.opcode) = '1' and stall_out_int = '0' and clear_in = '0' then
212 15 cwalter
      lock_reg_addr0 <= id_ex_register_next.rX_addr;
213
      set_reg_lock0  <= '1';
214 63 cwalter
    elsif id_ex_register_next.opcode = OPCODE_JMP then
215
      lock_reg_addr0 <= LR_REGISTER_ADDR;
216
      set_reg_lock0  <= '1';
217 4 cwalter
    else
218 15 cwalter
      lock_reg_addr0 <= (others => '-');
219
      set_reg_lock0  <= '0';
220 4 cwalter
    end if;
221
  end process;
222 15 cwalter
 
223
 
224 111 cwalter
  ry_decode_and_fetch : process (reset, if_id_register, id_ex_register_next, ry)
225 4 cwalter
  begin
226 11 cwalter
    -- make sure we don't synthesize a latch for ry_addr_int
227 15 cwalter
    ry_addr_int <= (others => '0');
228
 
229 51 cwalter
    if reset = '0' then
230 15 cwalter
      id_ex_register_next.rY <= (others => '0');
231 4 cwalter
    else
232 15 cwalter
      ry_addr_int            <= if_id_register.ir(3 downto 0);
233 11 cwalter
      id_ex_register_next.rY <= ry;
234 4 cwalter
    end if;
235
  end process;
236 15 cwalter
 
237 111 cwalter
  rz_decode_and_fetch : process (reset, if_id_register, id_ex_register_next, rz)
238 4 cwalter
  begin
239 11 cwalter
    -- make sure we don't synthesize a latch for rz_addr_int
240 15 cwalter
    rz_addr_int <= (others => '0');
241
 
242 51 cwalter
    if reset = '0' then
243 15 cwalter
      id_ex_register_next.rZ <= (others => '0');
244 4 cwalter
    else
245
      -- only the lower 2-bits of rz are encoded in the instruction
246 15 cwalter
      rz_addr_int            <= "00" & if_id_register.ir(9 downto 8);
247 4 cwalter
      id_ex_register_next.rZ <= rz;
248
    end if;
249
  end process;
250 15 cwalter
 
251 9 cwalter
  -- The immediate fetch process checks for all opcodes needing constants
252
  -- and decides which immediate format was present. If the instruction
253
  -- does not include an immediate value the result is undefined and must
254
  -- not be used.
255 15 cwalter
  imm_fetch : process (reset, if_id_register, id_ex_register_next)
256 9 cwalter
  begin
257
    case id_ex_register_next.opcode is
258
      -- The immediate values holds the upper 8 bits of a 16 bit value.
259 15 cwalter
      when OPCODE_LD_IMM_HB =>
260 73 cwalter
        id_ex_register_next.immediate <= x"00" & if_id_register.ir(7 downto 0);
261 9 cwalter
        -- The immediate values holds the lower 8 bits of a 16 bit value. 
262 15 cwalter
      when OPCODE_LD_IMM =>
263
        id_ex_register_next.immediate <= x"00" & if_id_register.ir(7 downto 0);
264 9 cwalter
        -- Default format holds the lower 4 bits of a 16 bit value.
265
      when others =>
266 15 cwalter
        id_ex_register_next.immediate <= x"000" & if_id_register.ir(3 downto 0);
267 9 cwalter
    end case;
268
  end process;
269 15 cwalter
 
270 11 cwalter
  -- Check if all registers are available. If not stall the pipeline.
271 111 cwalter
  lock : process(reset, id_ex_register_next, rx_addr_int, ry_addr_int, rz_addr_int, lock_register, clear_in)
272 15 cwalter
    variable required : LOCK_REGISTER_T;
273 11 cwalter
  begin
274 15 cwalter
    required := (others => '0');
275 11 cwalter
    if id_ex_register_next.cond /= COND_UNCONDITIONAL then
276 15 cwalter
      required(TO_INTEGER(unsigned(SR_REGISTER_ADDR))) := '1';
277 11 cwalter
    end if;
278
    case id_ex_register_next.opcode is
279 59 cwalter
      -- looks strange but ld rX, #0xAA also needs the register because we
280
      -- can only load the high or low byte and the other one must be
281
      -- preserved.
282
      when OPCODE_LD_IMM =>
283
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
284
      when OPCODE_LD_IMM_HB =>
285
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
286 15 cwalter
      when OPCODE_LD_DISP =>
287
        required(TO_INTEGER(unsigned(rz_addr_int))) := '1';
288
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
289 11 cwalter
      when OPCODE_LD_DISP_MS =>
290 15 cwalter
        required(TO_INTEGER(unsigned(rz_addr_int))) := '1';
291
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
292 11 cwalter
      when OPCODE_LD_REG =>
293 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
294 11 cwalter
      when OPCODE_ST_DISP =>
295 15 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
296
        required(TO_INTEGER(unsigned(rz_addr_int))) := '1';
297
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
298 11 cwalter
      when OPCODE_ADD =>
299 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
300 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
301 111 cwalter
      when OPCODE_ADD_IMM =>
302
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
303 11 cwalter
      when OPCODE_SUB =>
304 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
305 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
306 111 cwalter
      when OPCODE_SUB_IMM =>
307
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
308 11 cwalter
      when OPCODE_NEG =>
309 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
310 11 cwalter
      when OPCODE_ARS =>
311 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
312 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
313 11 cwalter
      when OPCODE_ALS =>
314 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
315 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
316 11 cwalter
      when OPCODE_AND =>
317 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
318 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
319 11 cwalter
      when OPCODE_NOT =>
320 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
321 11 cwalter
      when OPCODE_EOR =>
322 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
323 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
324 11 cwalter
      when OPCODE_LS =>
325 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
326 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
327 11 cwalter
      when OPCODE_RS =>
328 111 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
329 15 cwalter
        required(TO_INTEGER(unsigned(ry_addr_int))) := '1';
330 11 cwalter
      when OPCODE_JMP =>
331 15 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
332 11 cwalter
      when OPCODE_TST =>
333 15 cwalter
        required(TO_INTEGER(unsigned(rx_addr_int))) := '1';
334 11 cwalter
      when others => null;
335
    end case;
336 15 cwalter
 
337 11 cwalter
    -- no checks if all registers are not locked.
338 32 cwalter
    stall_out_int <= '0';
339 92 jlechner
    if (required and lock_register) /= x"0000" and (clear_in = '0') then
340 32 cwalter
      stall_out_int <= '1';
341 11 cwalter
    end if;
342
  end process;
343
 
344 2 jlechner
end id_stage_rtl;

powered by: WebSVN 2.1.0

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