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

Subversion Repositories plasma_fpu

[/] [plasma_fpu/] [trunk/] [src/] [fpu/] [plasma_fpu_reg_bank.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 FPU register bank
5
-- AUTHORS:     Maximilian Reuter (maximilian.reuter@fs-etit.de)
6
--              Alex Schoenberger (Alex.Schoenberger@ies.tu-darmstadt.de)
7
-- COMMENT:     This project is based on Plasma CPU core by Steve Rhoads
8
--
9
-- www.ies.tu-darmstadt.de
10
-- TU Darmstadt
11
-- Institute for Integrated Systems
12
-- Merckstr. 25
13
-- 
14
-- 64283 Darmstadt - GERMANY
15
-- --------------------------------------------------------------------------
16
-- PROJECT:       Plasma CPU core with FPU
17
-- FILENAME:      plasma_fpu_reg_bank.vhd
18
-- --------------------------------------------------------------------------
19
-- COPYRIGHT: 
20
--  This project is distributed by GPLv2.0
21
--  Software placed into the public domain by the author.
22
--  Software 'as is' without warranty.  Author liable for nothing.
23
-- --------------------------------------------------------------------------
24
-- DESCRIPTION
25
--    register set of plasma FPU coprocessor I (FPU)
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        include implementation from Max Reuter 
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
 
45
entity plasma_fpu_reg_bank is
46
    generic(
47
      DEBUG_FLAG              : string := "OF"
48
    );
49
    port(
50
      control                 : in  t_main_control;
51
      reg_addr                : in  t_reg_addr;
52
      fpu_ctrl                : in  t_fpu_ctrl;
53
      alu_cause               : in  t_fpu_flags;
54
      comp_out                : in  std_logic;
55
      cc_out                  : out std_logic;
56
      reg_dest_new            : in  t_plasma_dword;
57
      reg_source_out          : out t_plasma_dword;
58
      reg_target_out          : out t_plasma_dword
59
    );
60
end entity plasma_fpu_reg_bank;
61
 
62
 
63
architecture structure_plasma_fpu_reg_bank of plasma_fpu_reg_bank is
64
 
65
  alias data_in_upp           : t_plasma_word is reg_dest_new(   2*PLASMA_DATA_WIDTH - 1 downto PLASMA_DATA_WIDTH);
66
  alias data_in_low           : t_plasma_word is reg_dest_new(     PLASMA_DATA_WIDTH - 1 downto                 0);
67
 
68
  alias data_rs_upp           : t_plasma_word is reg_source_out( 2*PLASMA_DATA_WIDTH - 1 downto PLASMA_DATA_WIDTH);
69
  alias data_rs_low           : t_plasma_word is reg_source_out(   PLASMA_DATA_WIDTH - 1 downto                 0);
70
 
71
  alias data_rt_upp           : t_plasma_word is reg_target_out( 2*PLASMA_DATA_WIDTH - 1 downto PLASMA_DATA_WIDTH);
72
  alias data_rt_low           : t_plasma_word is reg_target_out(   PLASMA_DATA_WIDTH - 1 downto                 0);
73
 
74
  --
75
  -- register bank memory
76
  --
77
  signal mem_reg_bank         : t_reg_bank;
78
  signal fcsr                 : t_fpu_fcsr;
79
 
80
  --
81
  -- convert FPU flags to bit vector
82
  --
83
  function flags2slv( flags : t_fpu_flags ) return std_logic_vector is
84
  begin
85
    return flags.v & flags.z & flags.o & flags.u & flags.i;
86
  end flags2slv;
87
 
88
  --
89
  -- convert bit vector to FPU flags
90
  --
91
  function slv2flags( vector : std_logic_vector ) return t_fpu_flags is
92
    variable res    : t_fpu_flags;
93
  begin
94
    res.v := vector(vector'left - 0);
95
    res.z := vector(vector'left - 1);
96
    res.o := vector(vector'left - 2);
97
    res.u := vector(vector'left - 3);
98
    res.i := vector(vector'left - 4);
99
 
100
    return res;
101
  end slv2flags;
102
 
103
  --
104
  -- convert FPU constrol/status register to bit vector
105
  --
106
  function fcsr2slv( fcsr_in : t_fpu_fcsr ) return t_plasma_word is
107
    variable res      : t_plasma_word;
108
  begin
109
    res :=  fcsr_in.fcc(7 downto 1)       &
110
            fcsr_in.fs                    &
111
            fcsr_in.fcc(0)                &
112
            fcsr_in.unused                &
113
            fcsr_in.cause_e               &
114
            flags2slv( fcsr_in.cause )    &
115
            flags2slv( fcsr_in.enables )  &
116
            flags2slv( fcsr_in.flags )    &
117
            fcsr_in.rm;
118
 
119
    return res;
120
  end fcsr2slv;
121
 
122
  --
123
  -- convert bit vector to FPU control/status regsiter
124
  --
125
  function slv2fcsr( vector : t_plasma_word ) return t_fpu_fcsr is
126
    variable res    : t_fpu_fcsr;
127
  begin
128
    res.fcc     := vector(31 downto 25) & vector(23);
129
    res.fs      := vector(24);
130
    res.unused  := vector(22 downto 18);
131
    res.cause_e := vector(17);
132
    res.cause   := slv2flags( vector(16 downto 12) );
133
    res.enables := slv2flags( vector(11 downto  7) );
134
    res.flags   := slv2flags( vector( 8 downto  2) );
135
    res.rm      := vector(1 downto 0);
136
 
137
    return res;
138
  end slv2fcsr;
139
 
140
begin
141
  -- _ _ _ ____ _ ___ ____ 
142
  -- | | | |__/ |  |  |___ 
143
  -- |_|_| |  \ |  |  |___ 
144
  --
145
  -- write process is a synchronous process
146
  --
147
write_process:process( control.clk )
148
 
149
    --
150
    -- ModelSIM causes error by direct call of slv2flags( flags2slv or flags2slv )
151
    --
152
    variable v_alu_cause      : std_logic_vector(4 downto 0);
153
    variable v_flags          : std_logic_vector(4 downto 0);
154
    variable v_or_flags       : std_logic_vector(4 downto 0);
155
 
156
   begin
157
      if rising_edge( control.clk ) then
158
         if control.rst = '1' then
159
            mem_reg_bank <= (others => PLASMA_ZERO_WORD);
160
            fcsr         <= slv2fcsr( PLASMA_ZERO_WORD );
161
         else
162
          if reg_addr.we = '1' then
163
 
164
            case fpu_ctrl.mode is
165
              when FPU_MODE_NONE  =>
166
 
167
              -- ############ REGULAR ALU ACCESS, write FGRs and flags
168
              when FPU_MODE_ALU   =>
169
                --
170
                -- write registers
171
                --
172
                mem_reg_bank( to_integer(unsigned(reg_addr.rd))    ) <= data_in_low;
173
                mem_reg_bank( to_integer(unsigned(reg_addr.rd)) + 1) <= data_in_upp;
174
 
175
                --
176
                -- write flags
177
                --
178
                fcsr.cause  <= alu_cause;
179
                -- fcsr.flags  <= slv2flags( flags2slv(alu_cause) or flags2slv(fcsr.flags));  -- in ModelSIM or results in a 2-bit vector
180
                v_alu_cause := flags2slv( alu_cause );
181
                v_flags     := flags2slv( fcsr.flags );
182
 
183
                v_or_flags  := v_alu_cause or v_flags;
184
 
185
                fcsr.flags  <= slv2flags( v_or_flags );
186
 
187
              -- ############# ACCESS TO FRG from main core (single precision only)
188
              when FPU_MODE_FGR   =>
189
                --
190
                -- main core provides only single precision
191
                --
192
                mem_reg_bank( to_integer(unsigned(reg_addr.rd))    ) <= data_in_low;
193
 
194
              -- ############# ACCESS TO CONTROL REGISTER
195
              when FPU_MODE_CTC   =>
196
                --
197
                -- write directly to control register
198
                --
199
                fcsr  <= slv2fcsr( data_in_low );
200
 
201
              -- ############# ACCESS TO COMPARATOR RESULT
202
              when FPU_MODE_C     =>
203
                --
204
                -- write CC bit
205
                --
206
                fcsr.fcc(0)   <= comp_out;
207
 
208
--synthesis translate_off              
209
              when others         => report "ERROR: FPU regbank write with unknown mode!";
210
--synthesis translate_on
211
 
212
            end case;
213
 
214
          end if;
215
         end if;
216
      end if;
217
   end process;
218
 
219
-- ____ ____ ____ ___  
220
-- |__/ |___ |__| |  \ 
221
-- |  \ |___ |  | |__/ 
222
--
223
-- read access is asynchronous
224
--
225
with fpu_ctrl.c_reg select
226
  data_rs_low    <= mem_reg_bank( to_integer(unsigned(reg_addr.rs)    ) )   when '0',
227
                    fcsr2slv( fcsr )                                        when others;
228
  data_rs_upp    <= mem_reg_bank( to_integer(unsigned(reg_addr.rs) + 1) );
229
 
230
  data_rt_low    <= mem_reg_bank( to_integer(unsigned(reg_addr.rt)    ) );
231
  data_rt_upp    <= mem_reg_bank( to_integer(unsigned(reg_addr.rt) + 1) );
232
 
233
  cc_out         <= fcsr.fcc(0);
234
 
235
-- synthesis translate_off
236
rb_debug: if DEBUG_FLAG = "ON" generate
237
 
238
   signal i_addr                 : t_mips_reg_addr;
239
   signal i_data                 : t_plasma_dword;
240
 
241
begin
242
debug_process: process( control.clk )
243
   begin
244
      if rising_edge( control.clk ) then
245
         if control.rst = '1' then
246
            i_addr <= (others => '0');
247
            i_data <= (others => '0');
248
         else
249
            if reg_addr.we = '1' then
250
               i_addr <= reg_addr.rd;
251
               i_data <= reg_dest_new;
252
 
253
               if (i_addr /= reg_addr.rd) or (i_data /= reg_dest_new) then
254
                  report "0 Addr " & sv2string(debug_prog_addr) &
255
                    " RB "  & "f" & integer'image(to_integer(unsigned(reg_addr.rd)))
256
                    & " " & sv2string(reg_dest_new);
257
               end if;
258
            end if;
259
         end if;
260
      end if;
261
   end process;
262
end generate;
263
 
264
 
265
plasma_fpu_bank   <= mem_reg_bank;
266
-- synthesis translate_on
267
 
268
end architecture structure_plasma_fpu_reg_bank;

powered by: WebSVN 2.1.0

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