Une MAJ de sécurité est nécessaire sur notre version actuelle. Elle sera effectuée lundi 02/08 entre 12h30 et 13h. L'interruption de service devrait durer quelques minutes (probablement moins de 5 minutes).

core.cpp 21.5 KB
Newer Older
1
#include <core.h>
2
#include <ac_int.h>
3

4
#ifndef __HLS__
5
#include "simulator.h"
6
#endif  // __HLS__
EGLOFF Valentin's avatar
EGLOFF Valentin committed
7

EGLOFF Valentin's avatar
EGLOFF Valentin committed
8

Joseph Paturel's avatar
Joseph Paturel committed
9 10
void fetch(ac_int<32, false> pc,
           struct FtoDC &ftoDC,
PATUREL Joseph's avatar
PATUREL Joseph committed
11
           ac_int<32, false> instruction)
EGLOFF Valentin's avatar
EGLOFF Valentin committed
12
{
PATUREL Joseph's avatar
PATUREL Joseph committed
13
    ftoDC.instruction = instruction;
ROKICKI Simon's avatar
ROKICKI Simon committed
14 15 16
    ftoDC.pc = pc;
    ftoDC.nextPCFetch = pc + 4;
    ftoDC.we = 1;
EGLOFF Valentin's avatar
EGLOFF Valentin committed
17 18
}

Joseph Paturel's avatar
Joseph Paturel committed
19 20
void decode(struct FtoDC ftoDC,
            struct DCtoEx &dctoEx,
Joseph Paturel's avatar
Joseph Paturel committed
21
            ac_int<32, true> registerFile[32])
EGLOFF Valentin's avatar
EGLOFF Valentin committed
22
{
ROKICKI Simon's avatar
ROKICKI Simon committed
23 24
    ac_int<32, false> pc = ftoDC.pc;
    ac_int<32, false> instruction = ftoDC.instruction;
EGLOFF Valentin's avatar
EGLOFF Valentin committed
25 26 27 28 29

    // R-type instruction
    ac_int<7, false> funct7 = instruction.slc<7>(25);
    ac_int<5, false> rs2 = instruction.slc<5>(20);
    ac_int<5, false> rs1 = instruction.slc<5>(15);
EGLOFF Valentin's avatar
EGLOFF Valentin committed
30
    ac_int<3, false> funct3 = instruction.slc<3>(12);
EGLOFF Valentin's avatar
EGLOFF Valentin committed
31
    ac_int<5, false> rd = instruction.slc<5>(7);
32
    ac_int<7, false> opCode = instruction.slc<7>(0);    // could be reduced to 5 bits because 1:0 is always 11
EGLOFF Valentin's avatar
EGLOFF Valentin committed
33

ROKICKI Simon's avatar
ROKICKI Simon committed
34 35
    //Construction of different immediate values
    ac_int<12, false> imm12_I = instruction.slc<12>(20);
Joseph Paturel's avatar
Joseph Paturel committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    ac_int<12, false> imm12_S = 0;
    imm12_S.set_slc(5, instruction.slc<7>(25));
    imm12_S.set_slc(0, instruction.slc<5>(7));

    ac_int<12, true> imm12_I_signed = instruction.slc<12>(20);
    ac_int<12, true> imm12_S_signed = 0;
    imm12_S_signed.set_slc(0, imm12_S.slc<12>(0));

    ac_int<13, false> imm13 = 0;
    imm13[12] = instruction[31];
    imm13.set_slc(5, instruction.slc<6>(25));
    imm13.set_slc(1, instruction.slc<4>(8));
    imm13[11] = instruction[7];

    ac_int<13, true> imm13_signed = 0;
    imm13_signed.set_slc(0, imm13);

    ac_int<32, true> imm31_12 = 0;
    imm31_12.set_slc(12, instruction.slc<20>(12));

    ac_int<21, false> imm21_1 = 0;
    imm21_1.set_slc(12, instruction.slc<8>(12));
    imm21_1[11] = instruction[20];
    imm21_1.set_slc(1, instruction.slc<10>(21));
    imm21_1[20] = instruction[31];

    ac_int<21, true> imm21_1_signed = 0;
    imm21_1_signed.set_slc(0, imm21_1);


    //Register access
    ac_int<32, false> valueReg1 = registerFile[rs1];
    ac_int<32, false> valueReg2 = registerFile[rs2];


    dctoEx.rs1 = rs1;
    dctoEx.rs2 = rs2;
ROKICKI Simon's avatar
ROKICKI Simon committed
73
    dctoEx.rs3 = rs2;
Joseph Paturel's avatar
Joseph Paturel committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
    dctoEx.rd = rd;
    dctoEx.opCode = opCode;
    dctoEx.funct3 = funct3;
    dctoEx.funct7 = funct7;
    dctoEx.instruction = instruction;
    dctoEx.pc = pc;

    //Initialization of control bits
    dctoEx.useRs1 = 0;
    dctoEx.useRs2 = 0;
    dctoEx.useRd = 0;
    dctoEx.we = ftoDC.we;
    dctoEx.isBranch = 0;



    switch (opCode)
    {
    case RISCV_LUI:
        dctoEx.lhs = imm31_12;
        dctoEx.useRs1 = 0;
        dctoEx.useRs2 = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
96
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
97 98 99 100 101 102 103 104
        dctoEx.useRd = 1;

        break;
    case RISCV_AUIPC:
        dctoEx.lhs = ftoDC.pc;
        dctoEx.rhs = imm31_12;
        dctoEx.useRs1 = 0;
        dctoEx.useRs2 = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
105
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
106 107 108 109 110 111 112 113
        dctoEx.useRd = 1;
        break;
    case RISCV_JAL:
        dctoEx.lhs = ftoDC.pc+4;
        dctoEx.rhs = 0;
        dctoEx.nextPCDC = ftoDC.pc + imm21_1_signed;
        dctoEx.useRs1 = 0;
        dctoEx.useRs2 = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
114
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
115 116 117 118 119
        dctoEx.useRd = 1;
        dctoEx.isBranch = 1;

        break;
    case RISCV_JALR:
ROKICKI Simon's avatar
ROKICKI Simon committed
120 121 122
        dctoEx.lhs = valueReg1;
        dctoEx.rhs = imm12_I_signed;
        dctoEx.useRs1 = 1;
Joseph Paturel's avatar
Joseph Paturel committed
123
        dctoEx.useRs2 = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
124
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
125 126 127 128 129 130 131 132
        dctoEx.useRd = 1;
        break;
    case RISCV_BR:

        dctoEx.lhs = valueReg1;
        dctoEx.rhs = valueReg2;
        dctoEx.useRs1 = 1;
        dctoEx.useRs2 = 1;
ROKICKI Simon's avatar
ROKICKI Simon committed
133
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
134 135 136 137 138 139 140 141 142
        dctoEx.useRd = 0;

        break;
    case RISCV_LD:

        dctoEx.lhs = valueReg1;
        dctoEx.rhs = imm12_I_signed;
        dctoEx.useRs1 = 1;
        dctoEx.useRs2 = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
143
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
144 145 146 147 148 149 150 151 152 153 154
        dctoEx.useRd = 1;

        break;

        //******************************************************************************************
        //Treatment for: STORE INSTRUCTIONS
    case RISCV_ST:
        dctoEx.lhs = valueReg1;
        dctoEx.rhs = imm12_S_signed;
        dctoEx.datac = valueReg2; //Value to store in memory
        dctoEx.useRs1 = 1;
ROKICKI Simon's avatar
ROKICKI Simon committed
155 156
        dctoEx.useRs2 = 0;
        dctoEx.useRs3 = 1;
Joseph Paturel's avatar
Joseph Paturel committed
157
        dctoEx.useRd = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
158
        dctoEx.rd = 0;
Joseph Paturel's avatar
Joseph Paturel committed
159 160 161 162 163 164
        break;
    case RISCV_OPI:
        dctoEx.lhs = valueReg1;
        dctoEx.rhs = imm12_I_signed;
        dctoEx.useRs1 = 1;
        dctoEx.useRs2 = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
165
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
166 167 168 169 170 171 172 173 174
        dctoEx.useRd = 1;
        break;

    case RISCV_OP:

        dctoEx.lhs = valueReg1;
        dctoEx.rhs = valueReg2;
        dctoEx.useRs1 = 1;
        dctoEx.useRs2 = 1;
ROKICKI Simon's avatar
ROKICKI Simon committed
175
        dctoEx.useRs3 = 0;
Joseph Paturel's avatar
Joseph Paturel committed
176 177 178 179 180 181 182 183 184 185 186 187
        dctoEx.useRd = 1;

        break;
    case RISCV_SYSTEM:
        //TODO

        break;
    default:

        break;

    }
188

189 190 191 192 193
    //If dest is zero, useRd should be at zero
	if (rd == 0){
		dctoEx.useRd = 0;
	}

194
    //If the instruction was dropped, we ensure that isBranch is at zero
ROKICKI Simon's avatar
ROKICKI Simon committed
195
    if (!ftoDC.we){
196
    	dctoEx.isBranch = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
197 198 199 200 201
    	dctoEx.useRd = 0;
    	dctoEx.useRs1 = 0;
    	dctoEx.useRs2 = 0;
    	dctoEx.useRs3 = 0;
    }
202

EGLOFF Valentin's avatar
EGLOFF Valentin committed
203 204
}

Joseph Paturel's avatar
Joseph Paturel committed
205 206
void execute(struct DCtoEx dctoEx,
             struct ExtoMem &extoMem)
EGLOFF Valentin's avatar
EGLOFF Valentin committed
207 208
{

ROKICKI Simon's avatar
ROKICKI Simon committed
209 210 211 212 213 214
    extoMem.pc = dctoEx.pc;
    extoMem.opCode = dctoEx.opCode;
    extoMem.rd = dctoEx.rd;
    extoMem.funct3 = dctoEx.funct3;
    extoMem.we = dctoEx.we;
    extoMem.isBranch = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
215
    extoMem.useRd = dctoEx.useRd;
216
    extoMem.isLongInstruction = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
217

Joseph Paturel's avatar
Joseph Paturel committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
    ac_int<13, false> imm13 = 0;
    imm13[12] = dctoEx.instruction[31];
    imm13.set_slc(5, dctoEx.instruction.slc<6>(25));
    imm13.set_slc(1, dctoEx.instruction.slc<4>(8));
    imm13[11] = dctoEx.instruction[7];

    ac_int<13, true> imm13_signed = 0;
    imm13_signed.set_slc(0, imm13);

    ac_int<5, false> shamt = dctoEx.instruction.slc<5>(20);


    // switch must be in the else, otherwise external op may trigger default case
    switch(dctoEx.opCode)
    {
    case RISCV_LUI:
        extoMem.result = dctoEx.lhs;
        break;
    case RISCV_AUIPC:
        extoMem.result = dctoEx.lhs + dctoEx.rhs;
        break;
    case RISCV_JAL:
        //Note: in current version, the addition is made in the decode stage
        //The value to store in rd (pc+4) is stored in lhs
        extoMem.result = dctoEx.lhs;
        break;
    case RISCV_JALR:
        //Note: in current version, the addition is made in the decode stage
        //The value to store in rd (pc+4) is stored in lhs
ROKICKI Simon's avatar
ROKICKI Simon committed
247 248 249 250
    	extoMem.nextPC = dctoEx.rhs + dctoEx.lhs;
    	extoMem.isBranch = 1;

        extoMem.result = dctoEx.pc+4;
Joseph Paturel's avatar
Joseph Paturel committed
251 252
        break;
    case RISCV_BR:
253
        extoMem.nextPC = extoMem.pc + imm13_signed;
PATUREL Joseph's avatar
PATUREL Joseph committed
254

Joseph Paturel's avatar
Joseph Paturel committed
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
        switch(dctoEx.funct3)
        {
        case RISCV_BR_BEQ:
            extoMem.isBranch = (dctoEx.lhs == dctoEx.rhs);
            break;
        case RISCV_BR_BNE:
            extoMem.isBranch = (dctoEx.lhs != dctoEx.rhs);
            break;
        case RISCV_BR_BLT:
            extoMem.isBranch = (dctoEx.lhs < dctoEx.rhs);
            break;
        case RISCV_BR_BGE:
            extoMem.isBranch = (dctoEx.lhs >= dctoEx.rhs);
            break;
        case RISCV_BR_BLTU:
            extoMem.isBranch = ((ac_int<32, false>)dctoEx.lhs < (ac_int<32, false>)dctoEx.rhs);
            break;
        case RISCV_BR_BGEU:
            extoMem.isBranch = ((ac_int<32, false>)dctoEx.lhs >= (ac_int<32, false>)dctoEx.rhs);
            break;
        }
        break;
    case RISCV_LD:
278
        extoMem.isLongInstruction = 1;
Joseph Paturel's avatar
Joseph Paturel committed
279 280 281
        extoMem.result = dctoEx.lhs + dctoEx.rhs;
        break;
    case RISCV_ST:
ROKICKI Simon's avatar
ROKICKI Simon committed
282
    	extoMem.datac = dctoEx.datac;
Joseph Paturel's avatar
Joseph Paturel committed
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
        extoMem.result = dctoEx.lhs + dctoEx.rhs;
        break;
    case RISCV_OPI:
        switch(dctoEx.funct3)
        {
        case RISCV_OPI_ADDI:
            extoMem.result = dctoEx.lhs + dctoEx.rhs;
            break;
        case RISCV_OPI_SLTI:
            extoMem.result = dctoEx.lhs < dctoEx.rhs;
            break;
        case RISCV_OPI_SLTIU:
            extoMem.result = (ac_int<32, false>)dctoEx.lhs < (ac_int<32, false>)dctoEx.rhs;
            break;
        case RISCV_OPI_XORI:
            extoMem.result = dctoEx.lhs ^ dctoEx.rhs;
            break;
        case RISCV_OPI_ORI:
            extoMem.result = dctoEx.lhs | dctoEx.rhs;
            break;
        case RISCV_OPI_ANDI:
            extoMem.result = dctoEx.lhs & dctoEx.rhs;
            break;
        case RISCV_OPI_SLLI: // cast rhs as 5 bits, otherwise generated hardware is 32 bits
            // & shift amount held in the lower 5 bits (riscv spec)
            extoMem.result = dctoEx.lhs << (ac_int<5, false>)dctoEx.rhs;
            break;
        case RISCV_OPI_SRI:
            if (dctoEx.funct7.slc<1>(5)) //SRAI
                extoMem.result = dctoEx.lhs >> (ac_int<5, false>)shamt;
            else //SRLI
                extoMem.result = (ac_int<32, false>)dctoEx.lhs >> (ac_int<5, false>)shamt;
            break;
        }
        break;
    case RISCV_OP:
319 320 321 322 323 324
        switch(dctoEx.funct3){
        case RISCV_OP_ADD:
            if (dctoEx.funct7.slc<1>(5))   // SUB
                extoMem.result = dctoEx.lhs - dctoEx.rhs;
            else   // ADD
                extoMem.result = dctoEx.lhs + dctoEx.rhs;
Joseph Paturel's avatar
Joseph Paturel committed
325
            break;
326 327
        case RISCV_OP_SLL:
            extoMem.result = dctoEx.lhs << (ac_int<5, false>)dctoEx.rhs;
Joseph Paturel's avatar
Joseph Paturel committed
328
            break;
329 330
        case RISCV_OP_SLT:
            extoMem.result = dctoEx.lhs < dctoEx.rhs;
Joseph Paturel's avatar
Joseph Paturel committed
331
            break;
332 333 334 335 336
        case RISCV_OP_SLTU:
            extoMem.result = (ac_int<32, false>)dctoEx.lhs < (ac_int<32, false>)dctoEx.rhs;
            break;
        case RISCV_OP_XOR:
            extoMem.result = dctoEx.lhs ^ dctoEx.rhs;
Joseph Paturel's avatar
Joseph Paturel committed
337
            break;
338 339 340 341 342
        case RISCV_OP_SR:
            if(dctoEx.funct7.slc<1>(5))   // SRA
                extoMem.result = dctoEx.lhs >> (ac_int<5, false>)dctoEx.rhs;
            else  // SRL
                extoMem.result = (ac_int<32, false>)dctoEx.lhs >> (ac_int<5, false>)dctoEx.rhs;
Joseph Paturel's avatar
Joseph Paturel committed
343
            break;
344 345
        case RISCV_OP_OR:
            extoMem.result = dctoEx.lhs | dctoEx.rhs;
Joseph Paturel's avatar
Joseph Paturel committed
346
            break;
347 348
        case RISCV_OP_AND:
            extoMem.result = dctoEx.lhs & dctoEx.rhs;
Joseph Paturel's avatar
Joseph Paturel committed
349 350
            break;
        }
351 352 353 354 355 356 357

        break;
    case RISCV_MISC_MEM:    // this does nothing because all memory accesses are ordered and we have only one core
        break;

    case RISCV_SYSTEM:
        //Nothing done here : CSR not handled in this branch
Joseph Paturel's avatar
Joseph Paturel committed
358 359
        break;
    }
360 361

    //If the instruction was dropped, we ensure that isBranch is at zero
ROKICKI Simon's avatar
ROKICKI Simon committed
362
    if (!dctoEx.we){
363
    	extoMem.isBranch = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
364 365
    	extoMem.useRd = 0;
    }
EGLOFF Valentin's avatar
EGLOFF Valentin committed
366 367
}

Joseph Paturel's avatar
Joseph Paturel committed
368
void memory(struct ExtoMem extoMem,
PATUREL Joseph's avatar
PATUREL Joseph committed
369
            struct MemtoWB &memtoWB)
EGLOFF Valentin's avatar
EGLOFF Valentin committed
370
{
EGLOFF Valentin's avatar
EGLOFF Valentin committed
371

372
    ac_int<2, false> datasize = extoMem.funct3.slc<2>(0);
373
    bool signenable = !extoMem.funct3.slc<1>(2);
374
    memtoWB.we = extoMem.we;
ROKICKI Simon's avatar
ROKICKI Simon committed
375
    memtoWB.useRd = extoMem.useRd;
ROKICKI Simon's avatar
ROKICKI Simon committed
376 377
    memtoWB.result = extoMem.result;
    memtoWB.rd = extoMem.rd;
378 379 380

    ac_int<32, false> mem_read;

Joseph Paturel's avatar
Joseph Paturel committed
381 382 383 384
    switch(extoMem.opCode)
    {
    case RISCV_LD:
        memtoWB.rd = extoMem.rd;
PATUREL Joseph's avatar
PATUREL Joseph committed
385

386 387
       	memtoWB.address = extoMem.result;
        memtoWB.isLoad = 1;
388
    //    formatread(extoMem.result, datasize, signenable, mem_read); //TODO
Joseph Paturel's avatar
Joseph Paturel committed
389 390
        break;
    case RISCV_ST:
ROKICKI Simon's avatar
ROKICKI Simon committed
391
//        mem_read = dataMemory[extoMem.result >> 2];
392
       // if(extoMem.we) //TODO0: We do not handle non 32bit writes
ROKICKI Simon's avatar
ROKICKI Simon committed
393
//        	dataMemory[extoMem.result >> 2] = extoMem.datac;
ROKICKI Simon's avatar
ROKICKI Simon committed
394 395 396 397 398
        	memtoWB.isStore = 1;
        	memtoWB.address = extoMem.result;
        	memtoWB.valueToWrite = extoMem.datac;
        	memtoWB.byteEnable = 0xf;

Joseph Paturel's avatar
Joseph Paturel committed
399
        break;
EGLOFF Valentin's avatar
EGLOFF Valentin committed
400 401 402
    }
}

403 404

void writeback(struct MemtoWB memtoWB,
405
				struct WBOut &wbOut)
EGLOFF Valentin's avatar
EGLOFF Valentin committed
406
{
simon rokicki's avatar
simon rokicki committed
407
	wbOut.we = memtoWB.we;
ROKICKI Simon's avatar
ROKICKI Simon committed
408
    if((memtoWB.rd != 0) && (memtoWB.we) && memtoWB.useRd){
409 410
      wbOut.rd = memtoWB.rd;
      wbOut.value = memtoWB.result;
ROKICKI Simon's avatar
ROKICKI Simon committed
411 412
    	wbOut.useRd = 1;
    }
EGLOFF Valentin's avatar
EGLOFF Valentin committed
413 414
}

415 416
void branchUnit(ac_int<32, false> nextPC_fetch,
		ac_int<32, false> nextPC_decode,
417
		bool isBranch_decode,
418
		ac_int<32, false> nextPC_execute,
419
		bool isBranch_execute,
420
		ac_int<32, false> &pc,
421
		bool &we_fetch,
422
		bool &we_decode,
ROKICKI Simon's avatar
ROKICKI Simon committed
423
		bool stall_fetch){
424

ROKICKI Simon's avatar
ROKICKI Simon committed
425 426 427 428 429 430 431 432 433 434 435 436 437
	if (!stall_fetch){
		if (isBranch_execute){
			we_fetch = 0;
			we_decode = 0;
			pc = nextPC_execute;
		}
		else if (isBranch_decode){
			we_fetch = 0;
			pc = nextPC_decode;
		}
		else {
			pc = nextPC_fetch;
		}
438
	}
439

440 441
}

ROKICKI Simon's avatar
ROKICKI Simon committed
442 443
void forwardUnit(
		ac_int<5, false> decodeRs1,
444
		bool decodeUseRs1,
ROKICKI Simon's avatar
ROKICKI Simon committed
445
		ac_int<5, false> decodeRs2,
446
		bool decodeUseRs2,
ROKICKI Simon's avatar
ROKICKI Simon committed
447
		ac_int<5, false> decodeRs3,
448
		bool decodeUseRs3,
ROKICKI Simon's avatar
ROKICKI Simon committed
449 450

		ac_int<5, false> executeRd,
451 452
		bool executeUseRd,
		bool executeIsLongComputation,
ROKICKI Simon's avatar
ROKICKI Simon committed
453 454

		ac_int<5, false> memoryRd,
455
		bool memoryUseRd,
ROKICKI Simon's avatar
ROKICKI Simon committed
456 457

		ac_int<5, false> writebackRd,
458
		bool writebackUseRd,
459

460
		bool stall[5],
simon rokicki's avatar
simon rokicki committed
461
		struct ForwardReg &forwardRegisters){
462 463

	if (decodeUseRs1){
ROKICKI Simon's avatar
ROKICKI Simon committed
464
		if (executeUseRd && decodeRs1 == executeRd){
ROKICKI Simon's avatar
ROKICKI Simon committed
465 466 467
			if (executeIsLongComputation){
				stall[0] = 1;
				stall[1] = 1;
468 469
			}
			else {
ROKICKI Simon's avatar
ROKICKI Simon committed
470
				forwardRegisters.forwardExtoVal1 = 1;
471 472
			}
		}
ROKICKI Simon's avatar
ROKICKI Simon committed
473
		else if (memoryUseRd && decodeRs1 == memoryRd){
ROKICKI Simon's avatar
ROKICKI Simon committed
474
			forwardRegisters.forwardMemtoVal1 = 1;
ROKICKI Simon's avatar
ROKICKI Simon committed
475 476
		}
		else if (writebackUseRd && decodeRs1 == writebackRd){
ROKICKI Simon's avatar
ROKICKI Simon committed
477
			forwardRegisters.forwardWBtoVal1 = 1;
ROKICKI Simon's avatar
ROKICKI Simon committed
478 479

		}
480 481 482
	}

	if (decodeUseRs2){
ROKICKI Simon's avatar
ROKICKI Simon committed
483
		if (executeUseRd && decodeRs2 == executeRd){
ROKICKI Simon's avatar
ROKICKI Simon committed
484 485 486
			if (executeIsLongComputation){
				stall[0] = 1;
				stall[1] = 1;
487 488
			}
			else {
ROKICKI Simon's avatar
ROKICKI Simon committed
489
				forwardRegisters.forwardExtoVal2 = 1;
490 491
			}
		}
ROKICKI Simon's avatar
ROKICKI Simon committed
492 493 494 495 496
		else if (memoryUseRd && decodeRs2 == memoryRd)
			forwardRegisters.forwardMemtoVal2 = 1;
		else if (writebackUseRd && decodeRs2 == writebackRd)
			forwardRegisters.forwardWBtoVal2 = 1;

497 498
	}

ROKICKI Simon's avatar
ROKICKI Simon committed
499
	if (decodeUseRs3){
ROKICKI Simon's avatar
ROKICKI Simon committed
500
		if (executeUseRd && decodeRs3 == executeRd){
ROKICKI Simon's avatar
ROKICKI Simon committed
501 502 503 504 505 506 507 508
			if (executeIsLongComputation){
				stall[0] = 1;
				stall[1] = 1;
			}
			else {
				forwardRegisters.forwardExtoVal3 = 1;
			}
		}
ROKICKI Simon's avatar
ROKICKI Simon committed
509 510 511 512 513
		else if (memoryUseRd && decodeRs3 == memoryRd)
			forwardRegisters.forwardMemtoVal3 = 1;
		else
			if (writebackUseRd && decodeRs3 == writebackRd)
				forwardRegisters.forwardWBtoVal3 = 1;
ROKICKI Simon's avatar
ROKICKI Simon committed
514
	}
515 516
}

517
/****************************************************************
518
 *  Copy functions
519 520
 ****************************************************************

521
void copyFtoDC(struct FtoDC &dest, struct FtoDC src){
PATUREL Joseph's avatar
PATUREL Joseph committed
522 523 524
    dest.pc = src.pc;
    dest.instruction = src.instruction;
    dest.nextPCFetch = src.nextPCFetch;
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
    dest.we = src.we;
}

void copyDCtoEx(struct DCtoEx &dest, struct DCtoEx src){
    dest.pc = src.pc;       // used for branch
    dest.instruction = src.instruction;

    dest.opCode = src.opCode;    // opCode = instruction[6:0]
    dest.funct7 = src.funct7;    // funct7 = instruction[31:25]
    dest.funct3 = src.funct3;    // funct3 = instruction[14:12]

    dest.lhs = src.lhs;   //  left hand side : operand 1
    dest.rhs = src.rhs;   // right hand side : operand 2
    dest.datac = src.datac; // ST, BR, JAL/R,

    //For branch unit
    dest.nextPCDC = src.nextPCDC;
    dest.isBranch = src.isBranch;

    //Information for forward/stall unit
    dest.useRs1 = src.useRs1;
    dest.useRs2 = src.useRs2;
ROKICKI Simon's avatar
ROKICKI Simon committed
547
    dest.useRs3 = src.useRs3;
548 549 550
    dest.useRd = src.useRd;
    dest.rs1 = src.rs1;       // rs1    = instruction[19:15]
    dest.rs2 = src.rs2;       // rs2    = instruction[24:20]
ROKICKI Simon's avatar
ROKICKI Simon committed
551
    dest.rs3 = src.rs3;
552 553 554 555 556 557 558 559 560 561 562 563
    dest.rd = src.rd;        // rd     = instruction[11:7]

    //Register for all stages
    dest.we = src.we;
}

void copyExtoMem(struct ExtoMem &dest, struct ExtoMem src){
    dest.pc = src.pc;
    dest.instruction = src.instruction;

    dest.result = src.result;    // result of the EX stage
    dest.rd = src.rd;        // destination register
ROKICKI Simon's avatar
ROKICKI Simon committed
564 565
    dest.useRd = src.useRd;
    dest.isLongInstruction = src.isLongInstruction;
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    dest.opCode = src.opCode;    // LD or ST (can be reduced to 2 bits)
    dest.funct3 = src.funct3;    // datasize and sign extension bit

    dest.datac = src.datac;     // data to be stored in memory or csr result

    //For branch unit
    dest.nextPC = src.nextPC;
    dest.isBranch = src.isBranch;

    //Register for all stages
    dest.we = src.we;
}

void copyMemtoWB(struct MemtoWB &dest, struct MemtoWB src){
    dest.result = src.result;    // Result to be written back
    dest.rd = src.rd;        // destination register
ROKICKI Simon's avatar
ROKICKI Simon committed
582 583 584 585 586 587
    dest.useRd = src.useRd;

    dest.address = src.address;
    dest.valueToWrite = src.valueToWrite;
    dest.byteEnable = src.byteEnable;
    dest.isStore = src.isStore;
588
    dest.isLoad = src.isLoad;
589 590 591 592

    //Register for all stages
    dest.we = src.we;
}
593
*/
594

Joseph Paturel's avatar
Joseph Paturel committed
595

simon rokicki's avatar
simon rokicki committed
596

597

598

599
void doCycle(struct Core &core, 		 //Core containing all values
600
		bool globalStall)
601
{
PATUREL Joseph's avatar
PATUREL Joseph committed
602
    core.stallSignals[0] = 0; core.stallSignals[1] = 0; core.stallSignals[2] = 0; core.stallSignals[3] = 0; core.stallSignals[4] = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
603
    core.stallIm = false; core.stallDm = false;
PATUREL Joseph's avatar
PATUREL Joseph committed
604

Joseph Paturel's avatar
Joseph Paturel committed
605
    //declare temporary structs
PATUREL Joseph's avatar
PATUREL Joseph committed
606 607 608 609
    struct FtoDC ftoDC_temp; ftoDC_temp.pc = 0; ftoDC_temp.instruction = 0; ftoDC_temp.nextPCFetch = 0; ftoDC_temp.we = 0;
    struct DCtoEx dctoEx_temp; dctoEx_temp.isBranch = 0; dctoEx_temp.useRs1 = 0; dctoEx_temp.useRs2 = 0; dctoEx_temp.useRs3 = 0; dctoEx_temp.useRd = 0; dctoEx_temp.we = 0;
    struct ExtoMem extoMem_temp; extoMem_temp.useRd = 0; extoMem_temp.isBranch = 0; extoMem_temp.we = 0;
    struct MemtoWB memtoWB_temp; memtoWB_temp.useRd = 0; memtoWB_temp.isStore = 0; memtoWB_temp.we = 0; memtoWB_temp.isLoad = 0;
610
    struct WBOut wbOut_temp; wbOut_temp.useRd = 0; wbOut_temp.we = 0; wbOut_temp.rd = 0;
simon rokicki's avatar
simon rokicki committed
611
    struct ForwardReg forwardRegisters; forwardRegisters.forwardExtoVal1 = 0; forwardRegisters.forwardExtoVal2 = 0; forwardRegisters.forwardExtoVal3 = 0; forwardRegisters.forwardMemtoVal1 = 0; forwardRegisters.forwardMemtoVal2 = 0; forwardRegisters.forwardMemtoVal3 = 0; forwardRegisters.forwardWBtoVal1 = 0; forwardRegisters.forwardWBtoVal2 = 0; forwardRegisters.forwardWBtoVal3 = 0;
ROKICKI Simon's avatar
ROKICKI Simon committed
612

ROKICKI Simon's avatar
ROKICKI Simon committed
613 614


Joseph Paturel's avatar
Joseph Paturel committed
615
    //declare temporary register file
PATUREL Joseph's avatar
PATUREL Joseph committed
616
    ac_int<32, false> nextInst;
ROKICKI Simon's avatar
ROKICKI Simon committed
617 618 619 620

    if (!globalStall && !core.stallDm)
    	core.im->process(core.pc, WORD, LOAD, 0, nextInst, core.stallIm);

PATUREL Joseph's avatar
PATUREL Joseph committed
621
    fetch(core.pc, ftoDC_temp, nextInst);
622
    decode(core.ftoDC, dctoEx_temp, core.regFile);
Joseph Paturel's avatar
Joseph Paturel committed
623
    execute(core.dctoEx, extoMem_temp);
PATUREL Joseph's avatar
PATUREL Joseph committed
624
    memory(core.extoMem, memtoWB_temp);
ROKICKI Simon's avatar
ROKICKI Simon committed
625
    writeback(core.memtoWB, wbOut_temp);
Joseph Paturel's avatar
Joseph Paturel committed
626

ROKICKI Simon's avatar
ROKICKI Simon committed
627

628
    //resolve stalls, forwards
ROKICKI Simon's avatar
ROKICKI Simon committed
629 630 631 632 633 634
    forwardUnit(dctoEx_temp.rs1, dctoEx_temp.useRs1,
    		dctoEx_temp.rs2, dctoEx_temp.useRs2,
			dctoEx_temp.rs3, dctoEx_temp.useRs3,
			extoMem_temp.rd, extoMem_temp.useRd, extoMem_temp.isLongInstruction,
			memtoWB_temp.rd, memtoWB_temp.useRd,
    		wbOut_temp.rd, wbOut_temp.useRd,
PATUREL Joseph's avatar
PATUREL Joseph committed
635
			core.stallSignals, forwardRegisters);
Joseph Paturel's avatar
Joseph Paturel committed
636

637
    if (!core.stallSignals[STALL_MEMORY] && !globalStall && memtoWB_temp.we && !core.stallIm){
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661

       memMask mask;
       //TODO: carry the data size to memToWb
       switch (core.extoMem.funct3) {
         case 0:
          mask = BYTE;
          break;
         case 1:
          mask = HALF;
          break;
        case 2:
          mask = WORD;
          break;
        case 4:
          mask = BYTE_U;
          break;
        case 5:
          mask = HALF_U;
          break;
        //Should NEVER happen
        default:
          mask = WORD;
          break;
       }
ROKICKI Simon's avatar
ROKICKI Simon committed
662
       core.dm->process(memtoWB_temp.address, mask, memtoWB_temp.isLoad ? LOAD : (memtoWB_temp.isStore ? STORE : NONE), memtoWB_temp.valueToWrite, memtoWB_temp.result, core.stallDm);
663
    }
Joseph Paturel's avatar
Joseph Paturel committed
664
    //commit the changes to the pipeline register
665
    if (!core.stallSignals[STALL_FETCH] && !globalStall && !core.stallIm && !core.stallDm){
666 667
    	//copyFtoDC(core.ftoDC, ftoDC_temp);
        core.ftoDC = ftoDC_temp;
ROKICKI Simon's avatar
ROKICKI Simon committed
668
    }
669

670
    if (!core.stallSignals[STALL_DECODE] && !globalStall && !core.stallIm && !core.stallDm){
671 672
    	//copyDCtoEx(core.dctoEx, dctoEx_temp);
        core.dctoEx = dctoEx_temp;
673

674 675
    	if (forwardRegisters.forwardExtoVal1 && extoMem_temp.we)
      	  core.dctoEx.lhs = extoMem_temp.result;
ROKICKI Simon's avatar
ROKICKI Simon committed
676 677 678 679 680
    	else if (forwardRegisters.forwardMemtoVal1 && memtoWB_temp.we)
    		core.dctoEx.lhs = memtoWB_temp.result;
    	else if (forwardRegisters.forwardWBtoVal1 && wbOut_temp.we)
    		core.dctoEx.lhs = wbOut_temp.value;

681
    	if (forwardRegisters.forwardExtoVal2 && extoMem_temp.we)
ROKICKI Simon's avatar
ROKICKI Simon committed
682 683 684 685 686 687 688 689 690 691 692 693 694 695
    		core.dctoEx.rhs = extoMem_temp.result;
    	else if (forwardRegisters.forwardMemtoVal2 && memtoWB_temp.we)
    		core.dctoEx.rhs = memtoWB_temp.result;
    	else if (forwardRegisters.forwardWBtoVal2 && wbOut_temp.we)
    		core.dctoEx.rhs = wbOut_temp.value;

    	if (forwardRegisters.forwardExtoVal3 && extoMem_temp.we)
    		core.dctoEx.datac = extoMem_temp.result;
    	else if (forwardRegisters.forwardMemtoVal3 && memtoWB_temp.we)
    		core.dctoEx.datac = memtoWB_temp.result;
    	else if (forwardRegisters.forwardWBtoVal3 && wbOut_temp.we)
    		core.dctoEx.datac = wbOut_temp.value;
    }

696
    if (core.stallSignals[STALL_DECODE] && !core.stallSignals[STALL_EXECUTE] && !core.stallIm && !core.stallDm){
ROKICKI Simon's avatar
ROKICKI Simon committed
697 698 699
    	core.dctoEx.we = 0; core.dctoEx.useRd = 0; core.dctoEx.isBranch = 0; core.dctoEx.instruction = 0; core.dctoEx.pc = 0;
    }

700
    if (!core.stallSignals[STALL_EXECUTE] && !globalStall && !core.stallIm && !core.stallDm){
701 702
    	//copyExtoMem(core.extoMem, extoMem_temp);
        core.extoMem = extoMem_temp;
ROKICKI Simon's avatar
ROKICKI Simon committed
703
    }
704

705
    if (!core.stallSignals[STALL_MEMORY] && !globalStall && !core.stallIm && !core.stallDm){
706 707
    	//copyMemtoWB(core.memtoWB, memtoWB_temp);
        core.memtoWB = memtoWB_temp;
ROKICKI Simon's avatar
ROKICKI Simon committed
708 709
    }

ROKICKI Simon's avatar
ROKICKI Simon committed
710
    if (wbOut_temp.we && wbOut_temp.useRd && !globalStall && !core.stallIm && !core.stallDm){
711
    	core.regFile[wbOut_temp.rd] = wbOut_temp.value;
ROKICKI Simon's avatar
ROKICKI Simon committed
712
    	 core.cycle++;
ROKICKI Simon's avatar
ROKICKI Simon committed
713 714
    }

ROKICKI Simon's avatar
ROKICKI Simon committed
715

716
	branchUnit(ftoDC_temp.nextPCFetch, dctoEx_temp.nextPCDC, dctoEx_temp.isBranch, extoMem_temp.nextPC, extoMem_temp.isBranch, core.pc, core.ftoDC.we, core.dctoEx.we, core.stallSignals[STALL_FETCH] || core.stallIm || core.stallDm || globalStall);
717

EGLOFF Valentin's avatar
EGLOFF Valentin committed
718
}
719

720 721
//void doCore(IncompleteMemory im, IncompleteMemory dm, bool globalStall)
void doCore(bool globalStall, ac_int<32, false> imData[DRAM_SIZE>>2], ac_int<32, false> dmData[DRAM_SIZE>>2])
722 723
{
    Core core;
ROKICKI Simon's avatar
ROKICKI Simon committed
724 725 726 727 728
    IncompleteMemory imInterface = IncompleteMemory(imData);
    IncompleteMemory dmInterface = IncompleteMemory(dmData);

    core.im = &imInterface;
    core.dm = &dmInterface;
729 730 731
    core.pc = 0;

    while(1) {
PATUREL Joseph's avatar
PATUREL Joseph committed
732
        doCycle(core, globalStall);
733 734
    }
}