#!/usr/bin/env python from myhdl import * def cplxMult(a_i, b_i, y_o, WIDTH): '''Compute the complex multiply of a * b (a+jb) * (c+jd) = (ac-bd +j bc+ad) I/O pins: ========= a_i : operand a, with the upper half being the real value and the lower bits the imaginary value b_i : operand b, with the upper half being the real value and the lower bits the imaginary value y_o : result of complex multiply a * b with the upper half being the real value and the lower bits the imaginary value. The bit width is input bit width + 2 Parameters: =========== WIDTH : bit width of a_i and b_i. The output bit width needs to be 2 * WIDTH + 2. WIDTH needs to be an even number and the real and imaginary value of input a_i and b_i are each WIDTH/2 bit wide. ''' smin = -2**(WIDTH-1) smax = 2**(WIDTH-1)-1 ac, bd, bc, ad = [Signal(intbv(0, min=smin, max=smax+1)) for i in range(4)] @always_comb def mult_logic(): ac.next = a_i[WIDTH:WIDTH//2].signed() * b_i[WIDTH:WIDTH//2].signed() bd.next = a_i[WIDTH//2:].signed() * b_i[WIDTH//2:].signed() bc.next = b_i[WIDTH:WIDTH//2].signed() * a_i[WIDTH//2:].signed() ad.next = b_i[WIDTH//2:].signed() * a_i[WIDTH:WIDTH//2].signed() @always_comb def add_sub_logic(): y_o.next = concat( intbv(ac - bd)[WIDTH+1:], intbv(bc + ad)[WIDTH+1:] ) return instances() ######################################################################## def convert(): DWIDTH = 2 IWIDTH = 2 * DWIDTH OWIDTH = 2 * IWIDTH + 2 a_i, b_i = [Signal(intbv(0)[IWIDTH:]) for i in range(2)] y_o = Signal(intbv(0)[OWIDTH:]) toVerilog(cplxMult, a_i, b_i, y_o, IWIDTH) toVHDL(cplxMult, a_i, b_i, y_o, IWIDTH) if __name__ == '__main__': convert()