Files
imdd_silas/Libs/move_it/prms_move_it.m

474 lines
17 KiB
Matlab

function [data_out ,state] = prms(data_in, state, para)
global loop loopmax
if nargin==0
if loop==-1,
% Abfrage der Ein- und Ausgnge
noinp=0 ;
noout=1;
% Zuordnung zu den Ausgangsvariablen
data_out=noinp;
state=noout;
else
% Parameterdefinition
para.bl=128;
comment.bl='Block length (Length of output vector)';
comment.short.bl='length';
comment.type.bl='number';
comment.level.bl=1;
para.rand=0 ;
comment.rand='Random (True) or pseudo-random (False)';
comment.short.rand='rand/prms';
comment.type.rand='boolean';
comment.level.rand=1;
para.dimension=2;
comment.dimension='dimension (i.e. number of parallel bit streams)';
comment.type.dimension='number';
comment.short.dimension='dimension';
comment.level.dimension=1;
para.order=2;
comment.order='order of PRMS (needs to be adapted to memory of DUT)';
comment.type.order='number';
comment.short.order='order';
comment.level.order=1;
para.skip=0;
comment.skip='Skip the first n Bits of sequence';
comment.type.skip='number';
comment.short.skip='skip';
comment.level.skip=1;
para.bruijn=1;
comment.bruijn='extends the PRBS sequence of length 2^n-1 to a deBruijn sequence of 2^n';
comment.type.bruijn='boolean';
comment.short.bruijn='deBruijn';
comment.level.bruijn=1;
para.reset_prms=0;
comment.reset_prms='reset the sequence generator every loop';
comment.type.reset_prms='boolean';
comment.short.reset_prms='Reset every loop';
comment.level.reset_prms=1;
para.method=1;
comment.method='false= old method , true = new method';
comment.type.method='Fast (c-file)|Slow (Matlab file)';
comment.short.method='method';
comment.level.method=1;
data_out=para;
state=comment;
end;
else
% Initialisierung
if loop==0,
% check for correct parameters
checkskalar(getfield(inputname(2),{1:length(inputname(2))-6}),para,[{'bl'} {'skip'} {'dimension'} {'order'}],...
[{'length'} {'skip'} {'dimension'} {'order'}]);
checkinteger(getfield(inputname(2),{1:length(inputname(2))-6}),para,[{'bl'} {'skip'} {'dimension'} {'order'}],...
[{'length'} {'skip'} {'dimension'} {'order'}]);
checkpos(getfield(inputname(2),{1:length(inputname(2))-6}),para,[{'bl'} {'skip'} {'dimension'} {'order'}],...
[{'length'} {'skip'} {'dimension'} {'order'}]);
% determine order of periodicity
% initializing of all state parameters
state.dimension = para.dimension;
state.order = para.order;
state.periodicity = para.dimension*para.order;
state.bl = para.bl;
state.reset_prms = para.reset_prms;
if ~para.rand % PRMS
%------------------------------------------------------------------
% prepare Matrix to map PRBS bits to PRMS values
%------------------------------------------------------------------
% create lookup-table for primitive element
if state.dimension>2,
% general case
bchpolynomial=zeros(1,state.dimension+1);
bchpolynomial([1 srgtaps(state.dimension)+1])=1;
betatable=fliplr(cyclgen_local(2^state.dimension-1,bchpolynomial).');
elseif state.dimension==2
% special case, by-hand solution
betatable=[0 1;1 0;1 1];
elseif state.dimension==1
% special case, by-hand solution
betatable=1;
end;
binvec = 2.^(state.dimension-1:-1:0);
modulo_mask = 2^state.dimension-1;
betatable_sort_forward = sum(repmat(binvec,2^state.dimension-1,1).*betatable,2);
[dummy,betatable_sort_inverse] = sort(betatable_sort_forward);
betatable_sort_inverse = betatable_sort_inverse-1;
% perform polynomial division by x+beta
dividend=zeros(state.dimension+1,2);
dividend([state.dimension-srgtaps(state.dimension)+1 end],1)=1;
h=zeros(state.dimension,2);
for digit=1:state.dimension,
% add new coefficient
h(digit,1:2)=dividend(digit,1:2);
dividend(digit,1:2)=[0 0];
% update dividend
newdiv_binary=xor(betatable(dividend(digit+1,2)+1,:)*dividend(digit+1,1),...
betatable(rem(h(digit,2)+1,modulo_mask)+1,:)*h(digit,1));
dividend(digit+1,1)=sum(newdiv_binary)>0;
% compute new dividend, exclude case of last iteration where
% dividend should end up with 0
if (digit~=state.dimension) && dividend(digit+1,1),
dividend(digit+1,2)=dividend(digit+1,1)*betatable_sort_inverse(sum(newdiv_binary.*binvec));
else
dividend(digit+1,2)=0;
end;
end;
% initialize the prms
% init parameters for deBruijn sequence
state.bruijn = para.bruijn;
state.bruijn_counter = -1;
if para.method == 1, %new way
% Initialize the PRBS registers
tmp_srgtaps = srgtaps(state.periodicity);
state.srgtaps = zeros(4,1,'int64');
mat_table = betatable(h(:,2)+1,:);
state.mat_table = int64(mat_table * 2.^(0:state.dimension-1)');
for n=1:length(tmp_srgtaps)
state.srgtaps(n)=int64(2^(tmp_srgtaps(n)-1));
end
tmp_reg = int64(2^49-1);
state.reg = zeros(state.dimension,1,'int64');
tmp_reg = prms_c(int32(1),tmp_reg,state.srgtaps);
state.reg(1)= tmp_reg;
offset = (2^state.periodicity-1)/modulo_mask;
for n=2:state.dimension
tmp_reg = prms_c(int32(offset),tmp_reg,state.srgtaps);
state.reg(n)= tmp_reg;
end
if para.skip>0
[prbs_register, bruijn, bruijn_counter,data_out ]= prms_c(int32(para.skip),...
state.reg,...
state.srgtaps,...
int32(state.order),...
state.mat_table,...
int32(state.bruijn),...
int64(state.bruijn_counter));
state.reg = prbs_register;
state.bruijn = bruijn;
state.bruijn_counter = bruijn_counter;
end
else
% Initialize the PRBS registers
state.reg = ones(1,state.periodicity);
state.srgtaps = srgtaps(state.periodicity);
state.mat_table = betatable(h(:,2)+1,:);
% determine indices into past PRBS
state.PRBS_inx=1+(0:state.dimension-1)*(2^state.periodicity-1)/modulo_mask;
% fill PRBS_memory by creating the first part of the PRBS
[state.reg,state.PRBS_memory]=prms_prbs_init_mex(state.periodicity,state.srgtaps,state.PRBS_inx(end));
% init for deBruijn sequence
% skip first bits
skipped=0;
PRBS_memory_pointer=0;
while skipped<para.skip,
% consider deBruijn symbol
if state.bruijn==2 && skipped>1,
skipped = skipped+1;
state.bruijn = 1;
continue;
end;
% compute current PRMS-symbol
PRBS_inx=mod(state.PRBS_inx+PRBS_memory_pointer-1,state.PRBS_inx(end))+1;
symbol_temp=rem(sum(repmat(double(state.PRBS_memory(PRBS_inx).'),1,state.dimension).*...
state.mat_table,1),2).';
% compute new PRBS_memory
state.reg=[rem(sum(state.reg(state.srgtaps)),2) state.reg(1:end-1)];
state.PRBS_memory(PRBS_memory_pointer+1)=state.reg(end);
PRBS_memory_pointer=mod(PRBS_memory_pointer+1,state.PRBS_inx(end));
skipped=skipped+1;
% consider deBruijn option
if state.bruijn==1,
if state.bruijn_counter<0,
% counter not yet locked
if any([~sum(symbol_temp) state.order==1]),
% zero symbol detected
state.bruijn_counter=state.bruijn_counter-1;
if any([state.bruijn_counter== -state.order state.order==1]),
% lock counter
state.bruijn_counter=2^state.periodicity-1;
state.bruijn=2;
end;
else
% no zero, so reset counter
state.bruijn_counter=-1;
end;
else
% counter already locked
state.bruijn_counter=state.bruijn_counter-1;
if state.bruijn_counter==0,
% reset counter
state.bruijn_counter = 2^state.periodicity-1;
state.bruijn=2;
end;
end;
end;
end;
end;
end
data_out=zeros(state.dimension,state.bl);
else
% Execution Stage
% update status window
% status(getfield(inputname(2),{1:length(inputname(2))-6}));
bl = state.bl;
if ~para.rand % PRMS
if para.method == 1 % fast implementation
[prbs_register, bruijn, bruijn_counter,data_out ]= prms_c(int32(state.bl),...
state.reg,...
state.srgtaps,...
int32(state.order),...
state.mat_table,...
int32(state.bruijn),...
int64(state.bruijn_counter));
if ~state.reset_prms
state.reg = prbs_register;
state.bruijn = bruijn;
state.bruijn_counter = bruijn_counter;
end
data_out = double(data_out);
else %old way slow implementation
if ((loop==1) || ~state.reset_prms)
% Initialisierung des Ausgangsvektors
data_out = zeros(state.dimension,bl);
% Successives Berechnen der Ausgangsfolge
counter=0;
PRBS_memory_pointer=0;
while counter<bl,
% check for zero symbol to be inserted for de Bruijn
% sequence
if state.bruijn==2,
counter = counter+1;
state.bruijn = 1;
continue;
end;
% compute current PRMS-symbol
PRBS_inx=mod(state.PRBS_inx+PRBS_memory_pointer-1,state.PRBS_inx(end))+1;
data_out(:,counter+1)=rem(sum(repmat(double(state.PRBS_memory(PRBS_inx).'),1,state.dimension).*...
state.mat_table,1),2).';
% compute new PRBS_memory
state.reg=[rem(sum(state.reg(state.srgtaps)),2) state.reg(1:end-1)];
state.PRBS_memory(PRBS_memory_pointer+1)=state.reg(end);
counter=counter+1;
PRBS_memory_pointer=mod(PRBS_memory_pointer+1,state.PRBS_inx(end));
% consider deBruijn option
if state.bruijn==1,
if state.bruijn_counter<0,
% counter not yet locked
if any([~sum(data_out(:,counter)) state.order==1]),
% zero symbol detected
state.bruijn_counter=state.bruijn_counter-1;
if any([state.bruijn_counter== -state.order state.order==1]),
% lock counter
state.bruijn_counter=2^state.periodicity-1;
state.bruijn=2;
end;
else
% no zero, so reset counter
state.bruijn_counter=-1;
end;
else
% counter already locked
state.bruijn_counter=state.bruijn_counter-1;
if state.bruijn_counter==0,
% reset counter
state.bruijn_counter = 2^state.periodicity-1;
state.bruijn=2;
end;
end;
end;
end;
% resort PRBS_memory for next block
state.PRBS_memory=[state.PRBS_memory(PRBS_memory_pointer+1:end) state.PRBS_memory(1:PRBS_memory_pointer)];
if state.reset_prms
state.data_mem = data_out;
end
else
data_out=state.data_mem;
end
end
else
data_out = round(rand(para.dimension,bl)) ;
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A D D I T I O N A L F U N C T I O N S %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% generate feedback taps for shift register %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function taps=srgtaps(inx)
data={[1] ...
[2 1] ...
[3 1] ...
[4 1] ...
[5 2] ...
[6 1] ...
[7 1] ...
[8 7 2 1] ...
[9 4] ...
[10 3] ...
[11 2] ...
[12 10 2 1] ...
[13 8 5 3] ...
[14 12 11 1] ...
[15 1] ...
[16 15 12 10] ...
[17 3] ...
[18 7] ...
[19 10 9 3] ...
[20 3] ...
[21 2] ...
[22 1] ...
[23 5] ...
[24 11 5 2] ...
[25 3] ...
[26 23 15 13] ...
[27 23 22 17] ...
[28 3] ...
[29 2] ...
[30 27 10 9] ...
[31 3] ...
[32 16 7 2] ...
[33 13] ...
[34 17 12 8] ...
[35 2] ...
[36 11] ...
[37 22 14 2] ...
[38 27 6 5] ...
[39 4] ...
[40 29 27 23] ...
[41 3] ...
[42 34 31 30] ...
[43 27 22 5] ...
[44 39 35 18] ...
[45 39 28 4] ...
[46 40 31 18] ...
[47 5] ...
[48 19 9 1]};
taps=data{inx};
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% adapted and faster version of generator for cyclic code %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function code=cyclgen_local(columns,polynomial)
rows=log2(columns+1);
code=zeros(rows,columns);
code(1,1)=1;
% create columns
for s=2:columns,
code(:,s)=[0;code(1:end-1,s-1)];
% check for overflow
if code(end,s-1),
code(:,s)=rem(code(:,s)+polynomial(1:end-1).',2);
end;
end;
end