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

Subversion Repositories rv01_riscv_core

[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_pipe_a.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
-----------------------------------------------------------------
2
--                                                             --
3
-----------------------------------------------------------------
4
--                                                             --
5
-- Copyright (C) 2015 Stefano Tonello                          --
6
--                                                             --
7
-- This source file may be used and distributed without        --
8
-- restriction provided that this copyright statement is not   --
9
-- removed from the file and that any derivative work contains --
10
-- the original copyright notice and the associated disclaimer.--
11
--                                                             --
12
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
13
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
14
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
15
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
16
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
17
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
19
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
20
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
21
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
22
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
23
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
24
-- POSSIBILITY OF SUCH DAMAGE.                                 --
25
--                                                             --
26
-----------------------------------------------------------------
27
 
28
---------------------------------------------------------------
29
-- RV01 pipeline-A (dedicated) decoder 
30
---------------------------------------------------------------
31
 
32
library IEEE;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
 
36
library WORK;
37
use WORK.RV01_CONSTS_PKG.all;
38
use WORK.RV01_TYPES_PKG.all;
39
use work.RV01_IDEC_PKG.all;
40
use WORK.RV01_OP_PKG.all;
41
 
42
entity RV01_PIPE_A_DEC is
43
  port(
44
    INSTR_i : in DEC_INSTR_T;
45
 
46
    FWDE_o : out std_logic;
47
    SEL_o :  out std_logic_vector(4-1 downto 0)
48
  );
49
end RV01_PIPE_A_DEC;
50
 
51
architecture ARC of RV01_PIPE_A_DEC is
52
 
53
begin
54
 
55
  -- Result forward-enable flag
56
 
57
  FWDE_o <= '1' when (
58
    INSTR_i.IMNMC = IM_ADD or
59
    INSTR_i.IMNMC = IM_ADDI or
60
    INSTR_i.IMNMC = IM_SLL or
61
    INSTR_i.IMNMC = IM_SLLI or
62
    INSTR_i.IMNMC = IM_SRL or
63
    INSTR_i.IMNMC = IM_SRLI or
64
    INSTR_i.IMNMC = IM_SRA or
65
    INSTR_i.IMNMC = IM_SRAI or
66
    INSTR_i.IMNMC = IM_AND or
67
    INSTR_i.IMNMC = IM_ANDI or
68
    INSTR_i.IMNMC = IM_OR or
69
    INSTR_i.IMNMC = IM_ORI or
70
    INSTR_i.IMNMC = IM_XOR or
71
    INSTR_i.IMNMC = IM_XORI or
72
    INSTR_i.IMNMC = IM_LW
73
  ) else '0';
74
 
75
  -- pipe-A operation selector
76
 
77
  process(INSTR_i)
78
  begin
79
    case INSTR_i.IMNMC is
80
      when IM_ADD|IM_ADDI => SEL_o <= "0001";
81
      when IM_SLL|IM_SLLI|IM_SRL|IM_SRLI|IM_SRA|IM_SRAI => SEL_o <= "0010";
82
      when IM_AND|IM_ANDI|IM_OR|IM_ORI|IM_XOR|IM_XORI  => SEL_o <= "0100";
83
      when others => SEL_o <= "1000"; -- lw
84
    end case;
85
  end process;
86
 
87
end ARC;
88
 
89
---------------------------------------------------------------
90
-- A-pipeline ALU
91
---------------------------------------------------------------
92
 
93
library IEEE;
94
use IEEE.std_logic_1164.all;
95
use IEEE.numeric_std.all;
96
 
97
library WORK;
98
use WORK.RV01_CONSTS_PKG.all;
99
use WORK.RV01_TYPES_PKG.all;
100
use WORK.RV01_FUNCS_PKG.all;
101
use WORK.RV01_ARITH_PKG.all;
102
use work.RV01_IDEC_PKG.all;
103
use WORK.RV01_OP_PKG.all;
104
 
105
entity RV01_PIPE_A_ALU is
106
  port(
107
    SEL_i :  in std_logic_vector(4-1 downto 0);
108
    SU_i : in std_logic;
109
    OP_i : in ALU_OP_T;
110
    OPA_i : in SDWORD_T;
111
    OPB_i : in SDWORD_T;
112
 
113
    RES_o : out SDWORD_T --  result
114
  );
115
end RV01_PIPE_A_ALU;
116
 
117
architecture ARC of RV01_PIPE_A_ALU is
118
 
119
  constant OP_ADD : natural := 0;
120
  constant OP_SHF : natural := 1;
121
  constant OP_LOG : natural := 2;
122
  constant OP_LOAD : natural := 3;
123
 
124
  component RV01_ADDER_F is
125
    generic(
126
      LEN1 : integer := 16;
127
      LEN2 : integer := 16
128
    );
129
    port(
130
      OPA_i : in signed(LEN1+LEN2-1 downto 0);
131
      OPB_i : in signed(LEN1+LEN2-1 downto 0);
132
      CI_i : in std_logic;
133
 
134
      SUM_o : out signed(LEN1+LEN2-1 downto 0)
135
    );
136
  end component;
137
 
138
  component RV01_LOGICU is
139
    port(
140
      CTRL_i : in LOG_CTRL;
141
      OPA_i : in SDWORD_T;
142
      OPB_i : in SDWORD_T;
143
 
144
      RES_o : out SDWORD_T
145
    );
146
  end component;
147
 
148
  signal ZERO : std_logic := '0';
149
  signal ONE : std_logic := '1';
150
  signal ADD_RES : SDWORD_T;
151
  signal LOG_RES : SDWORD_T;
152
  signal LC : LOG_CTRL;
153
  signal RES : SDWORD_T;
154
 
155
begin
156
 
157
  ------------------------------------
158
  -- addition
159
  ------------------------------------
160
 
161
  -- carry-select adder (to improve timing)
162
 
163
  U_ADD : RV01_ADDER_F
164
    generic map(
165
      LEN1 => SDLEN/2,
166
      LEN2 => SDLEN/2
167
    )
168
    port map(
169
      OPA_i => OPA_i,
170
      OPB_i => OPB_i,
171
      CI_i => ZERO,
172
      SUM_o => ADD_RES
173
    );
174
 
175
  ------------------------------------
176
  -- Logic unit operation selection
177
  ------------------------------------
178
 
179
  process(OP_i)
180
  begin
181
    case OP_i is
182
      when ALU_AND =>
183
        LC <= LC_AND;
184
      when ALU_OR =>
185
        LC <= LC_OR;
186
      when others =>
187
        LC <= LC_XOR;
188
    end case;
189
  end process;
190
 
191
  ------------------------------------
192
  -- Logic unit
193
  ------------------------------------
194
 
195
  U_LOG : RV01_LOGICU
196
    port map(
197
      CTRL_i => LC,
198
      OPA_i => OPA_i,
199
      OPB_i => OPB_i,
200
 
201
      RES_o => LOG_RES
202
    );
203
 
204
  -- Result mux
205
 
206
  RES <= ADD_RES when (SEL_i(OP_ADD) = '1') else LOG_RES;
207
 
208
  RES_o <= RES;
209
 
210
end ARC;
211
 
212
---------------------------------------------------------------
213
-- A-pipeline result mux (IX2 stage)
214
---------------------------------------------------------------
215
 
216
library IEEE;
217
use IEEE.std_logic_1164.all;
218
use IEEE.numeric_std.all;
219
 
220
library WORK;
221
use WORK.RV01_CONSTS_PKG.all;
222
use WORK.RV01_TYPES_PKG.all;
223
use WORK.RV01_FUNCS_PKG.all;
224
use work.RV01_IDEC_PKG.all;
225
 
226
entity RV01_PIPE_A_RMX_X2 is
227
  generic(
228
    NW : natural := 2
229
  );
230
  port(
231
    OPA_V_i :  in std_logic;
232
    OPB_V_i :  in std_logic;
233
    OPA_i : in SDWORD_T;
234
    OPB_i : in SDWORD_T;
235
    INSTR_i : in DEC_INSTR_T;
236
    IX3_V_i : in std_logic_vector(NW-1 downto 0);
237
    IX3_INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0);
238
    IX3_RES0_i : in SDWORD_T;
239
    IX3_RES1_i : in SDWORD_T;
240
 
241
    OPA_V_o :  out std_logic;
242
    OPB_V_o :  out std_logic;
243
    OPA_o : out SDWORD_T;
244
    OPB_o : out SDWORD_T
245
 
246
  );
247
end RV01_PIPE_A_RMX_X2;
248
 
249
architecture ARC of RV01_PIPE_A_RMX_X2 is
250
 
251
  signal SELA1,SELB1 : std_logic;
252
  signal UOPA,UOPB : SDWORD_T;
253
  signal UOPA_V,UOPB_V : std_logic;
254
 
255
begin
256
 
257
  ------------------------------------
258
  -- Notes
259
  ------------------------------------
260
 
261
  -- Stage IX3 provides (up to) two results per cycle,
262
  -- requiring a mux to select the desired one.
263
 
264
  -- OPA source selection flag
265
  SELA1 <= IX3_V_i(1) when (
266
    IX3_INSTR_i(1).WRD = '1' and
267
    IX3_INSTR_i(1).RD = INSTR_i.RS1
268
  ) else '0';
269
 
270
  -- Updated OPA operand source mux
271
  UOPA <= IX3_RES1_i when (SELA1 = '1') else IX3_RES0_i;
272
 
273
  -- Updated OPA operand valid flag (flag is set if there's
274
  -- a valid value for it from IX3 stage).
275
 
276
  UOPA_V <=  '1' when (
277
    (
278
      IX3_V_i(0) = '1' and
279
      IX3_INSTR_i(0).WRD = '1' and
280
      IX3_INSTR_i(0).RD = INSTR_i.RS1
281
     ) or (
282
      IX3_V_i(1) = '1' and
283
      IX3_INSTR_i(1).WRD = '1' and
284
      IX3_INSTR_i(1).RD = INSTR_i.RS1
285
     )
286
  ) else '0';
287
 
288
  -- OPB source selection flag
289
  SELB1 <= IX3_V_i(1) when (
290
    IX3_INSTR_i(1).WRD = '1' and
291
    IX3_INSTR_i(1).RD = INSTR_i.RS2
292
  ) else '0';
293
 
294
  -- Updated OPB operand source mux
295
  UOPB <= IX3_RES1_i when (SELB1 = '1') else IX3_RES0_i;
296
 
297
  -- Updated OPB operand valid flag (flag is set if there's
298
  -- a valid value for it from IX3 stage).
299
 
300
  UOPB_V <= '1' when (
301
    (
302
      IX3_V_i(0) = '1' and
303
      IX3_INSTR_i(0).WRD = '1' and
304
      IX3_INSTR_i(0).RD = INSTR_i.RS2
305
     ) or (
306
      IX3_V_i(1) = '1' and
307
      IX3_INSTR_i(1).WRD = '1' and
308
      IX3_INSTR_i(1).RD = INSTR_i.RS2
309
     )
310
  ) else '0';
311
 
312
  OPA_V_o <= OPA_V_i or UOPA_V;
313
 
314
  OPB_V_o <= OPB_V_i or UOPB_V;
315
 
316
  OPA_o <= OPA_i when (OPA_V_i = '1') else UOPA;
317
 
318
  OPB_o <= OPB_i when (OPB_V_i = '1') else UOPB;
319
 
320
end ARC;
321
 
322
---------------------------------------------------------------
323
-- A-pipeline result mux  (IX1 stage)
324
---------------------------------------------------------------
325
 
326
library IEEE;
327
use IEEE.std_logic_1164.all;
328
use IEEE.numeric_std.all;
329
 
330
library WORK;
331
use WORK.RV01_CONSTS_PKG.all;
332
use WORK.RV01_TYPES_PKG.all;
333
use WORK.RV01_FUNCS_PKG.all;
334
use work.RV01_IDEC_PKG.all;
335
 
336
entity RV01_PIPE_A_RMX_X1 is
337
  generic(
338
    NW : natural := 2
339
  );
340
  port(
341
    OPA_V_i :  in std_logic;
342
    OPB_V_i :  in std_logic;
343
    OPA_i : in SDWORD_T;
344
    OPB_i : in SDWORD_T;
345
    INSTR_i : in DEC_INSTR_T;
346
    IX2_V_i : in std_logic_vector(NW-1 downto 0);
347
    IX2_INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0);
348
    IX2_RES0_i : in SDWORD_T;
349
    IX2_RES1_i : in SDWORD_T;
350
    IX3_V_i : in std_logic_vector(NW-1 downto 0);
351
    IX3_INSTR_i : in DEC_INSTR_VEC_T(NW-1 downto 0);
352
    IX3_RES0_i : in SDWORD_T;
353
    IX3_RES1_i : in SDWORD_T;
354
 
355
    OPA_V_o :  out std_logic;
356
    OPB_V_o :  out std_logic;
357
    OPA_o : out SDWORD_T;
358
    OPB_o : out SDWORD_T
359
 
360
  );
361
end RV01_PIPE_A_RMX_X1;
362
 
363
architecture ARC of RV01_PIPE_A_RMX_X1 is
364
 
365
  signal SELA0_X2,SELB0_X2 : std_logic;
366
  signal SELA0_X3,SELB0_X3 : std_logic;
367
  signal SELA1_X2,SELB1_X2 : std_logic;
368
  signal SELA1_X3,SELB1_X3 : std_logic;
369
  signal UOPA,UOPB : SDWORD_T;
370
  signal UOPA_V,UOPB_V : std_logic;
371
 
372
begin
373
 
374
  ------------------------------------
375
  -- Notes
376
  ------------------------------------
377
 
378
  -- Stages IX2 and IX3 provide (up to) two results per
379
  -- cycle, each, requiring a mux to select the desired one.
380
 
381
  -- OPA source selection flag
382
 
383
  SELA0_X2 <= IX2_V_i(0) when (
384
    IX2_INSTR_i(0).WRD = '1' and
385
    IX2_INSTR_i(0).RD = INSTR_i.RS1
386
  ) else '0';
387
 
388
  SELA1_X2 <= IX2_V_i(1) when (
389
    IX2_INSTR_i(1).WRD = '1' and
390
    IX2_INSTR_i(1).RD = INSTR_i.RS1
391
  ) else '0';
392
 
393
  SELA0_X3 <= IX3_V_i(0) when (
394
    IX3_INSTR_i(0).WRD = '1' and
395
    IX3_INSTR_i(0).RD = INSTR_i.RS1
396
  ) else '0';
397
 
398
  SELA1_X3 <= IX3_V_i(1) when (
399
    IX3_INSTR_i(1).WRD = '1' and
400
    IX3_INSTR_i(1).RD = INSTR_i.RS1
401
  ) else '0';
402
 
403
  -- Updated OPA operand source mux
404
  process(
405
    SELA0_X2,SELA1_X2,SELA0_X3,SELA1_X3,
406
    IX2_RES0_i,IX2_RES1_i,IX3_RES0_i,IX3_RES1_i
407
  )
408
    variable S : std_logic_vector(4-1 downto 0);
409
  begin
410
    S := SELA1_X3 & SELA0_X3 & SELA1_X2 & SELA0_X2;
411
    case S is
412
      when "0001"|"0101"|"1001"|"1101" =>
413
        UOPA <= IX2_RES0_i;
414
      when "0010"|"0011"|"0110"|"0111"|"1010"|"1011"|"1110"|"1111" =>
415
        UOPA <= IX2_RES1_i;
416
      when "0100" =>
417
        UOPA <= IX3_RES0_i;
418
      when others =>
419
        UOPA <= IX3_RES1_i;
420
    end case;
421
  end process;
422
 
423
  -- Updated OPA operand valid flag (flag is set if there's
424
  -- a valid value for it from IX2 or IX3 stage).
425
 
426
  UOPA_V <=
427
    SELA0_X2 or
428
    SELA1_X2 or
429
    SELA0_X3 or
430
    SELA1_X3;
431
 
432
  -- OPB source selection flag
433
 
434
  SELB0_X2 <= IX2_V_i(0) when (
435
    IX2_INSTR_i(0).WRD = '1' and
436
    IX2_INSTR_i(0).RD = INSTR_i.RS2
437
  ) else '0';
438
 
439
  -- OPA source selection flag
440
  SELB1_X2 <= IX2_V_i(1) when (
441
    IX2_INSTR_i(1).WRD = '1' and
442
    IX2_INSTR_i(1).RD = INSTR_i.RS2
443
  ) else '0';
444
 
445
  -- OPA source selection flag
446
  SELB0_X3 <= IX3_V_i(0) when (
447
    IX3_INSTR_i(0).WRD = '1' and
448
    IX3_INSTR_i(0).RD = INSTR_i.RS2
449
  ) else '0';
450
 
451
  SELB1_X3 <= IX3_V_i(1) when (
452
    IX3_INSTR_i(1).WRD = '1' and
453
    IX3_INSTR_i(1).RD = INSTR_i.RS2
454
  ) else '0';
455
 
456
  -- Updated OPB operand source mux
457
  process(
458
    SELB0_X2,SELB1_X2,SELB0_X3,SELB1_X3,
459
    IX2_RES0_i,IX2_RES1_i,IX3_RES0_i,IX3_RES1_i
460
  )
461
    variable S : std_logic_vector(4-1 downto 0);
462
  begin
463
    S := SELB1_X3 & SELB0_X3 & SELB1_X2 & SELB0_X2;
464
    case S is
465
      when "0001"|"0101"|"1001"|"1101" =>
466
        UOPB <= IX2_RES0_i;
467
      when "0010"|"0011"|"0110"|"0111"|"1010"|"1011"|"1110"|"1111" =>
468
        UOPB <= IX2_RES1_i;
469
      when "0100" =>
470
        UOPB <= IX3_RES0_i;
471
      when others =>
472
        UOPB <= IX3_RES1_i;
473
    end case;
474
  end process;
475
 
476
  -- Updated OPB operand valid flag (flag is set if there's
477
  -- a valid value for it from IX2 or IX3 stages).
478
 
479
  UOPB_V <=
480
    SELB0_X2 or
481
    SELB1_X2 or
482
    SELB0_X3 or
483
    SELB1_X3;
484
 
485
  OPA_V_o <= OPA_V_i or UOPA_V;
486
 
487
  OPB_V_o <= OPB_V_i or UOPB_V;
488
 
489
  OPA_o <= OPA_i when (OPA_V_i = '1') else UOPA;
490
 
491
  OPB_o <= OPB_i when (OPB_V_i = '1') else UOPB;
492
 
493
end ARC;

powered by: WebSVN 2.1.0

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