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

Subversion Repositories minimips_superscalar

[/] [minimips_superscalar/] [trunk/] [sources/] [alu2.vhd] - Blame information for rev 10

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

Line No. Rev Author Line
1 2 mcafruni
--------------------------------------------------------------------------
2
--                                                                      --
3
--                                                                      --
4
-- miniMIPS Superscalar Processor : Arithmetical and logical unit 2     --
5
-- based on miniMIPS Processor                                          --
6
--                                                                      --
7
--                                                                      --
8
-- Author : Miguel Cafruni                                              --
9
-- miguel_cafruni@hotmail.com                                           --
10
--                                                      December 2018   --
11
--------------------------------------------------------------------------
12
 
13
library IEEE;
14
use IEEE.std_logic_1164.all;
15
use IEEE.numeric_std.all;
16
 
17
library work;
18
use work.pack_mips.all;
19
 
20
entity alu2 is
21
port
22
(
23
    clock : in bus1;
24
    reset : in bus1;
25
    op1 : in bus32;            -- Operand 1
26
    op2 : in bus32;            -- Operand 2
27
    ctrl : in alu_ctrl_type;   -- Opearator control
28
    hilo_p1 : in bus64;
29
    hilo_p2p1 : out bus64;
30
    res : out bus32;           -- The result is 32 bit long
31
    overflow : out bus1        -- Overflow of the result
32
);
33
end alu2;
34
 
35
 
36
architecture rtl of alu2 is
37
 
38
    -- Signals to pre-process the operands
39
    signal efct_op1, efct_op2 : bus33;        -- Effective operands of the adder (33 bits)
40
    signal comp_op2 : bus1;                   -- Select the opposite of operand 2
41
    signal igno_op2 : bus1;                   -- Ignore op 2 (put zeros)
42
    signal sign_op1 : bus1;                   -- High bit of op 1
43
    signal sign_op2 : bus1;                   -- High bit of op 2
44
    signal signe : bus1;                      -- Signed operation (bit sign extension)
45
    signal shift_val : natural range 0 to 31; -- Value of the shift
46
 
47
    -- Signals for internal results
48
    signal res_shl, res_shr : bus32; -- Results of left and right shifter
49
    signal res_lui : bus32;          -- Result of Load Upper Immediate
50
    signal res_add : bus33;          -- Result of the adder
51
    signal res_mul : std_logic_vector(31 downto 0);          -- Resultado da multiplicacao 25.05.18
52
    signal carry : bus33;            -- Carry for the adder
53
    signal nul : bus1;               -- Check if the adder result is zero
54
    signal hilo : bus64;             -- Internal registers to store the multiplication operation
55
    signal tmp_hilo : bus64;         -- Internal registers to store the multiplication operation (synchronised)
56
    signal hilop1 : bus64;
57
    signal i_mult : bus1;
58
 
59
begin
60
 
61
    --  Process if the operation is signed compliant
62
    signe <= '1' when (ctrl=OP_ADD or ctrl=OP_SUB or ctrl=OP_SLT or ctrl=OP_SNEG or ctrl=OP_SPOS or ctrl=OP_LNEG or ctrl=OP_LPOS)
63
                 else
64
             '0';
65
 
66
    sign_op1 <= signe and op1(31);
67
    sign_op2 <= signe and op2(31);
68
 
69
    -- Selection of the value of the second operand : op2 or -op2 (ie not op2 + 1)
70
    comp_op2 <= '1' when -- The opposite of op2 is used
71
                           (ctrl=OP_SUB or ctrl=OP_SUBU) -- Opposite of the operand 2 to obtain a substraction
72
                        or (ctrl=OP_SLT or ctrl=OP_SLTU) -- Process the difference to check the lesser than operation for the operands
73
                        or (ctrl=OP_EQU or ctrl=OP_NEQU) -- Process the difference to check the equality of the operands
74
                    else
75
                '0'; -- by default, op2 is used
76
 
77
    igno_op2 <= '1' when -- Op 2 will be zero (when comp_op2='0')
78
                           (ctrl=OP_SPOS or ctrl=OP_LNEG) -- Process if the op1 is nul with op1+0
79
                    else
80
                '0';
81
 
82
    -- Effective signals for the adder
83
    efct_op2 <= not (sign_op2 & op2) when (comp_op2='1') else -- We take the opposite of op2 to get -op2 (we will add 1 with the carry)
84
                (others => '0')  when (igno_op2='1') else     -- Op2 is zero
85
                (sign_op2 & op2);                             -- by default we use op2 (33 bits long)
86
 
87
    efct_op1 <= sign_op1 & op1;
88
 
89
    -- Execution of the addition
90
    carry <= X"00000000" & comp_op2; -- Carry to one when -op2 is needed
91
    res_add <= std_logic_vector(unsigned(efct_op1) + unsigned(efct_op2) + unsigned(carry));
92
    res_mul <= std_logic_vector(signed(efct_op1(15 downto 0))*signed(efct_op2(15 downto 0)));
93
    nul <= '1' when (res_add(31 downto 0)=X"00000000") else '0'; -- Check the nullity of the result (se os registradores contiverem o mesmo valor o resultado é 1)
94
 
95
    -- Value of the shift for the programmable shifter
96
    shift_val <= to_integer(unsigned(op1(4 downto 0)));
97
 
98
    res_shl <= bus32(shift_left(unsigned(op2), shift_val));
99
    res_shr <= not bus32(shift_right(unsigned(not op2) , shift_val)) when (ctrl=OP_SRA and op2(31)='1') else
100
               bus32(shift_right(unsigned(op2), shift_val));
101
    res_lui <= op2(15 downto 0) & X"0000";
102
 
103
    -- Affectation of the hilo register if necessary
104
    tmp_hilo <= std_logic_vector(signed(op1)*signed(op2)) when (ctrl=OP_MULT) else
105
                std_logic_vector(unsigned(op1)*unsigned(op2)) when (ctrl=OP_MULTU) else
106
                op1 & hilo(31 downto 0) when (ctrl=OP_MTHI) else
107
                hilo(63 downto 32) & op1 when (ctrl=OP_MTLO) else
108
                (others => '0');
109
 
110
    hilo_p2p1 <= tmp_hilo;
111
 
112
    -- Check the overflows
113
    overflow <= '1' when ((ctrl=OP_ADD and op1(31)=efct_op2(31) and op1(31)/=res_add(31))
114
                      or  (ctrl=OP_SUB and op1(31)/=op2(31) and op1(31)/=res_add(31))) else
115
                '0'; -- Only ADD and SUB can overflow
116
 
117
    -- Result affectation
118
    res <=
119
        -- Arithmetical operations
120
        res_add(31 downto 0)                     when (ctrl=OP_ADD or ctrl=OP_ADDU or ctrl=OP_SUB or ctrl=OP_SUBU) else
121
        res_mul(31 downto 0)                      when (ctrl=OP_MULT2) else
122
        -- Logical operations
123
        op1 and op2                              when (ctrl=OP_AND)  else
124
        op1 or op2                               when (ctrl=OP_OR)   else
125
        op1 nor op2                              when (ctrl=OP_NOR)  else
126
        op1 xor op2                              when (ctrl=OP_XOR)  else
127
        -- Different tests : the result is one when the test is succesful
128
        (0 => res_add(32), others=>'0')          when (ctrl=OP_SLTU or ctrl=OP_SLT) else
129
        (0 => nul, others=>'0')                  when (ctrl=OP_EQU)  else
130
        (0 => not nul, others=>'0')              when (ctrl=OP_NEQU) else -- inverte o sinal nul, se nao sao iguais os valores dos registradores, entao o branch sera tomado
131
        (0 => op1(31), others=>'0')              when (ctrl=OP_SNEG) else
132
        (0 => not (op1(31) or nul), others=>'0') when (ctrl=OP_SPOS) else
133
        (0 => (op1(31) or nul), others=>'0')     when (ctrl=OP_LNEG) else
134
        (0 => not op1(31), others=>'0')          when (ctrl=OP_LPOS) else
135
        -- Shifts
136
        res_shl                                  when (ctrl=OP_SLL)  else
137
        res_shr                                  when (ctrl=OP_SRL or ctrl=OP_SRA)  else
138
        res_lui                                  when (ctrl=OP_LUI)  else
139
        -- Internal registers
140
        hilo(63 downto 32)                       when (ctrl=OP_MFHI and i_mult='1') else
141
        hilo(31 downto 0)                        when ((ctrl=OP_MFLO or ctrl=OP_MULT or ctrl=OP_MULTU) and i_mult='1') else
142
        hilop1(63 downto 32)                     when (ctrl=OP_MFHI and i_mult='0') else
143
        hilop1(31 downto 0)                      when (ctrl=OP_MFLO and i_mult='0') else -- veio do pipe 1 20-12-2018  or ctrl=OP_MULT or ctrl=OP_MULTU
144
        op1                                      when (ctrl=OP_MTHI or ctrl=OP_MTLO) else
145
        op2                                      when (ctrl=OP_OP2) else
146
        -- Always true
147
        X"00000001"                              when (ctrl=OP_OUI) else -- J (jump)
148
        -- Unknown operation or nul result desired
149
        (others => '0');
150
 
151
    -- Save the hilo register
152
    process (clock)
153
    begin
154
        if falling_edge(clock) then
155
            if reset = '1' then
156
                hilo <= (others => '0');
157
                                         i_mult <= '0';
158
            elsif (ctrl = OP_MULT) or (ctrl = OP_MULTU) or (ctrl = OP_MTLO) or (ctrl = OP_MTHI) then
159
                hilo <= tmp_hilo;
160
                                    i_mult <= '1';
161
                                else
162
                                         i_mult <= '0';
163
            end if;
164
        end if;
165
    end process;
166
 
167
    process (hilo_p1)
168
    begin
169
             hilop1 <= hilo_p1; -- salva entrada assincrona do resultado da multiplicacao feita no pipe 1 20-12-2018
170
    end process;
171
 
172
end rtl;

powered by: WebSVN 2.1.0

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