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 skipped1, 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