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

Subversion Repositories qfp32

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

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
   return level;
129
  end CLALevelMk;
130
 
131
  function CLALevelMk (
132
    level : cla_level_t;
133
    group_size : natural)
134
    return cla_level_t is
135
 
136
    variable lb,ub : natural;
137
    variable slice : cla_level_t(group_size-1 downto 0);
138
    variable level_out : cla_level_t((level'length-1)/group_size downto 0);
139
  begin
140
    for i in 0 to (level'length-1)/group_size loop
141
      lb := i*group_size;
142
      ub := min(lb+group_size,level'length)-1;
143
      slice(ub-lb downto 0) := level(ub downto lb);
144
      level_out(i) := CLAGroupMk(slice(ub-lb downto 0));
145
    end loop;
146
    return level_out;
147
  end CLALevelMk;
148
 
149
  -- purpose: propagates carry through group and returns expanded carry vector
150
  function CLAExpandCy (
151
    level : cla_level_t;
152
    cy_in  : std_ulogic)
153
    return std_ulogic_vector is
154
 
155
    variable cy : std_ulogic;
156
    variable cy_out : std_ulogic_vector(level'length downto 0);
157
  begin  -- CLAExpandCy
158
    cy := cy_in;
159
    cy_out(0) := cy;
160
    for i in 0 to level'length-1 loop
161
      cy := level(i).gen or (level(i).pro and cy);
162
      cy_out(i+1) := cy;
163
    end loop;  -- i     
164
    return cy_out;
165
  end CLAExpandCy;
166
 
167
  -- purpose: propagates carry through each group (maybe more than one) and returns expanded carry vector
168
  function CLAExpandCy (
169
    level : cla_level_t;
170
    cy_in  : std_ulogic_vector)
171
    return std_ulogic_vector is
172
 
173
    constant group_size : natural := 1+(level'length-1)/(cy_in'length-1);  -- length cy_in = number of groups+1          
174
    variable ub,lb : natural;
175
    variable slice : cla_level_t(group_size-1 downto 0);
176
    variable cy_out : std_ulogic_vector(level'length downto 0);
177
  begin  -- CLAExpandCy  
178
    cy_out(cy_out'length-1) := cy_in(cy_in'length-1);
179
    for i in 0 to (level'length-1)/group_size loop
180
      lb := i*group_size;
181
      ub := min(lb+group_size,level'length)-1;
182
      slice(ub-lb downto 0) := level(ub downto lb);
183
      cy_out(ub downto lb) := CLAExpandCy(slice(ub-lb downto 0),cy_in(i))(ub-lb downto 0);
184
    end loop;
185
    return cy_out;
186
  end CLAExpandCy;
187
 
188
  -- purpose: adds vector a and b with using carry information from groups
189
  function CLAParallelAdd (
190
    a : unsigned;
191
    b : unsigned;
192
    cy_in : std_ulogic_vector)
193
    return unsigned is
194
 
195
    constant adder_size : integer := 1+(a'length-1)/(cy_in'length-1);
196
    variable lb,ub : natural;
197
    variable result : unsigned(a'length-1 downto 0);
198
    variable cy_vec : std_ulogic_vector(adder_size-1 downto 0) := (others => '0');
199
  begin  -- CLAParallelAdd
200
    result := to_unsigned(0,result'length);
201
 
202
    for i in 0 to (a'length-1)/adder_size loop
203
      lb := i*adder_size;
204
      ub := min(lb+adder_size,a'length)-1;
205
      cy_vec(0) := cy_in(i);
206
      result(ub downto lb) := a(ub downto lb)+b(ub downto lb)+unsigned(cy_vec(ub-lb downto 0));
207
    end loop;  -- i     
208
    return result;
209
  end CLAParallelAdd;
210
 
211
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.