Skip to content

Instantly share code, notes, and snippets.

@cs150bf
Last active December 28, 2015 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cs150bf/7553585 to your computer and use it in GitHub Desktop.
Save cs150bf/7553585 to your computer and use it in GitHub Desktop.
FFT Unscrambling in Software
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% 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{:});
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% 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 %%%%%%%%%%%%%%%%%%
reorder_block = find_system(gcb, ‘lookUnderMasks’, ‘all’, ‘FollowLinks’, ‘on’, ‘SearchDepth’, 2, ‘Name’, ‘reorder’)
map = get_param(reorder_block, ‘map’)
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)
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