URL
https://opencores.org/ocsvn/dmt_tx/dmt_tx/trunk
Subversion Repositories dmt_tx
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 30 to Rev 31
- ↔ Reverse comparison
Rev 30 → Rev 31
/dmt_tx/trunk/myhdl/test/test_cmath.py
4,7 → 4,7
from myhdl import * |
|
|
from rtl.cmath import cadd, csub |
from rtl.cmath import cadd, csub, cmult |
|
class TestCplxMath(unittest.TestCase): |
|
154,4 → 154,86
|
|
def test_cmult(self): |
pass |
'''Verify complex multiplier''' |
|
def bench(): |
width = 4 |
owidth = width |
|
umax = 2**width -1 |
smax = 2**(width-1)-1 |
smin = -2**(width-1) |
#print 'cmult in value range: ', smin, smax |
|
osmax = 2**(owidth-1)-1 |
osmin = -2**(owidth-1) |
#print 'cmult out value range: ', osmin, osmax |
|
a_re, a_im, b_re, b_im = [Signal(intbv(0, min=smin, max=smax)) \ |
for i in range(4)] |
y_re, y_im = [Signal(intbv(0, min=osmin, max=osmax)) \ |
for i in range(2)] |
overflow = Signal(bool(0)) |
|
cmult_inst = cmult(a_re, a_im, b_re, b_im, y_re, y_im, overflow) |
|
|
@instance |
def stimulus(): |
a_re.next = 0 |
a_im.next = 0 |
b_re.next = 0 |
b_im.next = 0 |
yield delay(10) |
|
for ar in range(smin, smax): |
for ai in range(smin, smax): |
for br in range(smin, smax): |
for bi in range(smin, smax): |
|
# calculate expected values |
prod_a = (ar * br) >> width |
prod_b = (ai * bi) >> width |
prod_c = (ai * br) >> width |
prod_d = (ar * bi) >> width |
|
re = prod_a - prod_b |
im = prod_c + prod_d |
|
exp_ovfl = False |
|
# test expected overflow |
if re >= smax: |
exp_ovfl = True |
elif re < smin: |
exp_ovfl = True |
|
if im >= smax: |
exp_ovfl = True |
elif im < smin: |
exp_ovfl = True |
|
a_re.next = ar |
a_im.next = ai |
b_re.next = br |
b_im.next = bi |
|
yield delay(1) |
|
self.assertEqual(overflow, exp_ovfl) |
|
if not overflow: |
self.assertEqual(y_re, re) |
self.assertEqual(y_im, im) |
|
yield delay(10) |
|
raise StopSimulation |
|
return instances() |
|
############################### |
tb = bench() |
sim = Simulation(tb) |
sim.run() |
|
/dmt_tx/trunk/myhdl/rtl/cmath.py
89,3 → 89,80
overflow.next = ovfl_re or ovfl_im |
|
return instances() |
|
|
def cmult(a_re, a_im, b_re, b_im, y_re, y_im, overflow): |
''' Perform the complex multiplication of a * b = y |
|
This turns out to be: |
|
y_re = a_re * b_re - a_im * b_im |
y_im = a_re * b_im + a_im * b_re |
|
|
I/O pins: |
========= |
a : input a |
b : input b |
y : output a * b |
overflow : signal overflow |
|
''' |
|
@always_comb |
def logic(): |
|
# use input width of a_re, assume a_im, b_re and b_im are the same |
width = len(a_re) |
|
# calculate min and max value range |
smin = -2**(width-1) |
smax = 2**(width-1)-1 |
|
#print 'cmult input width: ', width |
|
prod_a = a_re * b_re |
prod_b = a_im * b_im |
prod_c = a_re * b_im |
prod_d = a_im * b_re |
|
# scaling back the product to stay on input width |
prod_a = prod_a >> width |
prod_b = prod_b >> width |
prod_c = prod_c >> width |
prod_d = prod_d >> width |
|
#print 'cmult in: ', a_re, a_im, b_re, b_im |
#print 'cmult prod: ', prod_a, prod_b, prod_c, prod_d |
|
prod_diff = prod_a - prod_b |
prod_sum = prod_c + prod_d |
|
ovfl = False |
|
if prod_sum >= smax: |
prod_sum = smax-1 |
ovfl = True |
|
elif prod_sum < smin: |
prod_sum = smin |
ovfl = True |
|
if prod_diff >= smax: |
prod_diff = smax-1 |
ovfl = True |
elif prod_diff < smin: |
prod_diff = smin |
ovfl = True |
|
# here we would need a bit growth, but only signal it as overflow |
y_re.next = prod_diff |
y_im.next = prod_sum |
overflow.next = ovfl |
|
#print 'cmult: a_re: %d, a_im: %d, b_re: %d, b_im: %d'%( |
# a_re, a_im, b_re, b_im) |
#print 'cmult: y_re: %d, y_im: %d, overflow: %d'%(y_re, y_im, |
# overflow) |
|
return instances() |