CentraleSupélecDépartement informatique
Plateau de Moulon
3 rue Joliot-Curie
F-91192 Gif-sur-Yvette cedex
Documentation des composants de Logisim

Cette page présente une description sommaire des principaux composants de Logisim dont vous aurez besoin à l'occasion du premier bureau d'étude et de la première étude de laboratoire.

1. Register

Il s'agit d'un registre edge-triggered classique, dont la taille est indiquée via l'attribut Bit Width.

1.1 Base

La valeur du registre est donnée en permanence sur la sortie {$Q$}. Pour mémoriser une nouvelle valeur, il faut la présenter sur l'entrée {$D$} et envoyer un front montant sur la commande d'horloge (petit triangle situé en bas).

En fonctionnement de base, ne rien connecter sur {$clr$}.

En cours de simulation, il est possible de saisir manuellement une valeur dans le registre. Pour cela, cliquer dessus avec l'outil d'interaction, puis taper une valeur en hexadécimal.

1.2 Pour en savoir plus

La valeur du registre est forcée à 0 si un signal à 1 est présent sur la commande {$clr$}.

2. RAM

Le composant RAM de Logisim est une mémoire en lecture-écriture. On peut spécifier la taille des mots mémoire (attribut Data Bit Width) ainsi que la taille des adresses (et donc la taille de la mémoire, attribut Address Bit Width).

2.1 Fonctionnement de base

La mémoire peut fournir des valeurs situées à une adresse, ou bien écrire des valeurs à cette adresse. L'adresse doit être spécifiée en permanence sur l'entrée {$A$}. Notez bien que si {$A$} change, alors l'adresse pointée par la mémoire change immédiatement : il n'y a pas de mémorisation de l'adresse. Pour mémoriser l'adresse, il peut donc être opportun d'ajouter un registre d'adresse mémoire ({$RADM$}) en amont de l'entrée {$A$}.

Lecture. Pour faire fonctionner la mémoire en mode lecture, il faut mettre le port ld à 1. Alors, les données lues sont disponibles sur le port {$D$} sur le côté droite de la mémoire.

Écriture. Pour écrire une donnée en mémoire, il faut présenter cette donnée sur le port {$D$} sur le côté gauche, tout en appliquant une valeur 1 sur le port {$str$}. La mémorisation est effectuée lorsqu'un front montant est envoyé sur l'entrée d'horloge (petit triangle situé en bas).

Important. Il faut faire en sorte que la valeur imposée sur le port {$ld$} soit toujours inversée par rapport à la valeur sur {$str$}

Il n'est pas nécessaire de connecter les ports {$sel$} et {$clr$}.

2.2 Fonctionnement avancé

Le port {$clr$} permet de mettre toute la mémoire à zéro (appliquer une valeur 1).

Le port {$sel$} permet d'inhiber la mémoire (en appliquant une valeur 0), ce qui permet de connecter plusieurs boîtiers mémoire en parallèle sur une même sortie.

2.3 Manipulation du contenu de la mémoire

Un clic droit sur un composant mémoire ouvre un menu contextuel qui permet d'en manipuler le contenu :

  • Edit Contents : ouvre une fenêtre qui permet de modifier le contenu de la mémoire ;
  • Clear Contents : met la mémoire à zéro ;
  • Load/Save Image : permet de charger et d'enregistrer le contenu de la mémoire dans un fichier.

3. ALU

Le composant UAL (en anglais ALU pour Arithmetic and Logic Unit) est purement combinatoire ; il réalise diverses opérations sur deux entrées {$A$} et {$B$} dont la taille en bits peut être spécifiée. Le résultat sera disponible sur le port de sortie {$S$}.

L'opération effectuée par l'UAL est indiquée grâce aux quatre bits de contrôle {$U0$}...{$U3$}. La table suivante montre les opérations que l'UAL est capable d'effectuer et les valeurs correspondantes des bits de contrôle.

U3U2U1U0Opération
0000S = A
0001S = A ou B
0010S = non (A ou B)
0011S = non (A et B)
0100S = A et B
0101S = B
0110S = non B
0111S = A xor B
1000S = A - B
1001S = A + B
1010S = A + A
1011S = A - 1
1100S = A + 1
1101S = FFFF
1110S = 0
1111S = non A

En sortie, l'UAL comporte quatre indicateurs :

  • {$N$} : indicateur de signe, vaut 1 si {$S$} < 0 ;
  • {$Z$} : indicateur de résultat nul, vaut 1 si {$S$} = 0 ;
  • {$C$} : indicateur de retenue, vaut 1 si une retenue apparaît lors du calcul de {$S$} ;
  • {$V$} : indicateur de dépassement de capacité, vaut 1 si le calcul de {$S$} produit un dépassement.

4. Control Unit

Le séquenceur réalise deux fonctions complémentaires :

  • Génération en interne de signaux d'horloge (circuit synchrone, fixe),
  • Mise en œuvre d'un circuit purement combinatoire défini par des équations logiques. Ces équations sont à saisir dans une fenêtre dédiée.

4.1 Génération des signaux d'horloge

Le module d'horloge génère des signaux {$T_i$} et {$P_i$} comme ci-dessous. Notez bien que dans la réalité, ces signaux peuvent facilement être générés par un ensemble de bascules {$D$} reliées entre elles.

Ces signaux sont dérivés de l'horloge de Logisim. C'est pourquoi un composant standard horloge doit impérativement être connecté à l'entrée d'horloge du séquenceur (connecteur du haut, en forme de triangle).

Le nombre de temps doit être précisé (attribut Cycle Length). Après le dernier temps, l'unité d'horloge recommence au temps 1.

L'évolution de ces signaux d'horloge peut suivre différents modes qui doivent être sélectionnés en cliquant en mode simulation sur l'un des boutons situés en bas du composant séquenceur ({$P$}, {$T$}, {$C$}, {$A$}). Au début, le séquenceur est arrêté.

  • Pas à pas ({$S$} pour Step). Le séquenceur avance d'un tiers de temps (par exemple, passe de {$T_1$} à {$T_1+P_1$}), puis s'arrête.
  • Temps à temps ({$T$}). Le séquenceur avance d'un temps (par exemple, de {$T_1$} à {$T_2$}), puis s'arrête.
  • Cycle à cycle ({$C$}). Le séquenceur avance d'un cycle et s'arrête en début du cycle suivant (i.e. sur {$T_1$}).
  • Automatique ({$A$}). Fonctionnement en continu.

Dans le menu contextuel du séquenceur (clic droit), l'option Reset permet de repartir du début de {$T_1$}.

4.2 Calcul des sorties

Le comportement combinatoire du séquenceur est défini par un ensemble d'équations à saisir dans la fenêtre prévue à cet effet, qui s'ouvre lorsque l'on clique sur le texte click to edit de l'attribut Equations du séquenceur.

Dans cette fenêtre on indique essentiellement quelles sont les entrées, quelles sont les sorties, et on exprime les sorties en fonction des entrées et des signaux internes {$T_i$}/{$P_i$}. À des fins de commodité, il est également possible de définir d'autres signaux internes, de façon à factoriser le calcul de certaines formules.

La syntaxe à utiliser pour les équations est la suivante :

  • Ligne du type input nom : définit une entrée ;
  • Ligne du type internal nom = equation : définit un signal interne par la donnée d'une équation, dans laquelle peuvent apparaître les entrées, les {$T_i$}/{$P_i$} et les autres signaux internes définis plus haut dans la fenêtre ;
  • Ligne du type output nom = equation : définit une sortie par la donnée d'une équation, dans laquelle peuvent apparaître les entrées, les {$T_i$}/{$P_i$} et les signaux internes ;
  • On peut utiliser les constantes 0 et 1 dans les équations ;
  • Sur une ligne, si un # apparaît, toute la fin de la ligne est ignorée (commentaire) ;
  • Les espaces ne sont pas significatifs ;
  • Les lignes vides sont ignorées.
  • Les opérateurs logiques s'écrivent de la manière suivante :
    • & et * sont utilisés indifféremment pour écrire un ET logique.
    • | et + sont utilisés indifféremment pour écrire un OU logique.
    • ! est utilisé pour écrire un NON logique.

Le séquenceur accepte toute expression bien parenthésée. Les opérateurs sont ainsi ordonnés par ordre de priorités décroissantes : ! > & > |.

À tout moment, il est possible de modifier les équations. Dès validation de la fenêtre de saisie par Ok, les valeurs des sorties du séquenceur sont immédiatement remises à jour.

Le composant séquenceur affiche sur ses broches le nom des entrées et des sorties qui leur a été donné. Les entrées apparaissent à gauche ; les sorties à droite. Les broches apparaissent dans l'ordre dans lequel elles sont spécifiées dans la liste des équations. Si vous avez placé le séquenceur dans un schéma et que vous modifiez les équations, veillez donc à conserver le même ordre pour les signaux, sous peine de devoir modifier votre câblage.

4.3 États d'erreur du séquenceur

Lorsque le séquenceur est en fonctionnement normal, il affiche tout en haut le mot Control Unit en noir. S'il a détecté une erreur, un texte en rouge s'affiche, qui indique le type d'erreur qui est survenu. Les erreurs sont les suivantes :

  • Séq#E/S : erreur pendant le chargement des équations.
  • Séq#PARSE : erreur de syntaxe dans les équations : le programme n'a pas pu interpréter l'une des lignes.
  • Séq#EVAL : erreur lors de l'évaluation des équations, en général due à l'utilisation dans une équation d'un nom de signal qui n'a pas été défini auparavant.

Lorsque le séquenceur se trouve dans un état d'erreur, un clic sur le composant avec l'outil interaction permet d'afficher un message d'erreur détaillé.

4.4 Exemple d'utilisation du séquenceur

Cette section présente un exemple simple d'utilisation du séquenceur, pour réaliser non pas un ordinateur, mais un petit système synchrone. Le but de ce système est de faire compter un registre de 0 à 9, puis repartir à 0, et ainsi de suite. On construit le circuit suivant, composé d'un registre, d'une UAL et d'un séquenceur :

Le séquenceur suit des cycles de deux temps ; son fonctionnement est le suivant :

  • Au temps 1, l'UAL ajoute un au contenu du registre. La nouvelle valeur est chargée dans le registre sur le front montant de {$P_1$} ;
  • Au temps 2, l'UAL compare le contenu du registre et le nombre 10. Si le premier est supérieur ou égal à 10, alors le registre est remis à zéro.

La liste d'équations pour le séquenceur est ainsi rédigée :

input N

input Z

internal negatif_ou_nul = Z | N

output U0 = 1

output U1 = T2

output U2 = T1

output U3 = 0

output load = P1

output clr = P2 & negatif_ou_nul

5. Register File

Le Register File est une collection de {$n$} registres, identifiés par les entiers 0, 1, ..., {$n-1$}. Pour spécifier le nombre {$n$} de registres, il faut changer la valeur de l'attribut Selector bits à {$\log_2 n$}. Pour spécifier la taille des registres, il faut changer la valeur de l'attribut Data bits.

Le Register File a deux sorties, out1 et out2, et cinq entrées :

  • in : Les données à enregistrer dans un registre.
  • is : L'identifiant du registre dans lequel les données en entrée doivent être enregistrées.
  • rst : Détruit le contenu des registres (on peut l'ignorer).
  • os1 : L'identifiant du registre la valeur de laquelle est imposée sur la sortie out1.
  • os2 : L'identifiant du registre la valeur de laquelle est imposée sur la sortie out2.

Il y a également quatre drapeaux :

  • on1 et oz1, qui ont valeur 1 si la valeur sur la sortie out1 est négative ou nulle respectivement.
  • on2 et oz2, qui ont valeur 1 si la valeur sur la sortie out2 est négative ou nulle respectivement.

6. Registre à incrément

Ce registre dérive du registre de base de Logisim, à ceci près qu'il est capable de s'incrémenter de lui-même. Cela permet par exemple de réaliser facilement un compteur ordinal.

Sur un front montant de son horloge, ce registre mémorise l'entrée D, ou bien incrémente sa valeur, selon le signal appliqué sur la commande C :

  • si C = 0 : incrémentation de la valeur précédente ;
  • si C = 1 : mémorisation de l'entrée D.