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

Subversion Repositories qfp32

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

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

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