Last active
December 28, 2015 19:58
-
-
Save cs150bf/7553585 to your computer and use it in GitHub Desktop.
FFT Unscrambling in Software
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
% % | |
% Center for Astronomy Signal Processing and Electronics Research % | |
% http://seti.ssl.berkeley.edu/casper/ % | |
% Copyright (C) 2007 Terry Filiba, Aaron Parsons % | |
% Copyright (C) 2010 Hong Chen % | |
% % | |
% This program 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 2 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, write to the Free Software Foundation, Inc., % | |
% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. % | |
% % | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
function fft_init(blk, varargin) | |
% Initialize and configure the complex FFT. | |
% | |
% fft_init(blk, varargin) | |
% | |
% blk = The block to configure. | |
% varargin = {'varname', 'value', ...} pairs | |
% | |
% Valid varnames for this block are: | |
% FFTSize = Size of the FFT (2^FFTSize points). | |
% input_bit_width = Bit width of input and output data. | |
% coeff_bit_width = Bit width of coefficients. | |
% n_inputs = Number of parallel input streams | |
% quantization = Quantization behavior. | |
% overflow = Overflow behavior. | |
% add_latency = The latency of adders in the system. | |
% mult_latency = The latency of multipliers in the system. | |
% bram_latency = The latency of BRAM in the system. | |
% Declare any default values for arguments you might like. | |
defaults = {}; | |
if same_state(blk, 'defaults', defaults, varargin{:}), return, end | |
check_mask_type(blk, 'fft'); | |
munge_block(blk, varargin{:}); | |
FFTSize = get_var('FFTSize', 'defaults', defaults, varargin{:}); | |
input_bit_width = get_var('input_bit_width', 'defaults', defaults, varargin{:}); | |
coeff_bit_width = get_var('coeff_bit_width', 'defaults', defaults, varargin{:}); | |
n_inputs = get_var('n_inputs', 'defaults', defaults, varargin{:}); | |
quantization = get_var('quantization', 'defaults', defaults, varargin{:}); | |
overflow = get_var('overflow', 'defaults', defaults, varargin{:}); | |
add_latency = get_var('add_latency', 'defaults', defaults, varargin{:}); | |
mult_latency = get_var('mult_latency', 'defaults', defaults, varargin{:}); | |
bram_latency = get_var('bram_latency', 'defaults', defaults, varargin{:}); | |
arch = get_var('arch', 'defaults', defaults, varargin{:}); | |
opt_target = get_var('opt_target', 'defaults', defaults, varargin{:}); | |
coeffs_bit_limit = get_var('coeffs_bit_limit', 'defaults', defaults, varargin{:}); | |
delays_bit_limit = get_var('delays_bit_limit', 'defaults', defaults, varargin{:}); | |
specify_mult = get_var('specify_mult', 'defaults', defaults, varargin{:}); | |
mult_spec = get_var('mult_spec', 'defaults', defaults, varargin{:}); | |
dsp48_adders = get_var('dsp48_adders', 'defaults', defaults, varargin{:}); | |
unscrambler_active = get_var('unscrambler_active', 'defaults', defaults, varargin{:}); | |
if( strcmp(specify_mult, 'on') && length(mult_spec) ~= FFTSize ), | |
error('fft_init.m: Multiplier use specification for stages does not match FFT size'); | |
return | |
end | |
biplexes = find_system(blk, 'lookUnderMasks', 'all', 'FollowLinks','on','masktype', 'fft_biplex'); | |
outports = find_system(blk, 'lookUnderMasks', 'on', 'FollowLinks','on','SearchDepth',1,'BlockType', 'Outport'); | |
num_biplexes = length(biplexes); | |
num_outports = length(outports); | |
delete_lines(blk); | |
% Add Ports | |
reuse_block(blk, 'sync', 'built-in/inport', 'Position', [30 32 60 48], 'Port', '1'); | |
reuse_block(blk, 'shift', 'built-in/inport', 'Position', [30 82 60 98], 'Port', '2'); | |
reuse_block(blk, 'sync_out', 'built-in/outport', 'Position', [725 35 755 50], 'Port', '1'); | |
if n_inputs < 1, | |
reuse_block(blk, 'pol0', 'built-in/inport', 'Position', [30 100 60 115], 'Port', '3'); | |
reuse_block(blk, 'pol1', 'built-in/inport', 'Position', [30 200 60 215], 'Port', '4'); | |
reuse_block(blk, 'out0', 'built-in/outport', 'Position', [725 100 755 115], 'Port', '2'); | |
reuse_block(blk, 'out1', 'built-in/outport', 'Position', [725 200 755 215], 'Port', '3'); | |
reuse_block(blk, 'of', 'built-in/outport', 'Position', [725 300 755 315], 'Port', '4'); | |
else, | |
for i=0:2^n_inputs-1, | |
reuse_block(blk, ['in',num2str(i)], 'built-in/inport', 'Position', [30 45*i+125 60 45*i+140], 'Port', num2str(i+3)); | |
reuse_block(blk, ['out',num2str(i)], 'built-in/outport', 'Position', [725 45*i+80 755 45*i+100], 'Port', num2str(i+2)); | |
end | |
reuse_block(blk, 'of', 'built-in/outport', 'Position', [725 45*(2^n_inputs)+120 755 45*(2^n_inputs)+135], 'Port', num2str(2^n_inputs+2)); | |
end | |
% Add biplex FFTs | |
if n_inputs < 1, | |
pos = [100 100 220 255]; | |
name = 'fft_biplex0'; | |
reuse_block(blk, name, 'casper_library/FFTs/fft_biplex', ... | |
'FFTSize', num2str(FFTSize-n_inputs), 'input_bit_width', tostring(input_bit_width), ... | |
'coeff_bit_width', tostring(coeff_bit_width), 'add_latency', tostring(add_latency), ... | |
'mult_latency', tostring(mult_latency), 'bram_latency', tostring(bram_latency), ... | |
'quantization', tostring(quantization), 'overflow', tostring(overflow), ... | |
'arch', tostring(arch), 'opt_target', tostring(opt_target), ... | |
'coeffs_bit_limit', tostring(coeffs_bit_limit), ... | |
'delays_bit_limit', tostring(delays_bit_limit), ... | |
'Position', pos); | |
add_line(blk, 'pol0/1', [name,'/1']); | |
add_line(blk, 'pol1/1', [name,'/2']); | |
add_line(blk, 'shift/1', [name,'/4']); | |
add_line(blk, 'sync/1', [name,'/3']); | |
elseif n_inputs ~= FFTSize, | |
reuse_block(blk, 'of_or', 'xbsIndex_r4/Logical', ... | |
'logical_function', 'OR', 'inputs', tostring(2^(n_inputs-1)+1), 'latency', '1', ... | |
'Position', [575 210 625 200+(2^n_inputs)*20]); | |
for i=0:2^(n_inputs-1)-1, | |
pos = [100 200*i+100 220 200*i+255]; | |
name = ['fft_biplex',num2str(i)]; | |
reuse_block(blk, name, 'casper_library/FFTs/fft_biplex', ... | |
'FFTSize', num2str(FFTSize-n_inputs), 'input_bit_width', tostring(input_bit_width), ... | |
'coeff_bit_width', tostring(coeff_bit_width), 'add_latency', tostring(add_latency), ... | |
'mult_latency', tostring(mult_latency), 'bram_latency', tostring(bram_latency), ... | |
'quantization', tostring(quantization), 'overflow', tostring(overflow), ... | |
'arch', tostring(arch), 'opt_target', tostring(opt_target), ... | |
'coeffs_bit_limit', tostring(coeffs_bit_limit), ... | |
'delays_bit_limit', tostring(delays_bit_limit), ... | |
'Position', pos); | |
add_line(blk, ['in',num2str(2*i),'/1'], [name,'/1']); | |
add_line(blk, ['in',num2str(2*i+1),'/1'], [name,'/2']); | |
add_line(blk, 'shift/1', [name,'/4']); | |
add_line(blk, 'sync/1', [name,'/3']); | |
add_line(blk, [name,'/3'], ['of_or/',num2str(i+2)]); | |
end | |
end | |
% Add direct FFTs | |
if n_inputs < 1, | |
add_line(blk, 'fft_biplex0/1', 'out0/1'); | |
add_line(blk, 'fft_biplex0/2', 'out1/1'); | |
add_line(blk, 'fft_biplex0/4', 'sync_out/1'); | |
add_line(blk, 'fft_biplex0/3', 'of/1') | |
elseif n_inputs == FFTSize, | |
pos = [400 20 520 175]; | |
reuse_block(blk, 'fft_direct', 'casper_library/FFTs/fft_direct', ... | |
'FFTSize', num2str(n_inputs), 'input_bit_width', tostring(input_bit_width), ... | |
'coeff_bit_width', tostring(coeff_bit_width), 'add_latency', tostring(add_latency), ... | |
'mult_latency', tostring(mult_latency), 'bram_latency', tostring(bram_latency), ... | |
'quantization', tostring(quantization), 'overflow', tostring(overflow), ... | |
'arch', tostring(arch), 'opt_target', tostring(opt_target), ... | |
'coeffs_bit_limit', tostring(coeffs_bit_limit), ... | |
'map_tail', 'off', 'Position', pos); | |
add_line(blk, 'sync/1', 'fft_direct/1'); | |
add_line(blk, 'shift/1', 'fft_direct/2'); | |
add_line(blk, 'fft_direct/1', 'sync_out/1'); | |
for i=0:2^n_inputs-1, | |
add_line(blk, ['in',num2str(i),'/1'], ['fft_direct/',num2str(i+3)]); | |
add_line(blk, ['fft_direct/',num2str(i+2)], ['out',num2str(i),'/1']); | |
end | |
add_line(blk, ['fft_direct/',num2str(2^n_inputs+3-1)], 'of/1'); | |
else, | |
pos = [400 20 520 175]; | |
reuse_block(blk, 'fft_direct', 'casper_library/FFTs/fft_direct', ... | |
'FFTSize', num2str(n_inputs), 'map_tail', 'on', ... | |
'input_bit_width', tostring(input_bit_width), ... | |
'coeff_bit_width', tostring(coeff_bit_width), 'add_latency', tostring(add_latency), ... | |
'mult_latency', tostring(mult_latency), 'bram_latency', tostring(bram_latency), ... | |
'quantization', tostring(quantization), 'overflow', tostring(overflow), ... | |
'LargerFFTSize', num2str(FFTSize), 'StartStage', num2str(FFTSize-n_inputs+1), ... | |
'arch', tostring(arch), 'opt_target', tostring(opt_target), ... | |
'coeffs_bit_limit', tostring(coeffs_bit_limit), ... | |
'Position', pos); | |
reuse_block(blk, 'slice', 'xbsIndex_r4/Slice', ... | |
'mode', 'Lower Bit Location + Width', 'bit0', num2str(FFTSize-n_inputs), 'nbits', num2str(n_inputs), ... | |
'Position', [100 82 130 100]); | |
add_line(blk, 'shift/1', 'slice/1'); | |
add_line(blk, 'slice/1', 'fft_direct/2'); | |
add_line(blk, 'fft_biplex0/4', 'fft_direct/1'); | |
for i=0:2^(n_inputs-1)-1, | |
bi_name = ['fft_biplex',num2str(i)]; | |
add_line(blk, [bi_name,'/1'], ['fft_direct/',num2str(3+2*i)]); | |
add_line(blk, [bi_name,'/2'], ['fft_direct/',num2str(3+2*i+1)]); | |
end | |
%add overflow | |
add_line(blk, ['fft_direct/',num2str(2^n_inputs+3-1)], 'of_or/1'); | |
add_line(blk, 'of_or/1', 'of/1'); | |
% Add Unscrambler | |
reuse_block(blk, 'fft_unscrambler', 'casper_library/FFTs/fft_unscrambler', ... | |
'FFTSize', num2str(FFTSize), 'n_inputs', num2str(n_inputs), 'bram_latency', num2str(bram_latency), 'unscrambler_active', tostring(unscrambler_active), ... | |
'Position', [550 20 670 160]); % No.2 | |
for i=1:2^n_inputs+1, | |
add_line(blk, ['fft_direct/',num2str(i)], ['fft_unscrambler/',num2str(i)]); | |
if i==1, add_line(blk, ['fft_unscrambler/',num2str(i)], 'sync_out/1'); | |
else, add_line(blk, ['fft_unscrambler/',num2str(i)], ['out',num2str(i-2),'/1']); | |
end | |
end | |
end | |
% Propagate dynamic variables | |
vec_biplex = 2.*ones(1, FFTSize-n_inputs); | |
vec_direct = 2.*ones(1, n_inputs); | |
if strcmp(specify_mult, 'on'), | |
%generate vectors of multiplier use from vectors passed in | |
vec_biplex(1:FFTSize-n_inputs) = mult_spec(1: FFTSize-n_inputs); | |
vec_direct = mult_spec(FFTSize-n_inputs+1:FFTSize); | |
end | |
if n_inputs < 1, | |
name = [blk,'/fft_biplex0']; | |
set_param(name, 'dsp48_adders', tostring(dsp48_adders), ... | |
'specify_mult', tostring(specify_mult), 'mult_spec', tostring(vec_biplex)); | |
else, | |
if n_inputs ~= FFTSize, | |
for i=0:2^(n_inputs-1)-1, | |
name = [blk,'/fft_biplex',num2str(i)]; | |
set_param(name, 'dsp48_adders', tostring(dsp48_adders), ... | |
'specify_mult', tostring(specify_mult), 'mult_spec', tostring(vec_biplex)); | |
end | |
end | |
name = [blk,'/fft_direct']; | |
set_param(name, 'dsp48_adders', tostring(dsp48_adders), ... | |
'specify_mult', tostring(specify_mult), 'mult_spec', tostring(vec_direct)); | |
end | |
clean_blocks(blk); | |
fmtstr = sprintf('FFTSize=%d, n_inputs=%d', FFTSize, n_inputs); | |
set_param(blk, 'AttributesFormatString', fmtstr); | |
save_state(blk, 'defaults', defaults, varargin{:}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
% % | |
% Center for Astronomy Signal Processing and Electronics Research % | |
% http://seti.ssl.berkeley.edu/casper/ % | |
% Copyright (C) 2007 Terry Filiba, Aaron Parsons % | |
% Copyright (C) 2010 Hong Chen % | |
% % | |
% This program 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 2 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, write to the Free Software Foundation, Inc., % | |
% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. % | |
% % | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
function fft_unscrambler_init(blk, varargin) | |
% Initialize and configure the FFT unscrambler. | |
% | |
% fft_unscrambler_init(blk, varargin) | |
% | |
% blk = The block to configure. | |
% varargin = {'varname', 'value', ...} pairs | |
% | |
% Valid varnames for this block are: | |
% FFTSize = Size of the FFT (2^FFTSize points). | |
% n_inputs = Number of parallel input streams | |
% bram_latency = The latency of BRAM in the system. | |
% Declare any default values for arguments you might like. | |
defaults = {}; | |
if same_state(blk, 'defaults', defaults, varargin{:}), return, end | |
check_mask_type(blk, 'fft_unscrambler'); | |
munge_block(blk, varargin{:}); | |
FFTSize = get_var('FFTSize', 'defaults', defaults, varargin{:}); | |
n_inputs = get_var('n_inputs', 'defaults', defaults, varargin{:}); | |
bram_latency = get_var('bram_latency', 'defaults', defaults, varargin{:}); | |
unscrambler_active = get_var('unscrambler_active', 'defaults', defaults, varargin{:}); | |
if n_inputs >= FFTSize - 2, | |
errordlg('FFT Unscrambler: 2^n_inputs must be < 2^(FFT size-2).'); | |
end | |
part_mat = [0:2^(FFTSize-2*n_inputs)-1]*2^(n_inputs); | |
map_mat = []; | |
for i=0:2^n_inputs-1, | |
map_mat = [map_mat, part_mat+i]; | |
end | |
map_str = tostring(map_mat); | |
delete_lines(blk); | |
% Add ports | |
reuse_block(blk, 'sync', 'built-in/inport', 'Position', [30 60 60 74], 'Port', '1'); | |
reuse_block(blk, 'sync_out', 'built-in/outport', 'Position', [500 40 530 54], 'Port', '1'); | |
for i=1:2^n_inputs, | |
reuse_block(blk, ['In',num2str(i)], 'built-in/inport', 'Position', [30 20*i+60 60 20*i+74], 'Port', num2str(i+1)); | |
reuse_block(blk, ['Out',num2str(i)], 'built-in/outport', 'Position', [500 55*i+40 530 55*i+54], 'Port', num2str(i+1)); | |
end | |
if strcmp(unscrambler_active,'on'), | |
% Just do whatever old FFT block would do | |
% Add static blocks | |
reuse_block(blk, 'square_transposer', 'casper_library/Reorder/square_transposer', ... | |
'n_inputs', num2str(n_inputs), 'Position', [85 30 170 2^n_inputs*20+80]); | |
reuse_block(blk, 'reorder', 'casper_library/Reorder/reorder', ... | |
'map', map_str, 'bram_latency', num2str(bram_latency), ... | |
'n_inputs', num2str(2^n_inputs), 'map_latency', num2str(1),... | |
'double_buffer', '0',... | |
'Position', [265 37 360 93]); | |
reuse_block(blk, 'const', 'xbsIndex_r4/Constant', ... | |
'arith_type', 'Boolean', 'explicit_period', 'on', 'Position', [225 57 250 73]); | |
% Add static lines | |
add_line(blk, 'sync/1', 'square_transposer/1'); | |
add_line(blk, 'square_transposer/1', 'reorder/1'); | |
add_line(blk, 'reorder/1', 'sync_out/1'); | |
add_line(blk, 'const/1', 'reorder/2'); | |
% Add dynamic lines | |
for i=1:2^n_inputs, | |
in_name = ['In',num2str(i)]; | |
out_name = ['Out',num2str(i)]; | |
add_line(blk, [in_name,'/1'], ['square_transposer/',num2str(i+1)]); | |
add_line(blk, ['square_transposer/',num2str(i+1)], ['reorder/',num2str(i+2)]); | |
add_line(blk, ['reorder/',num2str(i+2)], [out_name,'/1']); | |
end | |
else | |
% Instead of add square_transposer block and reorder block, add delay blocks | |
% And output a file as well as print instructions on screen | |
% tell users how to do square transpose and reorder in software | |
% Add static blocks | |
map_order=compute_order(map_mat); | |
reuse_block(blk, 'delay0', 'xbsIndex_r4/Delay', ... | |
'latency', num2str(bram_latency+1+(map_order-1)*1+length(map_mat)+5), ... | |
'Position', [265 37 290 50]); | |
% Add dynamic blocks | |
for i=1:2^n_inputs, | |
reuse_block(blk,['delay', num2str(i)], 'xbsIndex_r4/Delay', ... | |
'latency',num2str(bram_latency+1+(map_order-1)*1+length(map_mat)+5), .. | |
'Position', [265 i*25+50, 295, i*25+63]); | |
end | |
% Add static lines | |
add_line(blk, 'sync/1', 'delay0/1'); | |
add_line(blk, 'delay0/1', 'sync_out/1'); | |
% Add dynamic lines | |
for i=1:2^n_inputs, | |
in_name = ['In',num2str(i)]; | |
out_name = ['Out',num2str(i)]; | |
add_line(blk, [in_name,'/1'], ['delay', num2str(i),'/1']); | |
add_line(blk, ['delay', num2str(i), '/1'], [out_name,'/1']); | |
end | |
fileID=fopen('reorder.m','w'); | |
line1='% reorder'; | |
line2='% Permutes a vector of samples to into the desired order. '; | |
line3='% map = The desired output order.'; | |
line4='function out = reorder(map,input)'; | |
line5='s = size(input);'; | |
line6='L = s(2);'; | |
line7='w = s(1);'; | |
line8='out_temp=zeros(w,L);'; | |
line9='for k=1:2,'; | |
line10='\tfor l=1:L,'; | |
line11='\t\tout_temp(k,l)=uint32(input(k,l));'; | |
line12='\tend;'; | |
line13='end;'; | |
line14='for k=3:w,'; | |
line15='\tfor i=1:L,'; | |
line16='\t\tmap_ind=mod(i,map_length);'; | |
line17='\t\tif map_ind==0,'; | |
line18='\t\t\tind=map(map_length)-map_length;'; | |
line19='\t\telse'; | |
line20='\t\t\tind=map(map_ind);'; | |
line21='\t\tend;'; | |
line22='\t\tif map_length*(idivide(i,map_length))+ind+1>L,'; | |
line23='\t\t\tcontinue;'; | |
line24='\t\telse'; | |
line25='\t\t\tout_temp(k,i)=uint32(input(k,map_length*(idivide(i,map_length))+ind+1));'; | |
line26='\t\tend;'; | |
line27='\tend;'; | |
line28='end;'; | |
line29='out = out_temp;'; | |
out_format=''; | |
for i=1:29, | |
out_format=strcat(out_format,'%s\n'); | |
end; | |
out_format=strcat(out_format,'\n'); | |
fprintf(fileID,out_format,line1,line2,line3,line4, ... | |
line5,line6,line7,line8,line9,line10,line11,line12,line13, ... | |
line14,line15,line16,line17,line18,line19,line20,line21,line22, ... | |
line23,line24,line25,line26,line27,line28,line29); | |
fclose(fileID); | |
fprintf(1,'m=%s\n',map_str); | |
fprintf(1,out_format,line1,line2,line3,line4,line5, ... | |
line5,line6,line7,line8,line9,line10,line11,line12,line13, ... | |
line14,line15,line16,line17,line18,line19,line20,line21,line22, ... | |
line23,line24,line25,line26,line27,line28,line29); | |
end | |
clean_blocks(blk); | |
fmtstr = sprintf('FFTSize=%d, n_inputs=%d', FFTSize, n_inputs); | |
set_param(blk, 'AttributesFormatString', fmtstr); | |
save_state(blk, 'defaults', defaults, varargin{:}); | |
%%%%%% End of fft_unscrambler_init.m %%%%%%%%%%%%%%%%%% |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
reorder_block = find_system(gcb, ‘lookUnderMasks’, ‘all’, ‘FollowLinks’, ‘on’, ‘SearchDepth’, 2, ‘Name’, ‘reorder’) | |
map = get_param(reorder_block, ‘map’) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
These code were written in 2010 trying to modify the CASPER library and make the "Unscramble" option in FFT (complex) blocks optional. The memo describing this process is at - https://drive.google.com/file/d/1qsmW965nrVnAMkiKumTIdqMEaGDK0hechbji_I5gohqrbxGuUBZyUDP7Z-RK/edit?usp=sharing (Written in Summer 2010 with slight revision in October 2013). | |
Google doc version of fft_init.m, with related changes highlighted is availble at - https://docs.google.com/document/pub?id=1rd4XtOVeFQZ0cYhMqB3m5uoPSdkPAXcNaGGQUtxdD2k | |
Google doc version of fft_unscramble_init.m, with related changes highlighted is availble at - https://docs.google.com/document/pub?id=1Tq0SjqQyVQIev6N41YnVwKVjNE_-NRVg4kl6A0VrwKM | |
A quick note on software unscrambing is at - https://docs.google.com/document/d/13TU2CqZM3NziDy4LkQwGHzmg3azJlARHUGoPtQA80SU/edit?usp=sharing (No change made to the library or _init.m scripts - the unscramble on/off function is available for current fft blocks in current Casper library - September 2013 commit) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function output = unscramble(map, input,start_row) | |
% Written in Summer 2010 by Hong Chen | |
% Apologies for the messiness | |
% unscramble | |
% combine square_transpose and reorder | |
% map = The desired output order. | |
% start_row is the row from which we start to apply the vector permutation | |
% The assumed input data format (the 'input' parameter of this function - sorry | |
% for the sloppiness) of this function is a 2-D vector with | |
% first column corresponding to the first output port of fft block (complex), | |
% second column corresponding to the second output port, etc. And the first few rows | |
% (row 1 to start_row) should be discarded (check with the sync_out signal). | |
% ------------ Square Transposing --------------- | |
real_input = input(start_row:end,1:end); % exclude first few rows that we don't want to permute | |
map_length = int32(length(map)); | |
s = size(real_input); | |
L = s(2); | |
w = s(1); | |
k = w+1; | |
square_transposed=real_input(1:end,1:k-1)'; | |
while (k+w-1)<=L, | |
square_transposed = [square_transposed,real_input(1:end,k:k+w-1)']; | |
k=k+w; | |
end; | |
if k <= L, | |
comp1 = real_input(1:end,k:end); | |
sc = size(comp1); | |
len = L - k +1; | |
wc = sc(1); | |
comp2 = zeros(w-wc,len); | |
comp=[comp1(1:end,1:len);comp2]; | |
square_transposed=[square_transposed,comp]; | |
end; | |
square_transposed=[input(1:start_row-1,1:end);square_transposed]; | |
% ------------ Reordering --------------- | |
S=size(input); | |
W=S(1); | |
out_temp=zeros(W,L); | |
for k=1:start_row-1, | |
for l=1:L, | |
out_temp(k,l)=uint32(square_transposed(k,l)); | |
end; | |
end; | |
for k=start_row:W, | |
for i=1:L, | |
map_ind=mod(i,map_length); | |
if map_ind==0, | |
ind=map(map_length)-map_length; | |
else | |
ind=map(map_ind); | |
end; | |
if map_length*(idivide(i,map_length))+ind+1>L, | |
continue; | |
else | |
out_temp(k,i)=uint32(square_transposed(k,map_length*(idivide(i,map_length))+ind+1)); | |
end; | |
end; | |
end; | |
% ------------ Done --------------- | |
output=out_temp; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment