Map Microcontrôleur Zi3

Zilack3

Binary Power !
13 Mars 2013
118
54
140
27
Microcontrôleur Zi3
b8NdCX6.png


Bonjour !

Aujourd'hui je vous dévoile un nouveau circuit. Il a été construit en 6 mois (Janvier 2016 - Juin 2016).

Il est composé de:
- ALU 16 bits divisé en 4 étages pour atteindre de meilleur performance en réduisant le temps de calcul.
- 6 * 16 bits de DPRAM (RAM en dual read).
- 1 compteur programme de 6 bits (Il ne peut que charger car il ne possède que 6 D-Latch).
- 1 ROM pouvant réprésentant jusqu'à 56 lignes de avec un poids maximum de 294 octets.

Ce microcontrôleur peut faire plusieurs choses comme par exemple : des suites (compteur, suite de Fibonacci), opérations (addition, sustraction, division (avec ou sans virgule), multiplication), approximation (Nombre d'euler (=e^1)) etc...

Pour le tester, j'ai implémenté 4 programmes (Addition, Soustraction, Multiplication, Division) et des périphériques pour utiliser le microcontrôleur comme une calculatrice.

DL : https://drive.google.com/file/d/0B4Rrn2owLmJ8Y2lDLWV5Q1ZGam8/view

N4LkbYW.png

kWC9spW.png

ClovthV.png

0xiYRMk.png
  • Version : 1.10.2
  • Mode : solo
  • Distance de rendu : 16 chunks
  • Position du système :
    • x = 1505
    • y = 56
    • z = -701
  • Vous contrôlez un curseur (en bas à gauche de chaque chiffre) grâce à 4 boutons.
  • Quand le curseur est sur un chiffre, cliquez sur le bouton validé pour incrémenter.
  • "=" est allumé quand Zi3 calcul.
  • Du haut vers le bas et de la gauche à la droite de l'interface utilisateur:
    • Validé
    • Haut
    • Réinitialisé (arrêt de l'horloge et reset de A et B)
    • Gauche
    • Bas
    • Droite

  • A et B ne peuvent pas dépasser 255 (8 bits).
  • Et c'est tout !
  • clock : 125 mHz
  • storage : 12 bytes DPRAM
  • program counter width : 6 bits
  • program's length : 56 lines
  • program's weight : 294 bytes
  • ADD : 1min10s
  • SUB : 1min30s
  • MUL : 6min20s
  • DIV : 5min10s
  • Command block (only say command) : 77
  • Redstone lamp : 226
  • Redstone repeater : 3596
  • Redstone torch : 5675
  • Step : 2439
  • Redstone wire : 44038
  • Wool : 52300
LVL1
  • A + B
  • A - B
LVL2
  • A SL+0
  • A SL+1
  • A SR
  • A AND 1 OR AND FF
LVL3
  • A > B
  • A = B
  • A < B
LVL4
  • B SL+0
  • B SL+1
  • B SR
  • B AND 1 OR AND FF
READ LVL1 = 0 / READ LVL2 = 0 / READ LVL4 = 1
READ LVL1 = 0 / READ LVL2 = 1 / READ LVL4 = 1
READ LVL1 = 1 / READ LVL2 = 0 / READ LVL4 = 1
READ LVL1 = 1 / READ LVL2 = 1 / READ LVL4 = 0

READ LVL1, READ LVL2 and READ LVL4 are low active.
16 BITS INPUT

Ax001 // operand 1 [LVL4] (Bits are active-high)
AxSL7 // operand 1 + 7 shift left // NOT CONNECT [LVL4] (Bits are active-high)
Bx001 // operand 2 [LVL4] (Bits are active-high)
BxSL7 // operand 2 + 7 shift left [LVL4] (Bits are active-high)
Cx001 // 0000 0000 0000 0001 [LVL2] (Bits are active-high)
Cx009 // 0000 0000 0000 1001 [LVL2] (Bits are active-high)

16 BITS OUTPUT (Only B's accu are available)

Qx000 // result (Bits are active-high)
Sx000 // sign [0 = positive sign, 1 = negative sign] (Bits are active-high)

8 BITS OUTPUT

Zx999 // [7,6,5,4,3,2,1,0] (Bits are active-high)

BIT 7 : Read Ax001
BIT 6 : Put flag "stop clock cpu" to 1
BIT 5 : Read Bx001
BIT 4 : Read BxSL7
BIT 3 : Write Qx000
BIT 2 : Write Sx000
BIT 1 : Read Cx009
BIT 0 : Read Cx001
while(1){
if(BP_EQ ==1){
Sx000 = 0;
SET();
DDAA();
DDAB();
while(flag_DDAA == 0){
;
}
tempo(10000);
if(BP_ADD == 1){
ADD();
}
if(BP_SUB == 1){
SUB();
}
if(BP_MUL == 1){
MUL();
}
if(BP_DIV == 1){
DIV();
}
}
}
_________________________________________________
A1 = Ax001; {Zx999 = 80} //$0D [LV4]
B1 = Bx001; {Zx999 = 20} //$0E [LV4]
_________________________________________________
B2 = A1 + B1; //$11 [LV1]
_________________________________________________
Qx000 = B2; {Zx999 = 48} //$12 [LVX]
_________________________________________________

t(max) = t(min) : 5*(2+1+1) = 0min20.00s
_________________________________________________
A1 = Ax001; {Zx999 = 80} //$04 [LV4]
B1 = Bx001; {Zx999 = 20} //$05 [LV4]
_________________________________________________
if(A1 < B1){ //$06 [LVX]
B2 = B3; //$07 [LV4]
}
B1 = A1 - B1; //$08 [LV1]
if(B2 = Cx001){ {Zx999 = 01} //$09 [LVX]
B1 = 0 - B1; //$0A [LV1]
}
_________________________________________________
Qx000 = B1; {Zx999 = 08} //$0B [LVX]
Sx000 = B2; {Zx999 = 44} //$0C [LVX]
_________________________________________________

t(max) : 5*(2+5+2) = 0min45.00s
t(min) : 5*(2+3+2) = 0min35.00s
A1 = Ax001; {Zx999 = 80} //$13 [LV4]
B1 = Bx001; {Zx999 = 20} //$14 [LV4]
_________________________________________________
do{
A3 = B1 AND 1; //$15 [LV4]
if(A3 != 0){ //$16 [LVX]
B2 = B2 + A1; //$17 [LV1]
}
A1 = A1 SL+0; //$18 [LV2]
B1 = B1 SR; //$19 [LV4]
A2 = A2 - B3; //$1A [LV1]
}while(A2 != 0) //$1B [LVX]
_________________________________________________
Qx000 = B2; {Zx999 = 48} //$1C [LVX]
_________________________________________________

t(max) : 5*(2+9*7+1) = 5min30.00s
t(min) : 5*(2+9*6+1) = 4min45.00s
_________________________________________________
A1 = Ax001; {Zx999 = 80} //$1D [LV4]
B1 = BxSL7; {Zx999 = 20} //$1E [LV4]
_________________________________________________
A2 = A2 - B3; //$29 [LV1]
do{
if(A1 >= B1){ //$21 [LVX]
A1 = A1 - B1; //$22 [LV1]
B2 = B2 SL+1; //$23 [LV4]
}else{
B2 = B2 SL+0; //$24 [LV4]
}
A2 = A2 - B3; //$25 [LV1]
B1 = B1 SR; //$26 [LV4]
}while(A2 != 0) //$27 [LVX]
_________________________________________________
Qx000 = B2; {Zx999 = 48} //$28 [LVX]
_________________________________________________

t(max) : 5*(2+8*6+1) = 4min15.00s
t(min) : 5*(2+8*5+1) = 3min35.00s
_________________________________________________
A1,A2,A3,B1,B2,B3 = 0; //$01 [LVX]
B3 = Cx001; {Zx999 = 01} //$02 [LV2]
A2 = Cx009; {Zx999 = 02} //$03 [LV2]
_________________________________________________

t(max) = t(min) : 5*(3) = 0min15.00s
Bits are active-low.
- 0 = no torch
- 1 = torch

BIT0 (OUTPUT):
- 0 : Read LVL2
- 1 : Noting
BIT1 (OUTPUT):
- 0 : Read LVL1
- 1 : Nothing
BIT2 (INPUT):
- 0 : A<=B
- 1 : A>B
BIT3 (INPUT):
- 0 : A>=B
- 1 : A<B
BIT4 (INPUT):
- 0 : A=B
- 1 : A!=B
BIT5 (OUTPUT):
- 0 : Nothing
- 1 : Write A3
BIT6 (OUTPUT):
- 0 : Nothing
- 1 : Write A2
BIT7 (OUTPUT):
- 0 : Nothing
- 1 : Write A1
BIT8 (OUTPUT):
- 0 : Read A3
- 1 : Nothing
BIT9 (OUTPUT):
- 0 : Read A2
- 1 : Nothing
BIT10 (OUTPUT):
- 0 : Read A1
- 1 : Nothing
BIT11 (OUTPUT):
- 0 : Shift right
- 1 : No shift
BIT12 (OUTPUT):
- 0 : X or 0
- 1 : X or 1
BIT13 (OUTPUT):
- 0 : Shift left
- 1 : No shift
BIT14 (OUTPUT):
- 0 : X and FF
- 1 : X and 01
BIT15 (OUTPUT):
- 0 : Add
- 1 : Sub
BIT16 (OUTPUT):
- 0 : Nothing
- 1 : Write A1
BIT17 (OUTPUT):
- 0 : Nothing
- 1 : Write A2
BIT18 (OUTPUT):
- 0 : Nothing
- 1 : Write A3
BIT19 (OUTPUT):
- 0 : Read A3
- 1 : Nothing
BIT20 (OUTPUT):
- 0 : Read A2
- 1 : Nothing
BIT21 (OUTPUT):
- 0 : Read A1
- 1 : Nothing

Grâce à ce système vous pouvez écrire vos propres programmes et utiliser les périphériques déjà présents (convertisseur BCD -> BIN, convertisseur BIN -> BCD) ou bien créer les votres !

Enjoy !

PS : Tout les composants et les programmes ont été fait maison.
 
Dernière édition:
  • J'aime
Reactions: McBooster et Neph
Salut,
Bien joli travail !

Au début j'ai lu 125MHz au lieu de 125mHz... :wheatsprout:

Pourquoi tu mets le compteur ordinal en active-low ?

294b de prog, on peut commencer à s'amuser gentiment avec ça... !
Comment tu gère l'overflow ? J'ai rien vu à ce sujet.

Je pige que dalle à ton spoiler "Fonctionnement de l'ALU"), tu as une documentation sur la lecture de ce genre de truc ?
Ça a pas l'air d'être un ripple carry en tout cas, tu utilise quel schéma d'additionneur ? (Puisque tu fais de l'adder une sorte de bloc minimal dont les itérations viennent à créer les autres opérations)

Les registres sont stockés en bordel dans la DPRAM ou j'ai rien pigé ?
 
Bien joli travail !
Merci !

Pourquoi tu mets le compteur ordinal en active-low ?
Et bien cela provient du fait que j'ai relier le bus de set du PC au reset des D-Latch au lieu du set. Des bits actifs à l'état haut aurait permis une programmation plus simple du µC.

Comment tu gère l'overflow ?
Je ne le gère pas actuellement, pour répondre de manière plus large, ce µC ne possède pas de registre d'état (bits NZVC). Je pourrais peut-être le rajouter dans l'avenir.

Je pige que dalle à ton spoiler "Fonctionnement de l'ALU"), tu as une documentation sur la lecture de ce genre de truc ?
En faites, l'ALU est divisé en 4 étages (de bas en haut) et chaque étage possède différents modules. Le 1er niveau permet de faire A+B et A-B donc lorque tu auras un calcul du genre A1=A1+B1, il faudra mettre une torche sur le BIT0 (Read LV2) de OP et rien sur le BIT1 (Read LV1) de OP. Pour le niveau 2, il permet de faire un shift left OU 1, un shift right, un A AND 01, un A AND FF ou bien un shift left OU 0 que sur A. Le niveau 3 permet de faire des comparaisons entre A et B. Ce niveau possède les BIT2, 3 et 4 en entrée du bus OP. Enfin le niveau 4 permet de faire la même chose que le niveau 3 mais cette fois-ci qu'avec les accumulateurs connectées au bus d'entrée de l'ALU B. On accède au niveau 4 en mettant à 0 les BIT0 et 1 de OP .

Ça a pas l'air d'être un ripple carry en tout cas, tu utilise quel schéma d'additionneur ? (Puisque tu fais de l'adder une sorte de bloc minimal dont les itérations viennent à créer les autres opérations)
C'est un ripple carry adder ^^, 4 * ça -> (https://upload.wikimedia.org/wikipedia/commons/5/5d/4-bit_ripple_carry_adder.svg).

Les registres sont stockés en bordel dans la DPRAM ou j'ai rien pigé ?
Dans la DPRAM, il y a 6 "accumulateurs" et le bus Zx999 ne possède pas de registre, c'est la ROM directement qui agit sur les périphériques.
 
Merci pour tes explications !

Des bits actifs à l'état haut aurait permis une programmation plus simple du µC.
C'est pour ça que je posais la question huehue.

Dans la DPRAM, il y a 6 "accumulateurs" et le bus Zx999 ne possède pas de registre, c'est la ROM directement qui agit sur les périphériques.
C'est quoi le bus Zx999 ? :wheatsprout:

Y'a moyen de sévèrement accélérer le temps de processing alors non ?
 
C'est quoi le bus Zx999 ? :wheatsprout:
ça :

8 BITS OUTPUT

Zx999 // [7,6,5,4,3,2,1,0] (Bits are active-high)

BIT 7 : Read Ax001
BIT 6 : Put flag "stop clock cpu" to 1
BIT 5 : Read Bx001
BIT 4 : Read BxSL7
BIT 3 : Write Qx000
BIT 2 : Write Sx000
BIT 1 : Read Cx009
BIT 0 : Read Cx001

PS : Cette description est trouvable dans la présentation du µC dans la partie Entrées/Sorties.

C'est un bus qui permet de gérer les périphériques, ici, lancer les conversions, arrêter l'horloge du µC, écrire dans les registres et lire les ports.

Y'a moyen de sévèrement accélérer le temps de processing alors non ?
Si on parle que du ripple carry adder, son temps de propagation par bits est de 0.1s soit 1.6s juste pour le temps de propagation maximum. Après cette horloge possède une période relativement longue car il faut à la fois:
- Lire la DPRAM, attendre que les sorties de l'ALU soit stabilisées puis écrire dans la DPRAM mais aussi en parallèle si besoin,
- Lire la DPRAM, faire les comparaisons, charger le PC selon les BIT2, 3 et 4.
Cependant, on cherchant, il y aurait surement moyen d'augmenter la fréquence et pourquoi pas atteindre 125MHz xD.
 
PS : Cette description est trouvable dans la présentation du µC dans la partie Entrées/Sorties.
Mea culpa. :(

son temps de propagation par bits est de 0.1s
J'avais fait une ALU basée sur un ripple carry, et le full adder était loin d'être aussi rapide... Re-mea culpa :(

attendre que les sorties de l'ALU soit stabilisées puis écrire dans la DPRAM
C'est vrai que ça limite la capacité de traitement parallèle ça aussi.

pourquoi pas atteindre 125MHz
Pourquoi pas ? On pourrait jouer à Minecraft dans Minecraft comme ça. ^^
 
Cependant, on cherchant, il y aurait surement moyen d'augmenter la fréquence et pourquoi pas atteindre 125MHz xD.
Pourquoi pas ? On pourrait jouer à Minecraft dans Minecraft comme ça. ^^

Même avec en pipelinant (très français..) ta CPU, 125MHz sera impossible, tout comme 125kHz et certainement 125Hz. Après, si tu mets une clock à 125Mhz et que tu dis qu'une instruction prends 1M coups d'horloge...
 
C'était une blague et un clin d'oeil à l'erreur de lecture de 125 mHz de Le minaw ;). Sachant qu'un repeater à une latence de 0.1s, 10Hz semble être la fréquence max d'un circuit en redstone classique qui est un tant soit peu complexe. Et puis je doute que le jeu soit rafraîchi toutes les 125us :).