#include #include #include #include "moteur_simulateur.h" #include "gst_ual.h" #include "gst_cond.h" #include "gst_decodeur.h" #include "gst_micro_mem.h" #include "gst_cp.h" #include "gst_controleur_bus.h" #include "gst_mem_principale.h" #include "gst_micro_cp.h" #include "gst_reg.h" #include "gst_bus.h" #include "gst_eval_grp.h" #include "gst_ptr_pile.h" #define CLEF_MP "MAIN-MEMORY" #define CLEF_DECI "INSTRUCTION-DECODER" #define CLEF_MM "MICRO-MEMORY" static int compteur_cycles; static int **tab_mm; static int *tab_mp; static int *tab_deci; static int *mop; static bus_st bus_donnees, bus_adresses, bus_reset, bus_cp_cb, bus_regad_cb, bus_deci_mcp, bus_mcp_mm, bus_regdonnes_cb, bus_pptr_cb, bus_reg0_ual, bus_ual_reg1, bus_reg1_ual; static FIL fil_ual_regcond [NBRE_COND], fil_regcond_cond [NBRE_COND]; static FIL fil_cond_cp; static cp_st cp; static mp_st mp; static deci_st deci; static mcp_st mcp; static mm_st mm; static reg_st reg0, reg1, regad, regdonnees, regcond [NBRE_COND]; static cb_st cb_cp, cb_regad, cb_reg1, cb_regdonnes, cb_pptr; static ual_st ual; static cond_st sauts_cond; static pptr_st pptr; static evgr_st composants_sequentiels, composants_combinatoires; static int char_to_number(char c) { return (c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : c - 'A' + 10; } static void verifie_fichier (FILE *fic, char *clef, char *nom_fic) { int nbre_lu; char car; int cpt = 0; for (;;) { nbre_lu = fread (&car, 1, 1, fic); if ((car == 10 || car == 13) && clef[cpt] == 0) break; if (nbre_lu == 0 || clef [cpt] != car) { fprintf (stderr, "Fichier %s invalide ou incomplet.\n", nom_fic); fclose (fic); exit (EXIT_FAILURE); } cpt++; } } static void charge_mp (char *nom_fic, int *tab_mp) { FILE *fic = fopen(nom_fic, "r"); int i; if (fic == NULL) { fprintf(stderr, "Ne peut ouvrir le fichier mémoire principale, %s\n", nom_fic); exit(EXIT_FAILURE); } verifie_fichier (fic, CLEF_MP, nom_fic); for(i = 0; i < TAILLE_MP; i++) { int num = char_to_number (getc (fic)); num = num * 16 + char_to_number (getc (fic)); if (num < 0) { tab_mp [i] = 0; continue; } tab_mp [i] = num; /* skip until end of line */ while (getc (fic) != '\n') ; } fclose (fic); } static void charge_mm (char *nom_fic, int *tab_mm [NBRE_MOP]) { FILE *fic = fopen(nom_fic, "r"); int i; if (fic == NULL) { fprintf(stderr, "Ne peut ouvrir le fichier micro mémoire, %s\n", nom_fic); exit(EXIT_FAILURE); } verifie_fichier (fic, CLEF_MM, nom_fic); for(i = 0; i < TAILLE_MM; i++) { int j; *tab_mm [i] = 0; for(j = 1; j < NBRE_MOP; j++) *(tab_mm [i] + j) = (getc (fic) == '1'); /* skip until end of line */ while (getc (fic) != '\n') ; } fclose (fic); } static void charge_deci (char *nom_fic, int *tab_deci) { FILE *fic = fopen(nom_fic, "r"); int i; if(fic == NULL) { fprintf(stderr, "Ne peut ouvrir le fichier %s\n", nom_fic); exit(EXIT_FAILURE); } verifie_fichier (fic, CLEF_DECI, nom_fic); for(i = 0; i < TAILLE_DECI; i++) { int num = char_to_number (getc (fic)); num = num * 16 + char_to_number (getc (fic)); tab_deci [i] = num; while (getc (fic) != '\n') ; } fclose (fic); } static void mtr_reset (void) { int i; for (i = 0; i < NBRE_MOP; i++) mop[i] = 0; /* Reset */ *mop = 1; } /* Les noms des fichiers dont les champs sont à NULL seront ceux * précédemment utilisés */ void mtr_reset_et_charge_memoires (char *nom_fic_mp, char *nom_fic_deci, char *nom_fic_mm) { static char *nom_f_mp = NULL; static char *nom_f_deci = NULL; static char *nom_f_mm = NULL; if (nom_fic_mp) nom_f_mp = nom_fic_mp; else nom_fic_mp = nom_f_mp; if (nom_fic_deci) nom_f_deci = nom_fic_deci; else nom_fic_deci = nom_f_deci; if (nom_fic_mm) nom_f_mm = nom_fic_mm; else nom_fic_mm = nom_f_mm; charge_mm (nom_fic_mm, tab_mm); charge_mp (nom_fic_mp, tab_mp); charge_deci (nom_fic_deci, tab_deci); mtr_reset (); compteur_cycles = 0; } void mtr_cycle_precedant () { int i; int max = compteur_cycles - 1; if (max < 0) return; mtr_reset_et_charge_memoires (NULL, NULL, NULL); for (i = 0; i < max; i++) mtr_cycle_suivant (); } void mtr_cycle_suivant () { compteur_cycles++; evgr_evalue (composants_sequentiels); evgr_evalue (composants_combinatoires); } /* La structure mtr_infos doit avoir été allouée auparavant */ void mtr_init (mtr_infos *infos) { int i; /* Initialisation des mémoires */ tab_mm = (int **) malloc (sizeof (int) * TAILLE_MM); assert (tab_mm != NULL); for (i = 0; i < TAILLE_MM; i++) { tab_mm [i] = (int *) malloc (sizeof (int) * NBRE_MOP); assert (tab_mm [i] != NULL); } tab_mp = (int *) malloc (sizeof (int) * TAILLE_MP); assert (tab_mp != NULL); tab_deci = (int *) malloc (sizeof (int) * TAILLE_DECI); assert (tab_deci != NULL); mop = (int *) malloc (sizeof (int) * NBRE_MOP); mtr_reset (); /* Initialisation des bus */ bus_donnees = bus_init (); bus_adresses = bus_init (); bus_reset = bus_init (); bus_cp_cb = bus_init (); bus_regad_cb = bus_init (); bus_deci_mcp = bus_init (); bus_mcp_mm = bus_init (); bus_reg0_ual = bus_init (); bus_ual_reg1 = bus_init (); bus_reg1_ual = bus_init (); bus_regdonnes_cb = bus_init (); bus_pptr_cb = bus_init (); fil_cond_cp = 0; for (i = 0; i < NBRE_COND; i++) { fil_ual_regcond [i] = 0; fil_regcond_cond [i] = 0; } /* Initialisation des autres composants */ /* CP */ cp = cp_init (&fil_cond_cp, (int *) mop + 7, (int *) mop, bus_valeur (bus_adresses), bus_valeur (bus_cp_cb)); /* Contrôleur du bus CP au bus d'adresses */ cb_cp = cb_init ((int *) mop + 5, bus_valeur (bus_cp_cb), bus_valeur (bus_adresses)); /* Mémoire principale */ mp = mp_init ((int *) mop + 3, (int *) mop + 4, bus_valeur (bus_adresses), bus_valeur (bus_donnees), tab_mp, TAILLE_MP); /* Décodeur d'instruction */ deci = deci_init (bus_valeur (bus_donnees), bus_valeur (bus_deci_mcp), tab_deci, TAILLE_DECI); /* Micro cp */ mcp = mcp_init ((int *) mop, (int *) mop + 1, (int *) mop + 2, bus_valeur (bus_deci_mcp), bus_valeur (bus_mcp_mm)); /* Micro mémoire */ mm = mm_init (bus_valeur (bus_mcp_mm), mop, NBRE_MOP, tab_mm, TAILLE_MM); /* Contrôleur de bus regad - bus d'adresse */ cb_regad = cb_init ((int *) mop + 10, bus_valeur (bus_regad_cb), bus_valeur (bus_adresses)); /* Contrôleur de bus reg1 - ual / bus de données */ cb_reg1 = cb_init ((int *) mop + 8, bus_valeur (bus_reg1_ual), bus_valeur (bus_donnees)); /* Contrôleur de bus registre-données - bus de données */ cb_regdonnes = cb_init ((int *) mop + 22, bus_valeur (bus_regdonnes_cb), bus_valeur (bus_donnees)); /* C-B du pointeur de pile */ cb_pptr = cb_init ((int *) mop + 25, bus_valeur (bus_pptr_cb), bus_valeur (bus_adresses)); /* Registres */ reg0 = reg_init ((int *) mop + 11, bus_valeur (bus_donnees), bus_valeur (bus_reg0_ual)); reg1 = reg_init ((int *) mop + 12, bus_valeur (bus_ual_reg1), bus_valeur (bus_reg1_ual)); regad = reg_init ((int *) mop + 9, bus_valeur (bus_donnees), bus_valeur (bus_regad_cb)); regdonnees = reg_init ((int *) mop + 21, bus_valeur (bus_adresses), bus_valeur (bus_regdonnes_cb)); /* Unité arithmétique et logique */ ual = ual_init (bus_valeur (bus_reg0_ual), bus_valeur (bus_reg1_ual), bus_valeur (bus_ual_reg1), (int *) mop + 13, 8, fil_ual_regcond); /* Unité de gestion des sauts conditionnels */ sauts_cond = cond_init (fil_regcond_cond, &fil_cond_cp, (int *) mop + 6, (int *) mop + 17, (int *) mop + 18, (int *) mop + 19, (int *) mop + 20); /* Registres des conditions */ for (i = 0; i < NBRE_COND; i++) regcond [i] = reg_init ((int *) mop + 16, &(fil_ual_regcond [i]), &(fil_regcond_cond [i])); /* Pointeur de pile */ pptr = pptr_init ((int *) mop + 23, (int *) mop + 24, (int *) mop, bus_valeur (bus_pptr_cb), TAILLE_MP - 1); /** Association des composants combinatoires puis des composants séquentiels * pour une évaluation groupée */ composants_combinatoires = evgr_init (); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) cb_evalue, cb_cp, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) cb_evalue, cb_regad, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) cb_evalue, cb_pptr, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) cb_evalue, cb_regdonnes, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) mp_evalue, mp, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) cb_evalue, cb_reg1, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) ual_evalue, ual, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) cond_evalue, sauts_cond, 1); evgr_ajoute_composant (composants_combinatoires, (type_fct_evalue) deci_evalue, deci, 1); composants_sequentiels = evgr_init (); evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) mcp_evalue, mcp, 1); evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) reg_evalue, regad, 1); evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) reg_evalue, reg0, 1); evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) reg_evalue, reg1, 1); evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) reg_evalue, regdonnees, 1); for (i = 0; i < NBRE_COND; i++) { evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) reg_evalue, regcond [i], 1); } evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) pptr_evalue, pptr, 1); evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) cp_evalue, cp, 1); evgr_ajoute_composant (composants_sequentiels, (type_fct_evalue) mm_evalue, mm, 1); *infos = (struct mtr_infos) { mop, tab_mp, tab_deci, tab_mm, bus_valeur (bus_donnees), bus_valeur (bus_adresses), bus_valeur (bus_cp_cb), bus_valeur (bus_regad_cb), bus_valeur (bus_deci_mcp), bus_valeur (bus_mcp_mm), bus_valeur (bus_reg0_ual), bus_valeur (bus_ual_reg1), bus_valeur (bus_reg1_ual), bus_valeur (bus_regdonnes_cb), bus_valeur (bus_pptr_cb), fil_ual_regcond, fil_regcond_cond, &fil_cond_cp }; } void mtr_libere () { int i; for (i = 0; i < TAILLE_MM; i++) free (tab_mm [i]); free (tab_mm); free (tab_mp); free (mop); free (tab_deci); bus_libere (bus_donnees); bus_libere (bus_adresses); bus_libere (bus_reset); bus_libere (bus_cp_cb); bus_libere (bus_regad_cb); bus_libere (bus_deci_mcp); bus_libere (bus_mcp_mm); bus_libere (bus_reg0_ual); bus_libere (bus_ual_reg1); bus_libere (bus_reg1_ual); bus_libere (bus_regdonnes_cb); bus_libere (bus_pptr_cb); cp_libere (cp); cb_libere (cb_cp); mp_libere (mp); deci_libere (deci); mcp_libere (mcp); mm_libere (mm); cb_libere (cb_regad); cb_libere (cb_reg1); cb_libere (cb_regdonnes); cb_libere (cb_pptr); reg_libere (reg0); reg_libere (reg1); reg_libere (regad); reg_libere (regdonnees); ual_libere (ual); cond_libere (sauts_cond); for (i = 0; i < NBRE_COND; i++) reg_libere (regcond [i]); pptr_libere (pptr); evgr_libere (composants_sequentiels); evgr_libere (composants_combinatoires); }