réponses leçon 12

Question 1:

Question 1

Voici le code. Les fonctions sont placées en tête de programme. Le programme main ensuite appelle les fonctions: 2 fois saisie, calcule la somme puis appelle affichage.

-- fonction afficheur

-- attention les commentaires ne sont pas des lignes!!!!

Begin

mvi 0D Co

nop

-- saisie 16 bits

pause

mov Rsw Rsrc1

pause

mov Rsw Rsrc2

concat

pop CO

push Rdest zero

-- afficheur

pop R7seg

pop CO

pause

-- main

mvi 03 CO

pushi 0F zero

pop R1

MVI 03 CO

pushi 12 zero

pop Rsrc2

mov R1 Rsrc1

add

pushi 18 zero

mvi 0A CO

push Rdest zero

mvi 0D CO

nop

end

Question 2

Vous allez commencez par créer un composant LFSR. Je vous conseille de copier votre projet TP12 vers un nouveau projet TPRDM.

Vous avez bien sûr lu les informations sur LFSR. Pour un générateur 16 bits il suffit de 16 bascules D et de relier les sorties des bascules 3, 12, 14 et 15 par un Xor pour alimenter l'entrée de la bascule 0.

Comme vous voulez générer des nombres aléatoires seulement si l'instruction machine associée est exécutée, je vous propose d’instancier 16 bascules FDE qui seront activées par l'entrée CE seulement si une instruction RANDOM est décodée par la FSM.

Lorsque vous créez la première bascule, il faut impérativement placer la valeur initiale à 1! Il suffit d'ouvrir la fenêtre Object Properties de cette bascule et de changer la valeur INIT. Sans cela vos bascules produiront toujours x0000.

Ensuite copiez cette bascule et collez la 15 fois afin d'obtenir une grille de bascule 4x4. Placez un fil avec son I/O Marker clk sur tous les C, Placez un fil suivant et son I/O marker sur tous les CE. Reliez les bascules en cascade du Q vers le D de la suivante. Placez un XOR4 connecté aux 4 sorties des bascules 3, 11, 14 et 15. La sortie de ce XOR4 est directement connectée à l'entrée D de la bascule 0.

Il vous reste à récupérer le nombre aléatoire ainsi généré. Placez un bus RDN(15:0) avec son I/O Marker. Il vous suffit de nommer les sorties de chaque bascule RDN(0), RDN(1)..; RDN(15). Sauvez et créez le symbole associé.

Composant LFSR

Avant toute chose je vous propose de simuler ce composant . Utilisez Isim directement sur le LFSR.sch. Il vous suffit par un force clock d’initialiser clk et le signal suivant à 1 par un force constant. Vous devriez observer la séquence suivante.

Vous êtes prêt pour l'insertion dans le composant ALU. Il y reste plusieurs places libres. Pour simplifier la mise en oeuvre, je vous propose d'utiliser la dernière place dans l'arbre des mux2x16, en conséquence le code de cette instruction sera nécessairement x1F00. Afin de générer toujours la même suite de nombres aléatoires, indépendamment de la fréquence d'appel de l'instruction et donc de la clock du processeur, l'entrée suivant est active seulement lorsque le code OP(3:0) est égal à b1111. Placez une porte AND4 qui prend en compte cette configuration et valide l'entrée suivant du LFSR. Enfin ajoutez un fil clk avec son I/O Marker sur l'entrée correspondante de LFSR. Vous pouvez recréer le symbole associé à ALU.

LFSR dans ALU

Mettez à jour le composant ALU dans S3. Il doit y avoir un nouveau port clk sur ALU. Il suffit de le connecté au fil clk déjà en place.

Ajoutez le fil clk sur ALU

Mettez à jour votre assembleur, il suffit d'ajouter , avant la commande s/AND/ !! ( AND est inclus dans rANDom)

s/RANDOM/1F00/

Voici un premier programme testrdm.S3 qui vous permettra de tester votre nouvelle instruction. A chaque pression sur le bouton de la carte, le nombre aléatoire suivant dans la liste est affiché, c'est exactement le même ordre que ce que vous avez observé par simulation. Placez ce programme testrdm.coe dans insmem, mettez à jour S3 pour insmem, créez le symbole S3, mettre à jour toplevel. Vous pouvez générer toplevel.bit pour tester sur la carte.

-- test rdm

begin

random

mov rdest r7seg

mov 01 CO

PAUSE

end

Vous avez tout ce qu'il faut dans le processeur S3 pour maintenant écrire votre programme qui calcule PI par méthode Monté Carlo!

Voici un code que j'ai essayé. Il affiche la valeur du nombre de points dans le quart de cercle après xFF tirages et une précision de calcul sur 7 bits seulement afin de pouvoir calculer la somme des deux carrés sur 16 bits et de la comparer au carré du rayon du cercle de dimansion x7F. La valeur produite est xB7 et donne une valeur approchée de PI = xB7 / xFF * 4 = 2,87 !!! pas si mal avec aussi peut de précision.

-- Monte Carlo

begin

-- 3F01 dans R2

mvi 01 Rsrc1

mvi 3f Rsrc2

concat

mov Rdest R2

--8000 R3

mvi 00 Rsrc1

mvi 80 Rsrc2

concat

mov Rdest R3

-- 00 R4 nombre de points dans le cercle

mvi 00 R4

-- 01 init compteur de boucle à 255 tirages

mvi FF R1

--

random

mvi 7F Rsrc1

mov Rdest Rsrc2

and

mov Rdest Rsrc1

mov Rdest Rsrc2

mul8

mov Rdest R5

random

mvi 7F Rsrc1

mov Rdest Rsrc2

and

mov Rdest Rsrc1

mov Rdest Rsrc2

mul8

mov Rdest Rsrc1

mov R5 Rsrc2

add

mov R2 Rsrc1

mov Rdest Rsrc2

SUB

mov Rdest Rsrc1

mov R3 Rsrc2

and

miNZ 00 Rsrc1

miZ 01 Rsrc1

mov R4 Rsrc2

add

mov Rdest R4

mov R1 Rsrc1

dec

miNZ 0B CO

mov Rdest R1

mov R4 R7seg

pause

end

Vous pouvez facilement modifier le nombre de tirages, il suffit de changer la valeur initiale de R1. Attention l'adresse de boucle a changée!!!!

Avec x08FF tirages on obtient PI = 2,99.

Si le code est instable, il vous faudra baisser la clock du processeur S3!

Vous pouvez utiliser une bascule pour Nexys2, ou avec un IP_core and FPGA Features and Design>Clockin>Clocking Wizard pour Nexys3.

Pour Nexys3 voici les copies d'écrans: Créez une seconde sortie avec une fréquence de 50Mhz, puis supprimer reset et locked. Il vous suffit ensuite d'insérer une instance dans toplevel.