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

Subversion Repositories rise

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

Go to most recent revision | 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
 
15
 
16
entity id_stage is
17
 
18
  port (
19
    clk            : in std_logic;
20
    reset          : in std_logic;
21
 
22
    if_id_register : in IF_ID_REGISTER_T;
23
    id_ex_register : out ID_EX_REGISTER_T;
24
 
25
    rx_addr        : out REGISTER_ADDR_T;
26
    ry_addr        : out REGISTER_ADDR_T;
27
    rz_addr        : out REGISTER_ADDR_T;
28
 
29
    rx             : in REGISTER_T;
30
    ry             : in REGISTER_T;
31
    rz             : in REGISTER_T;
32
    sr             : in SR_REGISTER_T;
33
 
34
    lock_register  : in LOCK_REGISTER_T;
35
    set_reg_lock   : out std_logic;
36
    lock_reg_addr  : out REGISTER_ADDR_T;
37
 
38
    stall_in       : in std_logic;
39
    stall_out      : out std_logic;
40
    clear_in       : in std_logic);
41
 
42
 
43
end id_stage;
44
 
45
architecture id_stage_rtl of id_stage is
46
 
47 11 cwalter
  signal rx_addr_int : REGISTER_ADDR_T;
48
  signal ry_addr_int : REGISTER_ADDR_T;
49
  signal rz_addr_int : REGISTER_ADDR_T;
50 2 jlechner
  signal id_ex_register_int     : ID_EX_REGISTER_T;
51
  signal id_ex_register_next    : ID_EX_REGISTER_T;
52
 
53 4 cwalter
  function opcode_modifies_rx( opcode: in OPCODE_T ) return std_logic is
54
    variable modifies : std_logic;
55
  begin
56
    case opcode is
57 11 cwalter
      when OPCODE_JMP => modifies := '0';
58
      when OPCODE_TST => modifies := '0';
59
      when OPCODE_NOP => modifies := '0';
60
      when OPCODE_ST_DISP => modifies := '0';
61
      when others => modifies := '1';
62 4 cwalter
    end case;
63
    return modifies;
64
  end;
65
 
66 2 jlechner
begin  -- id_stage_rtl
67
 
68 11 cwalter
  rx_addr <= rx_addr_int;
69
  ry_addr <= ry_addr_int;
70
  rz_addr <= rz_addr_int;
71 4 cwalter
  id_ex_register        <= id_ex_register_int;
72 2 jlechner
 
73
--  process (clk, reset)
74
--  begin  -- process
75
--    if reset = '0' then                 -- asynchronous reset (active low)
76
--      id_ex_register_int        <= (others => (others => '0'));
77
--      id_ex_register_next       <= (others => (others => '0'));
78
--    elsif clk'event and clk = '1' then  -- rising clock edge
79
--      id_ex_register_int        <= id_ex_register_next;
80
--    end if;
81
--  end process;  
82
 
83 4 cwalter
  process (clk, reset )
84
  begin
85
    if reset = '0' then
86
      id_ex_register_int.sr <= RESET_SR_VALUE;
87
      id_ex_register_int.pc <= RESET_PC_VALUE;
88
      id_ex_register_int.opcode <= OPCODE_NOP;
89
      id_ex_register_int.cond <= COND_NONE;
90
      id_ex_register_int.rX_addr <= ( others => '0' );
91
      id_ex_register_int.rX <= ( others => '0' );
92
      id_ex_register_int.rY <= ( others => '0' );
93
      id_ex_register_int.rZ <= ( others => '0' );
94
      id_ex_register_int.immediate <= ( others => '0' );
95
    elsif clk'event and clk = '1' then
96
      id_ex_register_int <= id_ex_register_next;
97
    end if;
98
  end process;
99
 
100 9 cwalter
  -- The opc_extender decodes the two different formats used for the opcodes
101
  -- in the instruction set into a single 5-bit opcode format.
102 11 cwalter
  opc_extender: process ( clk, reset, if_id_register )
103
  begin
104 4 cwalter
    if reset = '0' then
105
      id_ex_register_next.opcode <= OPCODE_NOP;
106 9 cwalter
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
107
    elsif if_id_register.ir( 15 downto 13 ) = "100" then
108
      id_ex_register_next.opcode <= if_id_register.ir( 15 downto 13 ) & if_id_register.ir( 12 ) & "0";
109
      -- decodes: OPCODE_LD_DISP, OPCODE_LD_DISP_MS, OPCODE_ST_DISP
110 4 cwalter
    elsif if_id_register.ir(15) = '1' then
111
      id_ex_register_next.opcode <= if_id_register.ir( 15 downto 13 ) & "00";
112 9 cwalter
      -- decodes: OPCODE_XXX
113 4 cwalter
    else
114
      id_ex_register_next.opcode <= if_id_register.ir( 15 downto 11 );
115
    end if;
116
  end process;
117
 
118 11 cwalter
  cond_decode: process ( clk, reset, if_id_register )
119 4 cwalter
  begin
120
    if reset = '0' then
121
      id_ex_register_next.cond <= COND_NONE;
122 9 cwalter
      -- decodes: OPCODE_LD_IMM, OPCODE_LD_IMM_HB
123
    elsif if_id_register.ir( 15 downto 13 ) = "100" then
124
      id_ex_register_next.cond <= COND_UNCONDITIONAL;
125
      -- decodes: OPCODE_LD_DISP, OPCODE_LD_DISP_MS, OPCODE_ST_DISP      
126 4 cwalter
    elsif if_id_register.ir(15) = '1' then
127 11 cwalter
      id_ex_register_next.cond <= if_id_register.ir( 12 downto 10 );
128 9 cwalter
      -- decodes: OPCODE_XXX
129 4 cwalter
    else
130
      id_ex_register_next.cond <= if_id_register.ir( 10 downto 8 );
131
    end if;
132
  end process;
133
 
134 11 cwalter
  pc: process( reset, if_id_register )
135 4 cwalter
  begin
136 6 cwalter
    if reset = '0' then
137
      id_ex_register_next.pc <= RESET_PC_VALUE;
138
    else
139
      id_ex_register_next.pc <= if_id_register.pc;
140
    end if;
141 4 cwalter
  end process;
142
 
143 11 cwalter
  rx_decode_and_fetch: process ( reset, if_id_register, id_ex_register_next, rx)
144 4 cwalter
  begin
145
    -- make sure we don't synthesize a latch for rx_addr
146 11 cwalter
    rx_addr_int <= ( others => '0' );
147 4 cwalter
 
148
    if reset = '0' then
149
      id_ex_register_next.rX <= ( others => '0' );
150
      id_ex_register_next.rX_addr <= ( others => '0' );
151 9 cwalter
    elsif id_ex_register_next.opcode = OPCODE_LD_IMM or
152
      id_ex_register_next.opcode = OPCODE_LD_IMM_HB then
153 11 cwalter
      rx_addr_int <= if_id_register.ir( 11 downto 8 );
154 4 cwalter
      id_ex_register_next.rX <= rx;
155
      id_ex_register_next.rX_addr <= if_id_register.ir( 11 downto 8 );
156
    else
157 11 cwalter
      rx_addr_int <= if_id_register.ir( 7 downto 4 );
158 4 cwalter
      id_ex_register_next.rX <= rx;
159
      id_ex_register_next.rX_addr <= if_id_register.ir( 7 downto 4 );
160
    end if;
161
 
162
    if opcode_modifies_rx( id_ex_register_next.opcode ) = '1' then
163
      lock_reg_addr <= id_ex_register_next.rX_addr;
164
      set_reg_lock <= '1';
165
    else
166
      lock_reg_addr <= ( others => '0' );
167
      set_reg_lock <= '0';
168
    end if;
169
  end process;
170 6 cwalter
 
171 11 cwalter
  ry_decode_and_fetch: process ( reset, if_id_register, id_ex_register_next, ry )
172 4 cwalter
  begin
173 11 cwalter
    -- make sure we don't synthesize a latch for ry_addr_int
174
    ry_addr_int <= ( others => '0' );
175 4 cwalter
 
176
    if reset = '0' then
177
      id_ex_register_next.rY <= ( others => '0' );
178
    else
179 11 cwalter
      ry_addr_int <= if_id_register.ir( 3 downto 0 );
180
      id_ex_register_next.rY <= ry;
181 4 cwalter
    end if;
182
  end process;
183
 
184 11 cwalter
  rz_decode_and_fetch: process ( reset, if_id_register, id_ex_register_next, rz )
185 4 cwalter
  begin
186 11 cwalter
    -- make sure we don't synthesize a latch for rz_addr_int
187
    rz_addr_int <= ( others => '0' );
188 4 cwalter
 
189
    if reset = '0' then
190
      id_ex_register_next.rZ <= ( others => '0' );
191
    else
192
      -- only the lower 2-bits of rz are encoded in the instruction
193 11 cwalter
      rz_addr_int <= "00" & if_id_register.ir( 9 downto 8 );
194 4 cwalter
      id_ex_register_next.rZ <= rz;
195
    end if;
196
  end process;
197
 
198 9 cwalter
  -- The immediate fetch process checks for all opcodes needing constants
199
  -- and decides which immediate format was present. If the instruction
200
  -- does not include an immediate value the result is undefined and must
201
  -- not be used.
202
  imm_fetch: process (reset, if_id_register, id_ex_register_next)
203
  begin
204
    case id_ex_register_next.opcode is
205
      -- The immediate values holds the upper 8 bits of a 16 bit value.
206
      when OPCODE_LD_IMM_HB =>
207
        id_ex_register_next.immediate <= if_id_register.ir( 7 downto 0 ) & x"00";
208
        -- The immediate values holds the lower 8 bits of a 16 bit value. 
209
      when OPCODE_LD_IMM =>
210
        id_ex_register_next.immediate <= x"00" & if_id_register.ir( 7 downto 0 );
211
        -- Default format holds the lower 4 bits of a 16 bit value.
212
      when others =>
213
        id_ex_register_next.immediate <= x"000" & if_id_register.ir( 3 downto 0 );
214
    end case;
215
  end process;
216
 
217 11 cwalter
  -- Check if all registers are available. If not stall the pipeline.
218
  lock: process( reset, id_ex_register_next, rx_addr_int, ry_addr_int, rz_addr_int, lock_register )
219
    variable required: LOCK_REGISTER_T;
220
  begin
221
    required := ( others => '0' );
222
    if id_ex_register_next.cond /= COND_UNCONDITIONAL then
223
      required( TO_INTEGER( UNSIGNED( SR_REGISTER_ADDR ) ) ) := '1';
224
    end if;
225
    case id_ex_register_next.opcode is
226
      when OPCODE_LD_DISP =>
227
        required( TO_INTEGER( UNSIGNED( rz_addr_int ) ) ) := '1';
228
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
229
      when OPCODE_LD_DISP_MS =>
230
        required( TO_INTEGER( UNSIGNED( rz_addr_int ) ) ) := '1';
231
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
232
      when OPCODE_LD_REG =>
233
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
234
      when OPCODE_ST_DISP =>
235
        required( TO_INTEGER( UNSIGNED( rx_addr_int ) ) ) := '1';
236
        required( TO_INTEGER( UNSIGNED( rz_addr_int ) ) ) := '1';
237
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
238
      when OPCODE_ADD =>
239
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
240
      when OPCODE_SUB =>
241
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
242
      when OPCODE_NEG =>
243
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
244
      when OPCODE_ARS =>
245
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
246
      when OPCODE_ALS =>
247
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
248
      when OPCODE_AND =>
249
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
250
      when OPCODE_NOT =>
251
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
252
      when OPCODE_EOR =>
253
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
254
      when OPCODE_LS =>
255
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
256
      when OPCODE_RS =>
257
        required( TO_INTEGER( UNSIGNED( ry_addr_int ) ) ) := '1';
258
      when OPCODE_JMP =>
259
        required( TO_INTEGER( UNSIGNED( rx_addr_int ) ) ) := '1';
260
      when OPCODE_TST =>
261
        required( TO_INTEGER( UNSIGNED( rx_addr_int ) ) ) := '1';
262
      when others => null;
263
    end case;
264
 
265
    -- no checks if all registers are not locked.
266
    stall_out <= '0';
267
    if ( required & lock_register ) /= x"0000" then
268
      stall_out <= '1';
269
    end if;
270
  end process;
271
 
272 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.