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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [sparc/] [div.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tarookumic
 
2
 
3
 
4
 
5
----------------------------------------------------------------------------
6
--  This file is a part of the LEON VHDL model
7
--  Copyright (C) 1999  European Space Agency (ESA)
8
--
9
--  This library is free software; you can redistribute it and/or
10
--  modify it under the terms of the GNU Lesser General Public
11
--  License as published by the Free Software Foundation; either
12
--  version 2 of the License, or (at your option) any later version.
13
--
14
--  See the file COPYING.LGPL for the full details of the license.
15
 
16
 
17
-----------------------------------------------------------------------------
18
-- Entity:      div
19
-- File:        div.vhd
20
-- Author:      Jiri Gaisler - Gaisler Research
21
-- Description: This unit implemets a divide unit to execute the
22
--              UDIV/SDIV instructions. Divide leaves Y
23
--              register intact but does not produce a remainder.
24
--              Overflow detection is performed according to the
25
--              SPARC V8 manual, method B (page 116)
26
------------------------------------------------------------------------------
27
 
28
library IEEE;
29
use IEEE.std_logic_1164.all;
30
use IEEE.std_logic_unsigned."+";
31
use work.leon_config.all;
32
use work.leon_iface.all;
33
 
34
entity div is
35
port (
36
    rst     : in  std_logic;
37
    clk     : in  clk_type;
38
    holdn   : in  std_logic;
39
    divi    : in  div_in_type;
40
    divo    : out div_out_type
41
);
42
end;
43
 
44
architecture rtl of div is
45
 
46
type div_regtype is record
47
  x      : std_logic_vector(64 downto 0);
48
  state  : std_logic_vector(2 downto 0);
49
  zero   : std_logic;
50
  zero2  : std_logic;
51
  qzero  : std_logic;
52
  qmsb   : std_logic;
53
  ovf    : std_logic;
54
  neg    : std_logic;
55
  cnt    : std_logic_vector(4 downto 0);
56
end record;
57
 
58
signal r, rin : div_regtype;
59
signal addin1, addin2, addout: std_logic_vector(32 downto 0);
60
signal addsub : std_logic;
61
 
62
begin
63
 
64
  divcomb : process (r, rst, divi, addout)
65
  variable v : div_regtype;
66
  variable vready : std_logic;
67
  variable vaddin1, vaddin2, vaddout: std_logic_vector(32 downto 0);
68
  variable vaddsub, ymsb, remsign : std_logic;
69
  constant Zero: std_logic_vector(32 downto 0) := "000000000000000000000000000000000";
70
  begin
71
 
72
    vready := '0'; v := r;
73
    if addout = Zero then v.zero := '1'; else v.zero := '0'; end if;
74
    v.zero2 := r.zero;
75
    remsign := '0';
76
 
77
    vaddin1 := r.x(63 downto 31); vaddin2 := divi.op2;
78
    vaddsub := not (divi.op2(32) xor r.x(64));
79
 
80
    case r.state is
81
    when "000" =>
82
      v.cnt := "00000";
83
      if (divi.start = '1') then
84
        v.x(64) := divi.y(32); v.state := "001";
85
      end if;
86
    when "001" =>
87
      v.x := divi.y & divi.op1(31 downto 0);
88
      v.neg := divi.op2(32) xor divi.y(32);
89
      if divi.signed = '1' then
90
        vaddin1 := divi.y(31 downto 0) & divi.op1(31);
91
        v.ovf := not (addout(32) xor divi.y(32));
92
      else
93
        vaddin1 := divi.y; vaddsub := '1';
94
        v.ovf := not addout(32);
95
      end if;
96
      v.state := "010";
97
    when "010" =>
98
      if ((divi.signed and r.neg and r.zero) = '1') and (divi.op1 = Zero) then v.ovf := '0'; end if;
99
      v.qmsb := vaddsub; v.qzero := '1';
100
      v.x(64 downto 32) := addout;
101
      v.x(31 downto 0) := r.x(30 downto 0) & vaddsub;
102
      v.state := "011";
103
-- pragma translate_off
104
      if not is_x(r.cnt) then
105
-- pragma translate_on
106
        v.cnt := r.cnt + 1;
107
-- pragma translate_off
108
      end if;
109
-- pragma translate_on
110
    when "011" =>
111
      v.qzero := r.qzero and (vaddsub xor r.qmsb);
112
      v.x(64 downto 32) := addout;
113
      v.x(31 downto 0) := r.x(30 downto 0) & vaddsub;
114
      if (r.cnt = "11111") then v.state := "100"; else
115
-- pragma translate_off
116
        if not is_x(r.cnt) then
117
-- pragma translate_on
118
          v.cnt := r.cnt + 1;
119
-- pragma translate_off
120
        end if;
121
-- pragma translate_on
122
      end if;
123
    when others =>
124
      vaddin1 := ((not r.x(31)) & r.x(30 downto 0) & '1');
125
      vaddsub := r.x(31); vaddin2 := (others => '0'); vaddin2(0) := '1';
126
      remsign := r.x(64) xor divi.op2(32);
127
      if (r.zero = '0') and ( ((divi.signed = '0') and (r.x(64) /= r.neg)) or
128
        ((divi.signed = '1') and (remsign /= r.neg)) or (r.zero2 = '1'))
129
      then
130
        v.x(64 downto 32) := addout;
131
      else
132
        v.x(64 downto 32) := vaddin1; v.qzero := '0';
133
      end if;
134
      if (r.ovf = '1') then
135
        v.x(63 downto 32) := (others => '1');
136
        if divi.signed = '1' then
137
          if r.neg = '1' then v.x(62 downto 32) := (others => '0');
138
          else v.x(63) := '0'; end if;
139
        end if;
140
      end if;
141
      vready := '1';
142
      v.state := "000";
143
    end case;
144
 
145
    divo.icc <= r.x(63) & r.qzero & r.ovf & '0';
146
    if (rst = '0') or (divi.flush = '1') then v.state := "000"; end if;
147
    rin <= v;
148
    divo.ready <= vready;
149
    divo.result(31 downto 0) <= r.x(63 downto 32);
150
    addin1 <= vaddin1; addin2 <= vaddin2; addsub <= vaddsub;
151
 
152
  end process;
153
 
154
  divadd : process(addin1, addin2, addsub)
155
  variable b : std_logic_vector(32 downto 0);
156
  begin
157
    if addsub = '1' then b := not addin2; else b := addin2; end if;
158
-- pragma translate_off
159
    if not (is_x(addin1 & b & addsub)) then
160
-- pragma translate_on
161
      addout <= addin1 + b + addsub;
162
-- pragma translate_off
163
    else
164
      addout <= (others => 'X');
165
    end if;
166
-- pragma translate_on
167
  end process;
168
 
169
 
170
  reg : process(clk)
171
  begin
172
    if rising_edge(clk) then
173
      if (holdn = '1') then r <= rin; end if;
174
    end if;
175
  end process;
176
 
177
end;
178
 

powered by: WebSVN 2.1.0

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