OpenCores
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()

powered by: WebSVN 2.1.0

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