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

Subversion Repositories qfp32

[/] [qfp32/] [trunk/] [cla.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 mgraep
-------------------------------------------------------------------------------
2
-- Title      : Carry lookahead adder library
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : cla.vhd
6
-- Author     : Malte Graeper <malte@T430u>
7
-- Company    : 
8
-- Created    : 2013-11-10
9
-- Last update: 2014-06-29
10
-- Platform   : 
11
-- Standard   : VHDL'93/02
12
-------------------------------------------------------------------------------
13
-- Description: provides all functions for making carry lookahead adder of
14
-- arbitary deepth and width
15
-------------------------------------------------------------------------------
16
-- Copyright (c) 2013 
17
-------------------------------------------------------------------------------
18
-- Revisions  :
19
-- Date        Version  Author          Description
20
-- 2013-11-10  1.0      Malte Graeper   Created
21
-------------------------------------------------------------------------------
22
 
23
library IEEE;
24
use IEEE.std_logic_1164.all;
25
use IEEE.numeric_std.all;
26
 
27
package cla_p is
28
 
29
  type cla_group_t is record
30
          pro    : std_ulogic;
31
          gen    : std_ulogic;
32
  end record;
33
 
34
  type cla_level_t is array (natural range <>) of cla_group_t;
35
 
36
  function CLAGroupMk (
37
    a : unsigned;
38
    b : unsigned)
39
    return cla_group_t;
40
 
41
  function CLAGroupMk (
42
    level : cla_level_t)
43
    return cla_group_t;
44
 
45
  function CLALevelMk (
46
    a : unsigned;
47
    b : unsigned;
48
    group_size : natural)
49
    return cla_level_t;
50
 
51
  function CLALevelMk (
52
    level : cla_level_t;
53
    group_size : natural)
54
    return cla_level_t;
55
 
56
  -- purpose: propagates carry through groups and returns expanded carry vector
57
  function CLAExpandCy (
58
    level : cla_level_t;
59
    cy_in : std_ulogic)
60
    return std_ulogic_vector;
61
 
62
  function CLAExpandCy (
63
    level : cla_level_t;
64
    cy_in  : std_ulogic_vector)
65
    return std_ulogic_vector;
66
 
67
  -- purpose: adds vector a and b with using carry information from groups
68
  function CLAParallelAdd (
69
    a : unsigned;
70
    b : unsigned;
71
    cy_in : std_ulogic_vector)
72
    return unsigned;
73
 
74
end cla_p;
75
 
76
package body cla_p is
77
 
78
  function min(
79
    a : natural;
80
    b : natural)
81
    return natural is
82
  begin
83
    if a > b then
84
      return b;
85
    else
86
      return a;
87
    end if;
88
  end min;
89
 
90
  function CLAGroupMk (
91
    a : unsigned;
92
    b : unsigned)
93
    return cla_group_t is
94
 
95
    variable gen : std_ulogic;
96
    variable pro : std_ulogic;
97
  begin
98
    gen := '0';
99
    pro := '1';
100
    for i in a'length-1 downto 0 loop
101
      gen := (a(i) and b(i) and pro) or gen;
102
      pro := (a(i) or b(i)) and pro;
103
    end loop;
104
    return (pro,gen);
105
  end CLAGroupMk;
106
 
107
  function CLAGroupMk (
108
    level : cla_level_t)
109
    return cla_group_t is
110
 
111
    variable gen : std_ulogic;
112
    variable pro : std_ulogic;
113
  begin
114
    gen := '0';
115
    pro := '1';
116
    for i in level'length-1 downto 0 loop
117
      -- calc propagate/generate
118
      gen := (level(i).gen  and pro) or gen;
119
      pro := level(i).pro and pro;
120
    end loop;
121
    return (pro,gen);
122
  end CLAGroupMk;
123
 
124
  function CLALevelMk (
125
    a : unsigned;
126
    b : unsigned;
127
    group_size : natural)
128
    return cla_level_t is
129
 
130
    variable lb,ub : natural;
131
    variable slice_a,slice_b : unsigned(group_size-1 downto 0);
132
    variable level : cla_level_t((a'length-1)/group_size downto 0);
133
  begin
134
    for i in 0 to (a'length-1)/group_size loop
135
      lb := i*group_size;
136
      ub := min(lb+group_size,a'length)-1;
137
      slice_a(ub-lb downto 0) := a(ub downto lb);
138
      slice_b(ub-lb downto 0) := b(ub downto lb);
139
      level(i) := CLAGroupMk(slice_a(ub-lb downto 0),slice_b(ub-lb downto 0));
140
   end loop;
141
 
142
   --level(0) := CLAGroupMk(a(min(gsize,a'length-gsize)-1 downto 0),b(gsize-1 downto 0));
143
 
144
   -- recursive call
145
   --if level'length > 0 then
146
   --  level(level'length-1 downto 1) := CLALevelMk(a(a'length-1 downto gsize),b(b'length-1 downto gsize),gsize);
147
   --end if;
148
 
149
   return level;
150
  end CLALevelMk;
151
 
152
  function CLALevelMk (
153
    level : cla_level_t;
154
    group_size : natural)
155
    return cla_level_t is
156
 
157
    variable lb,ub : natural;
158
    variable slice : cla_level_t(group_size-1 downto 0);
159
    variable level_out : cla_level_t((level'length-1)/group_size downto 0);
160
  begin
161
    for i in 0 to (level'length-1)/group_size loop
162
      lb := i*group_size;
163
      ub := min(lb+group_size,level'length)-1;
164
      slice(ub-lb downto 0) := level(ub downto lb);
165
      level_out(i) := CLAGroupMk(slice(ub-lb downto 0));
166
    end loop;
167
    return level_out;
168
  end CLALevelMk;
169
 
170
  -- purpose: propagates carry through group and returns expanded carry vector
171
  function CLAExpandCy (
172
    level : cla_level_t;
173
    cy_in  : std_ulogic)
174
    return std_ulogic_vector is
175
 
176
    variable cy : std_ulogic;
177
    variable cy_out : std_ulogic_vector(level'length downto 0);
178
  begin  -- CLAExpandCy
179
    cy := cy_in;
180
    cy_out(0) := cy;
181
    for i in 0 to level'length-1 loop
182
      cy := level(i).gen or (level(i).pro and cy);
183
      cy_out(i+1) := cy;
184
    end loop;  -- i     
185
    return cy_out;
186
  end CLAExpandCy;
187
 
188
  -- purpose: propagates carry through each group (maybe more than one) and returns expanded carry vector
189
  function CLAExpandCy (
190
    level : cla_level_t;
191
    cy_in  : std_ulogic_vector)
192
    return std_ulogic_vector is
193
 
194
    constant group_size : natural := 1+(level'length-1)/(cy_in'length-1);  -- length cy_in = number of groups+1          
195
    variable ub,lb : natural;
196
    variable slice : cla_level_t(group_size-1 downto 0);
197
    variable cy_out : std_ulogic_vector(level'length downto 0);
198
  begin  -- CLAExpandCy  
199
    cy_out(cy_out'length-1) := cy_in(cy_in'length-1);
200
    for i in 0 to (level'length-1)/group_size loop
201
      lb := i*group_size;
202
      ub := min(lb+group_size,level'length)-1;
203
      slice(ub-lb downto 0) := level(ub downto lb);
204
      cy_out(ub downto lb) := CLAExpandCy(slice(ub-lb downto 0),cy_in(i))(ub-lb downto 0);
205
    end loop;
206
    return cy_out;
207
  end CLAExpandCy;
208
 
209
  -- purpose: adds vector a and b with using carry information from groups
210
  function CLAParallelAdd (
211
    a : unsigned;
212
    b : unsigned;
213
    cy_in : std_ulogic_vector)
214
    return unsigned is
215
 
216
    constant adder_size : integer := 1+(a'length-1)/(cy_in'length-1);
217
    variable lb,ub : natural;
218
    variable result : unsigned(a'length-1 downto 0);
219
    variable cy_vec : std_ulogic_vector(adder_size-1 downto 0) := (others => '0');
220
  begin  -- CLAParallelAdd
221
    result := to_unsigned(0,result'length);
222
 
223
    for i in 0 to (a'length-1)/adder_size loop
224
      lb := i*adder_size;
225
      ub := min(lb+adder_size,a'length)-1;
226
      cy_vec(0) := cy_in(i);
227
      result(ub downto lb) := a(ub downto lb)+b(ub downto lb)+unsigned(cy_vec(ub-lb downto 0));
228
    end loop;  -- i     
229
    return result;
230
  end CLAParallelAdd;
231
 
232
end package body cla_p;

powered by: WebSVN 2.1.0

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