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

Subversion Repositories plasma_fpu

[/] [plasma_fpu/] [trunk/] [src/] [subunits/] [plasma_alu.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 __alexs__
-- --------------------------------------------------------------------------
2
-- >>>>>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<
3
-- --------------------------------------------------------------------------
4
-- TITLE:       Plasma ALU
5
-- AUTHOR:      Alex Schoenberger (Alex.Schoenberger@ies.tu-darmstadt.de)
6
-- COMMENT:     This project is based on Plasma CPU core by Steve Rhoads
7
--
8
-- www.ies.tu-darmstadt.de
9
-- TU Darmstadt
10
-- Institute for Integrated Systems
11
-- Merckstr. 25
12
-- 
13
-- 64283 Darmstadt - GERMANY
14
-- --------------------------------------------------------------------------
15
-- PROJECT:       Plasma CPU core with FPU
16
-- FILENAME:      plasma_alu.vhd
17
-- --------------------------------------------------------------------------
18
-- COPYRIGHT: 
19
--  This project is distributed by GPLv2.0
20
--  Software placed into the public domain by the author.
21
--  Software 'as is' without warranty.  Author liable for nothing.
22
-- --------------------------------------------------------------------------
23
-- DESCRIPTION:
24
--    implements ALU operation depending on instruction code:
25
--    ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR, less than, less than signed
26
--
27
--    SYNTHESIZABLE
28
--
29
----------------------------------------------------------------------------
30
-- Revision History
31
-- --------------------------------------------------------------------------
32
-- Revision   Date    Author     CHANGES
33
-- 1.0       4/2014    AS        initial
34
-- 2.0       5/2015    AS        work with MIPS commands directly 
35
-- --------------------------------------------------------------------------
36
library IEEE;
37
  use IEEE.std_logic_1164.ALL;
38
  use IEEE.numeric_std.ALL;
39
 
40
library PLASMA;
41
  use PLASMA.mips_instruction_set.ALL;
42
  use PLASMA.plasma_pack.ALL;
43
 
44
entity plasma_alu is
45
    port(
46
      alu_a_in                : in  t_plasma_word;
47
      alu_b_in                : in  t_plasma_word;
48
      alu_func                : in  t_mips_function;
49
      alu_out                 : out t_plasma_word
50
    );
51
end entity plasma_alu;
52
 
53
--synthesis translate_off
54
-- ____ _ _  _ _  _ _    ____ ___ _ ____ _  _ 
55
-- [__  | |\/| |  | |    |__|  |  | |  | |\ | 
56
-- ___] | |  | |__| |___ |  |  |  | |__| | \| 
57
architecture sim_alu of plasma_alu is
58
 
59
  signal eq, equ      : Boolean;
60
 
61
begin
62
 
63
  eq  <= signed(alu_a_in) < signed(alu_b_in);
64
  equ <= unsigned(alu_a_in) < unsigned(alu_b_in);
65
 
66
  process( alu_a_in, alu_b_in, alu_func, eq, equ )
67
  begin
68
    alu_out   <= PLASMA_ZERO_WORD;      -- default value
69
 
70
    case alu_func(2 downto 0) is
71
      when "000" => alu_out    <= std_logic_vector(  signed(alu_a_in) +     signed(alu_b_in));        -- ADD
72
      when "001" => alu_out    <= std_logic_vector(unsigned(alu_a_in) +   unsigned(alu_b_in));        -- ADDU
73
      when "010" => if alu_func(5 downto 3) = "100" then
74
                    alu_out    <= std_logic_vector(  signed(alu_a_in) -     signed(alu_b_in));        -- SUB
75
                    else
76
                      if eq then alu_out <= PLASMA_SET_WORD; end if;                                  -- SLT
77
                    end if;
78
      when "011" => if alu_func(5 downto 3) = "100" then
79
                    alu_out    <= std_logic_vector(unsigned(alu_a_in) -   unsigned(alu_b_in));        -- SUBU
80
                    else
81
                      if equ then alu_out <= PLASMA_SET_WORD; end if;                                 -- SLTU
82
                    end if;
83
      when "100" => alu_out    <= alu_a_in and alu_b_in;                                              -- AND
84
      when "101" => alu_out    <= alu_a_in or  alu_b_in;                                              -- OR
85
      when "110" => alu_out    <= alu_a_in xor alu_b_in;                                              -- XOR
86
      when "111" => if alu_func(5) ='1' then
87
                    alu_out    <= alu_a_in nor alu_b_in;                                              -- NOR
88
                    else
89
                    alu_out    <= std_logic_vector(  signed(alu_a_in) +     signed(alu_b_in));        -- LUI
90
                    end if;
91
      when others =>
92
    end case;
93
  end process;
94
 
95
end architecture sim_alu;
96
--synthesis translate_on
97
 
98
-- ____ ___  ____ ____ 
99
-- |___ |__] | __ |__| 
100
-- |    |    |__] |  | 
101
architecture FPGA_alu of plasma_alu is begin
102
 
103
  process( alu_a_in, alu_b_in, alu_func )
104
    variable    temp_result   : t_plasma_word;
105
    variable    sign_xor      : std_logic;
106
  begin
107
    alu_out     <= PLASMA_ZERO_WORD;    -- default value
108
 
109
    case alu_func(2 downto 0) is
110
      when "000" => alu_out    <= std_logic_vector(  signed(alu_a_in) +     signed(alu_b_in));        -- ADD
111
      when "001" => alu_out    <= std_logic_vector(unsigned(alu_a_in) +   unsigned(alu_b_in));        -- ADDU
112
      when "010" => if alu_func(5 downto 3) = "100" then
113
                    alu_out    <= std_logic_vector(  signed(alu_a_in) -     signed(alu_b_in));        -- SUB
114
                    else                                                                              -- SLT
115
                      temp_result := std_logic_vector(signed(alu_a_in) - signed(alu_b_in));       -- calculate difference
116
                      sign_xor    :=
117
                        alu_a_in(PLASMA_DATA_WIDTH - 1) xor alu_b_in(PLASMA_DATA_WIDTH - 1);      -- check for different sign bits
118
 
119
                        if sign_xor = '0' then                                                    -- equal signs
120
                          alu_out(0) <= temp_result(PLASMA_DATA_WIDTH - 1);                       -- pass sign of difference
121
                        else                                                                      -- different signs
122
                          alu_out(0) <= alu_a_in(PLASMA_DATA_WIDTH - 1);                          -- if a < 0 -> a < b (because b > 0)
123
                        end if;                                                                   -- if a > 0 -> a > b (because b < 0)
124
 
125
                      alu_out(PLASMA_DATA_WIDTH - 1 downto 1)
126
                                    <= PLASMA_ZERO_WORD(PLASMA_DATA_WIDTH - 1 downto 1);          -- fill rest with zeros                                 
127
                    end if;
128
 
129
      when "011" => if alu_func(5 downto 3) = "100" then
130
                    alu_out    <= std_logic_vector(unsigned(alu_a_in) -   unsigned(alu_b_in));        -- SUBU
131
                    else                                                                              -- SLTU
132
                      temp_result := std_logic_vector(unsigned(alu_a_in) - unsigned(alu_b_in));       -- calculate difference
133
                      sign_xor    :=
134
                        alu_a_in(PLASMA_DATA_WIDTH - 1) xor alu_b_in(PLASMA_DATA_WIDTH - 1);        -- check for different sign bits
135
 
136
                      if sign_xor = '0' then                                                      -- operands have equal signs
137
                        alu_out(0)  <= temp_result(PLASMA_DATA_WIDTH - 1);                        -- pass difference sign
138
                      else                                                                        -- operands have different signs
139
                        alu_out(0)  <= alu_b_in(PLASMA_DATA_WIDTH - 1);                           -- if MSB(a) = 1 then a > b (MSB(b) must be 0)
140
                      end if;                                                                     -- if MSB(a) = 0 then a < b (MSB(b) must be 1)
141
 
142
                      alu_out(PLASMA_DATA_WIDTH - 1 downto 1)
143
                        <= PLASMA_ZERO_WORD(PLASMA_DATA_WIDTH - 1 downto 1);                        -- fill rest with zeros
144
                    end if;
145
      when "100" => alu_out    <= alu_a_in and alu_b_in;                                              -- AND
146
      when "101" => alu_out    <= alu_a_in or  alu_b_in;                                              -- OR
147
      when "110" => alu_out    <= alu_a_in xor alu_b_in;                                              -- XOR
148
      when "111" => if alu_func(5) ='1' then
149
                    alu_out    <= alu_a_in nor alu_b_in;                                              -- NOR
150
                    else
151
                    alu_out    <= std_logic_vector(  signed(alu_a_in) +     signed(alu_b_in));        -- LUI
152
                    end if;
153
      when others =>
154
 
155
    end case;
156
  end process;
157
 
158
end architecture FPGA_alu;

powered by: WebSVN 2.1.0

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