diff --git a/src/core/Common/Code.ts b/src/core/Common/Code.ts
index f4b13827..648bdf90 100644
--- a/src/core/Common/Code.ts
+++ b/src/core/Common/Code.ts
@@ -1,7 +1,7 @@
 import { Instruction } from "./Instruction";
 
-import { CodeParser } from "./CodeParser";
-import { Machine } from "./Machine";
+import { parseProgram } from "./CodeParser";
+import { MACHINE_REGISTER_SIZE, MACHINE_MEMORY_SIZE } from "./Machine";
 
 export class Code {
   private _lines: number;
@@ -25,7 +25,7 @@ export class Code {
   }
 
   public load(input: string) {
-    let codeParsed = new CodeParser(input, Machine.NGP, Machine.MEMORY_SIZE);
+    const program = parseProgram(input, MACHINE_REGISTER_SIZE, MACHINE_MEMORY_SIZE);
 
     // First we need the number of code lines
     this._lines = codeParsed.lines;
diff --git a/src/core/Common/CodeParser.ts b/src/core/Common/CodeParser.ts
index 5315d671..3d6f61c4 100644
--- a/src/core/Common/CodeParser.ts
+++ b/src/core/Common/CodeParser.ts
@@ -1,381 +1,300 @@
 import {
   type Token,
-  TokenError,
-  type TokenPosition,
-  alt_sc,
   apply,
   buildLexer,
-  expectEOF,
-  expectSingleResult,
-  opt_sc,
+  rule,
   rep_sc,
-  seq,
+  alt,
+  expectSingleResult,
+  expectEOF,
+  type TokenError,
+  kleft,
+  str,
   tok,
+  kright,
+  seq,
 } from "typescript-parsec";
-import { Instruction } from "./Instruction";
-import { Formats, FormatsNames } from "./InstructionFormats";
-import { OpcodesNames, opcodeToFormat } from "./Opcodes";
-
-enum Tokens {
-  Inmediate = 0,
-  RegFP = 1,
-  RegGP = 2,
-  Id = 3,
-  Label = 4,
-  BraketOpen = 5,
-  BraketClose = 6,
-  Number = 7,
-  Comma = 8,
-  Space = 9,
-  NewLine = 10,
-  Comment = 11,
+import type { OpcodeMnemonic, OpcodeType } from "./Opcode";
+import type { RegisterKind } from "./Register";
+
+/* Tokens and tokenizer */
+
+enum TokenKind {
+  Opcode = 0,
+  Register = 1,
+  Immediate = 2,
+  Label = 3,
+  Unsigned = 4,
+  OpenParen = 5,
+  CloseParen = 6,
+  Space = 7,
+  Comment = 8,
 }
 
-enum RegType {
-  FP = 0,
-  GP = 1,
-}
-const RegTypeNames: string[] = ["FP", "GP"];
+type TokenType = Token<TokenKind>;
 
-interface Reg {
-  type: RegType;
-  pos: TokenPosition;
-  num: number;
-  text: string;
-}
+const tokenizer = buildLexer([
+  [true, /^[A-Z]+g/, TokenKind.Opcode],
+  [true, /^[A-Z][0-9]+/g, TokenKind.Register],
+  [true, /^#[0-9]+/g, TokenKind.Immediate],
+  [true, /^[a-zA-Z_][a-zA-Z0-9_]*/g, TokenKind.Label],
+  [true, /^\d+/g, TokenKind.Unsigned],
+  [true, /^\(/g, TokenKind.OpenParen],
+  [true, /^\)/g, TokenKind.CloseParen],
+  [false, /^\s+/g, TokenKind.Space],
+  [false, /^[/][/][^\n]*\n/g, TokenKind.Comment],
+]);
 
-interface Address {
-  address: number;
-  reg: Reg;
-}
+/* AST definitions */
 
-interface OpcodeToken {
-  opcode: number;
-  pos: TokenPosition;
+interface Opcode<T extends OpcodeType> {
+  kind: `${Capitalize<Lowercase<T>>}Opcode`;
+  mnemonic: T;
 }
 
-const tokenizer = buildLexer([
-  [true, /^#[+-]?[0-9]+/g, Tokens.Inmediate],
-  [true, /^[Ff][0-9]+/g, Tokens.RegFP],
-  [true, /^[Rr][0-9]+/g, Tokens.RegGP],
-  [true, /^[A-Za-z][A-Za-z0-9]*\:/g, Tokens.Label],
-  [true, /^[A-Za-z][A-Za-z0-9]*/g, Tokens.Id],
-  [true, /^\(/g, Tokens.BraketOpen],
-  [true, /^\)/g, Tokens.BraketClose],
-  [true, /^[+-]?[0-9]+/g, Tokens.Number],
-  [false, /^\,/g, Tokens.Comma],
-  [false, /^[ \t\v\f]+/g, Tokens.Space],
-  [false, /^\r?\n/g, Tokens.NewLine],
-  [false, /^\/\/.*\n/g, Tokens.Comment],
-]);
+interface Immediate {
+  kind: "Immediate";
+  value: number;
+}
 
-const inmParser = apply(
-  tok(Tokens.Inmediate),
-  (num: Token<Tokens.Inmediate>) => {
-    return +num.text.slice(1);
-  },
-);
+interface GenericRegister<T extends RegisterKind> {
+  kind: `${T}Register`;
+  index: number;
+}
 
-const regParser = apply(
-  alt_sc(tok(Tokens.RegFP), tok(Tokens.RegGP)),
-  (reg: Token<Tokens.RegFP> | Token<Tokens.RegGP>) => {
-    let type = RegType.GP;
-    if (reg.kind === Tokens.RegFP) {
-      type = RegType.FP;
-    }
-    return {
-      type: type,
-      pos: reg.pos,
-      num: +reg.text.slice(1),
-      text: reg.text,
-    };
-  },
-);
+type GeneralPurposeRegister = GenericRegister<RegisterKind.GeneralPurpose>;
+type FloatingPointRegister = GenericRegister<RegisterKind.FloatingPoint>;
 
-const addressParser = apply(
-  seq(
-    opt_sc(tok(Tokens.Number)),
-    tok(Tokens.BraketOpen),
-    regParser,
-    tok(Tokens.BraketClose),
-  ),
-  (
-    address: [
-      Token<Tokens.Number>,
-      Token<Tokens.BraketOpen>,
-      Reg,
-      Token<Tokens.BraketClose>,
-    ],
-  ) => {
-    if (address[2].type === RegType.FP) {
-      throw new TokenError(
-        address[2].pos,
-        "Address register cannot be FP register",
-      );
-    }
-    return { address: address[0] ? +address[0].text : 0, reg: address[2] };
-  },
-);
+type Register = {
+  [T in RegisterKind]: GenericRegister<T>;
+}[RegisterKind];
 
-const opcodeParser = apply(
-  tok(Tokens.Id),
-  (opcodeTok: Token<Tokens.Id>): OpcodeToken => {
-    const opcode: number = OpcodesNames.indexOf(opcodeTok.text);
-    if (opcode !== -1) {
-      return { opcode: opcode, pos: opcodeTok.pos };
-    }
-    throw new TokenError(opcodeTok.pos, `Unknown opcode "${opcodeTok.text}".`);
-  },
-);
+interface Label {
+  kind: "Label";
+  name: string;
+}
 
-export class CodeParser {
-  private _instructions: Instruction[] = [];
-  private _labels: { [k: string]: number } = {};
+interface Addressing {
+  kind: "Addressing";
+  offset: number;
+  address: number;
+}
 
-  private _generalRegisters: number;
-  private _memorySize: number;
+type Operand = Immediate | Register | Label | Addressing;
 
-  public get instructions(): Instruction[] {
-    return this._instructions;
-  }
+type OperandSet<T extends Operand[]> = {
+  [Property in keyof T]: T[Property];
+};
 
-  public get labels(): { [k: string]: number } {
-    return this._labels;
-  }
-
-  public get lines(): number {
-    return this._instructions.length;
-  }
+interface GenericInstruction<T extends OpcodeType, U extends Operand[] = []> {
+  kind: `${Capitalize<Lowercase<T>>}Instruction`;
+  opcode: Opcode<T>;
+  operands?: OperandSet<U>;
+}
 
-  constructor(code: string, generalRegisters: number, memorySize: number) {
-    this._generalRegisters = generalRegisters;
-    this._memorySize = memorySize;
-    this.parse(code);
-  }
+type NopInstruction = GenericInstruction<OpcodeMnemonic.NOP>;
+
+type AddInstruction = GenericInstruction<
+  OpcodeMnemonic.ADD,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type AddiInstruction = GenericInstruction<
+  OpcodeMnemonic.ADDI,
+  [GeneralPurposeRegister, GeneralPurposeRegister, Immediate]
+>;
+
+type SubInstruction = GenericInstruction<
+  OpcodeMnemonic.SUB,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type AddfInstruction = GenericInstruction<
+  OpcodeMnemonic.ADDF,
+  [FloatingPointRegister, FloatingPointRegister, FloatingPointRegister]
+>;
+
+type SubfInstruction = GenericInstruction<
+  OpcodeMnemonic.SUBF,
+  [FloatingPointRegister, FloatingPointRegister, FloatingPointRegister]
+>;
+
+type MultInstruction = GenericInstruction<
+  OpcodeMnemonic.MULT,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type MultfInstruction = GenericInstruction<
+  OpcodeMnemonic.MULTF,
+  [FloatingPointRegister, FloatingPointRegister, FloatingPointRegister]
+>;
+
+type OrInstruction = GenericInstruction<
+  OpcodeMnemonic.OR,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type AndInstruction = GenericInstruction<
+  OpcodeMnemonic.AND,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type XorInstruction = GenericInstruction<
+  OpcodeMnemonic.XOR,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type NorInstruction = GenericInstruction<
+  OpcodeMnemonic.NOR,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type SllvInstruction = GenericInstruction<
+  OpcodeMnemonic.SLLV,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type SrlvInstruction = GenericInstruction<
+  OpcodeMnemonic.SRLV,
+  [GeneralPurposeRegister, GeneralPurposeRegister, GeneralPurposeRegister]
+>;
+
+type LwInstruction = GenericInstruction<
+  OpcodeMnemonic.LW,
+  [GeneralPurposeRegister, Addressing]
+>;
+
+type LfInstruction = GenericInstruction<
+  OpcodeMnemonic.LF,
+  [FloatingPointRegister, Addressing]
+>;
+
+type SwInstruction = GenericInstruction<
+  OpcodeMnemonic.SW,
+  [GeneralPurposeRegister, Addressing]
+>;
+
+type SfInstruction = GenericInstruction<
+  OpcodeMnemonic.SF,
+  [FloatingPointRegister, Addressing]
+>;
+
+type BneInstruction = GenericInstruction<
+  OpcodeMnemonic.BNE,
+  [GeneralPurposeRegister, GeneralPurposeRegister, Label]
+>;
+
+type BeqInstruction = GenericInstruction<
+  OpcodeMnemonic.BEQ,
+  [GeneralPurposeRegister, GeneralPurposeRegister, Label]
+>;
+
+type BgtInstruction = GenericInstruction<
+  OpcodeMnemonic.BGT,
+  [GeneralPurposeRegister, GeneralPurposeRegister, Label]
+>;
+
+type Instruction =
+  | NopInstruction
+  | AddInstruction
+  | AddiInstruction
+  | SubInstruction
+  | AddfInstruction
+  | SubfInstruction
+  | MultInstruction
+  | MultfInstruction
+  | OrInstruction
+  | AndInstruction
+  | XorInstruction
+  | NorInstruction
+  | SllvInstruction
+  | SrlvInstruction
+  | LwInstruction
+  | LfInstruction
+  | SwInstruction
+  | SfInstruction
+  | BneInstruction
+  | BeqInstruction
+  | BgtInstruction;
+
+interface LabelDefinition {
+  kind: "LabelDefinition";
+  name: string;
+  lineNumber: number;
+}
 
-  private parse(code: string) {
-    const result = expectSingleResult(
-      expectEOF(this.genCodeParser().parse(tokenizer.parse(code))),
-    );
+type Statement = Instruction | LabelDefinition;
 
-    // Create labels and instructions
-    let pos = 0;
-    for (let i = 0; i < result[1].length; i++) {
-      const line = result[1][i];
-      if ("kind" in line && line.kind === Tokens.Label) {
-        const name = line.text.slice(0, -1);
-        if (name in this._labels) {
-          throw new Error(
-            `Error at instruction ${pos}, label ${line.text.slice(
-              0,
-              -1,
-            )} already exists`,
-          );
-        }
-        this._labels[name] = pos;
-      } else if (line instanceof Instruction) {
-        this._instructions.push(line);
-        pos++;
-      } else {
-        throw new Error(`Unexpected code parser fail: ${JSON.stringify(line)}`);
-      }
-    }
-  }
+interface Program {
+  statements: Statement[];
+}
 
-  private genCodeParser() {
-    return seq(
-      opt_sc(tok(Tokens.Number)),
-      rep_sc(alt_sc(this.genOperationParser(), tok(Tokens.Label))),
-    );
+/* Parser implementation */
+
+const applyRegister = ([registerPrefix, index]: [
+  Token<TokenKind>,
+  Immediate,
+]): Register => {
+  switch (registerPrefix.text) {
+    case "R":
+      return { kind: "GeneralPurposeRegister", index: index.value };
+    case "F":
+      return { kind: "FloatingPointRegister", index: index.value };
   }
-
-  private genOperationParser() {
-    return apply(
-      alt_sc(
-        seq(opcodeParser, regParser, regParser, regParser),
-        seq(opcodeParser, regParser, regParser, inmParser),
-        seq(opcodeParser, regParser, regParser, tok(Tokens.Id)),
-        seq(opcodeParser, regParser, addressParser),
-        opcodeParser,
-      ), // The order is important, the first succesfull match is the one that is returned
-      (
-        operation:
-          | OpcodeToken
-          | [OpcodeToken, Reg, Reg, Reg]
-          | [OpcodeToken, Reg, Reg, number]
-          | [OpcodeToken, Reg, Address]
-          | [OpcodeToken, Reg, Reg, Token<Tokens.Id>],
-      ) => {
-        let type: Formats;
-        const instruction: Instruction = new Instruction();
-        let pos: TokenPosition;
-
-        // set the opcode and get the current position
-        if (Array.isArray(operation)) {
-          instruction.opcode = operation[0].opcode;
-          pos = operation[0].pos;
-        } else {
-          instruction.opcode = operation.opcode;
-          pos = operation.pos;
-        }
-
-        // Check the recived instruction format and set the operands
-        if (!Array.isArray(operation)) {
-          type = Formats.Noop;
-        } else if ("num" in operation[2] && operation.length === 4) {
-          if (operation[2].type !== operation[1].type) {
-            throw new TokenError(
-              operation[2].pos,
-              `Second operand register type(${
-                RegTypeNames[operation[2].type]
-              }) mistmatch. Expected ${RegTypeNames[operation[1].type]}`,
-            );
-          }
-
-          if (typeof operation[3] === "number") {
-            type = Formats.GeneralRegisterAndInmediate;
-
-            // Check that the registers are in bounds
-            if (operation[1].num > this._generalRegisters) {
-              throw new TokenError(
-                operation[1].pos,
-                "Destiny register number out of bounds",
-              );
-            }
-            if (operation[2].num > this._generalRegisters) {
-              throw new TokenError(
-                operation[2].pos,
-                "Operand 1 register number out of bounds",
-              );
-            }
-
-            instruction.setOperand(0, operation[1].num, operation[1].text);
-            instruction.setOperand(1, operation[2].num, operation[2].text);
-            instruction.setOperand(
-              2,
-              operation[3],
-              `#${operation[3].toString()}`,
-            );
-            if (operation[1].type === RegType.FP) {
-              throw new TokenError(
-                operation[1].pos,
-                "Inmediate operand not allowed for floating point registers",
-              );
-            }
-          } else if ("num" in operation[3]) {
-            if (operation[3].type !== operation[1].type) {
-              throw new TokenError(
-                operation[3].pos,
-                `Third operand register type(${
-                  RegTypeNames[operation[3].type]
-                }) mistmatch. Expected ${RegTypeNames[operation[1].type]}`,
-              );
-            }
-
-            if (operation[1].type === RegType.FP) {
-              type = Formats.TwoFloatingRegisters;
-            } else {
-              type = Formats.TwoGeneralRegisters;
-            }
-
-            // Check that the registers are in bounds
-            if (operation[1].num > this._generalRegisters) {
-              throw new TokenError(
-                operation[1].pos,
-                "Destiny register number out of bounds",
-              );
-            }
-            if (operation[2].num > this._generalRegisters) {
-              throw new TokenError(
-                operation[2].pos,
-                "Operand 1 register number out of bounds",
-              );
-            }
-            if (operation[3].num > this._generalRegisters) {
-              throw new TokenError(
-                operation[3].pos,
-                "Operand 2 register number out of bounds",
-              );
-            }
-
-            instruction.setOperand(0, operation[1].num, operation[1].text);
-            instruction.setOperand(1, operation[2].num, operation[2].text);
-            instruction.setOperand(2, operation[3].num, operation[3].text);
-          } else if ("pos" in operation[3]) {
-            type = Formats.Jump;
-
-            // Check that the registers are in bounds
-            if (operation[1].num > this._generalRegisters) {
-              throw new TokenError(
-                operation[1].pos,
-                "Operand 1 register number out of bounds",
-              );
-            }
-            if (operation[2].num > this._generalRegisters) {
-              throw new TokenError(
-                operation[2].pos,
-                "Operand 2 register number out of bounds",
-              );
-            }
-
-            instruction.setOperand(0, operation[1].num, operation[1].text);
-            instruction.setOperand(1, operation[2].num, operation[2].text);
-            instruction.setOperand(2, undefined, operation[3].text);
-          }
-        } else if (operation.length === 3) {
-          if (operation[1].type === RegType.FP) {
-            type = Formats.FloatingLoadStore;
-          } else {
-            type = Formats.GeneralLoadStore;
-          }
-
-          // Check that the registers are in bounds
-          if (operation[1].num > this._generalRegisters) {
-            throw new TokenError(
-              operation[1].pos,
-              "Destiny register number out of bounds",
-            );
-          }
-          if (operation[2].reg.num > this._generalRegisters) {
-            throw new TokenError(
-              operation[2].reg.pos,
-              "Adress register number out of bounds",
-            );
-          }
-          if (operation[2].address > this._memorySize) {
-            throw new TokenError(
-              operation[2].reg.pos,
-              "Memory address out of bounds",
-            );
-          }
-
-          instruction.setOperand(0, operation[1].num, operation[1].text);
-          instruction.setOperand(
-            1,
-            operation[2].address,
-            operation[2].address.toString(),
-          );
-          instruction.setOperand(
-            2,
-            operation[2].reg.num,
-            `(${operation[2].reg.text})`,
-          );
-        }
-
-        const expectedType = opcodeToFormat(instruction.opcode);
-        if (type !== expectedType) {
-          throw new TokenError(
-            pos,
-            `Invalid instruction format for ${
-              OpcodesNames[instruction.opcode]
-            }. Expected ${FormatsNames[expectedType]} format, got ${
-              FormatsNames[type]
-            } format or similar`,
-          );
-        }
-
-        return instruction;
-      },
+};
+
+const applyImmediate = (value: Token<TokenKind.Immediate>): Immediate => {
+  return { kind: "Immediate", value: +value.text };
+};
+
+const applyLabel = (value: Token<TokenKind.Label>): Label => {
+  return { kind: "Label", name: value.text };
+};
+
+const applyLabelDefinition = (
+  value: Label,
+  [token, _]: [Token<TokenKind>, Token<TokenKind>],
+): LabelDefinition => {
+  return {
+    kind: "LabelDefinition",
+    name: value.name,
+    lineNumber: token.pos.rowBegin, // TODO: test this
+  };
+};
+
+const applyStatement = (value: Instruction | LabelDefinition): Statement => {
+  return value;
+};
+
+const applyProgram = (value: Statement[]): Program => {
+  return {
+    statements: value,
+  };
+};
+
+export const REGISTER = rule<TokenKind, Register>();
+export const IMMEDIATE = rule<TokenKind, Immediate>();
+export const LABEL = rule<TokenKind, Label>();
+export const INSTR = rule<TokenKind, Instruction>();
+export const LABELDEF = rule<TokenKind, LabelDefinition>();
+export const STAT = rule<TokenKind, Statement>();
+export const PROGRAM = rule<TokenKind, Program>();
+
+REGISTER.setPattern(
+  apply(seq(alt(str("R"), str("F")), IMMEDIATE), applyRegister),
+);
+IMMEDIATE.setPattern(apply(tok(TokenKind.Immediate), applyImmediate));
+LABEL.setPattern(apply(tok(TokenKind.Label), applyLabel));
+LABELDEF.setPattern(apply(kleft(LABEL, str(":")), applyLabelDefinition));
+STAT.setPattern(apply(alt(INSTR, LABELDEF), applyStatement));
+PROGRAM.setPattern(apply(rep_sc(STAT), applyProgram));
+
+export const parseProgram = (programString: string): Program | TokenError => {
+  try {
+    return expectSingleResult(
+      expectEOF(PROGRAM.parse(tokenizer.parse(programString))),
     );
+  } catch (e) {
+    return e;
   }
-}
+};
diff --git a/src/core/Common/FunctionalUnit.ts b/src/core/Common/FunctionalUnit.ts
index 91494441..5d7a472e 100644
--- a/src/core/Common/FunctionalUnit.ts
+++ b/src/core/Common/FunctionalUnit.ts
@@ -1,16 +1,16 @@
-import { Instruction } from "./Instruction";
-import { Opcodes } from "./Opcodes";
+import type { Instruction } from "./Instruction";
+import type { Opcode } from "./Opcode";
 
-export enum FunctionalUnitType {
+export enum FunctionalUnitKind {
   INTEGERSUM = 0,
-  INTEGERMULTIPLY,
-  FLOATINGSUM,
-  FLOATINGMULTIPLY,
-  MEMORY,
-  JUMP,
+  INTEGERMULTIPLY = 1,
+  FLOATINGSUM = 2,
+  FLOATINGMULTIPLY = 3,
+  MEMORY = 4,
+  JUMP = 5,
 }
 
-export let FunctionalUnitTypeNames: string[] = [
+export const FunctionalUnitTypeNames: string[] = [
   "Integer Sum",
   "Integer Multiply",
   "Floating Sum",
@@ -20,7 +20,7 @@ export let FunctionalUnitTypeNames: string[] = [
 ];
 
 export const FUNCTIONALUNITTYPESQUANTITY =
-  FunctionalUnitType.JUMP - FunctionalUnitType.INTEGERSUM + 1;
+  FunctionalUnitKind.JUMP - FunctionalUnitKind.INTEGERSUM + 1;
 
 export interface FunctionalUntitVisualEntry {
   id: number;
@@ -28,22 +28,22 @@ export interface FunctionalUntitVisualEntry {
   uid: number;
 }
 
-const FunctionalUnitLantencies: Record<FunctionalUnitType, number> = {
-  [FunctionalUnitType.INTEGERSUM]: 1,
-  [FunctionalUnitType.INTEGERMULTIPLY]: 2,
-  [FunctionalUnitType.FLOATINGSUM]: 4,
-  [FunctionalUnitType.FLOATINGMULTIPLY]: 6,
-  [FunctionalUnitType.MEMORY]: 4,
-  [FunctionalUnitType.JUMP]: 2,
+const FunctionalUnitLantencies: Record<FunctionalUnitKind, number> = {
+  [FunctionalUnitKind.INTEGERSUM]: 1,
+  [FunctionalUnitKind.INTEGERMULTIPLY]: 2,
+  [FunctionalUnitKind.FLOATINGSUM]: 4,
+  [FunctionalUnitKind.FLOATINGMULTIPLY]: 6,
+  [FunctionalUnitKind.MEMORY]: 4,
+  [FunctionalUnitKind.JUMP]: 2,
 };
 
-export const FunctionalUnitNumbers: Record<FunctionalUnitType, number> = {
-  [FunctionalUnitType.INTEGERSUM]: 2,
-  [FunctionalUnitType.INTEGERMULTIPLY]: 2,
-  [FunctionalUnitType.FLOATINGSUM]: 2,
-  [FunctionalUnitType.FLOATINGMULTIPLY]: 2,
-  [FunctionalUnitType.MEMORY]: 2,
-  [FunctionalUnitType.JUMP]: 1,
+export const FunctionalUnitNumbers: Record<FunctionalUnitKind, number> = {
+  [FunctionalUnitKind.INTEGERSUM]: 2,
+  [FunctionalUnitKind.INTEGERMULTIPLY]: 2,
+  [FunctionalUnitKind.FLOATINGSUM]: 2,
+  [FunctionalUnitKind.FLOATINGMULTIPLY]: 2,
+  [FunctionalUnitKind.MEMORY]: 2,
+  [FunctionalUnitKind.JUMP]: 1,
 };
 
 export interface FunctionalUnitResult {
@@ -59,14 +59,14 @@ interface FunctionalUnitInstruction {
 }
 
 export class FunctionalUnit {
-  private _stalled: number = 0; // if >0, it is stalling (for ex because a memory fail) for that many cycles
+  private _stalled = 0; // if >0, it is stalling (for ex because a memory fail) for that many cycles
   private _instructions: FunctionalUnitInstruction[] = [];
 
-  private _nextRef: number = 0; //TODO: use instruction uid
+  private _nextRef = 0; //TODO: use instruction uid
   private _currentBlankTimeUnits: number;
-  private _hasExectutedInstBeforeTick: boolean = false;
+  private _hasExectutedInstBeforeTick = false;
 
-  public get type(): FunctionalUnitType {
+  public get type(): FunctionalUnitKind {
     return this._type;
   }
 
@@ -79,7 +79,7 @@ export class FunctionalUnit {
   }
 
   constructor(
-    private _type: FunctionalUnitType,
+    private _type: FunctionalUnitKind,
     private _latency: number = FunctionalUnitLantencies[_type]
   ) {
     this._currentBlankTimeUnits = this._latency - 1;
@@ -160,44 +160,44 @@ export class FunctionalUnit {
     // execute it
     let resul: number;
     switch (opcode) {
-      case Opcodes.ADD:
-      case Opcodes.ADDI:
-      case Opcodes.ADDF:
+      case OpcodeMnemonic.ADD:
+      case OpcodeMnemonic.ADDI:
+      case OpcodeMnemonic.ADDF:
         resul = firstValue + secondValue;
         break;
-      case Opcodes.SUB:
-      case Opcodes.SUBF:
+      case OpcodeMnemonic.SUB:
+      case OpcodeMnemonic.SUBF:
         resul = firstValue - secondValue;
         break;
-      case Opcodes.OR:
+      case OpcodeMnemonic.OR:
         resul = firstValue | secondValue;
         break;
-      case Opcodes.AND:
+      case OpcodeMnemonic.AND:
         resul = firstValue & secondValue;
         break;
-      case Opcodes.XOR:
+      case OpcodeMnemonic.XOR:
         resul = firstValue ^ secondValue;
         break;
-      case Opcodes.NOR:
+      case OpcodeMnemonic.NOR:
         resul = ~(firstValue | secondValue);
         break;
-      case Opcodes.SRLV:
+      case OpcodeMnemonic.SRLV:
         resul = firstValue >> secondValue;
         break;
-      case Opcodes.SLLV:
+      case OpcodeMnemonic.SLLV:
         resul = firstValue << secondValue;
         break;
-      case Opcodes.MULT:
-      case Opcodes.MULTF:
+      case OpcodeMnemonic.MULT:
+      case OpcodeMnemonic.MULTF:
         resul = firstValue * secondValue;
         break;
-      case Opcodes.BEQ:
+      case OpcodeMnemonic.BEQ:
         resul = firstValue === secondValue ? 1 : 0;
         break;
-      case Opcodes.BNE:
+      case OpcodeMnemonic.BNE:
         resul = firstValue !== secondValue ? 1 : 0;
         break;
-      case Opcodes.BGT:
+      case OpcodeMnemonic.BGT:
         resul = firstValue > secondValue ? 1 : 0;
         break;
       default:
@@ -256,4 +256,35 @@ export class FunctionalUnit {
 
     return list;
   }
+
+  public static newFromOpcode(opcode: Opcode) {
+    switch (opcode.mnemonic) {
+      case OpcodeMnemonic.ADD:
+      case OpcodeMnemonic.ADDI:
+      case OpcodeMnemonic.SUB:
+      case OpcodeMnemonic.OR:
+      case OpcodeMnemonic.AND:
+      case OpcodeMnemonic.NOR:
+      case OpcodeMnemonic.XOR:
+      case OpcodeMnemonic.SLLV:
+      case OpcodeMnemonic.SRLV:
+        return FunctionalUnitKind.INTEGERSUM;
+      case OpcodeMnemonic.ADDF:
+      case OpcodeMnemonic.SUBF:
+        return FunctionalUnitKind.FLOATINGSUM;
+      case OpcodeMnemonic.MULT:
+        return FunctionalUnitKind.INTEGERMULTIPLY;
+      case OpcodeMnemonic.MULTF:
+        return FunctionalUnitKind.FLOATINGMULTIPLY;
+      case OpcodeMnemonic.SW:
+      case OpcodeMnemonic.SF:
+      case OpcodeMnemonic.LW:
+      case OpcodeMnemonic.LF:
+        return FunctionalUnitKind.MEMORY;
+      case OpcodeMnemonic.BGT:
+      case OpcodeMnemonic.BNE:
+      case OpcodeMnemonic.BEQ:
+        return FunctionalUnitKind.JUMP;
+    }
+  } 
 }
diff --git a/src/core/Common/Instruction.ts b/src/core/Common/Instruction.ts
index db016911..ef3fae43 100644
--- a/src/core/Common/Instruction.ts
+++ b/src/core/Common/Instruction.ts
@@ -1,90 +1,65 @@
-import { OpcodesNames, Opcodes } from "./Opcodes";
-import { FunctionalUnitType } from "./FunctionalUnit";
-import { opcodeToFunctionalUnit } from "./Opcodes";
+import { Opcode, OpcodeMnemonic } from "./Opcode";
 
-export class Instruction {
-  public id: number;
-  public basicBlock: number;
-  public opcode: number;
-  protected _operands: number[] = new Array(3);
-  protected _operandsString: string[] = new Array(3);
-  protected _label: string;
-  protected _breakPoint: boolean = false;
-
-  public get uid(): number {
-    return this._uid;
-  }
 
-  public get breakPoint(): boolean {
-    return this._breakPoint;
-  }
+export enum InstructionFormat {
+  TwoGeneralRegisters = 0, // OP R1, R2, R3
+  TwoFloatingRegisters = 1, // OP F1, F2, F3
+  GeneralRegisterAndInmediate = 2, // OP R1, R2, #X
+  GeneralLoadStore = 3, // OP R1, X(R2)
+  FloatingLoadStore = 4, // OP F1, X(R2)
+  Jump = 5, // OP R1, R2, label
+  Noop = 6, // NOP
+}
 
-  public get operands(): number[] {
-    return this._operands;
-  }
+interface Operand {
+  a: string;
+}
 
-  public get label(): string {
-    return this._label;
-  }
+export interface Instruction {
 
-  public set label(value: string) {
-    this._label = value;
-  }
+}
 
-  public get operandsString(): string[] {
-    return this._operandsString;
-  }
+export class Instruction {
+  readonly id: number;
+  readonly basicBlock: number;
+  readonly opcode: Opcode;
+  readonly operands: Operand[];
+  readonly label: string;
+  readonly breakpoint = false;
 
   constructor(from?: Instruction, protected _uid?: number) {
     if (from) {
       this.id = from.id;
       this.basicBlock = from.basicBlock;
       this.opcode = from.opcode;
-      this._operands = from.operands.slice();
-      this._operandsString = from.operandsString.slice();
-      this._breakPoint = from.breakPoint;
+      this.operands = from.operands.slice();
+      this.breakpoint = from.breakpoint;
     }
   }
 
   toString(): string {
-    let aux: string = "";
-    if (this._operandsString[1]) {
-      aux += " " + this._operandsString[1];
-    }
-    if (this._operandsString[2]) {
-      aux += " " + this._operandsString[2];
-    }
-    return `${OpcodesNames[this.opcode]} ${this._operandsString[0]} ${aux}`;
-  }
-
-  setOperand(index: number, value: number, valueString: string) {
-    this._operands[index] = value;
-    this.operandsString[index] = valueString;
-  }
-
-  getOperand(index: number): number {
-    return this._operands[index];
+    return `${this.opcode.mnemonic} ${this.operands}`;
   }
 
   /**
    * isJumpInstruction - this method checks if the instruction is a jump instruction
    */
   public isJumpInstruction(): boolean {
-    return [Opcodes.BNE, Opcodes.BEQ, Opcodes.BGT].includes(this.opcode);
+    return [OpcodeMnemonic.BNE, OpcodeMnemonic.BEQ, OpcodeMnemonic.BGT].includes(this.opcode);
   }
 
   /**
    * isLoadInstruction - this method checks if the instruction that loads from memory
    */
   public isLoadInstruction() {
-    return [Opcodes.LW, Opcodes.LF].includes(this.opcode);
+    return [OpcodeMnemonic.LW, OpcodeMnemonic.LF].includes(this.opcode);
   }
 
   /**
    * isStoreInstruction - this method checks if the instruction that stores from memory
    */
   public isStoreInstruction(): boolean {
-    return [Opcodes.SF, Opcodes.SW].includes(this.opcode);
+    return [OpcodeMnemonic.SF, OpcodeMnemonic.SW].includes(this.opcode);
   }
 
   /**
@@ -94,7 +69,7 @@ export class Instruction {
     return (
       !this.isJumpInstruction() &&
       !this.isStoreInstruction() &&
-      ![Opcodes.NOP, Opcodes.OPERROR].includes(this.opcode)
+      ![OpcodeMnemonic.NOP, OpcodeMnemonic.OPERROR].includes(this.opcode)
     );
   }
 
@@ -103,11 +78,11 @@ export class Instruction {
    */
   public isDestinyRegisterFloat(): boolean {
     return [
-      Opcodes.ADDF,
-      Opcodes.SUBF,
-      Opcodes.MULTF,
-      Opcodes.LF,
-      Opcodes.SF,
+      OpcodeMnemonic.ADDF,
+      OpcodeMnemonic.SUBF,
+      OpcodeMnemonic.MULTF,
+      OpcodeMnemonic.LF,
+      OpcodeMnemonic.SF,
     ].includes(this.opcode);
   }
 
@@ -116,21 +91,21 @@ export class Instruction {
    */
   public getDestinyRegister(): number {
     switch (this.opcode) {
-      case Opcodes.ADD:
-      case Opcodes.SUB:
-      case Opcodes.MULT:
-      case Opcodes.OR:
-      case Opcodes.AND:
-      case Opcodes.NOR:
-      case Opcodes.XOR:
-      case Opcodes.SLLV:
-      case Opcodes.SRLV:
-      case Opcodes.ADDI:
-      case Opcodes.ADDF:
-      case Opcodes.SUBF:
-      case Opcodes.MULTF:
-      case Opcodes.LW:
-      case Opcodes.LF:
+      case OpcodeMnemonic.ADD:
+      case OpcodeMnemonic.SUB:
+      case OpcodeMnemonic.MULT:
+      case OpcodeMnemonic.OR:
+      case OpcodeMnemonic.AND:
+      case OpcodeMnemonic.NOR:
+      case OpcodeMnemonic.XOR:
+      case OpcodeMnemonic.SLLV:
+      case OpcodeMnemonic.SRLV:
+      case OpcodeMnemonic.ADDI:
+      case OpcodeMnemonic.ADDF:
+      case OpcodeMnemonic.SUBF:
+      case OpcodeMnemonic.MULTF:
+      case OpcodeMnemonic.LW:
+      case OpcodeMnemonic.LF:
         return this.operands[0];
       default:
         return -1;
@@ -141,7 +116,7 @@ export class Instruction {
    * isFirstOperandFloat
    */
   public isFirstOperandFloat(): boolean {
-    return [Opcodes.ADDF, Opcodes.SUBF, Opcodes.MULTF, Opcodes.SF].includes(
+    return [OpcodeMnemonic.ADDF, OpcodeMnemonic.SUBF, OpcodeMnemonic.MULTF, OpcodeMnemonic.SF].includes(
       this.opcode
     );
   }
@@ -151,25 +126,25 @@ export class Instruction {
    */
   public getFirstOperandRegister(): number {
     switch (this.opcode) {
-      case Opcodes.ADD:
-      case Opcodes.SUB:
-      case Opcodes.MULT:
-      case Opcodes.OR:
-      case Opcodes.AND:
-      case Opcodes.NOR:
-      case Opcodes.XOR:
-      case Opcodes.SLLV:
-      case Opcodes.SRLV:
-      case Opcodes.ADDI:
-      case Opcodes.ADDF:
-      case Opcodes.SUBF:
-      case Opcodes.MULTF:
+      case OpcodeMnemonic.ADD:
+      case OpcodeMnemonic.SUB:
+      case OpcodeMnemonic.MULT:
+      case OpcodeMnemonic.OR:
+      case OpcodeMnemonic.AND:
+      case OpcodeMnemonic.NOR:
+      case OpcodeMnemonic.XOR:
+      case OpcodeMnemonic.SLLV:
+      case OpcodeMnemonic.SRLV:
+      case OpcodeMnemonic.ADDI:
+      case OpcodeMnemonic.ADDF:
+      case OpcodeMnemonic.SUBF:
+      case OpcodeMnemonic.MULTF:
         return this.operands[1];
-      case Opcodes.SW:
-      case Opcodes.SF:
-      case Opcodes.BEQ:
-      case Opcodes.BNE:
-      case Opcodes.BGT:
+      case OpcodeMnemonic.SW:
+      case OpcodeMnemonic.SF:
+      case OpcodeMnemonic.BEQ:
+      case OpcodeMnemonic.BNE:
+      case OpcodeMnemonic.BGT:
         return this.operands[0];
       default:
         return -1;
@@ -180,7 +155,7 @@ export class Instruction {
    * isSecondOperandFloat
    */
   public isSecondOperandFloat(): boolean {
-    return [Opcodes.ADDF, Opcodes.SUBF, Opcodes.MULTF].includes(this.opcode);
+    return [OpcodeMnemonic.ADDF, OpcodeMnemonic.SUBF, OpcodeMnemonic.MULTF].includes(this.opcode);
   }
 
   /**
@@ -188,26 +163,26 @@ export class Instruction {
    */
   public getSecondOperandRegister(): number {
     switch (this.opcode) {
-      case Opcodes.ADD:
-      case Opcodes.SUB:
-      case Opcodes.MULT:
-      case Opcodes.OR:
-      case Opcodes.AND:
-      case Opcodes.NOR:
-      case Opcodes.XOR:
-      case Opcodes.SLLV:
-      case Opcodes.SRLV:
-      case Opcodes.ADDF:
-      case Opcodes.SUBF:
-      case Opcodes.MULTF:
-      case Opcodes.SW:
-      case Opcodes.SF:
-      case Opcodes.LW:
-      case Opcodes.LF:
+      case OpcodeMnemonic.ADD:
+      case OpcodeMnemonic.SUB:
+      case OpcodeMnemonic.MULT:
+      case OpcodeMnemonic.OR:
+      case OpcodeMnemonic.AND:
+      case OpcodeMnemonic.NOR:
+      case OpcodeMnemonic.XOR:
+      case OpcodeMnemonic.SLLV:
+      case OpcodeMnemonic.SRLV:
+      case OpcodeMnemonic.ADDF:
+      case OpcodeMnemonic.SUBF:
+      case OpcodeMnemonic.MULTF:
+      case OpcodeMnemonic.SW:
+      case OpcodeMnemonic.SF:
+      case OpcodeMnemonic.LW:
+      case OpcodeMnemonic.LF:
         return this.operands[2];
-      case Opcodes.BEQ:
-      case Opcodes.BNE:
-      case Opcodes.BGT:
+      case OpcodeMnemonic.BEQ:
+      case OpcodeMnemonic.BNE:
+      case OpcodeMnemonic.BGT:
         return this.operands[1];
 
       default:
@@ -220,14 +195,14 @@ export class Instruction {
    */
   public getAddressOperand(): number {
     switch (this.opcode) {
-      case Opcodes.SW:
-      case Opcodes.SF:
-      case Opcodes.LW:
-      case Opcodes.LF:
+      case OpcodeMnemonic.SW:
+      case OpcodeMnemonic.SF:
+      case OpcodeMnemonic.LW:
+      case OpcodeMnemonic.LF:
         return this.operands[1];
-      case Opcodes.BEQ:
-      case Opcodes.BNE:
-      case Opcodes.BGT:
+      case OpcodeMnemonic.BEQ:
+      case OpcodeMnemonic.BNE:
+      case OpcodeMnemonic.BGT:
         return this.operands[2];
       default:
         return -1;
@@ -238,21 +213,21 @@ export class Instruction {
    * hasImmediateOperand - this method checks if the instruction has an immediate operand
    */
   public hasImmediateOperand(): boolean {
-    return this.opcode === Opcodes.ADDI;
+    return this.opcode === OpcodeMnemonic.ADDI;
   }
 
   /**
    * getImmediateOperand - this method returns the immediate operand of the instruction or -1 if it doesn't have one
    */
   public getImmediateOperand(): number {
-    return this.opcode === Opcodes.ADDI ? this.operands[2] : -1;
+    return this.opcode === OpcodeMnemonic.ADDI ? this.operands[2] : -1;
   }
 
   public toggleBreakPoint() {
-    this._breakPoint = !this._breakPoint;
+    this.breakpoint = !this.breakpoint;
   }
 
-  public getFunctionalUnitType(): FunctionalUnitType {
+  public getFunctionalUnitType(): FunctionalUnitKind {
     return opcodeToFunctionalUnit(this.opcode);
   }
 }
diff --git a/src/core/Common/InstructionFormats.ts b/src/core/Common/InstructionFormats.ts
deleted file mode 100644
index 1bd5dbf5..00000000
--- a/src/core/Common/InstructionFormats.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Opcodes } from "./Opcodes";
-
-export enum Formats {
-  TwoGeneralRegisters = 0, // OP R1, R2, R3
-  TwoFloatingRegisters, // OP F1, F2, F3
-  GeneralRegisterAndInmediate, // OP R1, R2, #X
-  GeneralLoadStore, // OP R1, X(R2)
-  FloatingLoadStore, // OP F1, X(R2)
-  Jump, // OP R1, R2, label
-  Noop, // NOP
-}
-
-export let FormatsNames: string[] = [
-  "TwoGeneralRegisters",
-  "TwoFloatingRegisters",
-  "GeneralRegisterAndInmediate",
-  "GeneralLoadStore",
-  "FloatingLoadStore",
-  "Jump",
-  "Noop",
-];
diff --git a/src/core/Common/Machine.ts b/src/core/Common/Machine.ts
index 91006462..8e017285 100644
--- a/src/core/Common/Machine.ts
+++ b/src/core/Common/Machine.ts
@@ -2,14 +2,14 @@ import { Register } from "./Register";
 import {
   FunctionalUnit,
   FUNCTIONALUNITTYPESQUANTITY,
-  FunctionalUnitType,
+  type FunctionalUnitKind,
   FunctionalUnitNumbers,
 } from "./FunctionalUnit";
-import { Cache } from "./Cache";
+import type { Cache } from "./Cache";
 import { Memory } from "./Memory";
 
-const MACHINE_REGISTER_SIZE = 64;
-const MACHINE_MEMORY_SIZE = 1024;
+export const MACHINE_REGISTER_SIZE = 64;
+export const MACHINE_MEMORY_SIZE = 1024;
 const MACHINE_MEMORY_FAIL_LATENCY = 9;
 
 export interface MachineStatus {
@@ -156,10 +156,10 @@ export class Machine {
   }
 
   public changeFunctionalUnitLatency(
-    type: FunctionalUnitType,
+    type: FunctionalUnitKind,
     latency: number
   ) {
-    if (latency == 0) {
+    if (latency === 0) {
       return;
     }
 
@@ -168,7 +168,7 @@ export class Machine {
     }
   }
 
-  public changeFunctionalUnitNumber(type: FunctionalUnitType, num: number) {
+  public changeFunctionalUnitNumber(type: FunctionalUnitKind, num: number) {
     if (num === 0) {
       return;
     }
diff --git a/src/core/Common/Opcode.ts b/src/core/Common/Opcode.ts
new file mode 100644
index 00000000..5ba8f6ab
--- /dev/null
+++ b/src/core/Common/Opcode.ts
@@ -0,0 +1,29 @@
+export enum OpcodeMnemonic {
+  NOP = "NOP",
+  ADD = "ADD",
+  ADDI = "ADDI",
+  SUB = "SUB",
+  ADDF = "ADDF",
+  SUBF = "SUBF",
+  MULT = "MULT",
+  MULTF = "MULTF",
+  OR = "OR",
+  AND = "AND",
+  XOR = "XOR",
+  NOR = "NOR",
+  SLLV = "SLLV",
+  SRLV = "SRLV",
+  LW = "LW",
+  LF = "LF",
+  SW = "SW",
+  SF = "SF",
+  BNE = "BNE",
+  BEQ = "BEQ",
+  BGT = "BGT",
+}
+
+export type OpcodeType = `${OpcodeMnemonic}`;
+
+export interface Opcode {
+  mnemonic: OpcodeMnemonic;
+}
diff --git a/src/core/Common/Opcodes.ts b/src/core/Common/Opcodes.ts
deleted file mode 100644
index b0dbb3d1..00000000
--- a/src/core/Common/Opcodes.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import { FunctionalUnitType } from "./FunctionalUnit";
-import { Formats } from "./InstructionFormats";
-
-export enum Opcodes {
-  NOP = 0,
-  ADD,
-  ADDI,
-  SUB,
-  ADDF,
-  SUBF,
-  MULT,
-  MULTF,
-  OR,
-  AND,
-  XOR,
-  NOR,
-  SLLV,
-  SRLV,
-  SW,
-  SF,
-  LW,
-  LF,
-  BNE,
-  BEQ,
-  BGT,
-  OPERROR,
-}
-
-export let OpcodesNames: string[] = [
-  "NOP",
-  "ADD",
-  "ADDI",
-  "SUB",
-  "ADDF",
-  "SUBF",
-  "MULT",
-  "MULTF",
-  "OR",
-  "AND",
-  "XOR",
-  "NOR",
-  "SLLV",
-  "SRLV",
-  "SW",
-  "SF",
-  "LW",
-  "LF",
-  "BNE",
-  "BEQ",
-  "BGT",
-];
-
-export function opcodeToFunctionalUnit(opcode: Opcodes): FunctionalUnitType {
-  switch (opcode) {
-    case Opcodes.ADD:
-    case Opcodes.ADDI:
-    case Opcodes.SUB:
-    case Opcodes.OR:
-    case Opcodes.AND:
-    case Opcodes.NOR:
-    case Opcodes.XOR:
-    case Opcodes.SLLV:
-    case Opcodes.SRLV:
-      return FunctionalUnitType.INTEGERSUM;
-    case Opcodes.ADDF:
-    case Opcodes.SUBF:
-      return FunctionalUnitType.FLOATINGSUM;
-    case Opcodes.MULT:
-      return FunctionalUnitType.INTEGERMULTIPLY;
-    case Opcodes.MULTF:
-      return FunctionalUnitType.FLOATINGMULTIPLY;
-    case Opcodes.SW:
-    case Opcodes.SF:
-    case Opcodes.LW:
-    case Opcodes.LF:
-      return FunctionalUnitType.MEMORY;
-    case Opcodes.BGT:
-    case Opcodes.BNE:
-    case Opcodes.BEQ:
-      return FunctionalUnitType.JUMP;
-    default:
-      throw new Error(
-        "Error at opcodeToFunctionalUnit, unknown opcode : " +
-          OpcodesNames[opcode]
-      );
-  }
-}
-
-export function opcodeToFormat(opcode: Opcodes): Formats {
-  switch (opcode) {
-    case Opcodes.NOP:
-      return Formats.Noop;
-    case Opcodes.ADD:
-    case Opcodes.SUB:
-    case Opcodes.MULT:
-    case Opcodes.OR:
-    case Opcodes.AND:
-    case Opcodes.XOR:
-    case Opcodes.NOR:
-    case Opcodes.SLLV:
-    case Opcodes.SRLV:
-      return Formats.TwoGeneralRegisters;
-    case Opcodes.ADDF:
-    case Opcodes.SUBF:
-    case Opcodes.MULTF:
-      return Formats.TwoFloatingRegisters;
-    case Opcodes.ADDI:
-      return Formats.GeneralRegisterAndInmediate;
-    case Opcodes.SW:
-    case Opcodes.LW:
-      return Formats.GeneralLoadStore;
-    case Opcodes.SF:
-    case Opcodes.LF:
-      return Formats.FloatingLoadStore;
-    case Opcodes.BNE:
-    case Opcodes.BEQ:
-    case Opcodes.BGT:
-      return Formats.Jump;
-    default:
-      throw new Error("Invalid opcode: " + opcode);
-  }
-}
diff --git a/src/core/Common/Register.ts b/src/core/Common/Register.ts
index 3854afb9..2f156b7e 100644
--- a/src/core/Common/Register.ts
+++ b/src/core/Common/Register.ts
@@ -1,3 +1,10 @@
+export enum RegisterKind {
+  GeneralPurpose = "GeneralPurpose",
+  FloatingPoint = "FloatingPoint"
+}
+
+export type RegisterType = `${RegisterKind}`;
+
 export class Register {
   private _content: number[];
   private _bufferIn: number[];
@@ -13,7 +20,7 @@ export class Register {
 
   constructor(
     private _numberOfRegs: number,
-    private _zeroWritable: boolean = false
+    private _zeroWritable = false
   ) {
     this._busy = new Array(_numberOfRegs);
     this._content = new Array(_numberOfRegs);
diff --git a/src/core/Superscalar/Superscalar.ts b/src/core/Superscalar/Superscalar.ts
index 8b7236da..c6935217 100644
--- a/src/core/Superscalar/Superscalar.ts
+++ b/src/core/Superscalar/Superscalar.ts
@@ -6,7 +6,7 @@ import { PrefetchUnit } from "./PrefetchUnit";
 import { ReserveStation } from "./ReserveStation";
 import {
   FunctionalUnit,
-  FunctionalUnitType,
+  FunctionalUnitKind,
   FunctionalUnitNumbers,
   FUNCTIONALUNITTYPESQUANTITY,
 } from "../Common/FunctionalUnit";
@@ -27,7 +27,7 @@ export class Superscalar extends Machine {
   private _issue: number;
   private _code: Code;
 
-  private _reserveStations: Map<FunctionalUnitType, ReserveStation>;
+  private _reserveStations: Map<FunctionalUnitKind, ReserveStation>;
   private _reorderBuffer: ReorderBuffer;
   private _prefetchUnit: PrefetchUnit;
   private _decoder: PrefetchUnit;
@@ -83,7 +83,7 @@ export class Superscalar extends Machine {
     this.issue = Superscalar.ISSUE_DEF;
 
     this._jumpPrediction = new JumpPredictor(Superscalar.PREDTABLESIZE);
-    this._reserveStations = new Map<FunctionalUnitType, ReserveStation>();
+    this._reserveStations = new Map<FunctionalUnitKind, ReserveStation>();
     let total = 0; //  total ROB size
     for (let i = 0; i < FUNCTIONALUNITTYPESQUANTITY; i++) {
       let size = this.getReserveStationSize(i);
@@ -96,53 +96,53 @@ export class Superscalar extends Machine {
 
     this._code = null;
 
-    this._aluMem = new Array(FunctionalUnitNumbers[FunctionalUnitType.MEMORY]);
+    this._aluMem = new Array(FunctionalUnitNumbers[FunctionalUnitKind.MEMORY]);
 
-    for (let j = 0; j < FunctionalUnitNumbers[FunctionalUnitType.MEMORY]; j++) {
-      this.aluMem[j] = new FunctionalUnit(FunctionalUnitType.INTEGERSUM);
+    for (let j = 0; j < FunctionalUnitNumbers[FunctionalUnitKind.MEMORY]; j++) {
+      this.aluMem[j] = new FunctionalUnit(FunctionalUnitKind.INTEGERSUM);
     }
 
     this._currentCommitedInstrs = new Array<number>();
   }
 
   public changeFunctionalUnitLatency(
-    type: FunctionalUnitType,
+    type: FunctionalUnitKind,
     latency: number
   ) {
     super.changeFunctionalUnitLatency(type, latency);
 
     // Update the latency of the alu mem if the type is interger sum (same type of unit)
-    if (type === FunctionalUnitType.INTEGERSUM) {
+    if (type === FunctionalUnitKind.INTEGERSUM) {
       for (let j = 0; j < this.aluMem.length; j++) {
         this.aluMem[j] = new FunctionalUnit(
-          FunctionalUnitType.INTEGERSUM,
+          FunctionalUnitKind.INTEGERSUM,
           latency
         );
       }
     }
   }
 
-  public changeFunctionalUnitNumber(type: FunctionalUnitType, num: number) {
+  public changeFunctionalUnitNumber(type: FunctionalUnitKind, num: number) {
     super.changeFunctionalUnitNumber(type, num);
 
     // Update the number of alu mem units acortding to the number of memory units
-    if (type === FunctionalUnitType.MEMORY) {
+    if (type === FunctionalUnitKind.MEMORY) {
       let currentLatency = this.aluMem[0].latency;
       this._aluMem = new Array(num);
       for (let j = 0; j < num; j++) {
         this.aluMem[j] = new FunctionalUnit(
-          FunctionalUnitType.INTEGERSUM,
+          FunctionalUnitKind.INTEGERSUM,
           currentLatency
         );
       }
     }
   }
 
-  public getReserveStation(type: FunctionalUnitType): ReserveStation {
+  public getReserveStation(type: FunctionalUnitKind): ReserveStation {
     return this._reserveStations[type];
   }
 
-  public getReserveStationSize(type: FunctionalUnitType): number {
+  public getReserveStationSize(type: FunctionalUnitKind): number {
     return (
       this.functionalUnit[type].length *
       (this.functionalUnit[type][0].latency + 1)
@@ -355,7 +355,7 @@ export class Superscalar extends Machine {
 
   ticIssue() {
     while (!this._decoder.isEmpty()) {
-      let fuType: FunctionalUnitType = this.code.getFunctionalUnitType(
+      let fuType: FunctionalUnitKind = this.code.getFunctionalUnitType(
         this._decoder.getId()
       );
 
@@ -377,7 +377,7 @@ export class Superscalar extends Machine {
     }
   }
 
-  executeInstruction(type: FunctionalUnitType, num: number) {
+  executeInstruction(type: FunctionalUnitKind, num: number) {
     let readyInstsRefs = this._reserveStations[type].getReadyInstructions();
     for (let instrUID of readyInstsRefs) {
       let instruction = this._reorderBuffer.getInstruction(instrUID);
@@ -427,17 +427,17 @@ export class Superscalar extends Machine {
         // if an instruction is ready, write the result address to the reorder buffer and reserve station
         let instrUid = execution.instruction.uid;
         let baseAddress =
-          this._reserveStations[FunctionalUnitType.MEMORY].getAddressOperand(
+          this._reserveStations[FunctionalUnitKind.MEMORY].getAddressOperand(
             instrUid
           );
         let offset =
           this._reserveStations[
-            FunctionalUnitType.MEMORY
+            FunctionalUnitKind.MEMORY
           ].getSecondOperandValue(instrUid);
         let address = baseAddress + offset;
 
         this._reorderBuffer.writeResultAddress(instrUid, address);
-        this._reserveStations[FunctionalUnitType.MEMORY].setAddressOperand(
+        this._reserveStations[FunctionalUnitKind.MEMORY].setAddressOperand(
           instrUid,
           address
         );
@@ -449,7 +449,7 @@ export class Superscalar extends Machine {
     // Go again through all the memory reserve stations but this time sending the instructions to the address ALU
     for (let i = 0; i < this.aluMem.length; i++) {
       let readyInstsRefs =
-        this._reserveStations[FunctionalUnitType.MEMORY].getReadyInstructions(
+        this._reserveStations[FunctionalUnitKind.MEMORY].getReadyInstructions(
           true
         ); // we dont need the first operand ready, as we are only calculating the address
       for (let instrUID of readyInstsRefs) {
@@ -464,7 +464,7 @@ export class Superscalar extends Machine {
             // so their address can be calculated
             this.aluMem[i].addInstruction(instruction);
             this._reserveStations[
-              FunctionalUnitType.MEMORY
+              FunctionalUnitKind.MEMORY
             ].associateAddressALU(instrUID, i);
             this._reorderBuffer.executeInstruction(instrUID);
             break;
@@ -474,7 +474,7 @@ export class Superscalar extends Machine {
     }
   }
 
-  writeInstruction(type: FunctionalUnitType, num: number) {
+  writeInstruction(type: FunctionalUnitKind, num: number) {
     let resul;
     let instUid = this.functionalUnit[type][num].getReadyInstructionUid();
     if (instUid !== -1) {
@@ -538,7 +538,7 @@ export class Superscalar extends Machine {
     // so here we are doing the execution stage of the stores. And also, we are writing the result of all the stores at the same time with no limits
     // why? because potatos
     let readyLoadsRefs =
-      this._reserveStations[FunctionalUnitType.MEMORY].getReadyInstructions();
+      this._reserveStations[FunctionalUnitKind.MEMORY].getReadyInstructions();
     let refsToRemove = new Array<number>();
     for (let instrUID of readyLoadsRefs) {
       let instruction = this._reorderBuffer.getInstruction(instrUID);
@@ -552,7 +552,7 @@ export class Superscalar extends Machine {
         // write the result to the ROB and remove the instruction from the reserve station
         this._reorderBuffer.writeResultValue(
           instrUID,
-          this._reserveStations[FunctionalUnitType.MEMORY].getFirstOperandValue(
+          this._reserveStations[FunctionalUnitKind.MEMORY].getFirstOperandValue(
             instrUID
           )
         );
@@ -561,7 +561,7 @@ export class Superscalar extends Machine {
       }
     }
     for (let instrRef of refsToRemove) {
-      this._reserveStations[FunctionalUnitType.MEMORY].removeInstruction(
+      this._reserveStations[FunctionalUnitKind.MEMORY].removeInstruction(
         instrRef
       );
     }
diff --git a/src/core/VLIW/DependencyChecker.ts b/src/core/VLIW/DependencyChecker.ts
index ce0562c5..47072c88 100644
--- a/src/core/VLIW/DependencyChecker.ts
+++ b/src/core/VLIW/DependencyChecker.ts
@@ -1,6 +1,6 @@
-import { Opcodes } from '../Common/Opcodes';
+import { OpcodeMnemonic } from '../Common/Opcode';
 import { VLIWOperation } from './VLIWOperation';
-import { FunctionalUnitType } from '../Common/FunctionalUnit';
+import { FunctionalUnitKind } from '../Common/FunctionalUnit';
 
 export interface Check {
     latency: number;
@@ -11,104 +11,104 @@ export class DependencyChecker {
 
     public static checkTargetOperation(operation: VLIWOperation, checkGPR: Check[], checkFPR: Check[], functionalUnitLatencies: number[]) {
         switch (operation.opcode) {
-            case Opcodes.ADD:
-            case Opcodes.ADDI:
-                if (checkGPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitType.INTEGERSUM]) {
-                    checkGPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitType.INTEGERSUM];
+            case OpcodeMnemonic.ADD:
+            case OpcodeMnemonic.ADDI:
+                if (checkGPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitKind.INTEGERSUM]) {
+                    checkGPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitKind.INTEGERSUM];
                     checkGPR[operation.getOperand(0)].register = operation.id;
                 }
                 break;
-            case Opcodes.MULT:
-                if (checkGPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitType.INTEGERMULTIPLY]) {
-                    checkGPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitType.INTEGERMULTIPLY];
+            case OpcodeMnemonic.MULT:
+                if (checkGPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitKind.INTEGERMULTIPLY]) {
+                    checkGPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitKind.INTEGERMULTIPLY];
                     checkGPR[operation.getOperand(0)].register = operation.id;
                 }
                 break;
-            case Opcodes.ADDF:
-                if (checkFPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitType.FLOATINGSUM]) {
-                    checkFPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitType.FLOATINGSUM];
+            case OpcodeMnemonic.ADDF:
+                if (checkFPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitKind.FLOATINGSUM]) {
+                    checkFPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitKind.FLOATINGSUM];
                     checkFPR[operation.getOperand(0)].register = operation.id;
                 }
                 break;
-            case Opcodes.MULTF:
-                if (checkFPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitType.FLOATINGMULTIPLY]) {
-                    checkFPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitType.FLOATINGMULTIPLY];
+            case OpcodeMnemonic.MULTF:
+                if (checkFPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitKind.FLOATINGMULTIPLY]) {
+                    checkFPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitKind.FLOATINGMULTIPLY];
                     checkFPR[operation.getOperand(0)].register = operation.id;
                 }
                 break;
-            case Opcodes.LW:
-                if (checkGPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitType.MEMORY]) {
-                    checkGPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitType.MEMORY];
+            case OpcodeMnemonic.LW:
+                if (checkGPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitKind.MEMORY]) {
+                    checkGPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitKind.MEMORY];
                     checkGPR[operation.getOperand(0)].register = operation.id;
                 }
                 break;
-            case Opcodes.LF:
-                if (checkFPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitType.MEMORY]) {
-                    checkFPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitType.MEMORY];
+            case OpcodeMnemonic.LF:
+                if (checkFPR[operation.getOperand(0)].latency < functionalUnitLatencies[FunctionalUnitKind.MEMORY]) {
+                    checkFPR[operation.getOperand(0)].latency = functionalUnitLatencies[FunctionalUnitKind.MEMORY];
                     checkFPR[operation.getOperand(0)].register = operation.id;
                 }
                 break;
-            case Opcodes.SW:
-            case Opcodes.SF:
-            case Opcodes.BEQ:
-            case Opcodes.BNE:
-            case Opcodes.BGT:
+            case OpcodeMnemonic.SW:
+            case OpcodeMnemonic.SF:
+            case OpcodeMnemonic.BEQ:
+            case OpcodeMnemonic.BNE:
+            case OpcodeMnemonic.BGT:
                 break;
             default:
-                throw new Error("Error at checkTargetOperation, unknown opcode: " + Opcodes[operation.opcode]);
+                throw new Error("Error at checkTargetOperation, unknown opcode: " + OpcodeMnemonic[operation.opcode]);
         }
     }
 
     public static checkSourceOperands(operation: VLIWOperation, checkGPR: Check[], checkFPR: Check[]): boolean {
         let result = true;
         switch (operation.opcode) {
-            case Opcodes.ADD:
-            case Opcodes.MULT:
+            case OpcodeMnemonic.ADD:
+            case OpcodeMnemonic.MULT:
                 if (((checkGPR[operation.getOperand(1)].latency > 0) && (checkGPR[operation.getOperand(1)].register < operation.id))
                     || ((checkGPR[operation.getOperand(2)].latency > 0) && (checkGPR[operation.getOperand(2)].register < operation.id))) {
                     result = false;
                 }
                 break;
-            case Opcodes.ADDI:
+            case OpcodeMnemonic.ADDI:
                 if ((checkGPR[operation.getOperand(1)].latency > 0) && (checkGPR[operation.getOperand(1)].register < operation.id)) {
                     result = false;
                 }
                 break;
-            case Opcodes.ADDF:
-            case Opcodes.MULTF:
+            case OpcodeMnemonic.ADDF:
+            case OpcodeMnemonic.MULTF:
                 if (((checkFPR[operation.getOperand(1)].latency > 0) && (checkFPR[operation.getOperand(1)].register < operation.id))
                     || ((checkFPR[operation.getOperand(2)].latency > 0) && (checkFPR[operation.getOperand(2)].register < operation.id))) {
                     result = false;
                 }
                 break;
-            case Opcodes.LW:
-            case Opcodes.LF:
+            case OpcodeMnemonic.LW:
+            case OpcodeMnemonic.LF:
                 if ((checkGPR[operation.getOperand(2)].latency > 0) && (checkGPR[operation.getOperand(2)].register < operation.id)) {
                     result = false;
                 }
                 break;
-            case Opcodes.SW:
+            case OpcodeMnemonic.SW:
                 if (((checkGPR[operation.getOperand(0)].latency > 0) && (checkGPR[operation.getOperand(0)].register < operation.id))
                     || ((checkGPR[operation.getOperand(2)].latency > 0) && (checkGPR[operation.getOperand(2)].register < operation.id))) {
                     result = false;
                 }
                 break;
-            case Opcodes.SF:
+            case OpcodeMnemonic.SF:
                 if (((checkFPR[operation.getOperand(0)].latency > 0) && (checkFPR[operation.getOperand(0)].register < operation.id))
                     || ((checkGPR[operation.getOperand(2)].latency > 0) && (checkGPR[operation.getOperand(2)].register < operation.id))) {
                     result = false;
                 }
                 break;
-            case Opcodes.BEQ:
-            case Opcodes.BNE:
-            case Opcodes.BGT:
+            case OpcodeMnemonic.BEQ:
+            case OpcodeMnemonic.BNE:
+            case OpcodeMnemonic.BGT:
                 if (((checkGPR[operation.getOperand(0)].latency > 0) && (checkGPR[operation.getOperand(0)].register < operation.id))
                     || ((checkGPR[operation.getOperand(1)].latency > 0) && (checkGPR[operation.getOperand(1)].register < operation.id))) {
                     result = false;
                 }
                 break;
             default:
-                throw new Error("Error at checkSourceOperands, unknown opcode: " + Opcodes[operation.opcode]);
+                throw new Error("Error at checkSourceOperands, unknown opcode: " + OpcodeMnemonic[operation.opcode]);
         }
         return result;
     }
@@ -117,34 +117,34 @@ export class DependencyChecker {
 
         let result;
         switch (operation.opcode) {
-            case Opcodes.ADD:
-            case Opcodes.MULT:
+            case OpcodeMnemonic.ADD:
+            case OpcodeMnemonic.MULT:
                 result = NaTGP[operation.getOperand(1)] || NaTGP[operation.getOperand(2)];
                 break;
-            case Opcodes.ADDI:
+            case OpcodeMnemonic.ADDI:
                 result = NaTGP[operation.getOperand(1)];
                 break;
-            case Opcodes.ADDF:
-            case Opcodes.MULTF:
+            case OpcodeMnemonic.ADDF:
+            case OpcodeMnemonic.MULTF:
                 result = NaTFP[operation.getOperand(1)] || NaTFP[operation.getOperand(2)];
                 break;
-            case Opcodes.SW:
+            case OpcodeMnemonic.SW:
                 result = NaTGP[operation.getOperand(0)] || NaTGP[operation.getOperand(2)];
                 break;
-            case Opcodes.SF:
+            case OpcodeMnemonic.SF:
                 result = NaTFP[operation.getOperand(0)] || NaTGP[operation.getOperand(2)];
                 break;
-            case Opcodes.LW:
-            case Opcodes.LF:
+            case OpcodeMnemonic.LW:
+            case OpcodeMnemonic.LF:
                 result = NaTGP[operation.getOperand(2)];
                 break;
-            case Opcodes.BEQ:
-            case Opcodes.BNE:
-            case Opcodes.BGT:
+            case OpcodeMnemonic.BEQ:
+            case OpcodeMnemonic.BNE:
+            case OpcodeMnemonic.BGT:
                 result = NaTGP[operation.getOperand(0)] || NaTGP[operation.getOperand(1)];
                 break;
             default:
-                throw new Error("Error at checkNat, unknown opcode: " + Opcodes[operation.opcode]);
+                throw new Error("Error at checkNat, unknown opcode: " + OpcodeMnemonic[operation.opcode]);
         }
         return result;
     }
diff --git a/src/core/VLIW/VLIW.ts b/src/core/VLIW/VLIW.ts
index 267dc9ab..86ce37cd 100644
--- a/src/core/VLIW/VLIW.ts
+++ b/src/core/VLIW/VLIW.ts
@@ -1,7 +1,7 @@
 import { Machine } from '../Common/Machine';
-import { Opcodes } from '../Common/Opcodes';
+import { OpcodeMnemonic } from '../Common/Opcode';
 import { VLIWCode } from './VLIWCode';
-import { FunctionalUnit, FunctionalUnitType, FUNCTIONALUNITTYPESQUANTITY } from '../Common/FunctionalUnit';
+import { FunctionalUnit, FunctionalUnitKind, FUNCTIONALUNITTYPESQUANTITY } from '../Common/FunctionalUnit';
 import { DependencyChecker, Check } from './DependencyChecker';
 import { VLIWError } from './VLIWError';
 import { VLIWOperation } from './VLIWOperation';
@@ -110,13 +110,13 @@ export class VLIW extends Machine {
         let pending: boolean = false;
         this.status.cycle++;
 
-        if (!this.functionalUnit[FunctionalUnitType.JUMP][0].isEmpty()) {
+        if (!this.functionalUnit[FunctionalUnitKind.JUMP][0].isEmpty()) {
             pending = true;
         }
 
-        if (!this.functionalUnit[FunctionalUnitType.JUMP][0].isStalled()) {
+        if (!this.functionalUnit[FunctionalUnitKind.JUMP][0].isStalled()) {
 
-            let execution = this.functionalUnit[FunctionalUnitType.JUMP][0].executeReadyInstruction();
+            let execution = this.functionalUnit[FunctionalUnitKind.JUMP][0].executeReadyInstruction();
             let operation: any = (execution != null) ? execution.instruction : null;
             if (operation != null) {
                 if (this._predR[operation.getPred()]) {
@@ -125,7 +125,7 @@ export class VLIW extends Machine {
             }
         }
 
-        this.functionalUnit[FunctionalUnitType.JUMP][0].tic();
+        this.functionalUnit[FunctionalUnitKind.JUMP][0].tic();
 
         // check for stalled functional units
         let hasStalledFU = false;
@@ -198,15 +198,15 @@ export class VLIW extends Machine {
             let operation = instruction.getOperation(i);
             this.functionalUnit[operation.getFunctionalUnitType()][operation.getFunctionalUnitIndex()].addInstruction(operation);
 
-            if (operation.opcode === Opcodes.LW) {
+            if (operation.opcode === OpcodeMnemonic.LW) {
                 this._NaTGP[operation.getOperand(0)] = true;
             }
 
-            if (operation.opcode === Opcodes.LF) {
+            if (operation.opcode === OpcodeMnemonic.LF) {
                 this._NaTFP[operation.getOperand(0)] = true;
             }
 
-            if (operation.getFunctionalUnitType() === FunctionalUnitType.JUMP) {
+            if (operation.getFunctionalUnitType() === FunctionalUnitKind.JUMP) {
                 this._predR[operation.getPredTrue()] = false;
                 this._predR[operation.getPredFalse()] = false;
             }
@@ -235,28 +235,28 @@ export class VLIW extends Machine {
 
     private runOperation(operation: VLIWOperation, functionalUnit: FunctionalUnit) {
         switch (operation.opcode) {
-            case Opcodes.ADD:
+            case OpcodeMnemonic.ADD:
                 this._gpr.setContent(operation.getOperand(0), this._gpr.content[operation.getOperand(1)] + this._gpr.content[operation.getOperand(2)], true);
                 break;
-            case Opcodes.MULT:
+            case OpcodeMnemonic.MULT:
                 this._gpr.setContent(operation.getOperand(0), this._gpr.content[operation.getOperand(1)] * this._gpr.content[operation.getOperand(2)], true);
                 break;
-            case Opcodes.ADDI:
+            case OpcodeMnemonic.ADDI:
                 this._gpr.setContent(operation.getOperand(0), this._gpr.content[operation.getOperand(1)] + operation.getOperand(2), true);
                 break;
-            case Opcodes.ADDF:
+            case OpcodeMnemonic.ADDF:
                 this._fpr.setContent(operation.getOperand(0), this._fpr.content[operation.getOperand(1)] + this._fpr.content[operation.getOperand(2)], true);
                 break;
-            case Opcodes.MULTF:
+            case OpcodeMnemonic.MULTF:
                 this._fpr.setContent(operation.getOperand(0), this._fpr.content[operation.getOperand(1)] * this._fpr.content[operation.getOperand(2)], true);
                 break;
-            case Opcodes.SW:
+            case OpcodeMnemonic.SW:
                 this._memory.setData(this._gpr.content[operation.getOperand(2)] + operation.getOperand(1), this._gpr.content[operation.getOperand(0)]);
                 break;
-            case Opcodes.SF:
+            case OpcodeMnemonic.SF:
                 this._memory.setData(this._gpr.content[operation.getOperand(2)] + operation.getOperand(1), this._fpr.content[operation.getOperand(0)]);
                 break;
-            case Opcodes.LW: {
+            case OpcodeMnemonic.LW: {
                 const datumInteger = this._memory.getData(this._gpr.content[operation.getOperand(2)] + operation.getOperand(1));
 
                 //hack: as we dont have a well made error handling, intercept the error and just throw it
@@ -272,7 +272,7 @@ export class VLIW extends Machine {
                 this._NaTGP[operation.getOperand(0)] = false;
                 break;
             }
-            case Opcodes.LF: {
+            case OpcodeMnemonic.LF: {
                 const datumFloat = this._memory.getData(this._gpr.content[operation.getOperand(2)] + operation.getOperand(1));
 
                 //hack: as we dont have a well made error handling, intercept the error and just throw it
@@ -298,7 +298,7 @@ export class VLIW extends Machine {
     private runJump(operation: VLIWOperation): number {
 
         let newPC = this.pc;
-        if (operation.opcode === Opcodes.BEQ) {
+        if (operation.opcode === OpcodeMnemonic.BEQ) {
             if (this._gpr.content[operation.getOperand(0)] === this._gpr.content[operation.getOperand(1)]) {
                 newPC = operation.getOperand(2);
                 this._predR[operation.getPredTrue()] = true;
@@ -307,7 +307,7 @@ export class VLIW extends Machine {
                 this._predR[operation.getPredTrue()] = false;
                 this._predR[operation.getPredFalse()] = true;
             }
-        } else if (operation.opcode === Opcodes.BNE) {
+        } else if (operation.opcode === OpcodeMnemonic.BNE) {
             if (this._gpr.content[operation.getOperand(0)] !== this._gpr.content[operation.getOperand(1)]) {
                 newPC = operation.getOperand(2);
                 this._predR[operation.getPredTrue()] = true;
@@ -316,7 +316,7 @@ export class VLIW extends Machine {
                 this._predR[operation.getPredTrue()] = false;
                 this._predR[operation.getPredFalse()] = true;
             }
-        } else if (operation.opcode === Opcodes.BGT) {
+        } else if (operation.opcode === OpcodeMnemonic.BGT) {
             if (this._gpr.content[operation.getOperand(0)] > this._gpr.content[operation.getOperand(1)]) {
                 newPC = operation.getOperand(2);
                 this._predR[operation.getPredTrue()] = true;
@@ -383,11 +383,11 @@ export class VLIW extends Machine {
             }
             let instruction = this._code.getLargeInstruction(row);
             for (let j = 0; j < instruction.getVLIWOperationsNumber(); j++) {
-                if (instruction.getOperation(j).getFunctionalUnitType() === FunctionalUnitType.JUMP) {
+                if (instruction.getOperation(j).getFunctionalUnitType() === FunctionalUnitKind.JUMP) {
                     let check1: Check;
                     let check2: Check;
-                    check1.latency = this.functionalUnit[FunctionalUnitType.JUMP].length;
-                    check2.latency = this.functionalUnit[FunctionalUnitType.JUMP].length;
+                    check1.latency = this.functionalUnit[FunctionalUnitKind.JUMP].length;
+                    check2.latency = this.functionalUnit[FunctionalUnitKind.JUMP].length;
                     check1.register = instruction.getOperation(j).getPredTrue();
                     check2.register = instruction.getOperation(j).getPredFalse();
                     controlCheckList.push(check1);
diff --git a/src/core/VLIW/VLIWOperation.ts b/src/core/VLIW/VLIWOperation.ts
index 3616370e..cca796df 100644
--- a/src/core/VLIW/VLIWOperation.ts
+++ b/src/core/VLIW/VLIWOperation.ts
@@ -1,16 +1,16 @@
 import { Instruction } from '../Common/Instruction';
-import { FunctionalUnitType } from '../Common/FunctionalUnit';
-import { Opcodes } from '../Common/Opcodes';
+import { FunctionalUnitKind } from '../Common/FunctionalUnit';
+import { OpcodeMnemonic } from '../Common/Opcode';
 
 export class VLIWOperation extends Instruction {
 
-    private _functionalUnitType: FunctionalUnitType;
+    private _functionalUnitType: FunctionalUnitKind;
     private _functionalUnitIndex: number;
     private _predicate: number;
     private _predicateTrue: number;
     private _predicateFalse: number;
 
-    constructor(operation?: VLIWOperation, instruction?: Instruction, type?: FunctionalUnitType, functionalUnitIndex?: number) {
+    constructor(operation?: VLIWOperation, instruction?: Instruction, type?: FunctionalUnitKind, functionalUnitIndex?: number) {
         if (operation) {
             super(operation);
             this.buildFromVLIWOperation(operation);
@@ -33,7 +33,7 @@ export class VLIWOperation extends Instruction {
         this._predicateFalse = operation._predicateFalse;
     }
 
-    buildFromInstruction(instruction: Instruction, functionalUnitType: FunctionalUnitType, functionalUnitIndex: number) {
+    buildFromInstruction(instruction: Instruction, functionalUnitType: FunctionalUnitKind, functionalUnitIndex: number) {
         this._functionalUnitType = functionalUnitType;
         this._functionalUnitIndex = functionalUnitIndex;
         this._predicate = 0;
@@ -42,7 +42,7 @@ export class VLIWOperation extends Instruction {
     }
 
     // Getters
-    public getFunctionalUnitType(): FunctionalUnitType {
+    public getFunctionalUnitType(): FunctionalUnitKind {
         return this._functionalUnitType;
     }
 
@@ -63,7 +63,7 @@ export class VLIWOperation extends Instruction {
     }
 
     // Setters
-    public setFunctionalUnitType(t: FunctionalUnitType) {
+    public setFunctionalUnitType(t: FunctionalUnitKind) {
         this._functionalUnitType = t;
     }
 
diff --git a/src/core/VLIW/VLIWParser.ts b/src/core/VLIW/VLIWParser.ts
index 26671509..87c0156c 100644
--- a/src/core/VLIW/VLIWParser.ts
+++ b/src/core/VLIW/VLIWParser.ts
@@ -16,7 +16,7 @@ import {
 } from "typescript-parsec";
 import {
   FUNCTIONALUNITTYPESQUANTITY,
-  type FunctionalUnitType,
+  type FunctionalUnitKind,
   FunctionalUnitTypeNames,
 } from "../Common/FunctionalUnit";
 import { LargeInstruction } from "./LargeInstructions";
@@ -40,7 +40,7 @@ const tokenizer = buildLexer([
 
 const functionalUnitTypeParser = apply(
   tok(Tokens.Number),
-  (num: Token<Tokens.Number>): FunctionalUnitType => {
+  (num: Token<Tokens.Number>): FunctionalUnitKind => {
     const type = +num.text;
     if (type > FUNCTIONALUNITTYPESQUANTITY - 1) {
       throw new TokenError(num.pos, `Invalid functional unit type ${type}`);
@@ -52,7 +52,7 @@ const functionalUnitTypeParser = apply(
 interface IndexParsed {
   index: number;
   isJump: boolean;
-  functionalUnitType: FunctionalUnitType;
+  functionalUnitType: FunctionalUnitKind;
 }
 
 export function Parse(input: string, code: Code): LargeInstruction[] {
@@ -87,7 +87,7 @@ export function Parse(input: string, code: Code): LargeInstruction[] {
 
   const operationParser = apply(
     operationCombiner,
-    (componets: [FunctionalUnitType, Token<Tokens>[]]) => {
+    (componets: [FunctionalUnitKind, Token<Tokens>[]]) => {
       // Check if we received the right amount of operands
       if (componets[1].length < 2) {
         throw new TokenError(
diff --git a/src/integration/superscalar-integration.ts b/src/integration/superscalar-integration.ts
index 29c72580..a2d83ca2 100644
--- a/src/integration/superscalar-integration.ts
+++ b/src/integration/superscalar-integration.ts
@@ -25,7 +25,7 @@ import {
 
 import { displayBatchResults } from '../interface/actions/modals';
 
-import { FunctionalUnitType } from '../core/Common/FunctionalUnit';
+import { FunctionalUnitKind } from '../core/Common/FunctionalUnit';
 
 import { pushHistory, takeHistory, resetHistory } from '../interface/actions/history';
 import { MAX_HISTORY_SIZE } from '../interface/reducers/machine';
@@ -345,65 +345,65 @@ export class SuperscalarIntegration extends MachineIntegration {
 
     saveSuperConfig = (superConfig) => {
         this.superscalar.changeFunctionalUnitNumber(
-          FunctionalUnitType.INTEGERSUM,
+          FunctionalUnitKind.INTEGERSUM,
           +superConfig.integerSumQuantity,
         );
         this.superscalar.changeFunctionalUnitLatency(
-          FunctionalUnitType.INTEGERSUM,
+          FunctionalUnitKind.INTEGERSUM,
           +superConfig.integerSumLatency,
         );
 
         this.superscalar.changeFunctionalUnitNumber(
-          FunctionalUnitType.INTEGERMULTIPLY,
+          FunctionalUnitKind.INTEGERMULTIPLY,
           +superConfig.integerMultQuantity,
         );
         this.superscalar.changeFunctionalUnitLatency(
-          FunctionalUnitType.INTEGERMULTIPLY,
+          FunctionalUnitKind.INTEGERMULTIPLY,
           +superConfig.integerMultLatency,
         );
 
         this.superscalar.changeFunctionalUnitNumber(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +superConfig.floatingSumQuantity,
         );
         this.superscalar.changeFunctionalUnitLatency(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +superConfig.floatingSumLatency,
         );
 
         this.superscalar.changeFunctionalUnitNumber(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +superConfig.floatingSumQuantity,
         );
         this.superscalar.changeFunctionalUnitLatency(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +superConfig.floatingSumLatency,
         );
 
         this.superscalar.changeFunctionalUnitNumber(
-          FunctionalUnitType.FLOATINGMULTIPLY,
+          FunctionalUnitKind.FLOATINGMULTIPLY,
           +superConfig.floatingMultQuantity,
         );
         this.superscalar.changeFunctionalUnitLatency(
-          FunctionalUnitType.FLOATINGMULTIPLY,
+          FunctionalUnitKind.FLOATINGMULTIPLY,
           +superConfig.floatingMultLatency,
         );
 
         this.superscalar.changeFunctionalUnitNumber(
-          FunctionalUnitType.JUMP,
+          FunctionalUnitKind.JUMP,
           +superConfig.jumpQuantity,
         );
         this.superscalar.changeFunctionalUnitLatency(
-          FunctionalUnitType.JUMP,
+          FunctionalUnitKind.JUMP,
           +superConfig.jumpLatency,
         );
 
         this.superscalar.changeFunctionalUnitNumber(
-          FunctionalUnitType.MEMORY,
+          FunctionalUnitKind.MEMORY,
           +superConfig.memoryQuantity,
         );
         this.superscalar.changeFunctionalUnitLatency(
-          FunctionalUnitType.MEMORY,
+          FunctionalUnitKind.MEMORY,
           +superConfig.memoryLatency,
         );
 
diff --git a/src/integration/vliw-integration.ts b/src/integration/vliw-integration.ts
index 8f62070a..dcbaa73e 100644
--- a/src/integration/vliw-integration.ts
+++ b/src/integration/vliw-integration.ts
@@ -30,7 +30,7 @@ import { displayBatchResults } from '../interface/actions/modals';
 
 import { Stats } from '../stats/stats';
 import { StatsAgregator } from '../stats/aggregator';
-import { FunctionalUnitType } from '@/core/Common/FunctionalUnit';
+import { FunctionalUnitKind } from '@/core/Common/FunctionalUnit';
 
 export class VLIWIntegration extends MachineIntegration {
     // Global objects for binding React to the View
@@ -350,65 +350,65 @@ export class VLIWIntegration extends MachineIntegration {
 
     saveVliwConfig = (vliwConfig) => {
         this.vliw.changeFunctionalUnitNumber(
-          FunctionalUnitType.INTEGERSUM,
+          FunctionalUnitKind.INTEGERSUM,
           +vliwConfig.integerSumQuantity,
         );
         this.vliw.changeFunctionalUnitLatency(
-          FunctionalUnitType.INTEGERSUM,
+          FunctionalUnitKind.INTEGERSUM,
           +vliwConfig.integerSumLatency,
         );
 
         this.vliw.changeFunctionalUnitNumber(
-          FunctionalUnitType.INTEGERMULTIPLY,
+          FunctionalUnitKind.INTEGERMULTIPLY,
           +vliwConfig.integerMultQuantity,
         );
         this.vliw.changeFunctionalUnitLatency(
-          FunctionalUnitType.INTEGERMULTIPLY,
+          FunctionalUnitKind.INTEGERMULTIPLY,
           +vliwConfig.integerMultLatency,
         );
 
         this.vliw.changeFunctionalUnitNumber(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +vliwConfig.floatingSumQuantity,
         );
         this.vliw.changeFunctionalUnitLatency(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +vliwConfig.floatingSumLatency,
         );
 
         this.vliw.changeFunctionalUnitNumber(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +vliwConfig.floatingSumQuantity,
         );
         this.vliw.changeFunctionalUnitLatency(
-          FunctionalUnitType.FLOATINGSUM,
+          FunctionalUnitKind.FLOATINGSUM,
           +vliwConfig.floatingSumLatency,
         );
 
         this.vliw.changeFunctionalUnitNumber(
-          FunctionalUnitType.FLOATINGMULTIPLY,
+          FunctionalUnitKind.FLOATINGMULTIPLY,
           +vliwConfig.floatingMultQuantity,
         );
         this.vliw.changeFunctionalUnitLatency(
-          FunctionalUnitType.FLOATINGMULTIPLY,
+          FunctionalUnitKind.FLOATINGMULTIPLY,
           +vliwConfig.floatingMultLatency,
         );
 
         this.vliw.changeFunctionalUnitNumber(
-          FunctionalUnitType.JUMP,
+          FunctionalUnitKind.JUMP,
           +vliwConfig.jumpQuantity,
         );
         this.vliw.changeFunctionalUnitLatency(
-          FunctionalUnitType.JUMP,
+          FunctionalUnitKind.JUMP,
           +vliwConfig.jumpLatency,
         );
 
         this.vliw.changeFunctionalUnitNumber(
-          FunctionalUnitType.MEMORY,
+          FunctionalUnitKind.MEMORY,
           +vliwConfig.memoryQuantity,
         );
         this.vliw.changeFunctionalUnitLatency(
-          FunctionalUnitType.MEMORY,
+          FunctionalUnitKind.MEMORY,
           +vliwConfig.memoryLatency,
         );
 
diff --git a/src/interface/actions/table-actions.ts b/src/interface/actions/table-actions.ts
index 13f7cfa8..560a4baa 100644
--- a/src/interface/actions/table-actions.ts
+++ b/src/interface/actions/table-actions.ts
@@ -1,4 +1,4 @@
-import { FunctionalUnit, FunctionalUnitType } from '../../core/Common/FunctionalUnit';
+import { FunctionalUnit, FunctionalUnitKind } from '../../core/Common/FunctionalUnit';
 export const HEADER_TABLE_CYCLE = 'HEADER_TABLE_CYCLE';
 export const TABLE_CYCLE = 'TABLE_CYCLE';
 
@@ -44,33 +44,33 @@ function mapVLIWTableData(data, functionalUnitNumbers: number[]): any {
 
     for (let i = 0; i < data.getVLIWOperationsNumber(); i++) { // numero de instrucciones cortas en la instrucción larga
         for (let j = 0; j < cols.length; j++) {
-            if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitType.INTEGERSUM)
+            if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitKind.INTEGERSUM)
                 && (data.getOperation(i).getFunctionalUnitIndex() === j)) {
 
                 cols[j] = data.getOperation(i).id;
 
-            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitType.INTEGERMULTIPLY)
+            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitKind.INTEGERMULTIPLY)
                 && ((data.getOperation(i).getFunctionalUnitIndex() + functionalUnitNumbers[0]) === j)) {
 
                 cols[j] = data.getOperation(i).id;
 
-            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitType.FLOATINGSUM)
+            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitKind.FLOATINGSUM)
             && ((data.getOperation(i).getFunctionalUnitIndex() + functionalUnitNumbers[0] + functionalUnitNumbers[1]) === j)) {
 
                 cols[j] = data.getOperation(i).id;
 
-            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitType.FLOATINGMULTIPLY)
+            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitKind.FLOATINGMULTIPLY)
             && ((data.getOperation(i).getFunctionalUnitIndex() + functionalUnitNumbers[0] + functionalUnitNumbers[1] + functionalUnitNumbers[2]) === j)) {
 
                 cols[j] = data.getOperation(i).id;
 
-            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitType.MEMORY)
+            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitKind.MEMORY)
             && ((data.getOperation(i).getFunctionalUnitIndex() + functionalUnitNumbers[0] +
              functionalUnitNumbers[1] + functionalUnitNumbers[2] + functionalUnitNumbers[3]) === j)) {
 
                 cols[j] = data.getOperation(i).id;
 
-            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitType.JUMP)
+            } else if ((data.getOperation(i).getFunctionalUnitType() === FunctionalUnitKind.JUMP)
             && ((data.getOperation(i).getFunctionalUnitIndex() + functionalUnitNumbers[0] + functionalUnitNumbers[1]
             + functionalUnitNumbers[2] + functionalUnitNumbers[3] + functionalUnitNumbers[4]) === j)) {
 
diff --git a/src/interface/components/Superscalar/CodeComponent.tsx b/src/interface/components/Superscalar/CodeComponent.tsx
index 84de5c2c..fb11a06a 100644
--- a/src/interface/components/Superscalar/CodeComponent.tsx
+++ b/src/interface/components/Superscalar/CodeComponent.tsx
@@ -1,5 +1,5 @@
 import * as React from 'react';
-import { OpcodesNames } from '../../../core/Common/Opcodes';
+import { OpcodesNames } from '../../../core/Common/Opcode';
 
 import { Instruction } from '../../../core/Common/Instruction';
 
diff --git a/src/interface/components/VLIW/InstructionComponent.tsx b/src/interface/components/VLIW/InstructionComponent.tsx
index bfd5fd60..bfc0bb68 100644
--- a/src/interface/components/VLIW/InstructionComponent.tsx
+++ b/src/interface/components/VLIW/InstructionComponent.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
 
 import { useDrag } from 'react-dnd';
 
-import { OpcodesNames } from '../../../core/Common/Opcodes';
+import { OpcodesNames } from '../../../core/Common/Opcode';
 import { Instruction } from '../../../core/Common/Instruction';
 
 
diff --git a/src/test/functional/Superscalar/iteratelist.spec.ts b/src/test/functional/Superscalar/iteratelist.spec.ts
index f40f5ab5..f60fbbf6 100644
--- a/src/test/functional/Superscalar/iteratelist.spec.ts
+++ b/src/test/functional/Superscalar/iteratelist.spec.ts
@@ -2,7 +2,7 @@ import { expect, beforeEach, test } from 'vitest'
 import { Code } from '../../../core/Common/Code';
 import { Superscalar } from '../../../core/Superscalar/Superscalar';
 import { SuperscalarStatus } from '../../../core/Superscalar/SuperscalarEnums';
-import { FunctionalUnitType } from '../../../core/Common/FunctionalUnit';
+import { FunctionalUnitKind } from '../../../core/Common/FunctionalUnit';
 import { codeInput, memContent } from "../code/recorrelista";
 
 
@@ -38,9 +38,9 @@ test('recorrelista.pla is executed properly', t => {
 
             // Check that instructions are being executed in the correct Functional Units
             // 13 -> FLOATINGMULTIPLY, 16 -> MEMORY and 12 -> JUMP
-            expect(context.machine.functionalUnit[FunctionalUnitType.FLOATINGMULTIPLY][0].getVisualData().filter(e => e.id === 13).length).toBeGreaterThan(0); // Instruction 13 is not at FLOATINGMULTIPLY Functional unit at cycle 40');
-            expect(context.machine.functionalUnit[FunctionalUnitType.MEMORY][0].getVisualData().filter(e => e.id === 16).length).toBeGreaterThan(0); // Instruction 16 is not at MEMORY Functional unit at cycle 40');
-            expect(context.machine.functionalUnit[FunctionalUnitType.JUMP][0].getVisualData().filter(e => e.id === 12).length).toBeGreaterThan(0); // Instruction 12 is not at JUMP Functional unit at cycle 40');
+            expect(context.machine.functionalUnit[FunctionalUnitKind.FLOATINGMULTIPLY][0].getVisualData().filter(e => e.id === 13).length).toBeGreaterThan(0); // Instruction 13 is not at FLOATINGMULTIPLY Functional unit at cycle 40');
+            expect(context.machine.functionalUnit[FunctionalUnitKind.MEMORY][0].getVisualData().filter(e => e.id === 16).length).toBeGreaterThan(0); // Instruction 16 is not at MEMORY Functional unit at cycle 40');
+            expect(context.machine.functionalUnit[FunctionalUnitKind.JUMP][0].getVisualData().filter(e => e.id === 12).length).toBeGreaterThan(0); // Instruction 12 is not at JUMP Functional unit at cycle 40');
         }
 
         if (context.machine.status.cycle === 60 || context.machine.status.cycle === 70) { // at cycle 70 the jump is still looping
@@ -70,4 +70,4 @@ test('recorrelista.pla is executed properly', t => {
     // Check the result
     expect(Array.from(context.machine.memory)[9]).toBe(12);
 
-})
\ No newline at end of file
+})