• No results found

Anmärkningar och begrundan

I denna sektion kommenteras kända brister och slutsatser i valet av CORDIC-algoritm för implementation. Avsnitett är skrivet efter att xjobbet blivit färdigt.

Konsekvensen av att Householder-algoritmen och Langs-metod [42] ströks är ej bra. Om en utbredd parallell design i bakåtrotationsmoden ska implementeras är i dagsläget Householder-algoritmen, om den är så bra som Hsiao påstår, den metod som man bör titta närmare på om resultat med konstant skalfaktor önskas. Om däremot skalkonstanten ej behöver vara konstant så bör en designer ta algritmen [42] i beaktande. Denna anmärkning är motiverad med begrundandet att båda Householder-algoritmen och [42] är bättre än DCORDIC utifrån areasynpunkt, lätthet att implementera, att underhålla och att skräddarsy för framtida behov.

Det existerar även brister i jämförelsen mellan DCORDIC-algoritmen och Langs metod [4]. Med hänsyn till framtida behov och återanvändning av CORDICen så är DCORDIC- implementeringen mindre graciös än [4]. På grund av att DCORDICen inte är pipelinad lodrät med hänsyn till exekveringsriktningen utan tar hänsyn till att algoritmen exekverar med mest signifikanta siffran först blir det mer komplicerat att anpassa en DCORDIC- implementation för framtida behov, ty pipeliningen i arkitekturen är diagonal. Effekt- förbrukningen i en DCORDIC kommer därtill att bli relativt hög. Detta beror på att pipe- liningen på heladderarnivån kräver att DCORDICen klockas fort.

Jämförelsen med hänsyn på area och latency är heller ej tillräcklig och uttömmande. Timmermanns presenterar i rapporterna [72], [73] och [74] areareduceringstekniker som är applicerbara både på DCORDIC-algoritmen och Langs-metod i [4]. Latencyn kommer fortfarande att vara den samma i respektive metod men arean kommer att minska drastiskt i de båda metoderna. Med reduceringsteknikerna kan eventuellt Langs metod erhålla en mindre area än DCORDIC-algoritmen. Att ingen sådan jämförelse har utförts mellan metoderna beror på att skriftställaren kom över rapporterna efter att imple- mentering av den valda algoritmen redan hade utförts. Dessa areareducerande tekniker är gievtvis även applicerbara på Householder-CORDIC-algoritmen och Langs-algoritm i

[4]. En uttömmande undersökning vad dessa tekniker innebär för en aktuell arkitektur bör givetvis utföras av en designer som ska utföra en implementation.

De flesta redundanta CORDIC-metoderna använder sig av Langs modifierade CORDIC- rotationer i bakåtrotationsmoden. Denna form av CORDIC måste normalisera input- operanden för att algoritmen överhuvudtaget ska konvergera. DCORDIC-algoritmen å andra sidan kräver inte denna normalisering utan enklare form av normalisering kan användas1. Denna enklare normaliseringskrets arbetandes tillsammans med DCORDIC- algoritmen modifierad att använda Langs-rotationer [61] kan vara ett attraktivt alternativ till Householder och Langs-metod. Det hela beror förstås på om normaliseringskretsen till DCORDICen är så pass mycket bättre att när man summerar ihop alla krets-realisationer som ska ingå i CORDIC-processorn så blir det totala resultatet bättre. Helt klart är i alla fall att byte av rotationsalgoritm i DCORDICen skänker en rad fördelar, se sektion 5.1.3.3 och 3.3.1. Dessa fördel ska givetvis exploateras om DCORDIC-algoritmen är aktuell för implementation.

1 Alla CORDIC-processorer som arbetar i bakåtrotationsmoden måste normalisera inputoperanderna för att

Appendix D

Matlab-

implementeringar

I detta avsnitt kommer två stycken Matlab-modeller av DCORDIC-algoritmen att presenteras: (i) Program A har använts vid verifiering av VHDL-implementeringen samt simulering för att ta fram ordbredden på alla datavägar och (ii) program B har enbart används i syfte för att förstå exekveringen av algoritmen bättre.

D.1 PROGRAM A

Exekveringen i programmet är ej identisk med DCORDIC-algoritmen. Istället för att exekvera operanderna med MSDF utförs evalueringen parallellt. Detta är gjort för att det ska bli lättare att verifiera resultat och bestämma ordlängder i alla datavägar. Programmet hanterar endast en beräkning åtgången, där resultatet är en respons av inputoperanden.

D.1.1 Simulering

1. Starta simulering genom att anropa funktionen CORDIC_processor(X, Y, Width, N, OutputWidth) där X är x-kordinaten och Y är y-kordinaten på vektorn som fasen ska beräknas på. X- och Y-parametern skall anges i tvåkomplements-representation med teckenbiten till höger. Width är den interna ordbredden, N är antalet iterationer och OutputWidth antalet bitar i resultatet.

2. Resultat: Funktionen CORDIC_processor returnerar följande värden: • Magn_pos/Magn_neg Magnituden i redundant representation. • Angle_pos/Angle_neg Fasen i redundant representation (MSD=22) • Angle_bin Fasen i tvåkomplements-representation (MSB=23).

D.1.2 Filer/program

• CORDIC_processor.m CORDIC-processorn.

• Normailization.m Normaliserar inputoperanderna.

• Pre_rot.m Placerar inputvektorn i konvergensområdet. • Post_rot.m Placerar resultatet i rätt kvadrant.

• BinToRed.m Binär till redundant konvertering. • RedToBin.m Redundant till binär konvertering. • Bsdabs.m Absolutvärdesberäkning i y-datavägen. • XY_block.m X/y-datavägen för en mikrorotation. • P_block.m P-datavägen för en mikrorotation.

• Skift Skiftoperationen i x/y-datavägen.

• HybridAdd.m SD hybrid adderare/subtraherare.

• Add_sub.m SD-adderaren i x/y-datavägen

• Arctan.m Returenerar arctangensvärden.

• Ppm.m Ppm cell.

D.2 PROGRAM B (MSDF)

Programmet simulerar en MSDF-implementation av DCORDIC-algoritmen med pipelineskärningen på heladderarnivå. Programmet skevar inputoperanderna och datan klockas in i CORDIC-processorn med en klockpuls mellanrum.

Arkitekturen på implementationen i Program B skiljer sig från Program A. I denna processor utförs operationerna i input steget i följande ordning: (1) konvergensrotation, (2) B2R-konvertering och (3) skevning. Normalieringsoperationen har helt utelämnats. Output steget skiljer sig även i implementeringarna. I MSDF-implementeringen utförs R2B-konverteringen och korrektionsrotationen i omvänd ordning. Då Program B endast har använts till att öka förståelsen av algoritmen spelar dessa skillnader ingen roll. CORDIC-processor-modellen producerar korrekta resultat, emellertid skiljer sig resultaten i ungefär 10% av fallen i låga bitpositioner jämfört med resultaten från exekveringen med program A. Denna skillnad härstammar ifrån att konvergens- rotationsblocket och B2R-konverteringen har bytt plats i program B.

D.2.1 Simulering

1. Skapa x- och y-inputvariablerna med den önskade ordbredden och stoppa in dem i två skilda matriser med variabelnamnen X och Y. Varje rad i matriserna X och Y kommer att utgöra en inputvektor till CORDIC-processorn. Observera att LSB är till vänster och MSB till höger.

2. Öppna DCORDIC.m och scrolla ner till initieringar och ställ in önskade parametrar. Starta sedan simuleringen. Parametrar som är möjliga att ändra på är:

• Antal mikrorotationer: N

• Intern ordbredd: Width

• Antalet klockpulser: Klockpuls

3. Resultaten kan avläsas i följande variabler:

• Magn_pos/Magn_neg Redundant magnitud (skevad). • Magn_pos_easy/Magn_neg_easy Redundant magnitud (icke skevad). • Angle_pos_red/Angle_neg_red Redundant fas innan output steget.

D.2.2 Filer/program

Implementeringen består av följande funktioner/program:

• DCORDIC.m Toppnivån i programmet

• Initializer.m Initierar variabler.

• Arctangens.m Returnerar arctangensvärden.

• Pre_rot.m Placerar inputvektorn i konvergensområdet. • Post_rot.m Placerar resultatet i rätt kvadrant.

• BinToRed.m Binär till redundant konvertering. • RedToBin.m Redundant till binär konvertering. • Skew.m Skevar inputoperanderna och inputformat. • Bsd_abs.m Absolutvärdesberäkning i y-datavägen. • Shifter.m Skiftoperationerna i x/y-datavägarna.

• Ppm.m/mmp.m Används till att utföra addition och subtraktion. • PseudoXY.m/PseudoP.m Åtgärdar pseudo-overflow i X/Y/P-datavägarna. • AddSub.m Används i post_rot/pre_rot för att rotera.

D.3 KOD PROGRAM A

D.3.1 CORDIC_processor

function [Magn_pos, Magn_neg, Angle_pos, Angle_neg, Angle_bin] = CORDIC_processor(X, Y, Width, N, OutputWidth)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Hela CORDIC-processorn

%

% Input - X = X-operanden

% - Y = Y-operanden

% - Width = Ordbredden på datavägen i CORDICen

% - N = Antalet mikrorotationer

%

% Output - Magn_pos : Magnituden på inputvektorn (positiva delen av BSD)

% - Magn_neg : Magnituden på inputvektorn (negativa delen av BSD)

% - Angle_pos: Fasen på inputvektorn (positiva delen av BSD)

% - Angle_neg: Fasen på inputvektorn (negativa delen av BSD)

% - Angle_bin: Binära fasen

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Guard bitar %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Msb_Guardbits = 2; Lsb_Guardbits = Width-Msb_Guardbits-length(X); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Input steg %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Normalisering

[Xnorm, Ynorm] = normalization(X,Y); % Inputformat

[Xp, Xn] = BinToRed(Xnorm); [Yp, Yn] = BinToRed(Ynorm); % Konvergensrotation

[Xp_pre, Xn_pre, Yp_pre, Yn_pre, Quadrant] = pre_rot(Xp,Xn,Yp,Yn); % Skevning

% Ingen skevning!

% Inputformat fyller ut med nollor i MSB och LSB % så att X- och Y-parametrarna får rätt ordbredd. lsb_XY = zeros(1,Lsb_Guardbits); msb_XY = zeros(1,Msb_Guardbits); Xp = [lsb_XY Xp_pre msb_XY]; Xn = [lsb_XY Xn_pre msb_XY]; Yp = [lsb_XY Yp_pre msb_XY];

Yn = [lsb_XY Yn_pre msb_XY];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % P-pathen ska ha noll som input i första iterationssteget.

% Använder samma ordbredd som i XY-datavägen

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% P_pos= zeros(1,length(Xp)); P_neg= zeros(1,length(Xp)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % CORDIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Block 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[Yp, Yn, Sign1] = Bsdabs(Yp,Yn);

for i=0:N-1

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Block 2

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [Xp, Xn, Yp, Yn, Sign2] = XY_block(Xp, Xn, Yp, Yn, i);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Block 3

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [P_pos, P_neg, Sign1] = P_block(P_pos, P_neg, Sign1, Sign2, i);

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Output steg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [Ppost_pos, Ppost_neg] = post_rot(P_pos, P_neg, Quadrant);

Angle_bin = RedToBin(Ppost_pos, Ppost_neg, OutputWidth); Magn_pos = Xp;

Magn_neg = Xn; Angle_pos = Ppost_pos; Angle_neg = Ppost_neg;

D.3.2 Normalization.m

function [X,Y] = normalization(X,Y)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Utför normalisering av inputoperanderna.

% Den största operanden kommer att vara i intervallet [0.5,1). %

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% fixed=1; counter=0; MSB=length(X); while fixed==1 fixed=0; if (( X(1, MSB:MSB)==1 & X(1, MSB-1:MSB-1)==1) | X(1, MSB-1:MSB)==[0 0]) if (( Y(1, MSB:MSB)==1 & Y(1, MSB-1:MSB-1)==1) | Y(1, MSB-1:MSB)==[0 0]) if counter < MSB-1 fixed=1; counter=counter+1; X=[0 X(1,1:MSB-1)]; Y=[0 Y(1,1:MSB-1)]; end end end end

D.3.3 Pre_rot.m

function [Xp_out, Xn_out, Yp_out, Yn_out, Quadrant] = pre_rot(Xp,Xn,Yp,Yn)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Pre_rot placerar inputvektorn i konvergensområdet.

%

% Input - X : X-värdet

% - Y : Y-värdet

%

% Output - X_out : X-värdet

% - Y_out : Y-värdet

% - Quadrant : Se nedan

%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Algoritm Verifiering DCORDIC

% (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Spar teckenbitarna

Quadrant(1,1) = Xn(length(Xn)); Quadrant(1,2) = Yn(length(Yn));

Xn_out = Yn; Yp_out = Xn; % -X Yn_out = Xp;

elseif Quadrant(1,1)==1 & Quadrant(1,2)==1 Xp_out = Yn; % -Y Xn_out = Yp; Yp_out = Xp; % X Yn_out = Xn; else Xp_out = Xp; Xn_out = Xn; Yp_out = Yp; Yn_out = Yn; end

D.3.4 Post_rot.m

function [hybrid_pos, hybrid_neg] = post_rot(Angle_pos, Angle_neg, Quadrant)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Post_rot placerar den beräknade fasenn i rätt kvadrant.

%

% Input - Value_in : Inputvinkeln

% - Quadrant : Värden från pre_rot, talar om i vilken kvadrant inputvektorn var i.

%

% Output - Value_out : Resultatet placerat i rätt kvadrant

%

% Notis: Binära punkten sitter efter bit 3 i variabeln Pi2_temp.

%

% MSD i P-datavägen är 2^1. MSB i konstanterna nedan är 2^2.

% Jag lägger till en nolla i MSD på värdet från P-datavägen

% så att alla bitar får rätt signifikans.

%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Algoritm Verifiering DCORDIC

% (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Pi2_temp = [1 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 0 1 0 0 1 0 0 1 1 0 0];

Pi2 = Pi2_temp(length(Pi2_temp)-length(Angle_pos) : length(Pi2_temp));

if Quadrant(1,1)==1 & Quadrant(1,2)==0 % Value_in + Pi2

[hybrid_pos, hybrid_neg] = HybridAdd([Angle_pos 0], [Angle_neg 0], Pi2, 1);

elseif Quadrant(1,1)==1 & Quadrant(1,2)==1 % Value_in - Pi2

[hybrid_pos, hybrid_neg] = HybridAdd([Angle_pos 0], [Angle_neg 0], Pi2, 0); else

hybrid_pos=[Angle_pos 0]; hybrid_neg=[Angle_neg 0]; end

D.3.5 BinToRed.m

function [Pos, Neg] = BinToRed(Input)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Binär till BSD representation

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [row,col]=size(Input);

for i=1:row

Pos(i,:) = [Input(i, 1:col-1) 0];

Neg(i,:) = [zeros(1,length(Input)-1) Input(i, col)]; end

D.3.6 RedToBin.m

function [Value_out] = RedToBin(P_pos, P_neg, OutputWidth)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Redundant till Binär representation

% Används i P-datavägen %

% Lägger till en bit i MSB för att konverteringen ska bli rätt.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Algoritm Verifiering DCORDIC

% (c) 2003 Rikard Hellberg %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% C(1)=0; for i=1:length(P_pos) [Summa(i),C(i+1)] = Mmp(C(i),P_neg(i),P_pos(i)); end Value = Summa; %Value = [Summa C(i+1)];

Value_out = Value(length(Value)-(OutputWidth-1) : length(Value));

D.3.7 BsdAbs.m

function [Result_pos,Result_neg, Sign] = bsdabs(P,N)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Funktionen returnerar absolutbeloppet och tecknet på inputvektorn (positiv alt. negativ)

%

% Notera: Denna kod verifierar endast funktionen hos BSD absolutvärdesberäkningen. Operationen beräknar ej med MSD

% först utan utför operationen parallellt.

%

% Programmet loopar igenom hela inputvektorn för att beräkna absolutbeloppet. Loopen går igenom vektorn med start

% i MSD. När en icke-"nollbit" påträffas första gången kan ett beslut av tecknet på vektorn utföras.

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % F är en beslutsvariabel som kan anta följande värden:

% 0 = negativ, 1 = positiv, 2 = nodec (inget beslut). % Initialvärdet på F är nodec.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% F = 2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Loopar igenom input vektorn med start i MSD.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for i=1:length(P) % startar med MSB position=length(P)+1-i; % F=positiv

% NULL (Ingen variabel ändras) % F=negativ if F==0 P(position) =~ P(position); N(position) =~ N(position); end % F=nodec if F==2

if P(position)==1 & N(position)==0 F=1;

elseif P(position)==0 & N(position)==1 F=0; P(position)=~ P(position); N(position)=~ N(position); else P(position)=P(position); N(position)=N(position); end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sätter Sign i sista iterationen. Sign=0 om vektorn är negativ

% alternativt Sign=1 om vektorn är positiv or nodec.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if F==0

Sign=0; %negativ else

Sign=1; %positiv or nodec end

% Output Result_pos=P;

D.3.8 XY_block.m/Skift

function [X_pos, X_neg, Y_pos, Y_neg, Sign] = XY_block(Xp, Xn, Yp, Yn, BlockId)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % XY_block är x/y-datavägen för en iteration i DCORDIC-algoritmen.

%

% Input - Xp = X_pos

% - Xn = X_neg

% - Yp = Y_pos

% - Yn = Y_neg

% - BlockId : Iteration som blocket ingår i.

%

% Output - X_pos = Se koden nedan

% - X_neg = "

% - Y_pos = "

% - Y_neg = "

% - sign : Information om Y-vektorn är positiv eller negativ.

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Skiftar

[XpS] = Skift(Xp, BlockId); [XnS] = Skift(Xn, BlockId); [YpS] = Skift(Yp, BlockId); [YnS] = Skift(Yn, BlockId); % X-datavägen: (addition)

[X_pos,X_neg] = Add_sub(Xp, Xn, YpS, YnS); % Y-datavägen: (subtraktion följt av abs) [Y_pos,Y_neg] = Add_sub(Yp, Yn, XnS, XpS); [Y_pos,Y_neg,Sign] = Bsdabs(Y_pos,Y_neg); function [shifted] = Skift(A,BlockID)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Vänsterskiftar <BlockId> bitar.

%

% Input - A : Vektorn som ska skiftas. % - BlockId : Antal skift som ska utföras. %

% Output - shifted : Den skiftade vektorn.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if BlockID ~= 0 B = zeros(1,BlockID); shifted = [A((1+BlockID):length(A)) B]; else shifted = A; end

D.3.9 P_block.m

function [hybrid_pos,hybrid_neg,Sign] = P_block(P_pos,P_neg,Sign1,Sign2,BlockId)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % P_blocket är P-datavägen för en iteration i DCORDIC-algoritmen.

%

% NOTIS: Width är vidden på hela P-datavägen och innehåller guardsiffror. P-datavägen har sifferposition 2^1 som msd. %

% Vidden på P-datavägen är lika bred som X/Y-datavägen. MSD i P-datavägen är dock fortfarande 2^1. % Detta innebär att vi erhåller bättre nogrannhet i LSD.

%

% Input - P_pos : aktuella P-värdet (BSD positiva delen)

% - P_neg : aktuella P-värdet (BSD negativa delen)

% - Sign1 : Sign från P_block(<BlockId>-1)

% - Sign2 : Sign från vectorblock(<BlockId>)

% - BlockId : Anger vilket P-block som är aktuellt

%

% Output - hybrid_pos : pos BSD summan/differensen

% - hybrid_neg : neg BSD summan/differensen

% - Sign : Mikrorotationsriktningen för nästa block.

%

% Algoritm verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Initiering Width=length(P_pos);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Hämta arctan värdet i ROM:et. Funktionen returnerar ett två

% komplements tal med bit position 2^1 2^0 = "00". 2^1 r % teckenbit.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [alfa] = Arctan(Width, BlockId);

% Styrd addition

[hybrid_pos,hybrid_neg] = HybridAdd(P_pos,P_neg, alfa, Sign1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Följande rad beräknar Sign (output)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Sign=~xor(Sign1,Sign2);

D.3.10 HybridAdd.m

function [hybrid_pos,hybrid_neg] = HybridAdd(SD_pos, SD_neg, alfa, Sign)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % SD hybrid addition/subtraktion

%

% Om Sign=0 ska alfa subtraheras med SD-operanden. % Detta görs genom att Alfa inverteras och "LSB" sätts till '1'. %

% Om Sign=1 ska alfa adderas med SD-operanden. % Detta görs genom att Alfa = Null och "LSB" sätts till '0'. %

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if Sign == 0 alfa=~alfa; end LSB=~Sign;

% PPM, utför hybrid addition/subtraktion [hybrid_pos,hybrid_neg] = Ppm(SD_pos,SD_neg,alfa);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Hybrid_pos skiftas så att bitarna får rätt signifikans och "LSB" biten stoppas in i LSB.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Width=length(SD_pos);

overflowbit_pos=hybrid_pos(Width); hybrid_pos=[LSB hybrid_pos(1:Width-1)];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Följande rader tar hand om Pseudo overflow.

% Notis: Kan göra enklare styrlogik för pseudo overflow då inputbitarna i msb för P_pos, P_neg alltid är '0'. Även msb på % arctan är '0' ty det är ett två komplements tal. Pga detta kan en av styrvariablerna sättas till ~Sign1.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if overflowbit_pos==1 & Sign~=0

hybrid_pos(Width)=1; hybrid_neg(Width)=0; elseif overflowbit_pos==0 & Sign~=1 hybrid_pos(Width)=0; hybrid_neg(Width)=1; end

D.3.11 Add_sub.m

function [Result_pos,Result_neg] = add_sub(A,B,C,D)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add_Sub cellen beräknar X+Y eller X-Y. Beroende på hur Y_pos och Y_neg routas sker antingen addition eller subtraktion. %

% Input Addition Subtraktion

% - A=X_pos A=X_pos

% - B=X_neg B=X_neg

% - C=Y_pos C=Y_neg

% - D=Y_neg D=Y_pos

%

% Output - Result_pos : summa alt. differans (positiva BSD vektorn)

% - Result_neg : summa alt. differans (negativa BSD vektorn)

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Width: Ordbredden på datavägen. Jag spar den här i en variabel pga att vidden på datavägen ska bevaras.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Width = length(A);

% PPM cell [Transfer,U] = Ppm(A,B,C);

Temp_trans = [0 Transfer(1,1:Width-1)]; Temp_pos(Width+1)=Transfer(Width); % MMP cell

[mmp_pos,mmp_neg] = Mmp(U, D, Temp_trans); Temp_pos(1,1:Width) = mmp_pos;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % För att få rätt signifikans på bitarna i Resultat_neg vektorn skiftas en '0':a in i LSB.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Temp_neg = [0 mmp_neg];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Åtgärdar Pseudo Overflow i MSB. En kompensering som garanterat fungerar är att styra med bitposition

% 2^3 ty om 2^3 är (1 alt. -1) så är bitposition 2^2 tvärsom.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if Temp_pos(Width+1)==1 & Temp_neg(Width+1)==0

Temp_pos(Width)=1; Temp_neg(Width)=0;

elseif Temp_pos(Width+1)==0 & Temp_neg(Width+1)==1 Temp_pos(Width)=0; Temp_neg(Width)=1; end Result_pos=Temp_pos(1:Width); Result_neg=Temp_neg(1:Width);

D.3.12 Arctan.m

function [alfa] = arctan(Width, BlockId)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Arctan cell ~ modullerar ett ROM med sparade arctan värden (två komplement)

%

% NOTIS: Det största värdet är atan(1)=0.7854. Det innebär att programmet sätter bit 2^-1 som MSB. Pga detta fyller jag ut datavägen med

% yterligare 2 stycken nollor [0 0] så att bitarna får rätt signifikans ty MSD har signifikans 2^1=2 i P-datavägen.

%

% Input - Width : Vidden på datavägen i P_blocket

% - BlockId : Anger vilket block som är aktuellt. (Block nummer ett har BlockId=0!)

%

% Output - alfa : atan(2^-BlockId)

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Reellt arctan värde för <BlockId>

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% value=atan(2^(-BlockId)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Bit position 2^1 2^0 = "00" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MSB=[0 0]; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Beräknar real => binärt för arctan värdet

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for i=2:(Width-1) value=2*value; if value >= 1 value=value-1; result(Width-i)=1; else result(Width-i)=0; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% alfa = [result MSB];

D.3.13 Ppm.m

function [Transfer,U] = ppm(A,B,C)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PPM cell (plus plus minus cell)

%

% Input Addition Subtraktion

% - A=X_pos A=X_pos

% - B=X_neg B=X_neg

% - C=Y_pos C=Y_neg

%

% Output - Transfer = Se nedan

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% B=~B;

Transfer = (A&B)|(B&C)|(A&C); % PPMT (PPM Transfer)

U = ~(xor(xor(A,B),C)); % PPMS (PPM Sum)

D.3.14 Mmp.m

function [mmp_pos,mmp_neg] = mmp(A,B,C)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % MMP cell (minus minus plus cell)

%

% Variablerna Transfer och U är outputs från PPM-cellerna i Add_sub. %

% Input Addition Subtraktion

% - A=U A=U

% - B=Y_neg B=Y_pos

% - C=Transfer C=Transfer

%

% Output - mmp_pos = Se uttrycket nedan

% - mmp_neg = Se uttrycket nedan

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% A=~A;

B=~B;

mmp_neg = ~((A&B)|(A&C)|(B&C)); % MMPT (MMP Transfer)

mmp_pos = xor(xor(A,B),C); % MMPS (MMP Sum)

D.4 KOD PROGRAM B (MSDF)

D.4.1 DCORDIC.m

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % DCORDIC (MSDF) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % VARIABLER: %

% N: Antalet iterationssteg. N måste vara mindre eller lika med Width (N =< Width).

% Width: Width är den interna ordbredden på CORDICENs datavägar. % Klockpuls: Antalet klockpulser.

% (LsbGuard:Antalet guardsiffror i LSD påverkas enligt följande: LSD_Guard = Width-(length(Inputdata)+2) ) %

% Exempel: Inputdatan är 16 siffror, MSDGuard är alltid 2. För att erhålla 4 stycken guardsiffror i LSD måste alltså Width sättas till 22. %

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % RESULTAT:

%

% Angle_out: Fasen på alla inputvektorer. Fasen på den första inputvektorn kan avläsas i variabeln vid klockpuls: (1+Width)+3*N+2.

% Angle_out_bin: Fasen på alla inputvektorer med start i första inputvektorn.

%

% För andra intressanta värden, se botten av denna fil. %

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %

% På grund av att Matlab-programmet exekveras sekventiellt så har programmet skrivits enligt följande:

% 1. Först evalueras XY-datavägens operationer.

% 2. Sedan exekveras registren i XY-datavägen.

% 3. P-dataväge exekveras.

% 4. Registren exekveras i P-datavägen.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Algoritm Verifiering DCORDIC

% (c) 2003 Rikard Hellberg

Antal klockpulser Klockpuls=300; % Antal mikrorotationer N=16; % Interna ordbredden Width=23; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initierar nästan alla variabler

initializer(N,Width);

global Xi_pos Xi_neg Yi_pos Yi_neg Pi_pos Pi_neg Xs_pos Xs_neg Ys_pos Ys_neg Xd_pos Xd_neg;

global Yd_pos Yd_neg X_PPMS X_PPMT Y_PPMS Y_PPMT P_PPMS P_PPMT X_MMPS X_MMPT Y_MMPS Y_MMPT; global Xo_pos Xo_neg Yo_pos Yo_neg Po_pos Po_neg Xd_pos_latched Yd_neg_latched P_pos P_neg;

global Sign_out Sign1 Skew_Matrix_Xpos Skew_Matrix_Xneg Skew_Matrix_Ypos Skew_Matrix_Yneg ; global Summa Value_out Xi Yi Yi_neg_temp Yi_pos_temp Xi_neg_temp Xi_pos_temp Xpre Ypre Xpos; global X_out_pos X_out_neg Y_out_pos Y_out_neg P_out_pos P_out_neg Sign Sign_XYblock Sign_in; global X_MSB Y_MSB P_MSB Xneg Ypos Yneg Q_value alfa Ai F F1 Quadrant;

%Antalet guardsiffror i MSB (Obs rör ej!) MsbGuard = 2;

% Antalet inputoperander i test-matrisen [Nb_of_input_values,kolumner] = size(X) % Sätter guardsiffror i LSB LsbGuard = Width-MsbGuard-kolumner; % Initierar ett "ROM" med alla arctangensvärden [Ai] = arctangens(Width, N);

% Antalet d-latchar i pipen (Quadrant). Värdena pipelinas från inputsteget till outputsteget. % Talar om i vilken kvadrant resultatet ska vara i.

pipes = (1+Width)+(3*N)+2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Loopen simulerar antalet klockpulser

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for k=1:Klockpuls

k

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % If-satsen kontrollerar om det finns värden kvar i testmatrisen. Om det finns testvärden kvar i matrisen klockas dessa in i pre_rot (första blocket).

% Om det däremot är slut på testvärden klockas det in nollor i pre_rot.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if k <= Nb_of_input_values Xi = X(k,:); Yi = Y(k,:); elseif k > Nb_of_input_values Xi = zeros(1,kolumner); Yi = zeros(1,kolumner); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Input steg %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [Xpre(2,:),Ypre(2,:), Quadrant(1,:)] = pre_rot(Xi,Yi);

[Xpos, Xneg] = BinToRed(Xpre(1,:)); [Ypos, Yneg] = BinToRed(Ypre(1,:));

[Xi_pos_temp, Skew_Matrix_Xpos] = skew(Skew_Matrix_Xpos, Xpos, LsbGuard,MsbGuard); [Xi_neg_temp, Skew_Matrix_Xneg] = skew(Skew_Matrix_Xneg, Xneg, LsbGuard,MsbGuard); [Yi_pos_temp, Skew_Matrix_Ypos] = skew(Skew_Matrix_Ypos, Ypos, LsbGuard,MsbGuard); [Yi_neg_temp, Skew_Matrix_Yneg] = skew(Skew_Matrix_Yneg, Yneg, LsbGuard,MsbGuard);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% XY_BLOCK

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Absolutvärdesberäknigen innan första XY_blocket.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [Yi_pos(1,:), Yi_neg(1,:) F1(2,:)] = bsd_abs(Yi_pos(1,:), Yi_neg(1,:), F1(1,:));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Invärdenden till alla XY_block/mikrorotationer utom det första blocket.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Xi_pos(2:N,:) = X_out_pos(1:N-1,:); Xi_neg(2:N,:) = X_out_neg(1:N-1,:); Yi_pos(2:N,:) = Y_out_pos(1:N-1,:); Yi_neg(2:N,:) = Y_out_neg(1:N-1,:); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Skift + Fördröjning %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Skiftar (alla blocken) [Ys_pos] = shifter(Yi_pos); [Ys_neg] = shifter(Yi_neg); [Xs_pos] = shifter(Xi_pos); [Xs_neg] = shifter(Xi_neg);

% Fördröjning efter skiftoperationen (alla blocken) % (Block Nr, kolumn, fördröjning) for i=1:N Yd_pos(i,:,i) = Ys_pos(i,:); Yd_neg(i,:,i) = Ys_neg(i,:); Xd_pos(i,:,i) = Xs_pos(i,:); Xd_neg(i,:,i) = Xs_neg(i,:); end; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Addition/subtraktion i X/Y-datavägen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Yd_neg_latched(:,:,2) = Yd_neg(:,:,1); Xd_pos_latched(:,:,2) = Xd_pos(:,:,1); % PPM

[X_PPMT, X_PPMS(:,:,2)] = Ppm(Xi_pos, Xi_neg, Yd_pos(:,:,1)); [Y_PPMT, Y_PPMS(:,:,2)] = Ppm(Yi_pos, Yi_neg, Xd_neg(:,:,1)); % Spar MSB och sätter PPMT(lsb)=0

X_MSB(:,1,3) = X_PPMT(:,Width); Y_MSB(:,1,3) = Y_PPMT(:,Width); X_PPMT = [zeros(N,1) X_PPMT(:, 1:Width-1)]; Y_PPMT = [zeros(N,1) Y_PPMT(:, 1:Width-1)]; % MMP

[X_MMPS(:,:,2), X_MMPT] = Mmp(X_PPMS(:,:,1), Yd_neg_latched(:,:,1), X_PPMT); [Y_MMPS(:,:,2), Y_MMPT] = Mmp(Y_PPMS(:,:,1), Xd_pos_latched(:,:,1), Y_PPMT); % Spar MSB och sätter MMPT(lsb)=0

X_MSB(:,2,2) = X_MMPT(:,Width); Y_MSB(:,2,2) = Y_MMPT(:,Width); X_MMPT = [zeros(N,1) X_MMPT(:, 1:Width-1)]; Y_MMPT = [zeros(N,1) Y_MMPT(:, 1:Width-1)]; % Pseudo overflow korrektion

[Xo_pos, Xo_neg] = pseudoXY(X_MSB, X_MMPS(:,:,1), X_MMPT); [Yo_pos(:,:,2), Yo_neg(:,:,2)] = pseudoXY(Y_MSB, Y_MMPS(:,:,1), Y_MMPT);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Absolutvärdesberäknigen i Y-datavägen

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % F är internt tillstånd i absolutoperationen

[Yo_pos(:,:,1), Yo_neg(:,:,1), F(:,:,2)] = bsd_abs(Yo_pos(:,:,2), Yo_neg(:,:,2), F(:,:,1));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% D-latchar (Pipeline) i X/Y-datavägen

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Pipeling av Quadrant

% Q_value anv i post_rot for att placera % resultatet i ratt kvadrant Q_value = Quadrant(pipes,:) Quadrant(2:pipes,:)=Quadrant(1:pipes-1,:); % D-latch efter Pre-processing Xpre(1,:) = Xpre(2,:); Ypre(1,:) = Ypre(2,:); % Latchar in skevatvärde Xi_pos(1,:) = Xi_pos_temp; Xi_neg(1,:) = Xi_neg_temp; Yi_pos(1,:) = Yi_pos_temp; Yi_neg(1,:) = Yi_neg_temp; % D-latch efter Pseudo Korrektion X_out_pos = Xo_pos; X_out_neg = Xo_neg; Y_out_pos = Yo_pos(:,:,1); Y_out_neg = Yo_neg(:,:,1);

% D-latchar i första Absolutvärdesberäkningen Sign1 = F1(2,1);

F1(1,1:Width-1) = F1(2,2:Width); F1(1,Width) = 2;

% D-latchar/fördröjning efter Skiftoperationen % (skiftar ner en slice)

Xd_pos(:,:,1:N-1) = Xd_pos(:,:,2:N); Xd_neg(:,:,1:N-1) = Xd_neg(:,:,2:N); Yd_pos(:,:,1:N-1) = Yd_pos(:,:,2:N); Yd_neg(:,:,1:N-1) = Yd_neg(:,:,2:N);

% Klockar Delay Y_neg och Y_pos (skiftar ner en slice) % Dessa latchar gar till MMP I1.

Yd_neg_latched(:,:,1) = Yd_neg_latched(:,:,2); Xd_pos_latched(:,:,1) = Xd_pos_latched(:,:,2);

% D-latch mellan PPM och MMP % (skiftar ner en slice) X_PPMS(:,:,1) = X_PPMS(:,:,2); Y_PPMS(:,:,1) = Y_PPMS(:,:,2); % D-latchar för att latcha värden som ska % styra pseudo overflow korrektionen. X_MSB(:,:,1:2) = X_MSB(:,:,2:3); Y_MSB(:,:,1:2) = Y_MSB(:,:,2:3); % En D-latch mellan MMPS och Pseudo overflow % korrektions operationen. X_MMPS(:,:,1) = X_MMPS(:,:,2); Y_MMPS(:,:,1) = Y_MMPS(:,:,2); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % P_BLOCK %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Invärden till alla P_block/mikrorotationer. Observera att inputvektorerna till P-rotationerna är noll.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Pi_pos(2:N,:) = P_out_pos(1:N-1,:);

Pi_neg(2:N,:) = P_out_neg(1:N-1,:);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sign1 är tecknet på Y-operanden i första absolutvärdesberäkningen. Är likaså mikrorotationsriktningen i % det första P_blocket.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Sign_in(1,1) = Sign1;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Sign_out är mikrorotationsriktningen som ska utföras.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Sign_in(2:N,1) = Sign_out(1:N-1,1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Styrd addition/subtraktion

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Byter tecken på arctanvärdet om sign=0

for i=1:N if Sign(i,3) == 0 alfa(i,:,2) = ~alfa(i,:,3); else alfa(i,:,2) = alfa(i,:,3); end end % PPM

[P_PPMT, P_PPMS] = Ppm(P_pos(:,:,1), P_neg(:,:,1), alfa(:,:,1)); % Spar MSB och sätter LSB=~Sign

P_MSB = P_PPMT(:,Width);

P_PPMT = [~Sign(:,2) P_PPMT(:, 1:Width-1)]; % Pseudo Korrektion

[Po_pos, Po_neg] = pseudoP(P_MSB, Sign(:,2), P_PPMT, P_PPMS);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Output steg (Obs endast P-datavägen)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Summa(2,:) = RedToBin(P_out_pos(N,:),P_out_neg(N,:));

[Value_out] = post_rot(Summa(1,:), Q_value);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% D-latchar i P-datavägen

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % D-latchar i P-datavägen innan PPM

P_pos(:,:,1) = P_pos(:,:,2); P_neg(:,:,1) = P_neg(:,:,2); P_pos(:,:,2) = Pi_pos; P_neg(:,:,2) = Pi_neg;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ai är arctanvärdena och alfa är den latchade datavägen.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% alfa(:,:,3) = Ai;

Sign(:,1:2) = Sign(:,2:3); Sign(:,3) = Sign_in;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Pipeline mellan styrda negationen av arctanvärdet och PPM. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% alfa(:,:,1) = alfa(:,:,2);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Pipeline efter Hybrid-additionen. Po_pos, Po_neg kommer från pseudo % korrektions cellen.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% P_out_pos = Po_pos;

P_out_neg = Po_neg;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % D-latch mellan Red=>Bin-operationen och post_rot.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Summa(1,:)=Summa(2,:); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Beräknar mikrorotationsriktningen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Sign_out(:,1) = ~xor(Sign(:,1),Sign_XYblock(:,1)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FORMAL VERIFICATION RADER

% Redundanta FASEN innan RedtoBin & post_rot.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Angle_pos_red_temp(k,:) = P_out_pos(N,:);

Angle_neg_red_temp(k,:) = P_out_neg(N,:);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FORMAL VERIFICATION RADER

% Redundanta MAGNITUDEN (OBS Skevad!)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Magn_pos(k,:) = X_out_pos(N,:);

Magn_neg(k,:) = X_out_neg(N,:);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FORMAL VERIFICATION RADER

% Spar alla värden som klockas ut ur output steget (post_rot).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Angle_out(k,:) = Value_out;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FORMAL VERIFICATION RADER

% Gör så att jag tydligare ser Magn_pos & Magn_neg (Obs ej skevad) % Varje rad i matriserna är magnituden på respektive inputvektor.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for i=1:Width Magn_pos_easy(:,Width+1-i) = Magn_pos((1+3*N+i):(3*N+Nb_of_input_values+i),Width+1-i); Magn_neg_easy(:,Width+1-i) = Magn_neg((1+3*N+i):(3*N+Nb_of_input_values+i),Width+1-i); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FORMAL VERIFICATION RADER

% Gör så att jag tydligare ser den redundanta FASEN innan RedtoBin & post_rot.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Angle_pos_red = Angle_pos_red_temp((Width+1)+3*N : Width+3*N+Nb_of_input_values, :);

Angle_neg_red = Angle_neg_red_temp((Width+1)+3*N : Width+3*N+Nb_of_input_values, :);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % FORMAL VERIFICATION RADER

% Gör så att jag tydligare ser den binra FASEN. (RESULTATET!!!)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Angle_out_bin = Angle_out((Width+3)+3*N: (Width+2)+3*N+Nb_of_input_values,:);

D.4.2 Initializer.m

%

% Algoritm Verifiering DCORDIC % (c) 2003 Rikard Hellberg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% global Xi_pos Xi_neg Yi_pos Yi_neg Pi_pos Pi_neg Xs_pos Xs_neg Ys_pos Ys_neg Xd_pos Xd_neg;

Related documents