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_b.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
 
2
 
3
-----------------------------------------------------------------
4
--                                                             --
5
-----------------------------------------------------------------
6
--                                                             --
7
-- Copyright (C) 2015 Stefano Tonello                          --
8
--                                                             --
9
-- This source file may be used and distributed without        --
10
-- restriction provided that this copyright statement is not   --
11
-- removed from the file and that any derivative work contains --
12
-- the original copyright notice and the associated disclaimer.--
13
--                                                             --
14
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
15
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
16
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
17
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
18
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
19
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
20
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
21
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
22
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
23
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
24
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
25
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
26
-- POSSIBILITY OF SUCH DAMAGE.                                 --
27
--                                                             --
28
-----------------------------------------------------------------
29
 
30
---------------------------------------------------------------
31
-- RV01 pipeline-B
32
---------------------------------------------------------------
33
 
34
library IEEE;
35
use IEEE.std_logic_1164.all;
36
use IEEE.numeric_std.all;
37
 
38
library WORK;
39
use WORK.RV01_CONSTS_PKG.all;
40
use WORK.RV01_TYPES_PKG.all;
41
use WORK.RV01_FUNCS_PKG.all;
42
use WORK.RV01_ARITH_PKG.all;
43
use WORK.RV01_OP_PKG.all;
44
 
45
entity RV01_PIPE_B is
46
  port(
47
    CLK_i : in std_logic;
48
    OP_i :  in ALU_OP_T;
49
    SU_i : in std_logic;
50
    PC0_i : in unsigned(SDLEN-1 downto 0); -- from IX1
51
    PC1_i : in unsigned(SDLEN-1 downto 0); -- from IX2
52
    OPA_i : in SDWORD_T;
53
    OPB_i : in SDWORD_T;
54
 
55
    RES_o : out SDWORD_T
56
  );
57
end RV01_PIPE_B;
58
 
59
architecture ARC of RV01_PIPE_B is
60
 
61
  component RV01_MULU is
62
    port(
63
      CLK_i : in std_logic;
64
      CTRL_i : in MUL_CTRL;
65
      OPA_i : in SDWORD_T;
66
      OPB_i : in SDWORD_T;
67
 
68
      RES_o : out SDWORD_T
69
    );
70
  end component;
71
 
72
  --component RV01_SHFTU is
73
  --  port(
74
  --    CTRL_i : in SHF_CTRL;
75
  --    SI_i : in SDWORD_T;
76
  --    SHFT_i : in unsigned(5-1 downto 0);
77
  --    SU_i : in std_logic;
78
  --
79
  --    SO_o : out SDWORD_T
80
  --  );
81
  --end component;
82
 
83
  --component RV01_LOGICU is
84
  --  port(
85
  --    CTRL_i : in LOG_CTRL;
86
  --    OPA_i : in SDWORD_T;
87
  --    OPB_i : in SDWORD_T;
88
  --
89
  --    RES_o : out SDWORD_T
90
  --  );
91
  --end component;
92
 
93
  signal OP_q :  ALU_OP_T;
94
  signal OPA_q : SDWORD_T;
95
  signal OPB_q : SDWORD_T;
96
  signal RES,MUL_RES,SHF_RES,LOG_RES,AUIPC_RES,SUB_RES,SLT_RES : SDWORD_T;
97
  signal SHF_RES_q,LOG_RES_q,AUIPC_RES_q,SUB_RES_q,SLT_RES_q : SDWORD_T;
98
  signal MC : MUL_CTRL;
99
  --signal SC : SHF_CTRL;
100
  --signal LC : LOG_CTRL;
101
  signal MUL_SEL,SHF_SEL,LOG_SEL : std_logic;
102
  signal MUL_SEL_q,SHF_SEL_q,LOG_SEL_q : std_logic;
103
  --signal SHFT : unsigned(5-1 downto 0);
104
  signal OPA_SGN,OPB_SGN,SUB_RES_SGN : std_logic;
105
 
106
begin
107
 
108
  -------------------------------------------------------
109
  -- Notes:
110
  -- This module handles multiplication, shifting and
111
  -- boolean instructions.
112
  -- Shifting and boolean instructions are executed in
113
  -- one cycle, while multiplication ones are executed
114
  -- in two cycles.
115
  -------------------------------------------------------
116
 
117
  ------------------------------------
118
  -- AUIPC adder
119
  ------------------------------------
120
 
121
  AUIPC_RES <= to_signed(PC0_i) + OPB_i;
122
 
123
  -- pipe register
124
  process(CLK_i)
125
  begin
126
    if(CLK_i = '1' and CLK_i'event) then
127
      AUIPC_RES_q <= AUIPC_RES;
128
    end if;
129
  end process;
130
 
131
  ------------------------------------
132
  -- Multiply unit operation selection
133
  ------------------------------------
134
 
135
  process(OP_i)
136
  begin
137
    MUL_SEL <= '1';
138
    case OP_i is
139
      when ALU_MUL =>
140
        MC <= MC_MUL;
141
      when ALU_MULH =>
142
        MC <= MC_MULH;
143
      when ALU_MULHSU =>
144
        MC <= MC_MULHSU;
145
      when ALU_MULHU =>
146
        MC <= MC_MULHU;
147
      when others =>
148
        MUL_SEL <= '0';
149
        MC <= MC_NIL;
150
    end case;
151
  end process;
152
 
153
--  ------------------------------------
154
--  -- Shift/normalize unit operation selection
155
--  ------------------------------------
156
--
157
--  process(OP_i)
158
--  begin
159
--    SHF_SEL <= '1';
160
--    case OP_i is
161
--      when ALU_SHL =>
162
--        SC <= SC_SHL;
163
--      when ALU_SHR =>
164
--        SC <= SC_SHR;
165
--      when others =>
166
--        SHF_SEL <= '0';
167
--        SC <= SC_NIL;
168
--    end case;
169
--  end process;
170
 
171
--  ------------------------------------
172
--  -- Logic unit operation selection
173
--  ------------------------------------
174
--
175
--  process(OP_i)
176
--  begin
177
--    LOG_SEL <= '1';
178
--    case OP_i is
179
--      when ALU_AND =>
180
--        LC <= LC_AND;
181
--      when ALU_OR =>
182
--        LC <= LC_OR;
183
--      when ALU_XOR =>
184
--        LC <= LC_XOR;
185
--      when others =>
186
--        LOG_SEL <= '0';
187
--        LC <= LC_NIL;
188
--    end case;
189
--  end process;
190
 
191
  ------------------------------------
192
  -- Multiply unit
193
  ------------------------------------
194
 
195
  -- Note: this is a 2-cycle unit, and therefore
196
  -- it doesn't need a pipe register!
197
 
198
  U_MUL : RV01_MULU
199
    port map(
200
      CLK_i => CLK_i,
201
      CTRL_i  => MC,
202
      OPA_i => OPA_i,
203
      OPB_i => OPB_i,
204
 
205
      RES_o => MUL_RES
206
    );
207
 
208
  -- pipe register
209
  process(CLK_i)
210
  begin
211
    if(CLK_i = '1' and CLK_i'event) then
212
      MUL_SEL_q <= MUL_SEL;
213
    end if;
214
  end process;
215
 
216
--  ------------------------------------
217
--  -- Shift
218
--  ------------------------------------
219
--
220
--  SHFT <= to_unsigned(OPB_i(5-1 downto 0));
221
--
222
--  U_SHF : RV01_SHFTU
223
--    port map(
224
--      CTRL_i => SC,
225
--      SI_i => OPA_i,
226
--      SHFT_i => SHFT,
227
--      SU_i => SU_i,
228
--  
229
--      SO_o => SHF_RES
230
--    );
231
--
232
--  -- pipe register
233
--  process(CLK_i)
234
--  begin
235
--    if(CLK_i = '1' and CLK_i'event) then
236
--      SHF_RES_q <= SHF_RES;
237
--      SHF_SEL_q <= SHF_SEL;
238
--    end if;
239
--  end process;
240
 
241
--  ------------------------------------
242
--  -- Logic unit
243
--  ------------------------------------
244
--
245
--  U_LOG : RV01_LOGICU
246
--    port map(
247
--      CTRL_i => LC,
248
--      OPA_i => OPA_i,
249
--      OPB_i => OPB_i,
250
--  
251
--      RES_o => LOG_RES
252
--    );
253
--
254
--  -- pipe register
255
--  process(CLK_i)
256
--  begin
257
--    if(CLK_i = '1' and CLK_i'event) then
258
--      LOG_RES_q <= LOG_RES;
259
--      LOG_SEL_q <= LOG_SEL;
260
--    end if;
261
--  end process;
262
 
263
  ------------------------------------
264
  -- Subtraction
265
  ------------------------------------
266
 
267
  SUB_RES <= (OPA_i - OPB_i);
268
 
269
  -- subtraction result sign (to be used
270
  -- by SLT* instructions)
271
 
272
  SUB_RES_SGN <= SUB_RES(SDLEN-1);
273
 
274
  -- pipe register
275
  process(CLK_i)
276
  begin
277
    if(CLK_i = '1' and CLK_i'event) then
278
      SUB_RES_q <= SUB_RES;
279
    end if;
280
  end process;
281
 
282
  ------------------------------------
283
  -- Set-less-than
284
  ------------------------------------
285
 
286
  -- operand A sign
287
  OPA_SGN <= OPA_i(SDLEN-1);
288
 
289
  -- operand B sign
290
  OPB_SGN <= OPB_i(SDLEN-1);
291
 
292
  -- signed less-than comparison
293
  -- msb(A) msb(B) | A < B
294
  -------------------------
295
  --    0      0   | msb(A-B)
296
  --    0      1   |   0
297
  --    1      0   |   1
298
  --    1      1   | msb(A-B)
299
 
300
  -- unsigned less-than comparison
301
  -- msb(A) msb(B) | A < B
302
  -------------------------
303
  --    0      0   | msb(A-B)
304
  --    0      1   |   1
305
  --    1      0   |   0
306
  --    1      1   | msb(A-B)
307
 
308
  process(SU_i,OPA_SGN,OPB_SGN,SUB_RES_SGN)
309
  begin
310
    SLT_RES <= (others => '0');
311
    if(SU_i = '1') then
312
      -- signed comparison
313
      if(
314
        (OPA_SGN = OPB_SGN)
315
      ) then
316
        SLT_RES(0) <= SUB_RES_SGN;
317
      else
318
        SLT_RES(0) <= OPA_SGN;
319
      end if;
320
    else
321
      -- unsigned comparison
322
      if(
323
        (OPA_SGN = OPB_SGN)
324
      ) then
325
        SLT_RES(0) <= SUB_RES_SGN;
326
      else
327
        SLT_RES(0) <= OPB_SGN;
328
      end if;
329
    end if;
330
  end process;
331
 
332
  -- pipe register
333
  process(CLK_i)
334
  begin
335
    if(CLK_i = '1' and CLK_i'event) then
336
      SLT_RES_q <= SLT_RES;
337
    end if;
338
  end process;
339
 
340
  ------------------------------------
341
  -- output flags and result mux
342
  ------------------------------------
343
 
344
  -- pipe register
345
  process(CLK_i)
346
  begin
347
    if(CLK_i = '1' and CLK_i'event) then
348
      --OPA_q <= OPA_i;
349
      OPB_q <= OPB_i;
350
      OP_q <= OP_i;
351
    end if;
352
  end process;
353
 
354
  -- This encoding allows to set relative priority among the
355
  -- functional unit according to timing requirements.
356
 
357
  process(
358
    OP_q,
359
    MUL_SEL_q,MUL_RES,
360
    --SHF_SEL_q,SHF_RES_q,
361
    --LOG_SEL_q,LOG_RES_q,
362
    AUIPC_RES_q,SUB_RES_q,SLT_RES_q,
363
    PC1_i,OPA_q,OPB_q
364
  )
365
  begin
366
    if(MUL_SEL_q = '1') then
367
      RES <= MUL_RES;
368
    --elsif(SHF_SEL_q = '1') then
369
    --  RES <= SHF_RES_q;
370
    elsif(OP_q = ALU_SLT) then
371
      RES <= SLT_RES_q;
372
    elsif(OP_q = ALU_SUB) then
373
      RES <= SUB_RES_q;
374
    elsif(OP_q = ALU_AUIPC) then
375
      RES <= AUIPC_RES_q;
376
    --elsif(LOG_SEL_q = '1') then
377
    --  RES <= LOG_RES_q;
378
    elsif(OP_q = ALU_JAL) then
379
      RES <= to_signed(PC1_i);
380
    --elsif(OP_q = ALU_MOVA) then
381
    --  RES <= OPA_q;
382
    else -- ALU_MOVB
383
      RES <= OPB_q; -- used by lui inst.
384
    end if;
385
  end process;
386
 
387
  -- result
388
  RES_o <= RES;
389
 
390
end ARC;

powered by: WebSVN 2.1.0

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