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

Subversion Repositories dmt_tx

[/] [dmt_tx/] [trunk/] [myhdl/] [rtl/] [cmath.py] - Blame information for rev 32

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 dannori
 
2
from myhdl import *
3
 
4
def cadd(a_re, a_im, b_re, b_im, y_re, y_im, overflow, width=8):
5
  '''Complex add
6
 
7
  I/O pins:
8
  =========
9
  a         : input a
10
  b         : input b
11
  y         : output a + b
12
  overflow  : signal overflow
13
 
14
  parameter:
15
  ==========
16
  width : data width for input and output
17
  '''
18
  @always_comb
19
  def logic():
20
    m = 2**(width-1)
21
 
22
    #
23
    # Real value calculation
24
    if (a_re + b_re) >= m:
25
      y_re.next = m-1
26
      ovfl_re = True
27
 
28
    elif (a_re + b_re) < -m:
29
      y_re.next = -m
30
      ovfl_re = True
31
 
32
    else:
33
      y_re.next = a_re + b_re
34
      ovfl_re = False
35
 
36
    #
37
    # Imaginary add
38
    if (a_im + b_im) >= m:
39
      y_im.next = m-1
40
      ovfl_im = True
41
 
42
    elif (a_im + b_im) < -m:
43
      y_im.next = -m
44
      ovfl_im = True
45
 
46
    else:
47
      y_im.next = a_im + b_im
48
      ovfl_im = False
49
 
50
    overflow.next = ovfl_re or ovfl_im
51
 
52
  return instances()
53
 
54
 
55
def csub(a_re, a_im, b_re, b_im, y_re, y_im, overflow, width=8):
56
 
57
  @always_comb
58
  def logic():
59
    m = 2**(width-1)
60
 
61
    #
62
    # Real value calculation
63
    if (a_re - b_re) >= m:
64
      y_re.next = m-1
65
      ovfl_re = True
66
 
67
    elif (a_re - b_re) < -m:
68
      y_re.next = -m
69
      ovfl_re = True
70
 
71
    else:
72
      y_re.next = a_re - b_re
73
      ovfl_re = False
74
 
75
    #
76
    # Imaginary add
77
    if (a_im - b_im) >= m:
78
      y_im.next = m-1
79
      ovfl_im = True
80
 
81
    elif (a_im - b_im) < -m:
82
      y_im.next = -m
83
      ovfl_im = True
84
 
85
    else:
86
      y_im.next = a_im - b_im
87
      ovfl_im = False
88
 
89
    overflow.next = ovfl_re or ovfl_im
90
 
91
  return instances()
92 31 dannori
 
93
 
94
def cmult(a_re, a_im, b_re, b_im, y_re, y_im, overflow):
95
  ''' Perform the complex multiplication of a * b = y
96
 
97
  This turns out to be:
98
 
99
  y_re = a_re * b_re - a_im * b_im
100
  y_im = a_re * b_im + a_im * b_re
101
 
102 32 dannori
  The output is expected to have at least the same width as the input.
103
  The products are scaled back to the input width and in case an extra
104
  bit would be needed due to the addition or subtraction, an overflow
105
  is signaled.
106 31 dannori
 
107 32 dannori
  At the moment the overflowing output is saturated to the respective
108
  limit, based on the input width. So a wider output width is not used
109
  with the current implementation.
110
 
111 31 dannori
  I/O pins:
112
  =========
113
  a         : input a
114
  b         : input b
115
  y         : output a * b
116
  overflow  : signal overflow
117
 
118
  '''
119
 
120
  @always_comb
121
  def logic():
122
 
123
    # use input width of a_re, assume a_im, b_re and b_im are the same
124
    width = len(a_re)
125
 
126
    # calculate min and max value range
127
    smin = -2**(width-1)
128 32 dannori
    smax = 2**(width-1)
129 31 dannori
 
130
    #print 'cmult input width: ', width
131
 
132
    prod_a = a_re * b_re
133
    prod_b = a_im * b_im
134
    prod_c = a_re * b_im
135
    prod_d = a_im * b_re
136
 
137
    # scaling back the product to stay on input width
138
    prod_a = prod_a >> width
139
    prod_b = prod_b >> width
140
    prod_c = prod_c >> width
141
    prod_d = prod_d >> width
142
 
143
    #print 'cmult in: ', a_re, a_im, b_re, b_im
144
    #print 'cmult prod: ', prod_a, prod_b, prod_c, prod_d
145
 
146
    prod_diff = prod_a - prod_b
147
    prod_sum = prod_c + prod_d
148
 
149
    ovfl = False
150
 
151
    if prod_sum >= smax:
152
      prod_sum = smax-1
153
      ovfl = True
154
 
155
    elif prod_sum < smin:
156
      prod_sum = smin
157
      ovfl = True
158
 
159
    if prod_diff >= smax:
160
      prod_diff = smax-1
161
      ovfl = True
162
    elif prod_diff < smin:
163
      prod_diff = smin
164
      ovfl = True
165
 
166
     # here we would need a bit growth, but only signal it as overflow
167
    y_re.next = prod_diff
168
    y_im.next = prod_sum
169
    overflow.next = ovfl
170
 
171
    #print 'cmult: a_re: %d, a_im: %d, b_re: %d, b_im: %d'%(
172
    #        a_re, a_im, b_re, b_im)
173
    #print 'cmult: y_re: %d, y_im: %d, overflow: %d'%(y_re, y_im,
174
    #    overflow)
175
 
176
  return instances()

powered by: WebSVN 2.1.0

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