Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 217 additions & 0 deletions wrappers/simulink/par_twiddle_factors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# Twiddle Generator :
# generates the complex Twiddles in B_ bit Binary format
# and writes VHDL package for R2SDF architecture implementation.
# -------------------------------------------------------------------------#
# Author: Raj Thilak Rajan:rajan at astron.nl: Nov 2009
# Copyright (C) 2009-2010
# ASTRON (Netherlands Institute for Radio Astronomy)
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This file is part of the UniBoard software suite.
# The file is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# -------------------------------------------------------------------------#
#
import os
from datetime import datetime
import numpy as np


def par_twiddle_pkg_gen(Np, Nb, destfolder):
# 'twiddle defintion'
w = np.exp(-1j * (2 * np.pi / Np))

W = w ** (np.arange(0, Np)[:, None] * np.arange(0, Np))

Wr = np.real(W) # Wr
Wi = np.imag(W) # Wi

# 'binary weights'
S_ = 2 ** (Nb - 1) - 1 # Binary scaling
sdfWr = Wr[0:(Np//2), 1] * S_ # Wr scaled W_0 to W_(Np/2)
sdfWi = Wi[0:(Np//2), 1] * S_ # Wi scaled W_0 to W_(Np/2)
print(sdfWr)
print(sdfWi)

# 'dec to binary: 2s complement'
wRe = []
wIm = []
for ii in range(sdfWr.shape[0]):
wRe.append(dec2bit(sdfWr[ii], Nb))
wIm.append(dec2bit(sdfWi[ii], Nb))

# 'obtain twiddle map'
wMap = getTwiddleMap(Np) + 1 # for R2SDF

# 'writing vhdl file'
writeTwiddlePkg(wRe, wIm, wMap, destfolder) # write weights and index into VHDL


def getTwiddleMap(N):
m = int(np.log2(N)) # number of stages
wMap = np.zeros((N//2, m)) # init Map

wMap[:, 0] = np.arange(0, (N//2))
for ii in range(1, m):
wMap[:, ii] = 2 * (wMap[:, ii - 1] % (N//4))

# wMap((N/2)+1:N,:)= wMap(1:N/2,:)
return wMap


def dec2bin(dec, bits):
assert(dec >= 0)
return f"{{:0{bits}b}}".format(dec)


def dec2bit(dec, bits):
if dec >= 0:
dec = int(np.floor(dec))
out = f"0{dec2bin(dec,bits-1)}"
else:
dec = int(np.round(dec))
const = 2 ** (bits - 1) - 1
out = f"1{dec2bin(const-abs(dec),bits-1)}"
return out


# Write Twiddles to VHDL
# writes twiddles and meta data into a VHDL package
# -------------------------------------------------------------------------#
# Author: Raj Thilak Rajan:rajan at astron.nl: Nov 2009
# Copyright (C) 2009-2010
# ASTRON (Netherlands Institute for Radio Astronomy):
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This file is part of the UniBoard software suite.
# The file is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.:
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# -------------------------------------------------------------------------#


def writeTwiddlePkg(w_re, w_im, wMap, destfolder):

Np = 2 * len(w_re)
print("Np", Np)
Nb = len(w_re[0])
print("Nb", Nb)

WRITE_RAW_TWIDDLES = 1
WRITE_TWIDDLE_MATRIX = 1

# write vhdl pkg containing the twiddles
# --header--
with open(os.path.join(destfolder, "twiddlesPkg.vhd"), "w") as fid:

fid.write("-------------------------------------\n")
fid.write("--FILE GENERATED BY TWIDDLE GENERATOR\n")
fid.write("--DO NOT EDIT THIS FILE !!!\n")
fid.write("-------------------------------------\n")
fid.write("--Author :R.T.Rajan \n")
fid.write(f"--Date :{datetime.now()}\n")
fid.write(f"--Npoints :{str(Np)}\n")
fid.write(f"--Nbits :{str(Nb)}\n")
fid.write("-------------------------------------\n\n\n")
# -----------

# --libraries--
fid.write("Library ieee;\n")
fid.write("use ieee.std_logic_1164.all;\n")
fid.write("use ieee.numeric_std.all;\n\n")
# -------------

# --package--
fid.write("package twiddlesPkg is\n")
fid.write("\tconstant copyRightNotice: string\n")
fid.write('\t\t:= "Copyright 2009 , ASTRON. All rights reserved.";\n\n')
# -----------

# --types--
fid.write(f"\tsubtype wTyp is std_logic_vector({Nb-1} downto 0);\n")
fid.write(f"\ttype wRowTyp is array(1 to {Np//2}) of wTyp;\n")

fid.write(
f"\ttype wMapTyp is array(integer range 0 to {wMap.shape[0]-1}, integer range {wMap.shape[1]} downto 1) of natural;\n\n"
)
# --------

# --twiddles---
if WRITE_RAW_TWIDDLES:
if Np == 1:
fid.write("\tconstant wRe: wRowTyp :=\n\t(\n")
fid.write("\t\t")
fid.write(f'1=>b"{w_re[0]}"')
fid.write("\n\t);\n\n")
fid.write("\tconstant wIm: wRowTyp :=\n\t(\n")
fid.write("\t\t")
fid.write(f'1=>b"{w_im[0]}"')
fid.write("\n\t);\n\n")
else:
fid.write("\tconstant wRe: wRowTyp :=\n\t(\n")
for index in range((Np//2)-1):
fid.write("\t\t")
fid.write(f'b"{w_re[index]}",')
fid.write("\n")
fid.write(f'\t\tb"{w_re[(Np//2)-1]}"\n\t);\n\n')

fid.write("\tconstant wIm: wRowTyp :=\n\t(\n")
for index in range((Np//2)-1):
fid.write("\t\t")
fid.write(f'b"{w_im[index]}",')
fid.write("\n")
fid.write(f'\t\tb"{w_im[(Np//2)-1]}"\n\t);\n\n')

# ------------

# --twiddle map---
if WRITE_TWIDDLE_MATRIX:
if Np == 1:
fid.write("\tconstant wMap: wMapTyp :=\n\t(\n")
fid.write("\t\t0 => (1 => 1)\n")
fid.write("\t);\n")
else:
fid.write("\tconstant wMap: wMapTyp :=\n\t(\n")
for ii in range(wMap.shape[0]):
fid.write("\t\t(")
for jj in range(wMap.shape[1]):
if jj == wMap.shape[1]-1:
fid.write(f"{int(wMap[ii, jj])}")
else:
fid.write(f"{int(wMap[ii, jj])},")

if ii == wMap.shape[0]-1:
fid.write(")\n")
else:
fid.write("),\n")

fid.write("\t);\n\n")

# -----------------

# -- package--
fid.write("package twiddlesPkg;\n")


if __name__ == "__main__":
import sys
par_twiddle_pkg_gen(int(sys.argv[1]), int(sys.argv[2]), sys.argv[3])
Loading