big overhaul

This commit is contained in:
Raphaël LACROIX 2023-05-31 23:20:18 +02:00
parent 30d2d7577d
commit 5e4be22e3d
53 changed files with 8527 additions and 0 deletions

View file

31
asm/asm2 Normal file
View file

@ -0,0 +1,31 @@
AFC 0 5
STORE 1 0
LOAD 0 1
STORE 0 0
AFC 0 8
STORE 1 0
LOAD 0 0
LOAD 1 1
EQ 2 1 0
STORE 2 2
LOAD 0 2
NOT 2 0
STORE 3 2
JMF 3 30
AFC 0 20
STORE 4 0
LOAD 0 0
LOAD 1 4
INF 2 0 1
STORE 2 2
JMF 2 30
AFC 0 2
STORE 1 0
LOAD 0 0
LOAD 1 1
ADD 0 0 1
STORE 4 0
LOAD 0 4
STORE 0 0
JMP 14
NOP

1
asm/asm3 Normal file
View file

@ -0,0 +1 @@
((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000800"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"07000200"),(x"0C020000"),(x"08030200"),(x"10031E00"),(x"06001400"),(x"08040000"),(x"07000000"),(x"07010400"),(x"09020001"),(x"08020200"),(x"10021E00"),(x"06000200"),(x"08010000"),(x"07000000"),(x"07010100"),(x"01000001"),(x"08040000"),(x"07000400"),(x"08000000"),(x"0F0E0000"),(x"FF000000"),others => (x"ff000000"))

36
compilateur/Makefile Normal file
View file

@ -0,0 +1,36 @@
GRM=yacc.y
LEX=lex.l
BIN=out
CC=gcc
CFLAGS=-Wall -g
OBJ=yacc.tab.o lex.yy.o table.o operations.o blocs.o asmTable.o
asm: $(BIN)
@touch ../tests/testFile # to prevent an error in case of deletion
./out < ../tests/testFile
build: $(BIN)
%.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
yacc.tab.c: $(GRM)
bison -d -t -v $<
lex.yy.c: $(LEX)
flex $<
$(BIN): $(OBJ)
$(CC) $(CFLAGS) $(CPPFLAGS) $^ -o $@
clean:
rm $(OBJ) yacc.tab.c yacc.tab.h lex.yy.c
vhdl: clean asm
python3 ../cross-Compiler/cross-compiler.py
inter: clean asm
python3 ../interpreter/graph_interpreter.py

13
compilateur/asm Normal file
View file

@ -0,0 +1,13 @@
AFC 1 5
COP 0 1
AFC 1 8
EQ 2 0 1
NOT 3 2
JMF 3 13
AFC 4 20
INF 2 0 4
JMF 2 13
AFC 1 2
ADD 4 0 1
COP 0 4
JMP 6

31
compilateur/asm2 Normal file
View file

@ -0,0 +1,31 @@
AFC 0 5
STORE 1 0
LOAD 0 1
STORE 0 0
AFC 0 8
STORE 1 0
LOAD 0 0
LOAD 1 1
EQ 2 1 0
STORE 2 2
LOAD 0 2
NOT 2 0
STORE 3 2
JMF 3 30
AFC 0 20
STORE 4 0
LOAD 0 0
LOAD 1 4
INF 2 0 1
STORE 2 2
JMF 2 30
AFC 0 2
STORE 1 0
LOAD 0 0
LOAD 1 1
ADD 0 0 1
STORE 4 0
LOAD 0 4
STORE 0 0
JMP 14
NOP

1
compilateur/asm3 Normal file
View file

@ -0,0 +1 @@
((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000800"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"07000200"),(x"0C020000"),(x"08030200"),(x"10031E00"),(x"06001400"),(x"08040000"),(x"07000000"),(x"07010400"),(x"09020001"),(x"08020200"),(x"10021E00"),(x"06000200"),(x"08010000"),(x"07000000"),(x"07010100"),(x"01000001"),(x"08040000"),(x"07000400"),(x"08000000"),(x"0F0E0000"),(x"FF000000"),others => (x"ff000000"))

109
compilateur/asmTable.c Normal file
View file

@ -0,0 +1,109 @@
#include <stdio.h>
#include "asmTable.h"
#include "stdlib.h"
#include <string.h>
static int labelCounter = 0;
/*At the start of the execution : the whole array is empty*/
static ASMLine* asmTable;
static int lineCounter = 0;
static int maxIndex = START_TABLE_SIZE;
#include "asmTable.h"
#include "table.h"
/* /!\ To be called at the beginning
* Initializes the array of Symbols*/
void initASMTable(){
asmTable = malloc(sizeof(ASMLine) * START_TABLE_SIZE);
}
/*Checks for the length of the array and reallocates if necessary*/
void checkASMArraySanity(){
if (lineCounter == maxIndex){
reallocateASMArray(maxIndex * 2);
}
}
/*reallocates the array with the specified size*/
void reallocateASMArray(int size){
ASMLine *temp = (ASMLine*) realloc(asmTable, (sizeof(ASMLine) * size));
if (temp != NULL){
asmTable = temp;
}
else {
error("Cannot allocate more memory.\n");
}
}
/*inserts an asm code line at the current index*/
void addLine(char* s) {
strcpy(asmTable[lineCounter].name,s);
asmTable[lineCounter].jumpLine = -1;
asmTable[lineCounter].conditionAddr = -1;
lineCounter++;
checkASMArraySanity();
displayASMTable();
}
/*inserts the address in case of jumps*/
void setJumpLine(int index, int addr) {
asmTable[index].jumpLine = addr;
displayASMTable();
}
/*inserts the condition's address in case of jumps*/
void setConditionAddr(int index, int addr) {
asmTable[index].conditionAddr = addr;
displayASMTable();
}
/*returns the current line (i.e. next one to insert)*/
int getCurrentLineNumber() {
return lineCounter;
}
/*displays the entire table at this moment*/
void displayASMTable(){
printf("\n");
doubleLine();
for (int i = 0; i < lineCounter; ++i) {
ASMLine a = asmTable[i];
if(a.jumpLine == -1) {
printf("%d | %s\n", i, a.name);
} else {
if(a.conditionAddr == -1) {
printf("%d | %s %d\n", i, a.name,a.jumpLine);
} else {
printf("%d | %s %d %d\n", i, a.name,a.conditionAddr,a.jumpLine);
}
}
if (i != lineCounter -1) {
line();
}
}
doubleLine();
}
/*exports the entire table to asm*/
void exportASMTable(){
FILE* fp;
fp = fopen("asm", "a");
for (int i = 0; i < lineCounter; ++i) {
ASMLine a = asmTable[i];
if(a.jumpLine == -1) {
fprintf(fp,"%s\n", a.name);
} else {
if(a.conditionAddr == -1) {
fprintf(fp,"%s %d\n", a.name,a.jumpLine);
} else {
fprintf(fp,"%s %d %d\n", a.name,a.conditionAddr,a.jumpLine);
}
}
}
fclose(fp);
}

48
compilateur/asmTable.h Normal file
View file

@ -0,0 +1,48 @@
//
// Created by chepycou on 4/18/23.
//
#ifndef PROJET_SYSTEMES_INFORMATIQUES_ASMTABLE_H
#define PROJET_SYSTEMES_INFORMATIQUES_ASMTABLE_H
#define START_TABLE_SIZE 128
#define LINE_MAX_LENGTH 50
typedef struct {
char name[LINE_MAX_LENGTH];
int conditionAddr;
int jumpLine;
} ASMLine;
/*============================
Array and Reallocation
============================*/
/*reallocates the array with the specified size*/
void reallocateASMArray(int size);
/*Checks for the length of the array and reallocates if necessary*/
void checkASMArraySanity();
/*inserts an asm code line at the current index*/
void addLine(char* s);
/* /!\ To be called at the beginning
* Initializes the array of Symbols*/
void initASMTable();
/*inserts the address in case of jumps*/
void setJumpLine(int index, int addr);
/*inserts the condition's address in case of jumps*/
void setConditionAddr(int index, int addr);
/*returns the current line (i.e. next one to insert)*/
int getCurrentLineNumber();
/*displays the entire table at this moment*/
void displayASMTable();
/*exports the entire table to asm*/
void exportASMTable();
#endif //PROJET_SYSTEMES_INFORMATIQUES_ASMTABLE_H

BIN
compilateur/asmTable.o Normal file

Binary file not shown.

59
compilateur/blocs.c Normal file
View file

@ -0,0 +1,59 @@
//
// Created by chepycou on 4/18/23.
//
#include "blocs.h"
#include "operations.h"
#include <stdio.h>
#include <string.h>
/*TODO on écrit tout dans un fichier asm extérieur puis on :
* - fait un parcours pour stocker dans une liste chaînée par exemple les valeur de ligne des labels
* - faire un parcours pour retirer les labels au début des lignes
* - faire un parcours pour remplacer les labels par leur valeur
* */
/*
int labelCount = 0;
int getNextLabel(){
return(labelCount++);
}
void printLabel(int labelWhile){
char label[LABEL_MAX_LENGTH];
sprintf(label,"%d_LABEL\n",labelWhile);
printf("%s",label);
FILE* fp;
fp = fopen("asm", "a");
fputs(label, fp);
fclose(fp);
}
int printNewLabel(){
int l = getNextLabel();
printLabel(l);
return l;
}
void printJumpToLabel(int labelWhile) {
char instr[ASM_TEXT_LEN];
sprintf(instr,"JMP %d_LABEL\n",labelWhile);
printf("%s",instr);
FILE* fp;
fp = fopen("asm", "a");
fputs(instr, fp);
fclose(fp);
}
void printJumpFToLabel(int labelWhile) {
char label[LABEL_MAX_LENGTH];
sprintf(label,"%d_LABEL\n",labelWhile);
printf("JMF %s",label);
FILE* fp;
fp = fopen("asm", "a");
fputs(label, fp);
fclose(fp);
}*/

26
compilateur/blocs.h Normal file
View file

@ -0,0 +1,26 @@
//
// Created by chepycou on 4/18/23.
//
#ifndef PROJET_SYSTEMES_INFORMATIQUES_BLOCS_H
#define PROJET_SYSTEMES_INFORMATIQUES_BLOCS_H
#define LABEL_MAX_LENGTH 20
/*======================
Label Management
======================*/
/*returns the next label*/
int getNextLabel();
// prints a new label and returns the index of it
int printNewLabel();
// prints a label and returns the index of it
void printLabel(int labelWhile);
// prints a jump to the label and returns the index of it
void printJumpToLabel(int labelWhile);
#endif //PROJET_SYSTEMES_INFORMATIQUES_BLOCS_H

BIN
compilateur/blocs.o Normal file

Binary file not shown.

71
compilateur/lex.l Normal file
View file

@ -0,0 +1,71 @@
%{
#include "table.h"
#include "yacc.tab.h"
%}
/*options for compiling*/
%option noyywrap
%option noinput
%option nounput
/*definition of the different types of comments*/
M_COMMENT (\/\/).*
S_COMMENT \/\*(.|\n)*?\*\/
/*definition of the Ids and types of ints*/
ID [a-zA-Z][a-zA-Z0-9]*
INT_DEC [0-9]+
INT_HEX 0x[0-9a-fA-F]+
%%
"if" return(tIF);
"else" return(tELSE);
"while" return(tWHILE);
"print" return(tPRINT);
"return" return(tRETURN);
"float" return(tFLOAT);
"int" return(tINT);
"void" return(tVOID);
"+" return(tADD);
"-" return(tSUB);
"*" return(tMUL);
"/" return(tDIV);
"<" return(tLT);
">" return(tGT);
"!=" return(tNE);
"==" return(tEQ);
">=" return(tGE);
"<=" return(tLE);
"=" return(tASSIGN);
"&&" return(tAND);
"||" return(tOR);
"!" return(tNOT);
"{" return(tLBRACE);
"}" return(tRBRACE);
"(" return(tLPAR);
")" return(tRPAR);
";" return(tSEMI);
"," return(tCOMMA);
{ID} {strncpy(yylval.str, yytext, NAME_MAX_LENGTH); return(tID);}
{INT_DEC} {yylval.nbInt = atoi(yytext); return(tNB);}
{INT_HEX} {yylval.nbInt = atoi(yytext); return(tNB);}
/*comments are ignored, same for spaces and lines*/
{M_COMMENT} ;
{S_COMMENT} ;
[ ]+ ;
\n ;
/*anything else is considered an error*/
. yyerror(yytext);
%%
// SI >> SC

1941
compilateur/lex.yy.c Normal file

File diff suppressed because it is too large Load diff

BIN
compilateur/lex.yy.o Normal file

Binary file not shown.

168
compilateur/operations.c Normal file
View file

@ -0,0 +1,168 @@
//
// Created by chepycou on 4/14/23.
//
#include <stdio.h>
#include "table.h"
#include "operations.h"
#include "asmTable.h"
/*prints to the stdout and the out asm file*/
void printOp(char* s){
//printf("%s",s);
addLine(s);
/*FILE* fp;
fp = fopen("asm", "a");
fputs(s, fp);
fclose(fp);*/
}
/*clears the out asm file*/
void clearOp(){
FILE* fp;
fp = fopen("asm", "w");
fclose(fp);
}
/*prints the ASM instruction for the addition computation
* and returns the address of the temporary variable*/
int operation_add(int addr1, int addr2){
int addr = addTempINTAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "ADD %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the subtraction computation
* and returns the address of the temporary variable*/
int operation_sub(int addr1, int addr2){
int addr = addTempINTAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "SUB %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the multiplication computation
* and returns the address of the temporary variable*/
int operation_mul(int addr1, int addr2){
int addr = addTempINTAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "MUL %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the integer division computation
* and returns the address of the temporary variable*/
int operation_divInt(int addr1, int addr2){
int addr = addTempINTAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "DIV_INT %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the remainder computation
* and returns the address of the temporary variable*/
int operation_divRem(int addr1, int addr2){
int addr = addTempINTAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "DIV_REM %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the affection of a variable
* EX :
* a = 2;
*/
void operation_afc_nb(int addr, int value){
char s[ASM_TEXT_LEN];
sprintf(s, "AFC %d %d", addr, value);
printOp(s);
}
/*prints the ASM instruction for the affection of a temporary variable
* EX :
* "1_TEMP = 2"
* and returns the address of the temp variable*/
int operation_afc_nb_tmp(int value){
int addr = addTempINTAndGetAddress();
operation_afc_nb(addr, value);
return addr;
}
/*prints the ASM instruction for the affection of a temporary variable
* EX :
* a = b;
*/
void operation_copy(int addr1, int addr2){
char s[ASM_TEXT_LEN];
sprintf(s, "COP %d %d", addr1, addr2);
printOp(s);
}
/*prints the ASM instruction for the inferior condition
* and returns the address of the temporary variable*/
int cond_inf(int addr1, int addr2){
int addr = addTempCONDAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "INF %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the superior condition
* and returns the address of the temporary variable*/
int cond_sup(int addr1, int addr2){
int addr = addTempCONDAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "SUP %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the equality condition
* and returns the address of the temporary variable*/
int cond_eq(int addr1, int addr2) {
int addr = addTempCONDAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "EQ %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the negation condition
* and returns the address of the temporary variable*/
int cond_not(int addr1){
int addr = addTempCONDAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "NOT %d %d", addr, addr1);
printOp(s);
return addr;
}
/*prints the ASM instruction for the and condition
* and returns the address of the temporary variable*/
int cond_and(int addr1, int addr2){
int addr = addTempCONDAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "AND %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}
/*prints the ASM instruction for the or condition
* and returns the address of the temporary variable*/
int cond_or(int addr1, int addr2){
int addr = addTempCONDAndGetAddress();
char s[ASM_TEXT_LEN];
sprintf(s, "OR %d %d %d", addr, addr1, addr2);
printOp(s);
return addr;
}

78
compilateur/operations.h Normal file
View file

@ -0,0 +1,78 @@
//
// Created by chepycou on 4/14/23.
//
#ifndef PROJET_SYSTEMES_INFORMATIQUES_OPERATIONS_H
#define PROJET_SYSTEMES_INFORMATIQUES_OPERATIONS_H
#define ASM_TEXT_LEN 40
/*clears the out asm file*/
void clearOp();
/*prints to the stdout and the out asm file*/
void printOp(char* s);
/*prints the ASM instruction for the addition computation
* and returns the address of the temporary variable*/
int operation_add(int addr1, int addr2);
/*prints the ASM instruction for the subtraction computation
* and returns the address of the temporary variable*/
int operation_sub(int addr1, int addr2);
/*prints the ASM instruction for the multiplication computation
* and returns the address of the temporary variable*/
int operation_mul(int addr1, int addr2);
/*prints the ASM instruction for the integer division computation
* and returns the address of the temporary variable*/
int operation_divInt(int addr1, int addr2);
/*prints the ASM instruction for the remainder computation
* and returns the address of the temporary variable*/
int operation_divRem(int addr1, int addr2);
/*prints the ASM instruction for the affection of a variable
* EX :
* a = 2;
*/
void operation_afc_nb(int addr, int value);
/*prints the ASM instruction for the affection of a temporary variable
* EX :
* "1_TEMP = 2"
* and returns the address of the temp variable*/
int operation_afc_nb_tmp(int value);
/*prints the ASM instruction for the affection of a temporary variable
* EX :
* a = b;
*/
void operation_copy(int addr1, int addr2);
/*prints the ASM instruction for the inferior condition
* and returns the address of the temporary variable*/
int cond_inf(int addr1, int addr2);
/*prints the ASM instruction for the superior condition
* and returns the address of the temporary variable*/
int cond_sup(int addr1, int addr2);
/*prints the ASM instruction for the equality condition
* and returns the address of the temporary variable*/
int cond_eq(int addr1, int addr2);
/*prints the ASM instruction for the negation condition
* and returns the address of the temporary variable*/
int cond_not(int addr1);
/*prints the ASM instruction for the and condition
* and returns the address of the temporary variable*/
int cond_and(int addr1, int addr2);
/*prints the ASM instruction for the or condition
* and returns the address of the temporary variable*/
int cond_or(int addr1, int addr2);
#endif //PROJET_SYSTEMES_INFORMATIQUES_OPERATIONS_H

BIN
compilateur/operations.o Normal file

Binary file not shown.

BIN
compilateur/out Executable file

Binary file not shown.

308
compilateur/table.c Normal file
View file

@ -0,0 +1,308 @@
#include <stdlib.h>
#include <string.h>
#include "table.h"
#define VERBOSITY 0 // 1 -> displays the table, 0 no display
int memorySizes[2] = {1,1};
int tempCounter = 0;
int condCounter = 0; // to store whether there is a conditional variable
/*At the start of the execution : the whole array is empty*/
static Symbol* symbolTable;
/*indexes in the array*/
static int currentIndex = 0; // the next to index to be used
static int maxIndex = START_TABLE_SIZE;
// stack pointers
static int esp = 0;
static int ebp = 0;
static int currentDepth = 0;
/* /!\ To be called at the beginning
* Initializes the array of Symbols*/
void initSymbolTable(){
symbolTable = malloc(sizeof(Symbol) * START_TABLE_SIZE);
}
/*resets the symbol table*/
void resetSymboltable(){
currentIndex = 0;
maxIndex = START_TABLE_SIZE;
// stack pointers
esp = 0;
ebp = 0;
currentDepth = 0;
}
/* Error display */
void error(char* mess){
printf("ERROR : %s\n", mess);
exit(-1);
}
/* Returns the offset from EBP to the symbol in the stack */
int getOffset(char* name){
return (ebp + getStruct(name).offset);
}
/* Returns the structure with this name */
Symbol getStruct(char* name){
for(int i=0; i < currentIndex; i++){
if (strcmp(symbolTable[i].name, name) == 0){
return symbolTable[i];
}
}
if (VERBOSITY) {
printf("\n\n%s not found \n\n", name);
displayTable();
}
error("No structure found");
return (createNewStructure("error", 0));
}
/* Returns the index with this name*/
int getIndex(char* name){
for(int i=0; i < currentIndex; i++){
if (strcmp(symbolTable[i].name, name) == 0){
return i;
}
}
printf("%s",name);
error("No index found");
return (0);
}
/* removes all symbols associated with the current Depth*/
void clearOutOfScopeVariable(){
int i = 0;
int memoryFreed = 0;
// we get to the first symbol that we need to remove
while(i < currentIndex) {
if (symbolTable[i].depth == currentDepth) {
break;
}
i++;
}
int futureCurrentIndex = i;
while(i < currentIndex) {
memoryFreed += memorySizes[symbolTable[i].varType];
i++;
}
// now we remove all the symbols
currentIndex = futureCurrentIndex;
checkArraySanity();
// and we free their memory (i.e. decrease esp)
esp -= memoryFreed;
if (VERBOSITY) {
printf("\n\nclearOutOfScopeVariable::After");
displayTable();
}
}
/* sets the init state of the symbol to true */
void setInit(char *name){
symbolTable[getIndex(name)].init = true;
if (VERBOSITY) {
printf("\n\nsetInit %s", name);
displayTable();
}
}
/*creates a new structure and updates variables*/
Symbol createNewStructure(char* name, enumVarType type){
Symbol s;
strcpy(s.name,name);
s.init = false;
s.varType = type;
s.offset = esp; // the offset is the current esp
s.depth = currentDepth;
return s;
}
/* Adds an element */
void addElement(char* name, enumVarType type){
Symbol element = createNewStructure(name, type);
//checks for overflow
checkArraySanity();
symbolTable[currentIndex] = element;
currentIndex ++;
esp += memorySizes[type];
if (VERBOSITY) {
printf("\n\nAddElement %s", name);
displayTable();
}
}
/* Adds an element and returns the offset of it */
int addElementAndGetAddress(char* name, enumVarType type){
addElement(name,type);
return getOffset(name);
}
/* Adds a temporary Int element and returns the offset of it */
int addTempINTAndGetAddress(){
char name[NAME_MAX_LENGTH];
if (tempCounter == 0){
// we create the first temporary variable and use it
addElement("0_TEMP_INT",INT);
strcpy(name, "0_TEMP_INT");
} else if (tempCounter == 1) {
// we create the second temporary variable and use it
addElement("1_TEMP_INT",INT);
strcpy(name, "1_TEMP_INT");
} else {
// we use the right temporary variable
sprintf(name, "%d_TEMP_INT", tempCounter % 2);
}
tempCounter++;
return getOffset(name);
}
/* removes all symbols */
void flushSymbolTable(){
currentIndex = 0;
checkArraySanity();
if (VERBOSITY) {
printf("\n\nflushSymbolTable::After");
displayTable();
}
}
/*Checks for the length of the array and reallocates if necessary*/
void checkArraySanity(){
if (currentIndex == maxIndex){
reallocateArray(maxIndex * 2);
} else {
if (currentIndex < maxIndex / 2 && maxIndex / 2 > START_TABLE_SIZE){
reallocateArray(maxIndex / 2);
}
}
}
/*reallocates the array with the specified size*/
void reallocateArray(int size){
Symbol *temp = (Symbol *)realloc(symbolTable, (sizeof(Symbol) * size));
if (temp != NULL){
symbolTable = temp;
}
else {
error("Cannot allocate more memory.\n");
}
}
/*increases the depth (i.e. when entering a block)*/
void increaseDepth(){
currentDepth++;
}
/*decreases the depth (i.e. when leaving a block)*/
void decreaseDepth(){
clearOutOfScopeVariable();
currentDepth--;
}
/*displays the entire table at this moment including all information
* regarding the symbols and the current depth*/
void displayTable(){
printf("\n");
doubleLine();
printf("Table of Symbols, depth = %d, length = %d, ESP = %d, EBP = %d\n", currentDepth, currentIndex, esp ,ebp);
printf("Name | init?, varType, offset, depth\n");
doubleLine();
for (int i = 0; i < currentIndex; ++i) {
Symbol a = symbolTable[i];
printf("%s | %d, %d, %d, %d\n", a.name, a.init, a.varType, a.offset, a.depth);
if (i != currentIndex -1) {
line();
}
}
doubleLine();
}
/*removes all temporary variables used for INTs*/
void suppressTempINTElements(){
if (tempCounter == 1){
suppressElement("0_TEMP_INT");
esp--;
} else {
if (tempCounter > 1){
suppressElement("0_TEMP_INT");
suppressElement("1_TEMP_INT");
esp-= 2;
}
}
tempCounter = 0;
}
/*removes one element*/
void suppressElement(char* name){
for(int i = getIndex(name); i < (currentIndex - 1); i ++){
symbolTable[i] = symbolTable[i+1];
}
currentIndex--;
checkArraySanity();
}
void line(){
printf("---------------------------------\n");
}
void doubleLine(){
printf("============================================================\n");
}
/*removes all temporary variables used for CONDITIONS*/
void suppressCONDElements(){
if (condCounter == 1){
suppressElement("0_TEMP_COND");
esp--;
} else {
if (condCounter > 1){
suppressElement("0_TEMP_COND");
suppressElement("1_TEMP_COND");
esp-= 2;
}
}
condCounter = 0;
}
/* Adds a temporary Conditional element and returns the offset of it */
int addTempCONDAndGetAddress(){
char name[NAME_MAX_LENGTH];
if (condCounter == 0){
// we create the first temporary variable and use it
addElement("0_TEMP_COND",INT);
strcpy(name, "0_TEMP_COND");
} else if (condCounter == 1) {
// we create the second temporary variable and use it
addElement("1_TEMP_COND",INT);
strcpy(name, "1_TEMP_COND");
} else {
// we use the right temporary variable
sprintf(name, "%d_TEMP_COND", condCounter % 2);
}
condCounter++;
return getOffset(name);
}

125
compilateur/table.h Normal file
View file

@ -0,0 +1,125 @@
#ifndef TABLE_H
#define TABLE_H
#include <stdio.h>
#include <stdbool.h>
/*defined constants*/
#define START_TABLE_SIZE 128
#define NAME_MAX_LENGTH 30
// a list of all type
typedef enum enumVarType {INT, FLOAT} enumVarType;
// a list of all type's sizes
extern int memorySizes[2];
typedef struct {
char name[NAME_MAX_LENGTH];
bool init;
enumVarType varType;
int offset;
int depth;
} Symbol;
/*============================
Array and Reallocation
============================*/
/*reallocates the array with the specified size*/
void reallocateArray(int size);
/*Checks for the length of the array and reallocates if necessary*/
void checkArraySanity();
/* /!\ To be called at the beginning
* Initializes the array of Symbols*/
void initSymbolTable();
/*resets the symbol table*/
void resetSymboltable();
/*inserts an asm code line at the current index*/
void addLine(char* s);
/*returns the current line (i.e. next one to insert)*/
int getCurrentLineNumber();
/*============================
Element Management
============================*/
/* removes all symbols associated with the current Depth*/
void clearOutOfScopeVariable();
/* removes all symbols */
void flushSymbolTable();
/* Adds an element */
void addElement(char* name, enumVarType type);
/* Adds an element and returns the offset of it */
int addElementAndGetAddress(char* name, enumVarType type);
/* Adds a temporary Int element and returns the offset of it */
int addTempINTAndGetAddress();
/* Adds a temporary Conditional element and returns the offset of it */
int addTempCONDAndGetAddress();
/*creates a new structure and updates variables*/
Symbol createNewStructure(char* name, enumVarType type);
/*============================
Element Edition
============================*/
/* sets the init state of the symbol to true */
void setInit(char *name);
/*removes one element*/
void suppressElement(char* name);
/*removes all temporary variables used for INTs*/
void suppressTempINTElements();
/*removes all temporary variables used for CONDITIONS*/
void suppressCONDElements();
/*============================
Element Access
============================*/
/* Returns the index with this name*/
int getIndex(char* name);
/* Returns the structure with this name */
Symbol getStruct(char* name);
/* Returns the offset from EBP to the symbol in the stack */
int getOffset(char* name);
/*==========================
Flow/Block control
=========================*/
/*increases the depth (i.e. when entering a block)*/
void increaseDepth();
/*decreases the depth (i.e. when leaving a block)*/
void decreaseDepth();
/*============================================
Display, Todo : put in another .h file
============================================*/
void error(char* mess);
void line();
void doubleLine();
/*displays the entire table at this moment including all information
* regarding the symbols and the current depth*/
void displayTable();
#endif

BIN
compilateur/table.o Normal file

Binary file not shown.

0
compilateur/testFile Normal file
View file

1459
compilateur/yacc.output Normal file

File diff suppressed because it is too large Load diff

1947
compilateur/yacc.tab.c Normal file

File diff suppressed because it is too large Load diff

120
compilateur/yacc.tab.h Normal file
View file

@ -0,0 +1,120 @@
/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_YY_YACC_TAB_H_INCLUDED
# define YY_YY_YACC_TAB_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 1
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
tELSE = 258, /* tELSE */
tRETURN = 259, /* tRETURN */
tPRINT = 260, /* tPRINT */
tFLOAT = 261, /* tFLOAT */
tINT = 262, /* tINT */
tVOID = 263, /* tVOID */
tSUB = 264, /* tSUB */
tADD = 265, /* tADD */
tMUL = 266, /* tMUL */
tDIV = 267, /* tDIV */
tASSIGN = 268, /* tASSIGN */
tLT = 269, /* tLT */
tGT = 270, /* tGT */
tNE = 271, /* tNE */
tEQ = 272, /* tEQ */
tGE = 273, /* tGE */
tLE = 274, /* tLE */
tAND = 275, /* tAND */
tOR = 276, /* tOR */
tNOT = 277, /* tNOT */
tLBRACE = 278, /* tLBRACE */
tRBRACE = 279, /* tRBRACE */
tLPAR = 280, /* tLPAR */
tRPAR = 281, /* tRPAR */
tSEMI = 282, /* tSEMI */
tCOMMA = 283, /* tCOMMA */
tID = 284, /* tID */
tNB = 285, /* tNB */
tIF = 286, /* tIF */
tWHILE = 287 /* tWHILE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 22 "yacc.y"
char str[NAME_MAX_LENGTH]; int nbInt; int addr; enumVarType type;
#line 99 "yacc.tab.h"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
int yyparse (void);
/* "%code provides" blocks. */
#line 17 "yacc.y"
int yylex (void);
void yyerror (const char *);
#line 119 "yacc.tab.h"
#endif /* !YY_YY_YACC_TAB_H_INCLUDED */

BIN
compilateur/yacc.tab.o Normal file

Binary file not shown.

209
compilateur/yacc.y Normal file
View file

@ -0,0 +1,209 @@
%define parse.error detailed
%{
#include <stdio.h>
#include <stdlib.h>
#include "table.h"
#include "operations.h"
#include "blocs.h"
#include "asmTable.h"
int t;
int labelWhileStart;
int labelWhileEnd;
int whileJumpAddr;
%}
%code provides{
int yylex (void);
void yyerror (const char *);
}
%union {char str[NAME_MAX_LENGTH]; int nbInt; int addr; enumVarType type; }
/*loops keywords*/
%token /*tWHILE tIF declared below*/ tELSE
/*reserved keywords*/
%token tRETURN tPRINT
/*types : integers, floats or void*/
%token tFLOAT tINT tVOID
/*operations, mul and div are precedent to sub and add*/
%left tSUB tADD
%left tMUL tDIV
/*Assignment*/
%left tASSIGN
/*comparisons*/
%left tLT tGT tNE tEQ tGE tLE
/*boolean operators*/
%left tAND tOR tNOT
/*syntaxic symbols*/
%token tLBRACE tRBRACE tLPAR tRPAR tSEMI tCOMMA
/*nametags and values*/
%token <str> tID
%token <nbInt> tNB
/* represents types with the values used in the table, see table.h */
%type <type> Type
%type <addr> Expression
%type <addr> ConditionalExpression
%type <addr> Declaration
%type <addr> NbOrVariable
%type <nbInt> IfStatement1
%type <addr> Condition
%type <nbInt> InnerBlock
%token <nbInt> tIF
%token <nbInt> tWHILE
%start Program
%%
Program : FunctionDef
| FunctionDef Program;
/* Lines = Any line in the code that is not within an if/while statement*/
Lines : Line
| Line Lines;
Line : IfStatement
| WhileStatement
| Assignment
| Declarations
| FunctionCall
| Return
| Print;
/*Innerblock = the inside of an if/else/while statement = { ... } or function = f(){...}*/
InnerBlock : tLBRACE tRBRACE // a function or while loop can be empty cf GCC
| tLBRACE {increaseDepth();} Lines tRBRACE {decreaseDepth();};
/*Condition = the evaluated boolean expression for an if or while = ( ... ) */
Condition : tLPAR ConditionalExpression tRPAR {$$ = $2;};
/*ConditionalExpression = expression that evaluates to a boolean*/
ConditionalExpression : tID { $$ = getOffset($1);}
| tNB {$$ = operation_afc_nb_tmp($1);}
| tLPAR ConditionalExpression tRPAR {$$ = $2;}// for cases like if((a or b) and (a or c)) where there are parenthesis inside
| NbOrVariable tLE NbOrVariable {$$ = cond_not(cond_sup($1, $3));}
| NbOrVariable tGE NbOrVariable {$$ = cond_not(cond_inf($1, $3));}
| NbOrVariable tEQ NbOrVariable {$$ = cond_eq($1, $3);}
| NbOrVariable tNE NbOrVariable {$$ = cond_not(cond_eq($1, $3));}
| NbOrVariable tLT NbOrVariable {$$ = cond_inf($1, $3);}
| NbOrVariable tGT NbOrVariable {$$ = cond_sup($1, $3);}
| tNOT ConditionalExpression {$$ = cond_not($2);}
| ConditionalExpression tOR ConditionalExpression {$$ = cond_or($1, $3);}
| ConditionalExpression tAND ConditionalExpression {$$ = cond_and($1, $3);};
/*end of added bloat*/
/*NbOrVariable is either a number or a variable of type int*/
NbOrVariable : tID { $$ = getOffset($1);}
| tNB {$$ = operation_afc_nb_tmp($1);};
/*List of all numerical operators*/
/*
NumericalOperator : tLE | tGE | tEQ | tNE | tLT | tGT;
*/
/*any arithmetic operation
Operation: tADD | tMUL | tSUB | tDIV;
*/
IfStatement1 : %empty {
int ligne =getCurrentLineNumber(); addLine("JMF"); $<nbInt>$ = ligne ;
};
IfStatement : tIF Condition IfStatement1 InnerBlock tELSE {
setConditionAddr($3,$2); int current = getCurrentLineNumber(); printf("current Line %d", current); addLine("JMP"); $1 = current; setJumpLine($3, current+1);
} InnerBlock {
int current = getCurrentLineNumber() ; printf("%d, %d",$1, current);setJumpLine($1, current);
}
| tIF Condition IfStatement1 InnerBlock {
setConditionAddr($3,$2); int current = getCurrentLineNumber(); printf("current Line %d", current); setJumpLine($3, current);
};
WhileStatement : tWHILE {
$1 = getCurrentLineNumber();
} Condition {
int current = getCurrentLineNumber();
addLine("JMF");
setConditionAddr(current,$3);
whileJumpAddr = current;
suppressCONDElements();
} InnerBlock {
addLine("JMP");
int current = getCurrentLineNumber();
setJumpLine(whileJumpAddr, current);
setJumpLine(current-1, $1);
};
Assignment : tID tASSIGN Expression tSEMI {
setInit($1); operation_copy(getOffset($1),$3); suppressTempINTElements();
};
/*Expression operation applied on variables or values*/
Expression : NbOrVariable {$$ = $1;}
| FunctionCall{$$ = 0;} // TODO : wait untile functions are implemented
| tLPAR Expression tRPAR {$$ = $2;}
/* replaced by the four following lines
//| Expression Operation Expression
*/
| Expression tADD Expression {$$ = operation_add($1, $3);}
| Expression tSUB Expression {$$ = operation_sub($1, $3);}
| Expression tMUL Expression {$$ = operation_mul($1, $3);}
| Expression tDIV Expression {$$ = operation_divInt($1, $3);};
/*end of added bloat*/
Expressions : Expression
| Expression tCOMMA Expressions;
FunctionCall : tID tLPAR Expressions tRPAR;
FunctionDef : Type tID FunctionParams InnerBlock {resetSymboltable();}
| tVOID tID FunctionParams InnerBlock {resetSymboltable();};
/*FunctionParams = the parameters of a function*/
FunctionParams : tLPAR tRPAR
| tLPAR tVOID tRPAR
| tLPAR VarsWithType tRPAR
VarsWithType : VarWithType
| VarWithType tCOMMA VarsWithType;
/*VarWithType = a variable associated to its type = int a*/
VarWithType : Type tID {addElement($2,$1);setInit($2);};
/*the return type or argument type*/
Type : tINT {$$ = INT;}
| tFLOAT {$$ = FLOAT;};
Declarations : Type { t = $1; } Declaration Declarations1 tSEMI ;
Declaration : tID {addElement($1, (enumVarType) t);}
| tID {addElement($1, (enumVarType) t); setInit($1);} tASSIGN Expression {operation_copy(getOffset($1),$4); suppressTempINTElements();} ;
Declarations1 : tCOMMA Declaration Declarations1 | %empty ;
Return : tRETURN Expression tSEMI {};
Print : tPRINT tLPAR Expression tRPAR tSEMI;
%%
void yyerror(const char *msg) {
fprintf(stderr, "\033[1m\033[31m[/!\\]\033[0m Error : %s\n", msg);
exit(1);
}
int main(void) {
clearOp();
initSymbolTable();
initASMTable();
yyparse();
exportASMTable();
}
// SI >> SC

View file

@ -0,0 +1,182 @@
import re
opToBinOP = {
"ADD": "01",
"MUL": "02",
"SUB": "03",
"DIV": "04",
"COP": "05",
"AFC": "06",
"LOAD": "07",
"STORE": "08",
"INF": "09",
"SUP": "0A",
"EQ": "0B",
"NOT": "0C",
"AND": "0D",
"OR": "0E",
"JMP": "0F",
"JMF": "10",
"CAL": "11",
"RET": "12",
"PRI": "13",
"NOP": "FF"
}
def output(s, num, oneline=False):
fileOutput = open(f'asm{num}', 'w')
if oneline:
fileOutput.write(s)
else :
fileOutput.write("\n".join(s))
fileOutput.close()
def convertToRegister(s):
l = []
if not re.match(r"\d_LABEL", s[0]):
optionalFlag = ""
incr = 0
op = s[0]
else:
optionalFlag = s[0] + " "
incr = 1
op = s[1]
match op:
case "ADD":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("ADD 0 0 1")
l.append("STORE " + s[1 + incr] + " 0")
case "MUL":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("MUL 0 0 1")
l.append("STORE " + s[1 + incr] + " 0")
case "SUB":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("SUB 0 0 1")
l.append("STORE " + s[1 + incr] + " 0")
case "DIV_INT":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("DIV 0 0 1")
l.append("STORE " + s[1 + incr] + " 0")
case "COP":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("STORE " + s[1 + incr] + " 0")
case "AFC":
l.append(optionalFlag + "AFC 0 " + s[2 + incr])
l.append("STORE " + s[1 + incr] + " 0")
case "JMP":
l.append(" ".join(s))
case "JMF":
if len(s) == 3:
l.append(" ".join(s))
else :
l.append(s[0]+ " 0 " + s[1])
case "INF":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("INF 2 0 1")
l.append("STORE " + s[1 + incr] + " 2")
case "SUP":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("SUP 2 1 0")
l.append("STORE " + s[1 + incr] + " 2")
case "EQ":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("EQ 2 1 0")
l.append("STORE " + s[1 + incr] + " 2")
case "PRI":
l.append(optionalFlag + "PRI " + s[2 + incr])
case "AND":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("AND 2 0 1")
l.append("STORE " + s[1 + incr] + " 2")
case "OR":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("LOAD 1 " + s[3 + incr])
l.append("OR 2 0 1")
l.append("STORE " + s[1 + incr] + " 2")
case "NOT":
l.append(optionalFlag + "LOAD 0 " + s[2 + incr])
l.append("NOT 2 0")
l.append("STORE " + s[1 + incr] + " 2")
case default:
l.append(" ".join(s))
""" R2 will contain the information whether to jump or not"""
return l
totalLine = 0
labelCount = 0 # used to create a new label each time
fileInput = open("asm", "r")
ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines()))
fileInput.close()
# added to prevent problems when cross compiling some code representing a jump to after the last line
ASMLines.append("NOP")
ASMLinesLabel = ASMLines[:] # will contain at the end of the first loop the code with labels inserted
ASMLinesRegister = [] # will contain at the end of the 2nd loop the registry-based code with labels
ASMLinesFinal = [] # will contain the output, register-based, code
for i, l in enumerate(ASMLines):
items = l.split(" ")
if items[0] in ["JMP", "JMF"]:
lineToJumpTo = int(items[-1])
if re.match(r"\d_LABEL .*", ASMLinesLabel[lineToJumpTo]):
ASMLinesLabel[i] = " ".join(ASMLines[i].split()[:-1] + [ASMLinesLabel[lineToJumpTo].split()[0]])
else:
ASMLinesLabel[lineToJumpTo] = f"{labelCount}_LABEL " + ASMLines[lineToJumpTo]
ASMLinesLabel[i] = " ".join(ASMLinesLabel[i].split()[:-1] + [f"{labelCount}_LABEL"])
labelCount += 1
print("labels : ", ASMLinesLabel)
for i, l in enumerate(ASMLinesLabel):
ASMLinesRegister.extend(convertToRegister(l.split()))
print("regs : ", ASMLinesRegister)
labels = {}
for i, l in enumerate(ASMLinesRegister):
if re.match(r"\d_LABEL .*", l):
labels[l.split()[0]] = i
ASMLinesRegister[i] = " ".join(ASMLinesRegister[i].split()[1:])
print(ASMLinesRegister)
for i, l in enumerate(ASMLinesRegister):
label = re.match(r"\d_LABEL", l.split()[-1])
if label:
ASMLinesFinal.append(" ".join(l.split()[:-1] + [str(labels[label[0]])]))
else:
ASMLinesFinal.append(l)
print(ASMLinesFinal)
output(ASMLinesFinal, 2)
lines = []
for i, l in enumerate(ASMLinesFinal):
arr = l.split()
while len(arr) < 4:
arr.append(0)
lines.append(f"(x\"{opToBinOP[arr[0]]}{int(arr[1]):02X}{int(arr[2]):02X}{int(arr[3]):02X}\")")
ASMLinesConverted = "(" + ",".join(lines) + ",others => (x\"ff000000\"))"
print("converted to VHDL-friendly format : " + ASMLinesConverted)
output(ASMLinesConverted, 3, True)
""" Used to generate the beautiful table in the report
for i in range(10):
print(f"{ASMLines[i]} & {ASMLinesFinal[i]} & {ASMLinesConverted.split(',')[i]} \\\\")
"""

View file

@ -0,0 +1,140 @@
import sys
try:
from textual.color import Color
from textual import events
from textual.app import App, ComposeResult
from textual.containers import Container, VerticalScroll
from textual.widgets import Footer, Header, Static
except:
print("please install textual and rich !")
def getLinesToShow(ip, lines):
if ip > 1 and ip + 2 < len(lines):
l= lines[ip - 2: ip + 3]
l[2] = "> " + l[2] + " <"
elif ip <= 1:
l= lines[0: 5]
l[ip] = "> " + l[ip] + " <"
else:
l= lines[-5:]
l[ip-len(lines)] = "> " + l[ip-len(lines)] + " <"
return l
def update_interpreter(self):
global ip
global ASMLines
global dataMem
if "NOP" not in ASMLines[ip]:
incr = 1
currLine = ASMLines[ip].split()
match currLine[0]:
case "ADD":
dataMem[currLine[1]] = dataMem[currLine[2]] + dataMem[currLine[3]]
case "MUL":
dataMem[currLine[1]] = dataMem[currLine[2]] * dataMem[currLine[3]]
case "SUB":
dataMem[currLine[1]] = dataMem[currLine[2]] - dataMem[currLine[3]]
case "DIV":
dataMem[currLine[1]] = dataMem[currLine[2]] / dataMem[currLine[3]]
case "COP":
dataMem[currLine[1]] = dataMem[currLine[2]]
case "AFC":
dataMem[currLine[1]] = int(currLine[2])
case "SUP":
dataMem[currLine[1]] = dataMem[currLine[2]] > dataMem[currLine[3]]
case "EQ":
dataMem[currLine[1]] = dataMem[currLine[2]] == dataMem[currLine[3]]
case "NOT":
dataMem[currLine[1]] = not dataMem[currLine[2]]
case "INF":
dataMem[currLine[1]] = dataMem[currLine[2]] < dataMem[currLine[3]]
case "AND":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "OR":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "JMP":
ip = int(currLine[1])
incr = 0
case "JMF":
if not dataMem[currLine[1]]:
incr = 0
ip = int(currLine[2])
print(ip)
case "CAL":
pass
case "RET":
pass
case "PRI":
pass
case default:
pass
print(ASMLines[ip], ", ".join([f"{i}:{dataMem.get(i)}" for i in dataMem]))
ip += incr
else:
cont = self.query_one("#cont", Container)
cont.styles.background = Color.parse("#151E3D")
code = self.query_one("#code", Static)
code.update(" ")
class codeLines(Static):
"""one line of assembly code"""
def update_code(self, line) -> None:
self.update(line)
class registers(Static):
"""one line of assembly code"""
def update_regs(self, line) -> None:
self.update(line)
class interpreter(App):
"""A Textual app to see your asm code run !."""
TITLE = "A Textual app to see your asm code run !."
CSS_PATH = "style.css"
BINDINGS = [
("q", "quit", "Quit"),
]
def compose(self) -> ComposeResult:
"""Compose our UI."""
path = "./" if len(sys.argv) < 2 else sys.argv[1]
yield Header()
with Container(id="cont"):
with VerticalScroll(id="code-view"):
yield codeLines("\n".join(getLinesToShow(ip, ASMLines)),id="code", expand=True)
yield registers(id="regs", expand=True)
yield Footer()
def on_key(self, event: events.Key) -> None:
code = self.query_one("#code", Static)
regs = self.query_one("#regs", Static)
update_interpreter(self)
global ip, ASMLines
code.update_code("\n".join(getLinesToShow(ip, ASMLines)))
l = []
for i in range(max([int(i)+1 for i in dataMem.keys()])):
if str(i) in dataMem.keys():
l.append([i, dataMem[str(i)]])
regs.update_regs("\n".join([f"@{k[0]} : {k[1]}" for k in l]))
if __name__ == "__main__":
fileInput = open("asm", "r")
global ASMLines
ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines()))
fileInput.close()
ASMLines.append("NOP")
global dataMem
dataMem = {}
global ip
ip = 0
interpreter().run()

View file

@ -0,0 +1,53 @@
fileInput = open("asm", "r")
ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines()))
fileInput.close()
ASMLines.append("NOP")
dataMem = {}
ip = 0
while ip < len(ASMLines):
incr = 1
currLine = ASMLines[ip].split()
match currLine[0]:
case "ADD":
dataMem[currLine[1]] = dataMem[currLine[2]] + dataMem[currLine[3]]
case "MUL":
dataMem[currLine[1]] = dataMem[currLine[2]] * dataMem[currLine[3]]
case "SUB":
dataMem[currLine[1]] = dataMem[currLine[2]] - dataMem[currLine[3]]
case "DIV":
dataMem[currLine[1]] = dataMem[currLine[2]] / dataMem[currLine[3]]
case "COP":
dataMem[currLine[1]] = dataMem[currLine[2]]
case "AFC":
dataMem[currLine[1]] = int(currLine[2])
case "SUP":
dataMem[currLine[1]] = dataMem[currLine[2]] > dataMem[currLine[3]]
case "EQ":
dataMem[currLine[1]] = dataMem[currLine[2]] == dataMem[currLine[3]]
case "NOT":
dataMem[currLine[1]] = not dataMem[currLine[2]]
case "INF":
dataMem[currLine[1]] = dataMem[currLine[2]] < dataMem[currLine[3]]
case "AND":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "OR":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "JMP":
ip = int(currLine[1])
incr = 0
case "JMF":
if not dataMem[currLine[1]]:
incr = 0
ip = int(currLine[2])
case "CAL":
pass
case "RET":
pass
case "PRI":
pass
case default:
pass
print(ASMLines[ip], ", ".join([f"{i}:{dataMem.get(i)}" for i in dataMem]))
ip += incr

View file

@ -0,0 +1,61 @@
from rich.console import Console
from rich.table import Table
table = Table()
table.add_column("Operation", justify="left", style="red", no_wrap=True)
table.add_column("Register State", justify="center", style="green")
fileInput = open("asm", "r")
ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines()))
fileInput.close()
ASMLines.append("NOP")
dataMem = {}
ip = 0
while ip < len(ASMLines):
incr = 1
currLine = ASMLines[ip].split()
match currLine[0]:
case "ADD":
dataMem[currLine[1]] = dataMem[currLine[2]] + dataMem[currLine[3]]
case "MUL":
dataMem[currLine[1]] = dataMem[currLine[2]] * dataMem[currLine[3]]
case "SUB":
dataMem[currLine[1]] = dataMem[currLine[2]] - dataMem[currLine[3]]
case "DIV":
dataMem[currLine[1]] = dataMem[currLine[2]] / dataMem[currLine[3]]
case "COP":
dataMem[currLine[1]] = dataMem[currLine[2]]
case "AFC":
dataMem[currLine[1]] = int(currLine[2])
case "SUP":
dataMem[currLine[1]] = dataMem[currLine[2]] > dataMem[currLine[3]]
case "EQ":
dataMem[currLine[1]] = dataMem[currLine[2]] == dataMem[currLine[3]]
case "NOT":
dataMem[currLine[1]] = not dataMem[currLine[2]]
case "INF":
dataMem[currLine[1]] = dataMem[currLine[2]] < dataMem[currLine[3]]
case "AND":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "OR":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "JMP":
ip = int(currLine[1])
incr = 0
case "JMF":
if not dataMem[currLine[1]]:
incr = 0
ip = int(currLine[2])
case "CAL":
pass
case "RET":
pass
case "PRI":
pass
case default:
pass
table.add_row(ASMLines[ip], ", ".join([f"{i}:{dataMem.get(i)}" for i in dataMem]))
ip += incr
console = Console()
console.print(table)

7
interpreter/style.css Normal file
View file

@ -0,0 +1,7 @@
#code {
overflow: auto scroll;
text-align: center;
padding-top: 3;
width: 100%;
}

BIN
out Executable file

Binary file not shown.

9
tests/testFile Normal file
View file

@ -0,0 +1,9 @@
int main() {
int a;
a = 5;
if (a != 8) {
while(a < 20){
a = a+2;
}
}
}

20
tests/testFile_fibo Normal file
View file

@ -0,0 +1,20 @@
int main() {
int i, n, nextTerm, t1, t2;
i = 0;
n = 20; // put here the number you want !
t1 = 0;
t2 = 1;
nextTerm = t1 + t2;
n = n - 3; // cause nextTerm already contains the 3rd term
while (i <= n){
t1 = t2;
t2 = nextTerm;
nextTerm = t1 + t2;
i = i+1;
}
}

9
tests/testFile_no_jmp Normal file
View file

@ -0,0 +1,9 @@
int main(){
int a, d;
int b, c = 2;
b = a;
a = b +2;
a = c;
a = 5;
c = 19 + 2 - (5 * a + 8) * 2;
}

13
tests/testFile_while Normal file
View file

@ -0,0 +1,13 @@
int compute(int a, int d) {
int b, c = a + d * 5;
b = a;
while(!(!(!(!((a > b)))))){
if (a == b){
a = b;
} else {
a = c;
}
}
a=5;
}

92
vhdl/ALU.vhd Normal file
View file

@ -0,0 +1,92 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 12.05.2023 16:14:24
-- Design Name:
-- Module Name: ALU - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ALU is
Port ( A : in STD_LOGIC_VECTOR (7 downto 0);
B : in STD_LOGIC_VECTOR (7 downto 0);
Ctrl_Alu : in STD_LOGIC_VECTOR (7 downto 0);
S : out STD_LOGIC_VECTOR (7 downto 0);
N : out STD_LOGIC;
O : out STD_LOGIC;
Z : out STD_LOGIC;
C : out STD_LOGIC;
JumpFlagOut : out STD_LOGIC; -- 0 false 1 true
JumpFlagIn : in STD_LOGIC
);
end ALU;
-- Instruction code
-- ADD x"01"
-- MUL x"02"
-- SUB x"03"
-- DIV x"04"
-- INF x"09"
-- SUP x"0A"
-- EQ x"0B"
-- NOT x"0C"
-- AND x"0D"
-- OR x"0E"
-- XOR x"0F"
architecture Behavioral of ALU is
signal res : STD_LOGIC_VECTOR(15 downto 0):= x"0000";
signal flag : STD_LOGIC := '0';
begin
process(A, B, Ctrl_Alu)
begin
N <= '0';
O <= '0';
Z <= '0';
C <= '0';
flag <= JumpFlagIn;
case Ctrl_Alu is
when x"01" => res <= (x"00" & A) + (x"00" & B) ; if (((x"00" & A) + (x"00" & B)) > 255) then C <= '1'; elsif (A+B = 0) then Z <= '1'; end if; -- ADD
when x"02" => res <= A * B; if (A * B > 255) then O <= '1'; elsif A * B = 0 then Z <= '1'; end if; -- MUL
when x"03" => res <= (x"00" & A) - (x"00" & B) ; if (B > A) then N <= '1'; elsif (B = A) then Z <= '1'; end if; -- SUB
when x"04" => if (B /= 0) then res <= (x"00" & std_logic_vector(to_unsigned(to_integer(unsigned(A)) / to_integer(unsigned(B)),8))); else res <= x"0000"; end if; -- DIV
when x"09" => if A < B then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if;
when x"0A" => if A > B then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if;
when x"0B" => if A = B then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if;
when x"0C" => if A > 0 then res <= x"0001"; flag <= '1'; else res <= x"0000"; flag <= '0'; end if;
when x"0D" => if (A > 0 and B > 0) then res <= x"0001" ; flag <= '1'; else res <= x"0000"; flag <= '0'; end if;
when x"0E" => if (A > 0 or B > 0) then res <= x"0001" ; flag <= '1'; else res <= x"0000"; flag <= '0'; end if;
when x"0F" => if ((A > 0 and B = 0) or (A = 0 and B >0)) then res <= x"0001" ; flag <= '1'; else res <= x"0000"; flag <= '0'; end if;
when others => res <= x"0000";
end case;
end process;
JumpFlagOut <= flag;
S <= res(7 downto 0);
end Behavioral;

77
vhdl/AleaControler.vhd Normal file
View file

@ -0,0 +1,77 @@
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
-- Instruction coEX
-- ADD 00000001
-- MUL 00000010
-- SUB 00000011
-- DIV 00000100
-- COP 00000101
-- AFC 00000110
-- LOAD 00000111
-- STORE 00001000
-- INF 00001001
-- SUP 00001010
-- EQ 00001011
-- NOT 00001100
-- AND 00001101
-- OR 00001110
-- NOP 11111111
-- when the just entered instruction causes a problem with an instruction already in the EX or Mem stage (a write-Back stage would not cause any harm) we:
-- we freeze IP on the current instruction
-- we insert NOPs in the LI_DI OP while there is a conflict in order to let the problematic instruction finish
entity AleaControler is
Port (
-- get the current op and variables from the 3 pipelines stages that can interract
Op_DI, Op_EX, Op_Mem, Op_Re : in STD_LOGIC_VECTOR (7 downto 0);
A_EX, A_Mem, A_Re : in STD_LOGIC_VECTOR (7 downto 0);
B_DI : in STD_LOGIC_VECTOR (7 downto 0);
C_DI : in STD_LOGIC_VECTOR (7 downto 0);
CNTRL : out STD_LOGIC);
end AleaControler;
architecture Behavioral of AleaControler is
signal alea_DI_EX, alea_DI_MEM: STD_LOGIC;
signal is_LI_arithmetic, is_DI_arithmetic: STD_LOGIC;
begin
CNTRL <= -- either a problem between the 1st and 2nd or 1st and 3rd
'1' when
-- read after write : Op1 other than STORE/NOP/JMP/JMF, op2 other than AFC/NOP/JMP/JMF, R(write) = R(read)
(
-- check Op1 & Op2
((OP_DI /= x"06" and OP_DI /= x"ff" and OP_Di /= x"0F" and OP_DI /= x"10") and (Op_EX /= x"08" and Op_EX /= x"ff" and Op_EX /= x"0f" and Op_EX /= x"10")) and
-- check Registers are the same
((A_Ex = B_DI) or (A_EX = C_DI))
) or
-- read after write : Op1 other than STORE/NOP/JMP/JMF, op3 other than AFC/NOP/JMP/JMF, R(write) = R(read)
(
-- check Op1 & Op2
((OP_DI /= x"06" and OP_DI /= x"ff" and OP_Di /= x"0F" and OP_DI /= x"10") and (Op_Mem /= x"08" and Op_Mem /= x"ff" and Op_Mem /= x"0f" and Op_Mem /= x"10")) and
-- check Registers are the same
((A_Mem = B_DI) or (A_Mem = C_DI))
) or
-- read after write : Op1 other than STORE/NOP/JMP/JMF, op4 other than AFC/NOP/JMP/JMF, R(write) = R(read)
(
-- check Op1 & Op2
((OP_DI /= x"06" and OP_DI /= x"ff" and OP_Di /= x"0F" and OP_DI /= x"10") and (Op_Re /= x"08" and Op_Re /= x"ff" and Op_Re /= x"0f" and Op_Re /= x"10")) and
-- check Registers are the same
((A_Re = B_DI) or (A_Re = C_DI))
)
or
(
Op_EX = x"10" -- or Op_Mem = x"10" or Op_Re = x"10"
)
else '0';
end Behavioral;

364
vhdl/CPU.vhd Normal file
View file

@ -0,0 +1,364 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 14:29:58
-- Design Name:
-- Module Name: CPU - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity CPU is
Port (Clk : in STD_LOGIC := '0';
reg_addr : in STD_LOGIC_VECTOR(3 downto 0) := "0000";
reg_val : out STD_LOGIC_VECTOR(7 downto 0));
end CPU;
architecture Behavioral of CPU is
component IP is
port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC; -- rst when 1
LOAD : in STD_LOGIC;
EN : in STD_LOGIC; -- enable when 0
Din : in STD_LOGIC_VECTOR (7 downto 0);
Dout : out STD_LOGIC_VECTOR (7 downto 0));
end component;
signal IP_out : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal rst : STD_LOGIC := '0';
component InstructionMemory
Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Inst_out : out STD_LOGIC_VECTOR (31 downto 0));
end component;
signal Li : STD_LOGIC_VECTOR (31 downto 0) := (others => '1');
component Stage_Li_Di
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_C : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0);
Out_C : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component Registers
Port ( Addr_A : in STD_LOGIC_VECTOR (3 downto 0);
Addr_B : in STD_LOGIC_VECTOR (3 downto 0);
Addr_W : in STD_LOGIC_VECTOR (3 downto 0);
Addr_C : in STD_LOGIC_VECTOR (3 downto 0); -- display on FPGA
W : in STD_LOGIC;
Data : in STD_LOGIC_VECTOR (7 downto 0);
Rst : in STD_LOGIC;
Clk : in STD_LOGIC;
QA : out STD_LOGIC_VECTOR (7 downto 0);
QB : out STD_LOGIC_VECTOR (7 downto 0);
QC : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
signal Di_A, Di_Op, Di_B, Di_C : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
signal Di_RegB, Di_FinalB, Di_C2 : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
component Stage_Di_Ex
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_C : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0);
Out_C : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
signal Ex_A, Ex_Op, Ex_B, Ex_C : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
component ALU
Port ( A : in STD_LOGIC_VECTOR (7 downto 0);
B : in STD_LOGIC_VECTOR (7 downto 0);
Ctrl_Alu : in STD_LOGIC_VECTOR (7 downto 0);
S : out STD_LOGIC_VECTOR (7 downto 0);
N : out STD_LOGIC;
O : out STD_LOGIC;
Z : out STD_LOGIC;
C : out STD_LOGIC;
JumpFlagOut : out STD_LOGIC; -- 0 false 1 true
JumpFlagIn : in STD_LOGIC
);
end component;
signal Ex_Ctrl_ALu, Ex_Res_Alu, Ex_FinalB : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
signal S_NFlag, S_Oflag, S_CFlag, S_ZFlag, Jump_Flag : STD_LOGIC;
component Stage_Ex_Mem
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
signal Mem_A, Mem_Op, Mem_B : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
signal Mem_RW : STD_LOGIC;
signal Mem_Addr, Mem_Data_Out, Mem_FinalB : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
component DataMemory
Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0);
Data_in : in STD_LOGIC_VECTOR (7 downto 0);
Rw : in STD_LOGIC;
Rst : in STD_LOGIC;
Clk : in STD_LOGIC;
Data_out : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component Stage_Mem_Re
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0)
);
end component;
component AleaControler is
Port ( Op_DI, Op_EX, Op_Mem, Op_Re : in STD_LOGIC_VECTOR (7 downto 0);
A_EX, A_Mem, A_Re : in STD_LOGIC_VECTOR (7 downto 0);
B_DI : in STD_LOGIC_VECTOR (7 downto 0);
C_DI : in STD_LOGIC_VECTOR (7 downto 0);
CNTRL : out STD_LOGIC
);
end component;
signal Re_A, Re_Op, Re_B : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
signal Re_W : STD_LOGIC;
-- to control jumping and where to jump
signal addr_to_jump : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal jump : STD_LOGIC := '0';
signal nop_Cntrl : STD_LOGIC;
signal OP_LI_DI : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
signal Di_Op_Final : STD_LOGIC_VECTOR (7 downto 0) := (others => '1');
begin
-- instructionPointer
inst_point : IP port map (
CLK=> clk,
Dout=> IP_out,
Din => addr_to_jump,
RST => rst,
EN => nop_Cntrl,
LOAD => jump);
-- instructionMemory
MemInst : InstructionMemory PORT MAP (
Addr => IP_out,
Clk => Clk,
Inst_out => Li);
-- Stage_Li_Di
Stage1 : Stage_Li_Di PORT MAP (
In_A => Li(23 downto 16),
In_B => Li(15 downto 8),
In_C => Li(7 downto 0),
In_Op => OP_LI_DI,
Clk => Clk,
Out_A => Di_A,
Out_B => Di_B,
Out_Op => Di_Op,
Out_C => Di_C);
-- Registers
RegisterFile : Registers PORT MAP (
Addr_A => Di_B(3 downto 0), -- because the registers are on 4 bits
Addr_B => Di_C(3 downto 0),
Addr_W => Re_A(3 downto 0),
Addr_C => reg_addr,
W => Re_W,
Data => Re_B,
Rst => Rst,
Clk => Clk,
QA => Di_RegB,
QB => Di_C2,
QC => reg_val);
-- Stage DI/EX
Stage2 : Stage_Di_Ex PORT MAP (
In_A => Di_A,
In_B => Di_FinalB,
In_C => Di_C2,
In_Op => Di_Op_Final,
Clk => Clk,
Out_A => Ex_A,
Out_B => Ex_B,
Out_Op => Ex_Op,
Out_C => Ex_C);
-- ALU
Ual : ALU PORT MAP (
A => Ex_B,
B => Ex_C,
Ctrl_Alu => Ex_Ctrl_ALu,
S => Ex_Res_Alu,
N => S_NFlag,
O => S_OFlag,
Z => S_ZFlag,
C => S_CFlag,
JumpFlagOut => Jump_Flag,
JumpFlagIn => Jump_Flag);
-- Stage Ex/Mem
Stage3 : Stage_Ex_Mem PORT MAP (
In_A => Ex_A,
In_B => Ex_FinalB,
In_Op => Ex_Op,
Clk => Clk,
Out_A => Mem_A,
Out_B => Mem_B,
Out_Op => Mem_Op);
-- DataMemory
DataMem : DataMemory PORT MAP (
Addr => Mem_Addr,
Data_in => Mem_B,
Rw => Mem_RW,
Rst => Rst,
Clk => Clk,
Data_out => Mem_Data_Out);
-- Stage Mem/RE
Stage4 : Stage_Mem_Re PORT MAP (
In_A => Mem_A,
In_B => Mem_FinalB,
In_Op => Mem_Op,
Clk => Clk,
Out_A => Re_A,
Out_B => Re_B,
Out_Op => Re_Op);
-- Instruction code
-- ADD x"01"
-- MUL x"02"
-- SUB x"03"
-- DIV x"04"
-- COP x"05"
-- AFC x"06"
-- LOAD x"07"
-- STORE x"08"
-- INF x"09"
-- SUP x"0A"
-- EQ x"0B"
-- NOT x"0C"
-- AND x"0D"
-- OR x"0E"
-- JMP x"0F"
-- JMF x"10"
-- CAL x"11"
-- RET x"12"
-- PRI x"13"
-- NOP x"FF"
-- Mux post registers
Di_FinalB <= Di_B when
Di_OP = x"06" or -- AFC
Di_OP = x"07" -- LOAD
else Di_RegB;
-- Mux post ALU
Ex_FinalB <= Ex_B when
Ex_Op = x"06" --AFC
or Ex_Op = x"05" --COP
or Ex_Op = x"07" --LOAD
or Ex_Op = x"08" --STORE
else Ex_Res_Alu;
-- LC pre ALU
Ex_Ctrl_ALu <= x"00" when Ex_Op = x"05" or Ex_Op = x"06" or Ex_Op = x"07" or Ex_Op = x"08" --(not using ALU)
else Ex_Op;
-- Mux post data memory
Mem_FinalB <= Mem_B when
Mem_Op = x"06" --AFC
or Mem_Op = x"05" --COP
or Mem_Op = x"01" --ADD
or Mem_Op = x"03" -- SUB
or Mem_Op = x"02" -- MUL
or Mem_Op = x"04" -- DIV
else Mem_Data_out ; --LOAD & STORE
-- Mux pre data memory
Mem_Addr <= Mem_B when Mem_Op = x"07" --LOAD
else Mem_A; --STORE
-- LC pre data memory
Mem_RW <= '0' when Mem_Op = x"08" --STORE
else '1'; --STORE
-- LC post Pip_Mem_Re
Re_W <= '0' when Re_Op = x"08" or Re_Op = x"ff" --STORE
else '1';
ControlUnit : AleaControler port map (
Op_DI => Li(31 downto 24), Op_EX => Di_Op, Op_Mem => Ex_Op, Op_Re => Mem_Op,
A_EX => Di_A, A_Mem => Ex_A, A_Re => Mem_A,
B_DI => Li(15 downto 8),
C_DI => Li(7 downto 0),
CNTRL => nop_Cntrl);
-- in case of alea : replace li(31 downto 24) by NOP
OP_LI_DI <= X"ff" when (nop_Cntrl='1' or
(Di_Op = x"10" and Jump_Flag = '1')) -- to prevent JMF
else Li(31 downto 24);
-- jump JMP
addr_to_jump <= DI_A when (DI_OP = x"0F") -- JMP
else Di_B when (Di_Op = x"10" and Jump_Flag = '0') -- JMF
else (others => '0');
jump <= '1' when DI_OP = x"0F" -- JMP
or (Di_Op = x"10" and Jump_Flag = '0') -- JMF
else '0';
-- case of JMF not triggering
Di_Op_Final <= x"ff" when (Di_Op = x"10" and Jump_Flag = '1')
else Di_Op;
end Behavioral;

61
vhdl/IP.vhd Normal file
View file

@ -0,0 +1,61 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 21.03.2023 15:57:28
-- Design Name:
-- Module Name: compteur_8bits - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity IP is
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC; -- rst when 1
LOAD : in STD_LOGIC;
EN : in STD_LOGIC; -- enable when 0
Din : in STD_LOGIC_VECTOR (7 downto 0);
Dout : out STD_LOGIC_VECTOR (7 downto 0));
end IP;
architecture Behavioral of IP is
signal aux: STD_LOGIC_VECTOR (7 downto 0) := x"00";
begin
process
begin
wait until rising_edge(CLK);
if (RST = '1') then
aux <= x"00";
elsif (LOAD = '1') then
aux <= Din;
elsif (EN = '0') then
aux <= aux + x"01";
end if;
end process;
Dout <= aux;
end Behavioral;

View file

@ -0,0 +1,53 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 13:55:29
-- Design Name:
-- Module Name: InstructionMemory - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity InstructionMemory is
Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Inst_out : out STD_LOGIC_VECTOR (31 downto 0));
end InstructionMemory;
architecture Behavioral of InstructionMemory is
type Mem_array is array (0 to 255) of STD_LOGIC_VECTOR (31 downto 0);
-- signal Mem : Mem_array := ((x"06000200"),(x"08020000"),(x"07000200"),(x"08000000"),(x"06000200"),(x"08020000"),(x"07000000"),(x"07010200"),(x"01000001"),(x"08030000"),(x"07000300"),(x"08010000"),others => (x"ff000000"));
-- signal Mem : Mem_array := ((x"06000200"),(x"08030000"),(x"07000300"),(x"08000000"),(x"06000600"),(x"08030000"),(x"07000000"),(x"07010300"),(x"02000001"),(x"08040000"),(x"07000400"),(x"08010000"),(x"06000200"),(x"08030000"),(x"07000100"),(x"07010300"),(x"04000001"),(x"08040000"),(x"07000400"),(x"07010000"),(x"01000001"),(x"08030000"),(x"07000300"),(x"08020000"),others => (x"ff000000"));
-- test JMP signal Mem : Mem_array := ((x"06000200"),(x"08030000"),(x"07000300"),(x"08000000"),(x"06000500"),(x"08030000"),(x"07000300"),(x"08010000"),(x"0F0D0000"),(x"06000800"),(x"08030000"),(x"07000300"),(x"08020000"),(x"06000900"),(x"08030000"),(x"07000300"),(x"08020000"),others => (x"ff000000"));
-- test JMF signal Mem : Mem_array := ((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000500"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"100F0000"),(x"06000800"),(x"08030000"),(x"07000300"),(x"08000000"),(x"FF000000"),others => (x"ff000000"));
-- test if else signal Mem : Mem_array := ((x"06000200"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000500"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"10021000"),(x"06000800"),(x"08030000"),(x"07000300"),(x"08000000"),(x"0F140000"),(x"06000C00"),(x"08020000"),(x"07000200"),(x"08000000"),(x"FF000000"),others => (x"ff000000"));
-- test boucle while
signal Mem : Mem_array := ((x"06000500"),(x"08010000"),(x"07000100"),(x"08000000"),(x"06000500"),(x"08010000"),(x"07000000"),(x"07010100"),(x"0B020100"),(x"08020200"),(x"10001B00"),(x"06001400"),(x"08030000"),(x"07000000"),(x"07010300"),(x"09020001"),(x"08040200"),(x"10041B00"),(x"06000200"),(x"08010000"),(x"07000000"),(x"07010100"),(x"01000001"),(x"08030000"),(x"07000300"),(x"08000000"),(x"0F0B0000"),(x"FF000000"),others => (x"ff000000"));
-- signal Mem : Mem_array := ((x"06000200"),(x"08040000"),(x"07000400"),(x"08030000"),(x"07000000"),(x"08020000"),(x"06000200"),(x"08040000"),(x"07000200"),(x"07010400"),(x"01000001"),(x"08050000"),(x"07000500"),(x"08000000"),(x"07000300"),(x"08000000"),(x"06000500"),(x"08040000"),(x"07000400"),(x"08000000"),(x"06001300"),(x"08040000"),(x"06000200"),(x"08050000"),(x"07000400"),(x"07010500"),(x"01000001"),(x"08040000"),(x"06000500"),(x"08050000"),(x"07000500"),(x"07010000"),(x"02000001"),(x"08040000"),(x"06000800"),(x"08050000"),(x"07000400"),(x"07010500"),(x"01000001"),(x"08040000"),(x"06000200"),(x"08050000"),(x"07000400"),(x"07010500"),(x"02000001"),(x"08040000"),(x"07000400"),(x"07010400"),(x"03000001"),(x"08050000"),(x"07000500"),(x"08030000"), others => (x"ff000000"));
begin
Inst_out <= Mem(to_integer(unsigned(Addr)));
end Behavioral;

60
vhdl/Memory.vhd Normal file
View file

@ -0,0 +1,60 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 13:37:41
-- Design Name:
-- Module Name: DataMemory - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DataMemory is
Port ( Addr : in STD_LOGIC_VECTOR (7 downto 0);
Data_in : in STD_LOGIC_VECTOR (7 downto 0);
Rw : in STD_LOGIC;
Rst : in STD_LOGIC;
Clk : in STD_LOGIC;
Data_out : out STD_LOGIC_VECTOR (7 downto 0));
end DataMemory;
architecture Behavioral of DataMemory is
type Mem_array is array (0 to 255) of STD_LOGIC_VECTOR (7 downto 0);
signal Mem : Mem_array := (others => x"00");
begin
process
begin
wait until clk'event and clk = '1';
if Rst = '1' then -- Reset
mem <= (others => x"00");
else if Rw = '0' then --writing
Mem(to_integer(unsigned(Addr))) <= Data_in;
end if;
end if;
end process;
Data_out <= Mem(to_integer(unsigned(Addr))); --reading
end Behavioral;

79
vhdl/Registers.vhd Normal file
View file

@ -0,0 +1,79 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 12:56:05
-- Design Name:
-- Module Name: registers - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Registers is
Port ( Addr_A : in STD_LOGIC_VECTOR (3 downto 0);
Addr_B : in STD_LOGIC_VECTOR (3 downto 0);
Addr_W : in STD_LOGIC_VECTOR (3 downto 0);
Addr_C : in STD_LOGIC_VECTOR (3 downto 0); -- display on FPGA
W : in STD_LOGIC;
Data : in STD_LOGIC_VECTOR (7 downto 0);
Rst : in STD_LOGIC;
Clk : in STD_LOGIC;
QA : out STD_LOGIC_VECTOR (7 downto 0);
QB : out STD_LOGIC_VECTOR (7 downto 0);
QC : out STD_LOGIC_VECTOR (7 downto 0));
end Registers;
architecture Behavioral of Registers is
type Reg_array is array (0 to 15) of STD_LOGIC_VECTOR (7 downto 0);
signal Regs : Reg_array := (others => x"00");
begin
process
begin
wait until clk'event and clk = '1';
if Rst = '1' then -- Reset
Regs <= (others => x"00");
elsif W = '1' then -- Writing
Regs(to_integer(unsigned(Addr_W))) <= Data;
end if;
end process;
QA <= Regs(to_integer(unsigned(Addr_A)))
when W = '0' or Addr_W /= Addr_A
else Regs(to_integer(unsigned(Addr_W))) ; -- to bypass D --> Q
QB <= Regs(to_integer(unsigned(Addr_B)))
when W = '0' or Addr_W /= Addr_B
else Regs(to_integer(unsigned(Addr_W))) ; -- to bypass D --> Q
QC <= Regs(to_integer(unsigned(Addr_C)))
when W = '0' or Addr_W /= Addr_C
--else Regs(to_integer(unsigned(Addr_W)))
else
x"11" ; -- to bypass D --> Q
end Behavioral;

59
vhdl/Stage_Di_Ex.vhd Normal file
View file

@ -0,0 +1,59 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 14:09:59
-- Design Name:
-- Module Name: Pipeline - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Stage_Di_Ex is
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_C : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0);
Out_C : out STD_LOGIC_VECTOR (7 downto 0)
);
end Stage_Di_Ex;
architecture Behavioral of Stage_Di_Ex is
begin
process
begin
wait until clk'event and clk = '1';
Out_A <= In_A;
Out_B <= In_B;
Out_C <= In_C;
Out_Op <= In_Op;
end process;
end Behavioral;

56
vhdl/Stage_Ex_Mem.vhd Normal file
View file

@ -0,0 +1,56 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 14:09:59
-- Design Name:
-- Module Name: Pipeline - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Stage_Ex_Mem is
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0)
);
end Stage_Ex_Mem;
architecture Behavioral of Stage_Ex_Mem is
begin
process
begin
wait until clk'event and clk = '1';
Out_A <= In_A;
Out_B <= In_B;
Out_Op <= In_Op;
end process;
end Behavioral;

59
vhdl/Stage_Li_Di.vhd Normal file
View file

@ -0,0 +1,59 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 14:09:59
-- Design Name:
-- Module Name: Pipeline - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Stage_Li_Di is
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_C : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0);
Out_C : out STD_LOGIC_VECTOR (7 downto 0)
);
end Stage_Li_Di;
architecture Behavioral of Stage_Li_Di is
begin
process
begin
wait until clk'event and clk = '1';
Out_A <= In_A;
Out_B <= In_B;
Out_C <= In_C;
Out_Op <= In_Op;
end process;
end Behavioral;

56
vhdl/Stage_Mem_Re.vhd Normal file
View file

@ -0,0 +1,56 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15.05.2023 14:09:59
-- Design Name:
-- Module Name: Pipeline - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Stage_Mem_Re is
Port ( In_A : in STD_LOGIC_VECTOR (7 downto 0);
In_B : in STD_LOGIC_VECTOR (7 downto 0);
In_Op : in STD_LOGIC_VECTOR (7 downto 0);
Clk : in STD_LOGIC;
Out_A : out STD_LOGIC_VECTOR (7 downto 0);
Out_B : out STD_LOGIC_VECTOR (7 downto 0);
Out_Op : out STD_LOGIC_VECTOR (7 downto 0)
);
end Stage_Mem_Re;
architecture Behavioral of Stage_Mem_Re is
begin
process
begin
wait until clk'event and clk = '1';
Out_A <= In_A;
Out_B <= In_B;
Out_Op <= In_Op;
end process;
end Behavioral;

145
vhdl/test_alu.vhd Normal file
View file

@ -0,0 +1,145 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 12.05.2023 17:40:52
-- Design Name:
-- Module Name: Test_Alu - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Test_Alu is
-- Port ( );
end Test_Alu;
architecture Behavioral of Test_Alu is
component ALU
Port ( A : in STD_LOGIC_VECTOR (7 downto 0);
B : in STD_LOGIC_VECTOR (7 downto 0);
Ctrl_Alu : in STD_LOGIC_VECTOR (7 downto 0); -- 000 + / 001 - / 010 * / 100 Div
S : out STD_LOGIC_VECTOR (7 downto 0);
N : out STD_LOGIC;
O : out STD_LOGIC;
Z : out STD_LOGIC;
C : out STD_LOGIC);
end component;
-- inputs
signal local_A : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal local_B : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal local_Ctrl_Alu : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
--outputs
signal local_S : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
signal local_N : STD_LOGIC := '0';
signal local_O : STD_LOGIC := '0';
signal local_Z : STD_LOGIC := '0';
signal local_C : STD_LOGIC := '0';
-- constant Clock_period : time := 10ns;
begin
-- instantiate
instance : ALU PORT MAP (
A => local_A,
B => local_B,
Ctrl_Alu => local_Ctrl_Alu,
S => local_S,
N => local_N,
O => local_O,
Z => local_Z,
C => local_C
);
local_Ctrl_Alu <= x"01", -- ADD
x"02" after 40 ns, -- MUL
x"03" after 60 ns, -- SUB
x"04" after 90 ns, -- DIV
x"09" after 120 ns, -- INF
x"0A" after 140 ns, -- SUP
x"0B" after 160 ns, -- EQ
x"0C" after 180 ns, -- NOT
x"0D" after 210 ns, -- XOR
x"0E" after 240 ns, -- OR
x"0F" after 270 ns; -- XOR
local_A <= x"00",
x"00" after 10 ns,
x"0A" after 20 ns,
x"96" after 30 ns,
x"1D" after 40 ns,
x"0A" after 50 ns,
x"0B" after 60 ns,
x"0F" after 70 ns,
x"19" after 80 ns,
x"12" after 90 ns,
x"18" after 100 ns,
x"19" after 110 ns,
x"10" after 120 ns,
x"20" after 130 ns,
x"10" after 150 ns,
x"0A" after 160 ns,
x"0B" after 170 ns,
x"01" after 180 ns,
x"25" after 190 ns,
x"00" after 200 ns,
x"0A" after 210 ns,
x"00" after 230 ns,
x"0A" after 240 ns,
x"00" after 260 ns,
x"0A" after 270 ns,
x"00" after 290 ns;
local_B <= x"00",
x"00" after 10 ns,
x"82" after 20 ns,
x"A0" after 30 ns,
x"09" after 40 ns,
x"04" after 50 ns,
x"0B" after 60 ns,
x"12" after 70 ns,
x"0B" after 80 ns,
x"00" after 90 ns,
x"06" after 100 ns,
x"07" after 110 ns,
x"20" after 120 ns,
x"10" after 130 ns,
x"20" after 150 ns,
x"0A" after 160 ns,
x"02" after 170 ns,
x"00" after 190 ns,
x"0B" after 210 ns,
x"00" after 220 ns,
x"0B" after 240 ns,
x"00" after 250 ns,
x"0B" after 270 ns,
x"00" after 280 ns;
end Behavioral;

65
vhdl/test_cpu.vhd Normal file
View file

@ -0,0 +1,65 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 12.05.2023 17:40:52
-- Design Name:
-- Module Name: Test_cpu - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity Test_CPU is
-- Port ( );
end Test_CPU;
architecture Behavioral of test_total is
component CPU
Port (Clk : in STD_LOGIC;
reg_addr : in STD_LOGIC_VECTOR(3 downto 0);
reg_val : out STD_LOGIC_VECTOR(7 downto 0));
end component;
constant clock_period : time := 10 ns;
signal clock : Std_logic := '0';
signal a : STD_LOGIC_VECTOR(7 downto 0);
begin
-- instantiate
Pl : CPU PORT MAP (
Clk => clock,
reg_addr => x"0",
reg_val => a
);
Clock_process : process
begin
clock <= not(clock);
wait for 100ns;
end process;
end Behavioral;

26
vhdl/test_cpu.xdc Normal file
View file

@ -0,0 +1,26 @@
set_property PACKAGE_PIN R2 [get_ports CLK]
set_property IOSTANDARD LVCMOS33 [get_ports CLK]
#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK]
#set_property -dicset_property -dict {PACKAGE_PIN T18 IOSTANDARD LVCMOS33} [get_ports CLK]
#set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS33} [get_ports CLK]
#create_clock -period 10.000 -name -sysclk_pin -waveform {0.000 5.000} [get_ports CLK]
set_property ALLOW_COMBINATORIAL_LOOPS TRUE [get_nets {Stage2/Jump_Flag}]
set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {reg_addr[0]}]
set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {reg_addr[1]}]
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {reg_addr[2]}]
set_property -dict {PACKAGE_PIN W17 IOSTANDARD LVCMOS33} [get_ports {reg_addr[3]}]
set_property -dict {PACKAGE_PIN U16 IOSTANDARD LVCMOS33} [get_ports {reg_val[0]}]
set_property -dict {PACKAGE_PIN E19 IOSTANDARD LVCMOS33} [get_ports {reg_val[1]}]
set_property -dict {PACKAGE_PIN U19 IOSTANDARD LVCMOS33} [get_ports {reg_val[2]}]
set_property -dict {PACKAGE_PIN V19 IOSTANDARD LVCMOS33} [get_ports {reg_val[3]}]
set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVCMOS33} [get_ports {reg_val[4]}]
set_property -dict {PACKAGE_PIN U15 IOSTANDARD LVCMOS33} [get_ports {reg_val[5]}]
set_property -dict {PACKAGE_PIN U14 IOSTANDARD LVCMOS33} [get_ports {reg_val[6]}]
set_property -dict {PACKAGE_PIN V14 IOSTANDARD LVCMOS33} [get_ports {reg_val[7]}]
set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
set_property SEVERITY {Warning} [get_drc_checks UCIO-1]