diff --git a/src/core/Common/FunctionalUnit.ts b/src/core/Common/FunctionalUnit.ts index c78dcae5..474c1387 100644 --- a/src/core/Common/FunctionalUnit.ts +++ b/src/core/Common/FunctionalUnit.ts @@ -59,12 +59,12 @@ interface FunctionalUnitInstruction { } export class FunctionalUnit { - private _stalled: number; // if >0, it is stalling (for ex because a memory fail) for that many cycles - private _instructions: FunctionalUnitInstruction[]; + private _stalled: number = 0; // if >0, it is stalling (for ex because a memory fail) for that many cycles + private _instructions: FunctionalUnitInstruction[] = []; - private _nextRef: number; //TODO: use instruction uid + private _nextRef: number = 0; //TODO: use instruction uid private _currentBlankTimeUnits: number; - private _hasExectutedInstBeforeTick: boolean; + private _hasExectutedInstBeforeTick: boolean = false; public get type(): FunctionalUnitType { return this._type; @@ -78,15 +78,7 @@ export class FunctionalUnit { private _type: FunctionalUnitType, private _latency: number = FunctionalUnitLantencies[_type] ) { - this.clean(); - } - - public clean() { - this._stalled = 0; - this._nextRef = 0; this._currentBlankTimeUnits = this._latency - 1; - this._hasExectutedInstBeforeTick = false; - this._instructions = []; } public tic() { diff --git a/src/core/Common/Instruction.ts b/src/core/Common/Instruction.ts index 33b7e1a2..0d413cad 100644 --- a/src/core/Common/Instruction.ts +++ b/src/core/Common/Instruction.ts @@ -6,7 +6,6 @@ export class Instruction { public id: number; public basicBlock: number; public opcode: number; - protected _uuid: number; protected _operands: number[] = new Array(3); protected _operandsString: string[] = new Array(3); protected _label: string; @@ -36,18 +35,15 @@ export class Instruction { return this._operandsString; } - instantiate(from: Instruction, cycle: number) { - this.copy(from); - this._uuid = cycle * 1000 + this.id; - } - - copy(other: Instruction) { - this.id = other.id; - this.basicBlock = other.basicBlock; - this.opcode = other.opcode; - this._operands = other.operands.slice(); - this._operandsString = other.operandsString.slice(); - this._breakPoint = other.breakPoint; + constructor(from?: Instruction, protected _uuid?: 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; + } } toString(): string { diff --git a/src/core/Common/Machine.ts b/src/core/Common/Machine.ts index c8323750..d012d062 100644 --- a/src/core/Common/Machine.ts +++ b/src/core/Common/Machine.ts @@ -109,7 +109,10 @@ export class Machine { this.pc = 0; for (let i = 0; i < FUNCTIONALUNITTYPESQUANTITY; i++) { for (let j = 0; j < this.functionalUnit[i].length; j++) { - this.functionalUnit[i][j].clean(); + this.functionalUnit[i][j] = new FunctionalUnit( + this.functionalUnit[i][j].type, + this.functionalUnit[i][j].latency + ); } } this.status.cycle = 0; diff --git a/src/core/Superescalar/JumpPredictor.ts b/src/core/Superescalar/JumpPredictor.ts index 349b225c..bb9dee7a 100644 --- a/src/core/Superescalar/JumpPredictor.ts +++ b/src/core/Superescalar/JumpPredictor.ts @@ -1,12 +1,12 @@ export class JumpPredictor { _table: number[]; - constructor(private _size: number) { - this._table = new Array(_size); - this._table.fill(0); + public get size(): number { + return this._size; } - public clean() { + constructor(private _size: number) { + this._table = new Array(_size); this._table.fill(0); } diff --git a/src/core/Superescalar/PrefetchUnit.ts b/src/core/Superescalar/PrefetchUnit.ts index e7eb11c6..30d5434f 100644 --- a/src/core/Superescalar/PrefetchUnit.ts +++ b/src/core/Superescalar/PrefetchUnit.ts @@ -15,10 +15,6 @@ export class PrefetchUnit { constructor(private _size: number) {} - public clean() { - this._entries = []; - } - public isFull() { return this._entries.length >= this._size; } diff --git a/src/core/Superescalar/ReorderBuffer.ts b/src/core/Superescalar/ReorderBuffer.ts index fa3fc9d0..fba4d97f 100644 --- a/src/core/Superescalar/ReorderBuffer.ts +++ b/src/core/Superescalar/ReorderBuffer.ts @@ -24,8 +24,12 @@ interface ReorderBufferEntry { // TODO: dont use rob entry pos as a reference to the instruction, use an instruction uid instead? export class ReorderBuffer { _queue: ReorderBufferEntry[] = []; - _GprMapping: { [reg: number]: number }; - _FprMapping: { [reg: number]: number }; + _GprMapping: { [reg: number]: number } = {}; + _FprMapping: { [reg: number]: number } = {}; + + public get size() { + return this._size; + } constructor(private _size: number) {} @@ -43,15 +47,6 @@ export class ReorderBuffer { return this._queue.length === 0; } - /** - * clear - this method clears the reorder buffer, it is called when the machine is reseted - */ - public clear() { - this._queue = []; - this._FprMapping = {}; - this._GprMapping = {}; - } - /** * isRegisterValueReady - this method checks if the rob entry wich will write in that register has already the new value */ diff --git a/src/core/Superescalar/ReserveStation.ts b/src/core/Superescalar/ReserveStation.ts index a47d692c..8b0bd8d4 100644 --- a/src/core/Superescalar/ReserveStation.ts +++ b/src/core/Superescalar/ReserveStation.ts @@ -24,6 +24,10 @@ export interface ReserveStationEntry { export class ReserveStation { private _entries: ReserveStationEntry[] = new Array(); + public get size(): number { + return this._size; + } + constructor(private _size: number) {} private getInstrPos(uuid: number): number { @@ -35,13 +39,6 @@ export class ReserveStation { return -1; } - /** - * clear - */ - public clear() { - this._entries = new Array(); - } - /** * isFull */ diff --git a/src/core/Superescalar/Superescalar.ts b/src/core/Superescalar/Superescalar.ts index bbd0c70c..d2f5fcb6 100644 --- a/src/core/Superescalar/Superescalar.ts +++ b/src/core/Superescalar/Superescalar.ts @@ -188,21 +188,29 @@ export class Superescalar extends Machine { // Clean functional Units and Reserve Stations, for (let i = 0; i < FUNCTIONALUNITTYPESQUANTITY; i++) { for (let j = 0; j < this.functionalUnit[i].length; j++) { - this.functionalUnit[i][j].clean(); - this._reserveStations[i].clear(); + this.functionalUnit[i][j] = new FunctionalUnit( + this.functionalUnit[i][j].type, + this.functionalUnit[i][j].latency + ); + this._reserveStations[i] = new ReserveStation( + this._reserveStations[i].size + ); } } // Clean the alus for the address calculus for (let i = 0; i < this.aluMem.length; i++) { - this.aluMem[i].clean(); + this.aluMem[i] = new FunctionalUnit( + this.aluMem[i].type, + this.aluMem[i].latency + ); } // Clean prefetch, decoder and reorder buffer, the simplest way is // to rebuild the objects - this._prefetchUnit.clean(); - this._decoder.clean(); - this._reorderBuffer.clear(); + this._prefetchUnit = new PrefetchUnit(this._prefetchUnit.size); + this._decoder = new PrefetchUnit(this._decoder.size); + this._reorderBuffer = new ReorderBuffer(this._reorderBuffer.size); // Clean the structures related to the registers this._gpr.setAllBusy(false); @@ -216,18 +224,23 @@ export class Superescalar extends Machine { init(reset: boolean) { super.init(reset); // Clean Gpr, Fpr, predSalto - this._jumpPrediction.clean(); + this._jumpPrediction = new JumpPredictor(this._jumpPrediction.size); for (let i = 0; i < FUNCTIONALUNITTYPESQUANTITY; i++) { - this._reserveStations[i].clear(); + this._reserveStations[i] = new ReserveStation( + this._reserveStations[i].size + ); } - this._reorderBuffer.clear(); - this._decoder.clean(); - this._prefetchUnit.clean(); + this._reorderBuffer = new ReorderBuffer(this._reorderBuffer.size); + this._decoder = new PrefetchUnit(this._decoder.size); + this._prefetchUnit = new PrefetchUnit(this._prefetchUnit.size); this._code = null; for (let j = 0; j < this.aluMem.length; j++) { - this.aluMem[j].clean(); + this.aluMem[j] = new FunctionalUnit( + this.aluMem[j].type, + this.aluMem[j].latency + ); } } @@ -236,8 +249,7 @@ export class Superescalar extends Machine { while (!this._prefetchUnit.isFull() && this.pc < this.code.lines) { // Importante: Hago una copia de la instrucción original para distinguir // las distintas apariciones de una misma inst. - let instruction = new Instruction(); - instruction.instantiate( + let instruction = new Instruction( this.code.instructions[this.pc], this.status.cycle * 100 + i ); diff --git a/src/core/VLIW/VLIWOperation.ts b/src/core/VLIW/VLIWOperation.ts index 061aedd1..3616370e 100644 --- a/src/core/VLIW/VLIWOperation.ts +++ b/src/core/VLIW/VLIWOperation.ts @@ -11,12 +11,14 @@ export class VLIWOperation extends Instruction { private _predicateFalse: number; constructor(operation?: VLIWOperation, instruction?: Instruction, type?: FunctionalUnitType, functionalUnitIndex?: number) { - super(); if (operation) { + super(operation); this.buildFromVLIWOperation(operation); } else if (instruction) { + super(instruction); this.buildFromInstruction(instruction, type, functionalUnitIndex); } else { + super(); this._predicate = 0; this._predicateTrue = 0; this._predicateFalse = 0; @@ -24,7 +26,6 @@ export class VLIWOperation extends Instruction { } buildFromVLIWOperation(operation: VLIWOperation) { - this.copy(operation); this._functionalUnitType = operation._functionalUnitType; this._functionalUnitIndex = operation._functionalUnitIndex; this._predicate = operation._predicate; @@ -33,7 +34,6 @@ export class VLIWOperation extends Instruction { } buildFromInstruction(instruction: Instruction, functionalUnitType: FunctionalUnitType, functionalUnitIndex: number) { - this.copy(instruction); this._functionalUnitType = functionalUnitType; this._functionalUnitIndex = functionalUnitIndex; this._predicate = 0; diff --git a/src/test/unit/core/Common/Instruction.spec.ts b/src/test/unit/core/Common/Instruction.spec.ts index d2d10176..7053795c 100644 --- a/src/test/unit/core/Common/Instruction.spec.ts +++ b/src/test/unit/core/Common/Instruction.spec.ts @@ -9,8 +9,7 @@ beforeEach(() => { }); test('Copied instructions should not keep the same reference', t => { - let newInstruction = new Instruction(); - newInstruction.copy(originalInstruction); + let newInstruction = new Instruction(originalInstruction); originalInstruction.id = 1; expect(newInstruction.operands).not.toBe(100); }); \ No newline at end of file