├── docs ├── MIPS_ISA.png └── MIPS_diagram.png ├── modules ├── adder.v ├── signExtend.v ├── pipeStages │ ├── WBStage.v │ ├── MEMStage.v │ ├── IFStage.v │ ├── EXEStage.v │ └── IDStage.v ├── register.v ├── controlUnit │ ├── conditionChecker.v │ └── controller.v ├── mux.v ├── pipeRegisters │ ├── IF2ID.v │ ├── MEM2WB.v │ ├── EXE2MEM.v │ └── ID2EXE.v ├── memoryModules │ ├── regFile.v │ ├── dataMem.v │ └── instructionMem.v ├── ALU.v └── hazard_forwarding │ ├── hazardDetection.v │ └── forwarding.v ├── .gitignore ├── testbench.v ├── alteraDE2SimulationFiles ├── 7segConv.v └── DE2_TOP.V ├── defines.v ├── instructions ├── rearrange_instructions.py └── example_source_code.txt ├── README.md └── topLevelCircuit.v /docs/MIPS_ISA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhyousefi/MIPS-pipeline-processor/HEAD/docs/MIPS_ISA.png -------------------------------------------------------------------------------- /docs/MIPS_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mhyousefi/MIPS-pipeline-processor/HEAD/docs/MIPS_diagram.png -------------------------------------------------------------------------------- /modules/adder.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module adder (in1, in2, out); 4 | input [`WORD_LEN-1:0] in1, in2; 5 | output [`WORD_LEN-1:0] out; 6 | 7 | assign out = in1 + in2; 8 | endmodule // adder 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.csv 2 | *.mpf 3 | *.qpf 4 | *.qsf 5 | *.v.bak 6 | *.wlf 7 | *.cr.mti 8 | .DS_Store 9 | 10 | configs/ 11 | db/ 12 | incremental_db/ 13 | output_files/ 14 | simulation/ 15 | work/ 16 | instructions/ready_instructions.txt 17 | -------------------------------------------------------------------------------- /modules/signExtend.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module signExtend (in, out); 4 | input [15:0] in; 5 | output [`WORD_LEN-1:0] out; 6 | 7 | assign out = (in[15] == 1) ? {16'b1111111111111111, in} : {16'b0000000000000000, in}; 8 | endmodule // signExtend 9 | -------------------------------------------------------------------------------- /modules/pipeStages/WBStage.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module WBStage (MEM_R_EN, memData, aluRes, WB_res); 4 | input MEM_R_EN; 5 | input [`WORD_LEN-1:0] memData, aluRes; 6 | output [`WORD_LEN-1:0] WB_res; 7 | 8 | assign WB_res = (MEM_R_EN) ? memData : aluRes; 9 | endmodule // WBStage 10 | -------------------------------------------------------------------------------- /modules/register.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module register (clk, rst, writeEn, regIn, regOut); 4 | input clk, rst, writeEn; 5 | input [`WORD_LEN-1:0] regIn; 6 | output reg [`WORD_LEN-1:0] regOut; 7 | 8 | always @ (posedge clk) begin 9 | if (rst == 1) regOut <= 0; 10 | else if (writeEn) regOut <= regIn; 11 | end 12 | endmodule // register 13 | -------------------------------------------------------------------------------- /testbench.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ns 2 | 3 | module testbench (); 4 | reg clk,rst, forwarding_EN; 5 | MIPS_Processor top_module (clk, rst, forwarding_EN); 6 | 7 | initial begin 8 | clk=1; 9 | repeat(5000) #50 clk=~clk ; 10 | end 11 | 12 | initial begin 13 | rst = 1; 14 | forwarding_EN = 0; 15 | #100 16 | rst = 0; 17 | end 18 | endmodule // test 19 | -------------------------------------------------------------------------------- /modules/pipeStages/MEMStage.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module MEMStage (clk, rst, MEM_R_EN, MEM_W_EN, ALU_res, ST_value, dataMem_out); 4 | input clk, rst, MEM_R_EN, MEM_W_EN; 5 | input [`WORD_LEN-1:0] ALU_res, ST_value; 6 | output [`WORD_LEN-1:0] dataMem_out; 7 | 8 | dataMem dataMem ( 9 | .clk(clk), 10 | .rst(rst), 11 | .writeEn(MEM_W_EN), 12 | .readEn(MEM_R_EN), 13 | .address(ALU_res), 14 | .dataIn(ST_value), 15 | .dataOut(dataMem_out) 16 | ); 17 | endmodule // MEMStage 18 | -------------------------------------------------------------------------------- /modules/controlUnit/conditionChecker.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module conditionChecker (reg1, reg2, cuBranchComm, brCond); 4 | input [`WORD_LEN-1: 0] reg1, reg2; 5 | input [1:0] cuBranchComm; 6 | output reg brCond; 7 | 8 | always @ ( * ) begin 9 | case (cuBranchComm) 10 | `COND_JUMP: brCond <= 1; 11 | `COND_BEZ: brCond <= (reg1 == 0) ? 1 : 0; 12 | `COND_BNE: brCond <= (reg1 != reg2) ? 1 : 0; 13 | default: brCond <= 0; 14 | endcase 15 | end 16 | endmodule // conditionChecker 17 | -------------------------------------------------------------------------------- /modules/mux.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module mux #(parameter integer LENGTH) (in1, in2, sel, out); 4 | input sel; 5 | input [LENGTH-1:0] in1, in2; 6 | output [LENGTH-1:0] out; 7 | 8 | assign out = (sel == 0) ? in1 : in2; 9 | endmodule // mxu 10 | 11 | module mux_3input #(parameter integer LENGTH) (in1, in2, in3, sel, out); 12 | input [LENGTH-1:0] in1, in2, in3; 13 | input [1:0] sel; 14 | output [LENGTH-1:0] out; 15 | 16 | assign out = (sel == 2'd0) ? in1 : 17 | (sel == 2'd1) ? in2 : in3; 18 | endmodule // mux 19 | -------------------------------------------------------------------------------- /modules/pipeRegisters/IF2ID.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module IF2ID (clk, rst, flush, freeze, PCIn, instructionIn, PC, instruction); 4 | input clk, rst, flush, freeze; 5 | input [`WORD_LEN-1:0] PCIn, instructionIn; 6 | output reg [`WORD_LEN-1:0] PC, instruction; 7 | 8 | always @ (posedge clk) begin 9 | if (rst) begin 10 | PC <= 0; 11 | instruction <= 0; 12 | end 13 | else begin 14 | if (~freeze) begin 15 | if (flush) begin 16 | instruction <= 0; 17 | PC <= 0; 18 | end 19 | else begin 20 | instruction <= instructionIn; 21 | PC <= PCIn; 22 | end 23 | end 24 | end 25 | end 26 | endmodule // IF2ID 27 | -------------------------------------------------------------------------------- /modules/memoryModules/regFile.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module regFile (clk, rst, src1, src2, dest, writeVal, writeEn, reg1, reg2); 4 | input clk, rst, writeEn; 5 | input [`REG_FILE_ADDR_LEN-1:0] src1, src2, dest; 6 | input [`WORD_LEN-1:0] writeVal; 7 | output [`WORD_LEN-1:0] reg1, reg2; 8 | 9 | reg [`WORD_LEN-1:0] regMem [0:`REG_FILE_SIZE-1]; 10 | integer i; 11 | 12 | always @ (negedge clk) begin 13 | if (rst) begin 14 | for (i = 0; i < `WORD_LEN; i = i + 1) 15 | regMem[i] <= 0; 16 | end 17 | 18 | else if (writeEn) regMem[dest] <= writeVal; 19 | regMem[0] <= 0; 20 | end 21 | 22 | assign reg1 = (regMem[src1]); 23 | assign reg2 = (regMem[src2]); 24 | endmodule // regFile 25 | -------------------------------------------------------------------------------- /modules/ALU.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module ALU (val1, val2, EXE_CMD, aluOut); 4 | input [`WORD_LEN-1:0] val1, val2; 5 | input [`EXE_CMD_LEN-1:0] EXE_CMD; 6 | output reg [`WORD_LEN-1:0] aluOut; 7 | 8 | always @ ( * ) begin 9 | case (EXE_CMD) 10 | `EXE_ADD: aluOut <= val1 + val2; 11 | `EXE_SUB: aluOut <= val1 - val2; 12 | `EXE_AND: aluOut <= val1 & val2; 13 | `EXE_OR: aluOut <= val1 | val2; 14 | `EXE_NOR: aluOut <= ~(val1 | val2); 15 | `EXE_XOR: aluOut <= val1 ^ val2; 16 | `EXE_SLA: aluOut <= val1 << val2; 17 | `EXE_SLL: aluOut <= val1 <<< val2; 18 | `EXE_SRA: aluOut <= val1 >> val2; 19 | `EXE_SRL: aluOut <= val1 >>> val2; 20 | default: aluOut <= 0; 21 | endcase 22 | end 23 | endmodule // ALU 24 | -------------------------------------------------------------------------------- /modules/pipeStages/IFStage.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module IFStage (clk, rst, brTaken, brOffset, freeze, PC, instruction); 4 | input clk, rst, brTaken, freeze; 5 | input [`WORD_LEN-1:0] brOffset; 6 | output [`WORD_LEN-1:0] PC, instruction; 7 | 8 | wire [`WORD_LEN-1:0] adderIn1, adderOut, brOffserTimes4; 9 | 10 | mux #(.LENGTH(`WORD_LEN)) adderInput ( 11 | .in1(32'd4), 12 | .in2(brOffserTimes4), 13 | .sel(brTaken), 14 | .out(adderIn1) 15 | ); 16 | 17 | adder add4 ( 18 | .in1(adderIn1), 19 | .in2(PC), 20 | .out(adderOut) 21 | ); 22 | 23 | register PCReg ( 24 | .clk(clk), 25 | .rst(rst), 26 | .writeEn(~freeze), 27 | .regIn(adderOut), 28 | .regOut(PC) 29 | ); 30 | 31 | instructionMem instructions ( 32 | .rst(rst), 33 | .addr(PC), 34 | .instruction(instruction) 35 | ); 36 | 37 | assign brOffserTimes4 = brOffset << 2; 38 | endmodule // IFStage 39 | -------------------------------------------------------------------------------- /modules/memoryModules/dataMem.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module dataMem (clk, rst, writeEn, readEn, address, dataIn, dataOut); 4 | input clk, rst, readEn, writeEn; 5 | input [`WORD_LEN-1:0] address, dataIn; 6 | output [`WORD_LEN-1:0] dataOut; 7 | 8 | integer i; 9 | reg [`MEM_CELL_SIZE-1:0] dataMem [0:`DATA_MEM_SIZE-1]; 10 | wire [`WORD_LEN-1:0] base_address; 11 | 12 | always @ (posedge clk) begin 13 | if (rst) 14 | for (i = 0; i < `DATA_MEM_SIZE; i = i + 1) 15 | dataMem[i] <= 0; 16 | else if (writeEn) 17 | {dataMem[base_address], dataMem[base_address + 1], dataMem[base_address + 2], dataMem[base_address + 3]} <= dataIn; 18 | end 19 | 20 | assign base_address = ((address & 32'b11111111111111111111101111111111) >> 2) << 2; 21 | assign dataOut = (address < 1024) ? 0 : {dataMem[base_address], dataMem[base_address + 1], dataMem[base_address + 2], dataMem[base_address + 3]}; 22 | endmodule // dataMem 23 | -------------------------------------------------------------------------------- /modules/pipeRegisters/MEM2WB.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module MEM2WB (clk, rst, WB_EN_IN, MEM_R_EN_IN, ALUResIn, memReadValIn, destIn, 4 | WB_EN, MEM_R_EN, ALURes, memReadVal, dest); 5 | input clk, rst; 6 | // TO BE REGISTERED FOR ID STAGE 7 | input WB_EN_IN, MEM_R_EN_IN; 8 | input [`REG_FILE_ADDR_LEN-1:0] destIn; 9 | input [`WORD_LEN-1:0] ALUResIn, memReadValIn; 10 | // REGISTERED VALUES FOR ID STAGE 11 | output reg WB_EN, MEM_R_EN; 12 | output reg [`REG_FILE_ADDR_LEN-1:0] dest; 13 | output reg [`WORD_LEN-1:0] ALURes, memReadVal; 14 | 15 | always @ (posedge clk) begin 16 | if (rst) begin 17 | {WB_EN, MEM_R_EN, dest, ALURes, memReadVal} <= 0; 18 | end 19 | else begin 20 | WB_EN <= WB_EN_IN; 21 | MEM_R_EN <= MEM_R_EN_IN; 22 | dest <= destIn; 23 | ALURes <= ALUResIn; 24 | memReadVal <= memReadValIn; 25 | end 26 | end 27 | endmodule // MEM2WB 28 | -------------------------------------------------------------------------------- /modules/pipeRegisters/EXE2MEM.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module EXE2MEM (clk, rst, WB_EN_IN, MEM_R_EN_IN, MEM_W_EN_IN, PCIn, ALUResIn, STValIn, destIn, 4 | WB_EN, MEM_R_EN, MEM_W_EN, PC, ALURes, STVal, dest); 5 | input clk, rst; 6 | // TO BE REGISTERED FOR ID STAGE 7 | input WB_EN_IN, MEM_R_EN_IN, MEM_W_EN_IN; 8 | input [`REG_FILE_ADDR_LEN-1:0] destIn; 9 | input [`WORD_LEN-1:0] PCIn, ALUResIn, STValIn; 10 | // REGISTERED VALUES FOR ID STAGE 11 | output reg WB_EN, MEM_R_EN, MEM_W_EN; 12 | output reg [`REG_FILE_ADDR_LEN-1:0] dest; 13 | output reg [`WORD_LEN-1:0] PC, ALURes, STVal; 14 | 15 | always @ (posedge clk) begin 16 | if (rst) begin 17 | {WB_EN, MEM_R_EN, MEM_W_EN, PC, ALURes, STVal, dest} <= 0; 18 | end 19 | else begin 20 | WB_EN <= WB_EN_IN; 21 | MEM_R_EN <= MEM_R_EN_IN; 22 | MEM_W_EN <= MEM_W_EN_IN; 23 | PC <= PCIn; 24 | ALURes <= ALUResIn; 25 | STVal <= STValIn; 26 | dest <= destIn; 27 | end 28 | end 29 | endmodule // EXE2MEM 30 | -------------------------------------------------------------------------------- /modules/hazard_forwarding/hazardDetection.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module hazard_detection(forward_EN, is_imm, ST_or_BNE, src1_ID, src2_ID, dest_EXE, WB_EN_EXE, dest_MEM, WB_EN_MEM, MEM_R_EN_EXE, branch_comm, hazard_detected); 4 | input [`REG_FILE_ADDR_LEN-1:0] src1_ID, src2_ID; 5 | input [`REG_FILE_ADDR_LEN-1:0] dest_EXE, dest_MEM; 6 | input [1:0] branch_comm; 7 | input forward_EN, WB_EN_EXE, WB_EN_MEM, is_imm, ST_or_BNE, MEM_R_EN_EXE; 8 | output hazard_detected; 9 | 10 | wire src2_is_valid, exe_has_hazard, mem_has_hazard, hazard, instr_is_branch; 11 | 12 | assign src2_is_valid = (~is_imm) || ST_or_BNE; 13 | 14 | assign exe_has_hazard = WB_EN_EXE && (src1_ID == dest_EXE || (src2_is_valid && src2_ID == dest_EXE)); 15 | assign mem_has_hazard = WB_EN_MEM && (src1_ID == dest_MEM || (src2_is_valid && src2_ID == dest_MEM)); 16 | 17 | assign hazard = (exe_has_hazard || mem_has_hazard); 18 | assign instr_is_branch = (branch_comm == `COND_BEZ || branch_comm == `COND_BNE); 19 | 20 | assign hazard_detected = ~forward_EN ? hazard : (instr_is_branch && hazard) || (MEM_R_EN_EXE && mem_has_hazard); 21 | endmodule // hazard_detection 22 | -------------------------------------------------------------------------------- /modules/pipeStages/EXEStage.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module EXEStage (clk, EXE_CMD, val1_sel, val2_sel, ST_val_sel, val1, val2, ALU_res_MEM, result_WB, ST_value_in, ALUResult, ST_value_out); 4 | input clk; 5 | input [`FORW_SEL_LEN-1:0] val1_sel, val2_sel, ST_val_sel; 6 | input [`EXE_CMD_LEN-1:0] EXE_CMD; 7 | input [`WORD_LEN-1:0] val1, val2, ALU_res_MEM, result_WB, ST_value_in; 8 | output [`WORD_LEN-1:0] ALUResult, ST_value_out; 9 | 10 | wire [`WORD_LEN-1:0] ALU_val1, ALU_val2; 11 | 12 | mux_3input #(.LENGTH(`WORD_LEN)) mux_val1 ( 13 | .in1(val1), 14 | .in2(ALU_res_MEM), 15 | .in3(result_WB), 16 | .sel(val1_sel), 17 | .out(ALU_val1) 18 | ); 19 | 20 | mux_3input #(.LENGTH(`WORD_LEN)) mux_val2 ( 21 | .in1(val2), 22 | .in2(ALU_res_MEM), 23 | .in3(result_WB), 24 | .sel(val2_sel), 25 | .out(ALU_val2) 26 | ); 27 | 28 | mux_3input #(.LENGTH(`WORD_LEN)) mux_ST_value ( 29 | .in1(ST_value_in), 30 | .in2(ALU_res_MEM), 31 | .in3(result_WB), 32 | .sel(ST_val_sel), 33 | .out(ST_value_out) 34 | ); 35 | 36 | ALU ALU( 37 | .val1(ALU_val1), 38 | .val2(ALU_val2), 39 | .EXE_CMD(EXE_CMD), 40 | .aluOut(ALUResult) 41 | ); 42 | endmodule // EXEStage 43 | -------------------------------------------------------------------------------- /modules/hazard_forwarding/forwarding.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module forwarding_EXE (src1_EXE, src2_EXE, ST_src_EXE, dest_MEM, dest_WB, WB_EN_MEM, WB_EN_WB, val1_sel, val2_sel, ST_val_sel); 4 | input [`REG_FILE_ADDR_LEN-1:0] src1_EXE, src2_EXE, ST_src_EXE; 5 | input [`REG_FILE_ADDR_LEN-1:0] dest_MEM, dest_WB; 6 | input WB_EN_MEM, WB_EN_WB; 7 | output reg [`FORW_SEL_LEN-1:0] val1_sel, val2_sel, ST_val_sel; 8 | 9 | always @ ( * ) begin 10 | // initializing sel signals to 0 11 | // they will change to enable forwrding if needed. 12 | {val1_sel, val2_sel, ST_val_sel} <= 0; 13 | 14 | // determining forwarding control signal for store value (ST_val) 15 | if (WB_EN_MEM && ST_src_EXE == dest_MEM) ST_val_sel <= 2'd1; 16 | else if (WB_EN_WB && ST_src_EXE == dest_WB) ST_val_sel <= 2'd2; 17 | 18 | // determining forwarding control signal for ALU val1 19 | if (WB_EN_MEM && src1_EXE == dest_MEM) val1_sel <= 2'd1; 20 | else if (WB_EN_WB && src1_EXE == dest_WB) val1_sel <= 2'd2; 21 | 22 | // determining forwarding control signal for ALU val2 23 | if (WB_EN_MEM && src2_EXE == dest_MEM) val2_sel <= 2'd1; 24 | else if (WB_EN_WB && src2_EXE == dest_WB) val2_sel <= 2'd2; 25 | end 26 | endmodule // forwarding 27 | -------------------------------------------------------------------------------- /alteraDE2SimulationFiles/7segConv.v: -------------------------------------------------------------------------------- 1 | module sevenSegConv (num, out1, out2); 2 | input [31:0] num; 3 | output [6:0] out1, out2; 4 | 5 | wire [31:0] numLower = num / 10; 6 | wire [31:0] numUpper = num % 10; 7 | 8 | assign out1 = (numLower == 32'd0) ? 7'b1000000: 9 | (numLower == 32'd1) ? 7'b1001111: 10 | (numLower == 32'd2) ? 7'b0100100: 11 | (numLower == 32'd3) ? 7'b0110000: 12 | (numLower == 32'd4) ? 7'b0011001: 13 | (numLower == 32'd5) ? 7'b0010010: 14 | (numLower == 32'd6) ? 7'b0000010: 15 | (numLower == 32'd7) ? 7'b1111000: 16 | (numLower == 32'd8) ? 7'b0000000: 17 | (numLower == 32'd9) ? 7'b0010000: 7'b1111111; 18 | 19 | assign out2 = (numUpper == 32'd0) ? 7'b1000000: 20 | (numUpper == 32'd1) ? 7'b1001111: 21 | (numUpper == 32'd2) ? 7'b0100100: 22 | (numUpper == 32'd3) ? 7'b0110000: 23 | (numUpper == 32'd4) ? 7'b0011001: 24 | (numUpper == 32'd5) ? 7'b0010010: 25 | (numUpper == 32'd6) ? 7'b0000010: 26 | (numUpper == 32'd7) ? 7'b1111000: 27 | (numUpper == 32'd8) ? 7'b0000000: 28 | (numUpper == 32'd9) ? 7'b0010000: 7'b1111111; 29 | endmodule // sevenSegConv 30 | -------------------------------------------------------------------------------- /defines.v: -------------------------------------------------------------------------------- 1 | // Wire widths 2 | `define WORD_LEN 32 3 | `define REG_FILE_ADDR_LEN 5 4 | `define EXE_CMD_LEN 4 5 | `define FORW_SEL_LEN 2 6 | `define OP_CODE_LEN 6 7 | 8 | // Memory constants 9 | `define DATA_MEM_SIZE 1024 10 | `define INSTR_MEM_SIZE 1024 11 | `define REG_FILE_SIZE 32 12 | `define MEM_CELL_SIZE 8 13 | 14 | // To be used inside controller.v 15 | `define OP_NOP 6'b000000 16 | `define OP_ADD 6'b000001 17 | `define OP_SUB 6'b000011 18 | `define OP_AND 6'b000101 19 | `define OP_OR 6'b000110 20 | `define OP_NOR 6'b000111 21 | `define OP_XOR 6'b001000 22 | `define OP_SLA 6'b001001 23 | `define OP_SLL 6'b001010 24 | `define OP_SRA 6'b001011 25 | `define OP_SRL 6'b001100 26 | `define OP_ADDI 6'b100000 27 | `define OP_SUBI 6'b100001 28 | `define OP_LD 6'b100100 29 | `define OP_ST 6'b100101 30 | `define OP_BEZ 6'b101000 31 | `define OP_BNE 6'b101001 32 | `define OP_JMP 6'b101010 33 | 34 | // To be used in side ALU 35 | `define EXE_ADD 4'b0000 36 | `define EXE_SUB 4'b0010 37 | `define EXE_AND 4'b0100 38 | `define EXE_OR 4'b0101 39 | `define EXE_NOR 4'b0110 40 | `define EXE_XOR 4'b0111 41 | `define EXE_SLA 4'b1000 42 | `define EXE_SLL 4'b1000 43 | `define EXE_SRA 4'b1001 44 | `define EXE_SRL 4'b1010 45 | `define EXE_NO_OPERATION 4'b1111 // for NOP, BEZ, BNQ, JMP 46 | 47 | // To be used in conditionChecker 48 | `define COND_JUMP 2'b10 49 | `define COND_BEZ 2'b11 50 | `define COND_BNE 2'b01 51 | `define COND_NOTHING 2'b00 52 | -------------------------------------------------------------------------------- /modules/pipeRegisters/ID2EXE.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module ID2EXE (clk, rst, destIn, reg2In, val1In, val2In, PCIn, EXE_CMD_IN, MEM_R_EN_IN, MEM_W_EN_IN, WB_EN_IN, brTaken_in, src1_in, src2_in, 4 | dest, ST_value, val1, val2, PC, EXE_CMD, MEM_R_EN, MEM_W_EN, WB_EN, brTaken_out, src1_out, src2_out); 5 | input clk, rst; 6 | // TO BE REGISTERED FOR ID STAGE 7 | input MEM_R_EN_IN, MEM_W_EN_IN, WB_EN_IN, brTaken_in; 8 | input [`EXE_CMD_LEN-1:0] EXE_CMD_IN; 9 | input [`REG_FILE_ADDR_LEN-1:0] destIn, src1_in, src2_in; 10 | input [`WORD_LEN-1:0] reg2In, val1In, val2In, PCIn; 11 | // REGISTERED VALUES FOR ID STAGE 12 | output reg MEM_R_EN, MEM_W_EN, WB_EN, brTaken_out; 13 | output reg [`EXE_CMD_LEN-1:0] EXE_CMD; 14 | output reg [`REG_FILE_ADDR_LEN-1:0] dest, src1_out, src2_out; 15 | output reg [`WORD_LEN-1:0] ST_value, val1, val2, PC; 16 | 17 | always @ (posedge clk) begin 18 | if (rst) begin 19 | {MEM_R_EN, MEM_R_EN, WB_EN, EXE_CMD, dest, ST_value, val1, val2, PC, brTaken_out, src1_out, src2_out} <= 0; 20 | end 21 | else begin 22 | MEM_R_EN <= MEM_R_EN_IN; 23 | MEM_W_EN <= MEM_W_EN_IN; 24 | WB_EN <= WB_EN_IN; 25 | EXE_CMD <= EXE_CMD_IN; 26 | dest <= destIn; 27 | ST_value <= reg2In; 28 | val1 <= val1In; 29 | val2 <= val2In; 30 | PC <= PCIn; 31 | brTaken_out <= brTaken_in; 32 | src1_out <= src1_in; 33 | src2_out <= src2_in; 34 | end 35 | end 36 | endmodule // ID2EXE 37 | -------------------------------------------------------------------------------- /instructions/rearrange_instructions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Rearranging instructions from a source file to a format suitable for the always statement under instructionMem.v 5 | # There is an example source code under this directory 6 | # In drafting your own code, make sure you follow the ISA in this project 7 | 8 | DESTINATION_FILE_NAME = "ready_instructions.txt" 9 | INSTR_MEM_ARRAY_NAME = "instMem" 10 | 11 | line_count = int(raw_input("Enter the number of instructions to rearrange: ")) 12 | source_file_name = raw_input("Enter the source file name: ") 13 | 14 | instructions = [] 15 | 16 | with open(source_file_name, "r") as instr_file: 17 | for i in range(line_count): 18 | instructions.append(instr_file.readline()[:-1]) 19 | 20 | with open(DESTINATION_FILE_NAME, "w") as dest_file: 21 | for i in range(len(instructions)): 22 | instr = instructions[i] 23 | dest_file.write(INSTR_MEM_ARRAY_NAME + "[" + str(i*4) + "] <= 8'b" + instr[0:8] + "; // ==> " + instr[34:] + "\n") 24 | dest_file.write(INSTR_MEM_ARRAY_NAME + "[" + str(i*4+1) + "] <= 8'b" + instr[8:16] + ";\n") 25 | dest_file.write(INSTR_MEM_ARRAY_NAME + "[" + str(i*4+2) + "] <= 8'b" + instr[16:24] + ";\n") 26 | dest_file.write(INSTR_MEM_ARRAY_NAME + "[" + str(i*4+3) + "] <= 8'b" + instr[24:32] + ";\n\n") 27 | 28 | 29 | print "💡💡💡 ==> instructions reformatted for instruction memory." 30 | print "To run them, copy and paste the content of ready_instructions.txt under the reset if statement in the instructionMem.v always statement." 31 | -------------------------------------------------------------------------------- /modules/pipeStages/IDStage.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module IDStage (clk, rst, hazard_detected_in, is_imm_out, ST_or_BNE_out, instruction, reg1, reg2, src1, src2_reg_file, src2_forw, val1, val2, brTaken, EXE_CMD, MEM_R_EN, MEM_W_EN, WB_EN, branch_comm); 4 | input clk, rst, hazard_detected_in; 5 | input [`WORD_LEN-1:0] instruction, reg1, reg2; 6 | output brTaken, MEM_R_EN, MEM_W_EN, WB_EN, is_imm_out, ST_or_BNE_out; 7 | output [1:0] branch_comm; 8 | output [`EXE_CMD_LEN-1:0] EXE_CMD; 9 | output [`REG_FILE_ADDR_LEN-1:0] src1, src2_reg_file, src2_forw; 10 | output [`WORD_LEN-1:0] val1, val2; 11 | 12 | wire CU2and, Cond2and; 13 | wire [1:0] CU2Cond; 14 | wire Is_Imm, ST_or_BNE; 15 | wire [`WORD_LEN-1:0] signExt2Mux; 16 | 17 | controller controller( 18 | // INPUT 19 | .opCode(instruction[31:26]), 20 | .branchEn(CU2and), 21 | // OUTPUT 22 | .EXE_CMD(EXE_CMD), 23 | .Branch_command(CU2Cond), 24 | .Is_Imm(Is_Imm), 25 | .ST_or_BNE(ST_or_BNE), 26 | .WB_EN(WB_EN), 27 | .MEM_R_EN(MEM_R_EN), 28 | .MEM_W_EN(MEM_W_EN), 29 | .hazard_detected(hazard_detected_in) 30 | ); 31 | 32 | mux #(.LENGTH(`REG_FILE_ADDR_LEN)) mux_src2 ( // determins the register source 2 for register file 33 | .in1(instruction[15:11]), 34 | .in2(instruction[25:21]), 35 | .sel(ST_or_BNE), 36 | .out(src2_reg_file) 37 | ); 38 | 39 | mux #(.LENGTH(`WORD_LEN)) mux_val2 ( // determins whether val2 is from the reg file or the immediate value 40 | .in1(reg2), 41 | .in2(signExt2Mux), 42 | .sel(Is_Imm), 43 | .out(val2) 44 | ); 45 | 46 | mux #(.LENGTH(`REG_FILE_ADDR_LEN)) mux_src2_forw ( // determins the value of register source 2 for forwarding 47 | .in1(instruction[15:11]), // src2 = instruction[15:11] 48 | .in2(5'd0), 49 | .sel(Is_Imm), 50 | .out(src2_forw) 51 | ); 52 | 53 | signExtend signExtend( 54 | .in(instruction[15:0]), 55 | .out(signExt2Mux) 56 | ); 57 | 58 | conditionChecker conditionChecker ( 59 | .reg1(reg1), 60 | .reg2(reg2), 61 | .cuBranchComm(CU2Cond), 62 | .brCond(Cond2and) 63 | ); 64 | 65 | assign brTaken = CU2and && Cond2and; 66 | assign val1 = reg1; 67 | assign src1 = instruction[20:16]; 68 | assign is_imm_out = Is_Imm; 69 | assign ST_or_BNE_out = ST_or_BNE; 70 | assign branch_comm = CU2Cond; 71 | endmodule // IDStage 72 | -------------------------------------------------------------------------------- /modules/controlUnit/controller.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module controller (opCode, branchEn, EXE_CMD, Branch_command, Is_Imm, ST_or_BNE, WB_EN, MEM_R_EN, MEM_W_EN, hazard_detected); 4 | input hazard_detected; 5 | input [`OP_CODE_LEN-1:0] opCode; 6 | output reg branchEn; 7 | output reg [`EXE_CMD_LEN-1:0] EXE_CMD; 8 | output reg [1:0] Branch_command; 9 | output reg Is_Imm, ST_or_BNE, WB_EN, MEM_R_EN, MEM_W_EN; 10 | 11 | always @ ( * ) begin 12 | if (hazard_detected == 0) begin 13 | {branchEn, EXE_CMD, Branch_command, Is_Imm, ST_or_BNE, WB_EN, MEM_R_EN, MEM_W_EN} <= 0; 14 | case (opCode) 15 | // operations writing to the register file 16 | `OP_ADD: begin EXE_CMD <= `EXE_ADD; WB_EN <= 1; end 17 | `OP_SUB: begin EXE_CMD <= `EXE_SUB; WB_EN <= 1; end 18 | `OP_AND: begin EXE_CMD <= `EXE_AND; WB_EN <= 1; end 19 | `OP_OR: begin EXE_CMD <= `EXE_OR; WB_EN <= 1; end 20 | `OP_NOR: begin EXE_CMD <= `EXE_NOR; WB_EN <= 1; end 21 | `OP_XOR: begin EXE_CMD <= `EXE_XOR; WB_EN <= 1; end 22 | `OP_SLA: begin EXE_CMD <= `EXE_SLA; WB_EN <= 1; end 23 | `OP_SLL: begin EXE_CMD <= `EXE_SLL; WB_EN <= 1; end 24 | `OP_SRA: begin EXE_CMD <= `EXE_SRA; WB_EN <= 1; end 25 | `OP_SRL: begin EXE_CMD <= `EXE_SRL; WB_EN <= 1; end 26 | // operations using an immediate value embedded in the instruction 27 | `OP_ADDI: begin EXE_CMD <= `EXE_ADD; WB_EN <= 1; Is_Imm <= 1; end 28 | `OP_SUBI: begin EXE_CMD <= `EXE_SUB; WB_EN <= 1; Is_Imm <= 1; end 29 | // memory operations 30 | `OP_LD: begin EXE_CMD <= `EXE_ADD; WB_EN <= 1; Is_Imm <= 1; ST_or_BNE <= 1; MEM_R_EN <= 1; end 31 | `OP_ST: begin EXE_CMD <= `EXE_ADD; Is_Imm <= 1; MEM_W_EN <= 1; ST_or_BNE <= 1; end 32 | // branch operations 33 | `OP_BEZ: begin EXE_CMD <= `EXE_NO_OPERATION; Is_Imm <= 1; Branch_command <= `COND_BEZ; branchEn <= 1; end 34 | `OP_BNE: begin EXE_CMD <= `EXE_NO_OPERATION; Is_Imm <= 1; Branch_command <= `COND_BNE; branchEn <= 1; ST_or_BNE <= 1; end 35 | `OP_JMP: begin EXE_CMD <= `EXE_NO_OPERATION; Is_Imm <= 1; Branch_command <= `COND_JUMP; branchEn <= 1; end 36 | default: {branchEn, EXE_CMD, Branch_command, Is_Imm, ST_or_BNE, WB_EN, MEM_R_EN, MEM_W_EN} <= 0; 37 | endcase 38 | end 39 | 40 | else if (hazard_detected == 1) begin 41 | // preventing any writes to the register file or the memory 42 | {EXE_CMD, WB_EN, MEM_W_EN} <= 0; 43 | end 44 | end 45 | endmodule // controller 46 | -------------------------------------------------------------------------------- /instructions/example_source_code.txt: -------------------------------------------------------------------------------- 1 | 10000000001000000000000000001010; Addi r1,r0,10 *** (1 begins) performing basic arithmetic operations 2 | 00000100010000000000100000000000; Add r2,r0,r1 *** 3 | 00001100011000000000100000000000; sub r3,r0,r1 *** 4 | 00010100100000100001100000000000; And r4,r2,r3 *** 5 | 10000100101000000000001000110100; Subi r5,r0,564 *** 6 | 00011000101001010001100000000000; or r5,r5,r3 *** 7 | 00011100110001010000000000000000; nor r6,r5,r0 *** 8 | 00100000000001010000100000000000; xor r0,r5,r1 *** 9 | 00100000111001010000100000000000; xor r7,r5,r1 *** 10 | 00100100111001000001000000000000; sla r7,r4,r2 *** 11 | 00101001000000110001000000000000; sll r8,r3,r2 *** 12 | 00101101001001100001000000000000; sra r9,r6,r2 *** 13 | 00110001010001100001000000000000; srl r10,r6,r2 *** (1 ends) 14 | 10000000001000000000010000000000; Addi r1,r0,1024 *** (2 begins) exchanging some data with the memory 15 | 10010100010000010000000000000000; st r2,r1,0 *** 16 | 10010001011000010000000000000000; ld r11,r1,0 *** 17 | 10010100011000010000000000000100; st r3,r1,4 *** 18 | 10010100100000010000000000001000; st r4,r1,8 *** 19 | 10010100101000010000000000001100; st r5,r1,12 *** 20 | 10010100110000010000000000010000; st r6,r1,16 *** 21 | 10010100111000010000000000010100; st r7,r1,20 *** 22 | 10010101000000010000000000011000; st r8,r1,24 *** 23 | 10010101001000010000000000011100; st r9,r1,28 *** 24 | 10010101010000010000000000100000; st r10,r1,32 *** 25 | 10010101011000010000000000100100; st r11,r1,36 *** (2 ends) 26 | 10000000001000000000000000000011; Addi r1,r0,3 *** =====> BUBBLE SORT BEGINS 27 | 10000000100000000000010000000000; Addi r4,r0,1024 *** 28 | 10000000010000000000000000000000; Addi r2,r0,0 *** 29 | 10000000011000000000000000000001; Addi r3,r0,1 *** (outer loop begins) 30 | 10000001001000000000000000000010; Addi r9,r0,2 *** (inner loop begins) 31 | 00101001000000110100100000000000; sll r8,r3,r9 *** (3 begins) loading two consecutive numbers to compare 32 | 00000101000001000100000000000000; Add r8,r4,r8 *** 33 | 10010000101010000000000000000000; ld r5,r8,0 *** 34 | 10010000110010001111111111111100; ld r6,r8,-4 *** 35 | 00001101001001010011000000000000; sub r9,r5,r6 *** 36 | 10000001010000001000000000000000; Addi r10,r0,0x8000 *** 37 | 10000001011000000000000000010000; Addi r11,r0,16 *** 38 | 00101001010010100101100000000000; sll r10,r10,r11 *** 39 | 00010101001010010101000000000000; And r9,r9,r10 *** (3 ends) 40 | 10100000000010010000000000000010; Bez r9,2 *** (4 begins) swapping the two loaded numbers if needed 41 | 10010100101010001111111111111100; st r5,r8,-4 *** 42 | 10010100110010000000000000000000; st r6,r8,0 *** (4 ends) 43 | 10000000011000110000000000000001; Addi r3,r3,1 *** R3++ 44 | 10100100011000011111111111110001; BNE r3,r1,-15 *** (inner loop ends) 45 | 10000000010000100000000000000001; Addi r2,r2,1 *** R2++ 46 | 10100100010000011111111111101110; BNE r2,r1,-18 *** (outer loop ends) =====> BUBBLE SORT ENDS 47 | 10000000001000000000010000000000; Addi r1,r0,1024 *** (5 begins) storing some register inside memory 48 | 10010000010000010000000000000000; ld r2,r1,0 *** 49 | 10010000011000010000000000000100; ld r3,r1,4 *** 50 | 10010000100000010000000000001000; ld r4,r1,8 *** 51 | 10010000101000010000000000001100; ld r5,r1,12 *** 52 | 10010000110000010000000000010000; ld r6,r1,16 *** 53 | 10010000111000010000000000010100; ld r7,r1,20 *** 54 | 10010001000000010000000000011000; ld r8,r1,24 *** 55 | 10010001001000010000000000011100; ld r9,r1,28 *** 56 | 10010001010000010000000000100000; ld r10,r1,32 *** 57 | 10010001011000010000000000100100; ld r11,r1,36 *** (5 ends) 58 | 10101000000000001111111111111111; JMP -1 *** will keep jumping to itself 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MIPS-pipeline-processor 2 | 3 | Thanks for visiting this repository! 4 | 5 | Developed during the Fall 2017 Computer Architecture Laboratory course at the University of Tehran, 6 | this project is an implementation of a pipelined MIPS processor featuring hazard detection as well as forwarding. 7 | This implementation is based on a limited ISA, the details for which are present in `docs/MIPS_ISA.png`. 8 | This code is synthesizable and can be run on an FPGA. We used Altera DE2 units for testing purposes. The implemtation has been verified using a relatively complex test program (found in `instructions/example_source_code.txt`). 9 | 10 | ![MIPS pipelened processor](https://github.com/mhyousefi/MIPS-pipeline-processor/blob/master/docs/MIPS_diagram.png?raw=true) 11 | 12 | ## Getting Started 13 | 14 | Download or clone the project, write your machine code to run (there already exists a default test program in the instruction memory), 15 | compile the Verilog files and and run testbench.v in a Verilog simulation environment such as ModelSim from Mentor Graphics. 16 | 17 | ### Instruction format 18 | 19 | Instructions should be provided to the instruction memory in reset time. We avoided the `readmemb` and `readmemh` functions to 20 | keep the code synthesizable. The instruction memory cells are 8 bits long, whereas each instruction is 32 bits long. 21 | Therefore, each instruction takes up four memory cells, as shown bellow. 22 | 23 | For example, an add instruction: `10000000001000000000000000001010` or `Addi r1,r0,10` will need to be given as 24 | 25 | ``` 26 | instMem[0] <= 8'b10000000; 27 | instMem[1] <= 8'b00100000; 28 | instMem[2] <= 8'b00000000; 29 | instMem[3] <= 8'b00001010; 30 | ``` 31 | 32 | ### Converting your raw machine codes 33 | 34 | A python script is provided under the `instructions/rearrange_instructions.py` directory which simply takes your 35 | machine code (in a specified format) and converts it to the format illustrated above. 36 | 37 | ### Enable/disable forwarding 38 | 39 | An instance of the top-level circuit is taken in `testbench.v`. 40 | The inputs of the `MIPS_Processor` include `clk`, `rst`, and `forwarding_EN`. 41 | Forwarding will be enabled if `forwarding_EN` is set to 1, and disabled otherwise. 42 | 43 | ## Under the hood 44 | 45 | There are five pipeline stages: 46 | 47 | 1. Instruction Fetch 48 | 2. Instruction Decode 49 | 3. Execution 50 | 4. Memory 51 | 5. Write Back 52 | 53 | ### Modular design 54 | 55 | All modules are organized under the `modules` directory. 56 | The top level description can be found under `topLevelCircuit.v`. It contains a **modular design** of the processor and 57 | encompasses five pipe stages and four pipe registers, the description for which are present under `modules/pipeStages` and 58 | `modules/pipeRegisters` respectively. The register file, the hazard detection and the forwarding units are also instantiated 59 | in `topLevelCircuit.v`. Pipe stages are made of and encapsulate other supporting modules. 60 | 61 | ### Constants 62 | 63 | `defines.v` contains project-wide constants for **opcodes**, **execution commands**, and **branch condition commands**. 64 | It also contains constants for wire widths and memory specifications. You can change memory size values to suit your needs. 65 | 66 | ### Wire naming convention 67 | 68 | To maintain conformity, most wire names follow the format {wire description}_{wire stage}, where the second part describes 69 | the stage where the wire is located. For example, `MEM_W_EN_ID` is the memory write enable signal present in the instruction decode stage. 70 | 71 | ## Contributions 72 | 73 | Contributions are welcomed, both general improvements as well as new features such as a more realistic memory heirarchy or branch prediction. However, please follow the coding styles and the naming convention. Another useful contribution would be more comprehensive testing and verification and bug report. 74 | -------------------------------------------------------------------------------- /topLevelCircuit.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module MIPS_Processor (input CLOCK_50, input rst, input forward_EN); 4 | wire clock = CLOCK_50; 5 | wire [`WORD_LEN-1:0] PC_IF, PC_ID, PC_EXE, PC_MEM; 6 | wire [`WORD_LEN-1:0] inst_IF, inst_ID; 7 | wire [`WORD_LEN-1:0] reg1_ID, reg2_ID, ST_value_EXE, ST_value_EXE2MEM, ST_value_MEM; 8 | wire [`WORD_LEN-1:0] val1_ID, val1_EXE; 9 | wire [`WORD_LEN-1:0] val2_ID, val2_EXE; 10 | wire [`WORD_LEN-1:0] ALURes_EXE, ALURes_MEM, ALURes_WB; 11 | wire [`WORD_LEN-1:0] dataMem_out_MEM, dataMem_out_WB; 12 | wire [`WORD_LEN-1:0] WB_result; 13 | wire [`REG_FILE_ADDR_LEN-1:0] dest_EXE, dest_MEM, dest_WB; // dest_ID = instruction[25:21] thus nothing declared 14 | wire [`REG_FILE_ADDR_LEN-1:0] src1_ID, src2_regFile_ID, src2_forw_ID, src2_forw_EXE, src1_forw_EXE; 15 | wire [`EXE_CMD_LEN-1:0] EXE_CMD_ID, EXE_CMD_EXE; 16 | wire [`FORW_SEL_LEN-1:0] val1_sel, val2_sel, ST_val_sel; 17 | wire [1:0] branch_comm; 18 | wire Br_Taken_ID, IF_Flush, Br_Taken_EXE; 19 | wire MEM_R_EN_ID, MEM_R_EN_EXE, MEM_R_EN_MEM, MEM_R_EN_WB; 20 | wire MEM_W_EN_ID, MEM_W_EN_EXE, MEM_W_EN_MEM; 21 | wire WB_EN_ID, WB_EN_EXE, WB_EN_MEM, WB_EN_WB; 22 | wire hazard_detected, is_imm, ST_or_BNE; 23 | 24 | regFile regFile( 25 | // INPUTS 26 | .clk(clock), 27 | .rst(rst), 28 | .src1(src1_ID), 29 | .src2(src2_regFile_ID), 30 | .dest(dest_WB), 31 | .writeVal(WB_result), 32 | .writeEn(WB_EN_WB), 33 | // OUTPUTS 34 | .reg1(reg1_ID), 35 | .reg2(reg2_ID) 36 | ); 37 | 38 | hazard_detection hazard ( 39 | // INPUTS 40 | .forward_EN(forward_EN), 41 | .is_imm(is_imm), 42 | .ST_or_BNE(ST_or_BNE), 43 | .src1_ID(src1_ID), 44 | .src2_ID(src2_regFile_ID), 45 | .dest_EXE(dest_EXE), 46 | .dest_MEM(dest_MEM), 47 | .WB_EN_EXE(WB_EN_EXE), 48 | .WB_EN_MEM(WB_EN_MEM), 49 | .MEM_R_EN_EXE(MEM_R_EN_EXE), 50 | // OUTPUTS 51 | .branch_comm(branch_comm), 52 | .hazard_detected(hazard_detected) 53 | ); 54 | 55 | forwarding_EXE forwrding_EXE ( 56 | .src1_EXE(src1_forw_EXE), 57 | .src2_EXE(src2_forw_EXE), 58 | .ST_src_EXE(dest_EXE), 59 | .dest_MEM(dest_MEM), 60 | .dest_WB(dest_WB), 61 | .WB_EN_MEM(WB_EN_MEM), 62 | .WB_EN_WB(WB_EN_WB), 63 | .val1_sel(val1_sel), 64 | .val2_sel(val2_sel), 65 | .ST_val_sel(ST_val_sel) 66 | ); 67 | 68 | //########################### 69 | //##### PIPLINE STAGES ###### 70 | //########################### 71 | IFStage IFStage ( 72 | // INPUTS 73 | .clk(clock), 74 | .rst(rst), 75 | .freeze(hazard_detected), 76 | .brTaken(Br_Taken_ID), 77 | .brOffset(val2_ID), 78 | // OUTPUTS 79 | .instruction(inst_IF), 80 | .PC(PC_IF) 81 | ); 82 | 83 | IDStage IDStage ( 84 | // INPUTS 85 | .clk(clock), 86 | .rst(rst), 87 | .hazard_detected_in(hazard_detected), 88 | .instruction(inst_ID), 89 | .reg1(reg1_ID), 90 | .reg2(reg2_ID), 91 | // OUTPUTS 92 | .src1(src1_ID), 93 | .src2_reg_file(src2_regFile_ID), 94 | .src2_forw(src2_forw_ID), 95 | .val1(val1_ID), 96 | .val2(val2_ID), 97 | .brTaken(Br_Taken_ID), 98 | .EXE_CMD(EXE_CMD_ID), 99 | .MEM_R_EN(MEM_R_EN_ID), 100 | .MEM_W_EN(MEM_W_EN_ID), 101 | .WB_EN(WB_EN_ID), 102 | .is_imm_out(is_imm), 103 | .ST_or_BNE_out(ST_or_BNE), 104 | .branch_comm(branch_comm) 105 | ); 106 | 107 | EXEStage EXEStage ( 108 | // INPUTS 109 | .clk(clock), 110 | .EXE_CMD(EXE_CMD_EXE), 111 | .val1_sel(val1_sel), 112 | .val2_sel(val2_sel), 113 | .ST_val_sel(ST_val_sel), 114 | .val1(val1_EXE), 115 | .val2(val2_EXE), 116 | .ALU_res_MEM(ALURes_MEM), 117 | .result_WB(WB_result), 118 | .ST_value_in(ST_value_EXE), 119 | // OUTPUTS 120 | .ALUResult(ALURes_EXE), 121 | .ST_value_out(ST_value_EXE2MEM) 122 | ); 123 | 124 | MEMStage MEMStage ( 125 | // INPUTS 126 | .clk(clock), 127 | .rst(rst), 128 | .MEM_R_EN(MEM_R_EN_MEM), 129 | .MEM_W_EN(MEM_W_EN_MEM), 130 | .ALU_res(ALURes_MEM), 131 | .ST_value(ST_value_MEM), 132 | // OUTPUTS 133 | .dataMem_out(dataMem_out_MEM) 134 | ); 135 | 136 | WBStage WBStage ( 137 | // INPUTS 138 | .MEM_R_EN(MEM_R_EN_WB), 139 | .memData(dataMem_out_WB), 140 | .aluRes(ALURes_WB), 141 | // OUTPUTS 142 | .WB_res(WB_result) 143 | ); 144 | 145 | //############################ 146 | //#### PIPLINE REGISTERS ##### 147 | //############################ 148 | IF2ID IF2IDReg ( 149 | // INPUTS 150 | .clk(clock), 151 | .rst(rst), 152 | .flush(IF_Flush), 153 | .freeze(hazard_detected), 154 | .PCIn(PC_IF), 155 | .instructionIn(inst_IF), 156 | // OUTPUTS 157 | .PC(PC_ID), 158 | .instruction(inst_ID) 159 | ); 160 | 161 | ID2EXE ID2EXEReg ( 162 | .clk(clock), 163 | .rst(rst), 164 | // INPUTS 165 | .destIn(inst_ID[25:21]), 166 | .src1_in(src1_ID), 167 | .src2_in(src2_forw_ID), 168 | .reg2In(reg2_ID), 169 | .val1In(val1_ID), 170 | .val2In(val2_ID), 171 | .PCIn(PC_ID), 172 | .EXE_CMD_IN(EXE_CMD_ID), 173 | .MEM_R_EN_IN(MEM_R_EN_ID), 174 | .MEM_W_EN_IN(MEM_W_EN_ID), 175 | .WB_EN_IN(WB_EN_ID), 176 | .brTaken_in(Br_Taken_ID), 177 | // OUTPUTS 178 | .src1_out(src1_forw_EXE), 179 | .src2_out(src2_forw_EXE), 180 | .dest(dest_EXE), 181 | .ST_value(ST_value_EXE), 182 | .val1(val1_EXE), 183 | .val2(val2_EXE), 184 | .PC(PC_EXE), 185 | .EXE_CMD(EXE_CMD_EXE), 186 | .MEM_R_EN(MEM_R_EN_EXE), 187 | .MEM_W_EN(MEM_W_EN_EXE), 188 | .WB_EN(WB_EN_EXE), 189 | .brTaken_out(Br_Taken_EXE) 190 | ); 191 | 192 | EXE2MEM EXE2MEMReg ( 193 | .clk(clock), 194 | .rst(rst), 195 | // INPUTS 196 | .WB_EN_IN(WB_EN_EXE), 197 | .MEM_R_EN_IN(MEM_R_EN_EXE), 198 | .MEM_W_EN_IN(MEM_W_EN_EXE), 199 | .PCIn(PC_EXE), 200 | .ALUResIn(ALURes_EXE), 201 | .STValIn(ST_value_EXE2MEM), 202 | .destIn(dest_EXE), 203 | // OUTPUTS 204 | .WB_EN(WB_EN_MEM), 205 | .MEM_R_EN(MEM_R_EN_MEM), 206 | .MEM_W_EN(MEM_W_EN_MEM), 207 | .PC(PC_MEM), 208 | .ALURes(ALURes_MEM), 209 | .STVal(ST_value_MEM), 210 | .dest(dest_MEM) 211 | ); 212 | 213 | MEM2WB MEM2WB( 214 | .clk(clock), 215 | .rst(rst), 216 | // INPUTS 217 | .WB_EN_IN(WB_EN_MEM), 218 | .MEM_R_EN_IN(MEM_R_EN_MEM), 219 | .ALUResIn(ALURes_MEM), 220 | .memReadValIn(dataMem_out_MEM), 221 | .destIn(dest_MEM), 222 | // OUTPUTS 223 | .WB_EN(WB_EN_WB), 224 | .MEM_R_EN(MEM_R_EN_WB), 225 | .ALURes(ALURes_WB), 226 | .memReadVal(dataMem_out_WB), 227 | .dest(dest_WB) 228 | ); 229 | 230 | assign IF_Flush = Br_Taken_ID; 231 | endmodule 232 | -------------------------------------------------------------------------------- /modules/memoryModules/instructionMem.v: -------------------------------------------------------------------------------- 1 | `include "defines.v" 2 | 3 | module instructionMem (rst, addr, instruction); 4 | input rst; 5 | input [`WORD_LEN-1:0] addr; 6 | output [`WORD_LEN-1:0] instruction; 7 | 8 | wire [$clog2(`INSTR_MEM_SIZE)-1:0] address = addr[$clog2(`INSTR_MEM_SIZE)-1:0]; 9 | reg [`MEM_CELL_SIZE-1:0] instMem [0:`INSTR_MEM_SIZE-1]; 10 | 11 | always @ (*) begin 12 | if (rst) begin 13 | // No nop added in between instructions since there is a hazard detection unit 14 | 15 | instMem[0] <= 8'b10000000; //-- Addi r1,r0,10 16 | instMem[1] <= 8'b00100000; 17 | instMem[2] <= 8'b00000000; 18 | instMem[3] <= 8'b00001010; 19 | 20 | instMem[4] <= 8'b00000100; //-- Add r2,r0,r1 21 | instMem[5] <= 8'b01000000; 22 | instMem[6] <= 8'b00001000; 23 | instMem[7] <= 8'b00000000; 24 | 25 | instMem[8] <= 8'b00001100; //-- sub r3,r0,r1 26 | instMem[9] <= 8'b01100000; 27 | instMem[10] <= 8'b00001000; 28 | instMem[11] <= 8'b00000000; 29 | 30 | instMem[12] <= 8'b00010100; //-- And r4,r2,r3 31 | instMem[13] <= 8'b10000010; 32 | instMem[14] <= 8'b00011000; 33 | instMem[15] <= 8'b00000000; 34 | 35 | instMem[16] <= 8'b10000100; //-- Subi r5,r0,564 36 | instMem[17] <= 8'b10100000; 37 | instMem[18] <= 8'b00000010; 38 | instMem[19] <= 8'b00110100; 39 | 40 | instMem[20] <= 8'b00011000; //-- or r5,r5,r3 41 | instMem[21] <= 8'b10100101; 42 | instMem[22] <= 8'b00011000; 43 | instMem[23] <= 8'b00000000; 44 | 45 | instMem[24] <= 8'b00011100; //-- nor r6,r5,r0 46 | instMem[25] <= 8'b11000101; 47 | instMem[26] <= 8'b00000000; 48 | instMem[27] <= 8'b00000000; 49 | 50 | instMem[28] <= 8'b00100000; //-- xor r0,r5,r1 51 | instMem[29] <= 8'b00000101; 52 | instMem[30] <= 8'b00001000; 53 | instMem[31] <= 8'b00000000; 54 | 55 | instMem[32] <= 8'b00100000; //-- xor r7,r5,r0 56 | instMem[33] <= 8'b11100101; 57 | instMem[34] <= 8'b00001000; 58 | instMem[35] <= 8'b00000000; 59 | 60 | instMem[36] <= 8'b00100100; //-- sla r7,r4,r2 61 | instMem[37] <= 8'b11100100; 62 | instMem[38] <= 8'b00010000; 63 | instMem[39] <= 8'b00000000; 64 | 65 | instMem[40] <= 8'b00101001; //-- sll r8,r3,r2 66 | instMem[41] <= 8'b00000011; 67 | instMem[42] <= 8'b00010000; 68 | instMem[43] <= 8'b00000000; 69 | 70 | instMem[44] <= 8'b00101101; //-- sra r9,r6,r2 71 | instMem[45] <= 8'b00100110; 72 | instMem[46] <= 8'b00010000; 73 | instMem[47] <= 8'b00000000; 74 | 75 | instMem[48] <= 8'b00110001; //-- srl r10,r6,r2 76 | instMem[49] <= 8'b01000110; 77 | instMem[50] <= 8'b00010000; 78 | instMem[51] <= 8'b00000000; 79 | 80 | instMem[52] <= 8'b10000000; //-- Addi r1,r0,1024 81 | instMem[53] <= 8'b00100000; 82 | instMem[54] <= 8'b00000100; 83 | instMem[55] <= 8'b00000000; 84 | 85 | instMem[56] <= 8'b10010100; //-- st r2,r1,0 86 | instMem[57] <= 8'b01000001; 87 | instMem[58] <= 8'b00000000; 88 | instMem[59] <= 8'b00000000; 89 | 90 | instMem[60] <= 8'b10010001; //-- ld r11,r1,0 91 | instMem[61] <= 8'b01100001; 92 | instMem[62] <= 8'b00000000; 93 | instMem[63] <= 8'b00000000; 94 | 95 | instMem[64] <= 8'b10010100; //-- st r3,r1,4 96 | instMem[65] <= 8'b01100001; 97 | instMem[66] <= 8'b00000000; 98 | instMem[67] <= 8'b00000100; 99 | 100 | instMem[68] <= 8'b10010100; //-- st r4,r1,8 101 | instMem[69] <= 8'b10000001; 102 | instMem[70] <= 8'b00000000; 103 | instMem[71] <= 8'b00001000; 104 | 105 | instMem[72] <= 8'b10010100; //-- st r5,r1,12 106 | instMem[73] <= 8'b10100001; 107 | instMem[74] <= 8'b00000000; 108 | instMem[75] <= 8'b00001100; 109 | 110 | instMem[76] <= 8'b10010100; //-- st r6,r1,16 111 | instMem[77] <= 8'b11000001; 112 | instMem[78] <= 8'b00000000; 113 | instMem[79] <= 8'b00010000; 114 | 115 | instMem[80] <= 8'b10010100; //-- st r7,r1,20 116 | instMem[81] <= 8'b11100001; 117 | instMem[82] <= 8'b00000000; 118 | instMem[83] <= 8'b00010100; 119 | 120 | instMem[84] <= 8'b10010101; //-- st r8,r1,24 121 | instMem[85] <= 8'b00000001; 122 | instMem[86] <= 8'b00000000; 123 | instMem[87] <= 8'b00011000; 124 | 125 | instMem[88] <= 8'b10010101; //-- st r9,r1,28 126 | instMem[89] <= 8'b00100001; 127 | instMem[90] <= 8'b00000000; 128 | instMem[91] <= 8'b00011100; 129 | 130 | instMem[92] <= 8'b10010101; //-- st r10,r1,32 131 | instMem[93] <= 8'b01000001; 132 | instMem[94] <= 8'b00000000; 133 | instMem[95] <= 8'b00100000; 134 | 135 | instMem[96] <= 8'b10010101; //-- st r11,r1,36 136 | instMem[97] <= 8'b01100001; 137 | instMem[98] <= 8'b00000000; 138 | instMem[99] <= 8'b00100100; 139 | 140 | instMem[100] <= 8'b10000000; //-- Addi r1,r0,3 141 | instMem[101] <= 8'b00100000; 142 | instMem[102] <= 8'b00000000; 143 | instMem[103] <= 8'b00000011; 144 | 145 | instMem[104] <= 8'b10000000; //-- Addi r4,r0,1024 146 | instMem[105] <= 8'b10000000; 147 | instMem[106] <= 8'b00000100; 148 | instMem[107] <= 8'b00000000; 149 | 150 | instMem[108] <= 8'b10000000; //-- Addi r2,r0,0 151 | instMem[109] <= 8'b01000000; 152 | instMem[110] <= 8'b00000000; 153 | instMem[111] <= 8'b00000000; 154 | 155 | instMem[112] <= 8'b10000000; //-- Addi r3,r0,1 156 | instMem[113] <= 8'b01100000; 157 | instMem[114] <= 8'b00000000; 158 | instMem[115] <= 8'b00000001; 159 | 160 | instMem[116] <= 8'b10000001; //-- Addi r9,r0,2 161 | instMem[117] <= 8'b00100000; 162 | instMem[118] <= 8'b00000000; 163 | instMem[119] <= 8'b00000010; 164 | 165 | instMem[120] <= 8'b00101001; //-- sll r8,r3,r9 166 | instMem[121] <= 8'b00000011; 167 | instMem[122] <= 8'b01001000; 168 | instMem[123] <= 8'b00000000; 169 | 170 | instMem[124] <= 8'b00000101; //-- Add r8,r4,r8 171 | instMem[125] <= 8'b00000100; 172 | instMem[126] <= 8'b01000000; 173 | instMem[127] <= 8'b00000000; 174 | 175 | instMem[128] <= 8'b10010000; //-- ld r5,r8,0 176 | instMem[129] <= 8'b10101000; 177 | instMem[130] <= 8'b00000000; 178 | instMem[131] <= 8'b00000000; 179 | 180 | instMem[132] <= 8'b10010000; //-- ld r6,r8,-4 181 | instMem[133] <= 8'b11001000; 182 | instMem[134] <= 8'b11111111; 183 | instMem[135] <= 8'b11111100; 184 | 185 | instMem[136] <= 8'b00001101; //-- sub r9,r5,r6 186 | instMem[137] <= 8'b00100101; 187 | instMem[138] <= 8'b00110000; 188 | instMem[139] <= 8'b00000000; 189 | 190 | instMem[140] <= 8'b10000001; //-- Addi r10,r0,0x8000 191 | instMem[141] <= 8'b01000000; 192 | instMem[142] <= 8'b10000000; 193 | instMem[143] <= 8'b00000000; 194 | 195 | instMem[144] <= 8'b10000001; //-- Addi r11,r0,16 196 | instMem[145] <= 8'b01100000; 197 | instMem[146] <= 8'b00000000; 198 | instMem[147] <= 8'b00010000; 199 | 200 | instMem[148] <= 8'b00101001; //-- sll r10,r10,r11 201 | instMem[149] <= 8'b01001010; 202 | instMem[150] <= 8'b01011000; 203 | instMem[151] <= 8'b00000000; 204 | 205 | instMem[152] <= 8'b00010101; //-- And r9,r9,r10 206 | instMem[153] <= 8'b00101001; 207 | instMem[154] <= 8'b01010000; 208 | instMem[155] <= 8'b00000000; 209 | 210 | instMem[156] <= 8'b10100000; //-- Bez r9,2 211 | instMem[157] <= 8'b00001001; 212 | instMem[158] <= 8'b00000000; 213 | instMem[159] <= 8'b00000010; 214 | 215 | instMem[160] <= 8'b10010100; //-- st r5,r8,-4 216 | instMem[161] <= 8'b10101000; 217 | instMem[162] <= 8'b11111111; 218 | instMem[163] <= 8'b11111100; 219 | 220 | instMem[164] <= 8'b10010100; //-- st r6,r8,0 221 | instMem[165] <= 8'b11001000; 222 | instMem[166] <= 8'b00000000; 223 | instMem[167] <= 8'b00000000; 224 | 225 | instMem[168] <= 8'b10000000; //-- Addi r3,r3,1 226 | instMem[169] <= 8'b01100011; 227 | instMem[170] <= 8'b00000000; 228 | instMem[171] <= 8'b00000001; 229 | 230 | instMem[172] <= 8'b10100100; //-- BNE r3,r1,-15 231 | instMem[173] <= 8'b01100001; 232 | instMem[174] <= 8'b11111111; 233 | instMem[175] <= 8'b11110001; 234 | 235 | instMem[176] <= 8'b10000000; //-- Addi r2,r2,1 236 | instMem[177] <= 8'b01000010; 237 | instMem[178] <= 8'b00000000; 238 | instMem[179] <= 8'b00000001; 239 | 240 | instMem[180] <= 8'b10100100; //-- BNE r2,r1,-18 241 | instMem[181] <= 8'b01000001; 242 | instMem[182] <= 8'b11111111; 243 | instMem[183] <= 8'b11101110; 244 | 245 | instMem[184] <= 8'b10000000; //-- Addi r1,r0,1024 246 | instMem[185] <= 8'b00100000; 247 | instMem[186] <= 8'b00000100; 248 | instMem[187] <= 8'b00000000; 249 | 250 | instMem[188] <= 8'b10010000; //-- ld r2,r1,0 251 | instMem[189] <= 8'b01000001; 252 | instMem[190] <= 8'b00000000; 253 | instMem[191] <= 8'b00000000; 254 | 255 | instMem[192] <= 8'b10010000; //-- ld r3,r1,4 256 | instMem[193] <= 8'b01100001; 257 | instMem[194] <= 8'b00000000; 258 | instMem[195] <= 8'b00000100; 259 | 260 | instMem[196] <= 8'b10010000; //-- ld r4,r1,8 261 | instMem[197] <= 8'b10000001; 262 | instMem[198] <= 8'b00000000; 263 | instMem[199] <= 8'b00001000; 264 | 265 | instMem[200] <= 8'b10010000; //-- ld r5,r1,12 266 | instMem[201] <= 8'b10100001; 267 | instMem[202] <= 8'b00000000; 268 | instMem[203] <= 8'b00001100; 269 | 270 | instMem[204] <= 8'b10010000; //-- ld r6,r1,16 271 | instMem[205] <= 8'b11000001; 272 | instMem[206] <= 8'b00000000; 273 | instMem[207] <= 8'b00010000; 274 | 275 | instMem[208] <= 8'b10010000; //-- ld r7,r1,20 276 | instMem[209] <= 8'b11100001; 277 | instMem[210] <= 8'b00000000; 278 | instMem[211] <= 8'b00010100; 279 | 280 | instMem[212] <= 8'b10010001; //-- ld r8,r1,24 281 | instMem[213] <= 8'b00000001; 282 | instMem[214] <= 8'b00000000; 283 | instMem[215] <= 8'b00011000; 284 | 285 | instMem[216] <= 8'b10010001; //-- ld r9,r1,28 286 | instMem[217] <= 8'b00100001; 287 | instMem[218] <= 8'b00000000; 288 | instMem[219] <= 8'b00011100; 289 | 290 | instMem[220] <= 8'b10010001; //-- ld r10,r1,32 291 | instMem[221] <= 8'b01000001; 292 | instMem[222] <= 8'b00000000; 293 | instMem[223] <= 8'b00100000; 294 | 295 | instMem[224] <= 8'b10010001; //-- ld r11,r1,36 296 | instMem[225] <= 8'b01100001; 297 | instMem[226] <= 8'b00000000; 298 | instMem[227] <= 8'b00100100; 299 | 300 | instMem[228] <= 8'b10101000; //-- JMP -1 301 | instMem[229] <= 8'b00000000; 302 | instMem[230] <= 8'b11111111; 303 | instMem[231] <= 8'b11111111; 304 | 305 | instMem[232] <= 8'b00000000; //-- NOPE 306 | instMem[233] <= 8'b00000000; 307 | instMem[234] <= 8'b00000000; 308 | instMem[235] <= 8'b00000000; 309 | end 310 | end 311 | 312 | assign instruction = {instMem[address], instMem[address + 1], instMem[address + 2], instMem[address + 3]}; 313 | endmodule // insttructionMem 314 | -------------------------------------------------------------------------------- /alteraDE2SimulationFiles/DE2_TOP.V: -------------------------------------------------------------------------------- 1 | module DE2_TOP 2 | ( 3 | //////////////////// Clock Input //////////////////// 4 | CLOCK_27, // 27 MHz 5 | CLOCK_50, // 50 MHz 6 | EXT_CLOCK, // External Clock 7 | //////////////////// Push Button //////////////////// 8 | KEY, // Pushbutton[3:0] 9 | //////////////////// DPDT Switch //////////////////// 10 | SW, // Toggle Switch[17:0] 11 | //////////////////// 7-SEG Dispaly //////////////////// 12 | HEX0, // Seven Segment Digit 0 13 | HEX1, // Seven Segment Digit 1 14 | HEX2, // Seven Segment Digit 2 15 | HEX3, // Seven Segment Digit 3 16 | HEX4, // Seven Segment Digit 4 17 | HEX5, // Seven Segment Digit 5 18 | HEX6, // Seven Segment Digit 6 19 | HEX7, // Seven Segment Digit 7 20 | //////////////////////// LED //////////////////////// 21 | LEDG, // LED Green[8:0] 22 | LEDR, // LED Red[17:0] 23 | //////////////////////// UART //////////////////////// 24 | UART_TXD, // UART Transmitter 25 | UART_RXD, // UART Receiver 26 | //////////////////////// IRDA //////////////////////// 27 | // IRDA_TXD, // IRDA Transmitter 28 | // IRDA_RXD, // IRDA Receiver 29 | ///////////////////// SDRAM Interface //////////////// 30 | DRAM_DQ, // SDRAM Data bus 16 Bits 31 | DRAM_ADDR, // SDRAM Address bus 12 Bits 32 | DRAM_LDQM, // SDRAM Low-byte Data Mask 33 | DRAM_UDQM, // SDRAM High-byte Data Mask 34 | DRAM_WE_N, // SDRAM Write Enable 35 | DRAM_CAS_N, // SDRAM Column Address Strobe 36 | DRAM_RAS_N, // SDRAM Row Address Strobe 37 | DRAM_CS_N, // SDRAM Chip Select 38 | DRAM_BA_0, // SDRAM Bank Address 0 39 | DRAM_BA_1, // SDRAM Bank Address 0 40 | DRAM_CLK, // SDRAM Clock 41 | DRAM_CKE, // SDRAM Clock Enable 42 | //////////////////// Flash Interface //////////////// 43 | FL_DQ, // FLASH Data bus 8 Bits 44 | FL_ADDR, // FLASH Address bus 22 Bits 45 | FL_WE_N, // FLASH Write Enable 46 | FL_RST_N, // FLASH Reset 47 | FL_OE_N, // FLASH Output Enable 48 | FL_CE_N, // FLASH Chip Enable 49 | //////////////////// SRAM Interface //////////////// 50 | SRAM_DQ, // SRAM Data bus 16 Bits 51 | SRAM_ADDR, // SRAM Address bus 18 Bits 52 | SRAM_UB_N, // SRAM High-byte Data Mask 53 | SRAM_LB_N, // SRAM Low-byte Data Mask 54 | SRAM_WE_N, // SRAM Write Enable 55 | SRAM_CE_N, // SRAM Chip Enable 56 | SRAM_OE_N, // SRAM Output Enable 57 | //////////////////// ISP1362 Interface //////////////// 58 | OTG_DATA, // ISP1362 Data bus 16 Bits 59 | OTG_ADDR, // ISP1362 Address 2 Bits 60 | OTG_CS_N, // ISP1362 Chip Select 61 | OTG_RD_N, // ISP1362 Write 62 | OTG_WR_N, // ISP1362 Read 63 | OTG_RST_N, // ISP1362 Reset 64 | OTG_FSPEED, // USB Full Speed, 0 = Enable, Z = Disable 65 | OTG_LSPEED, // USB Low Speed, 0 = Enable, Z = Disable 66 | OTG_INT0, // ISP1362 Interrupt 0 67 | OTG_INT1, // ISP1362 Interrupt 1 68 | OTG_DREQ0, // ISP1362 DMA Request 0 69 | OTG_DREQ1, // ISP1362 DMA Request 1 70 | OTG_DACK0_N, // ISP1362 DMA Acknowledge 0 71 | OTG_DACK1_N, // ISP1362 DMA Acknowledge 1 72 | //////////////////// LCD Module 16X2 //////////////// 73 | LCD_ON, // LCD Power ON/OFF 74 | LCD_BLON, // LCD Back Light ON/OFF 75 | LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read 76 | LCD_EN, // LCD Enable 77 | LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data 78 | LCD_DATA, // LCD Data bus 8 bits 79 | //////////////////// SD_Card Interface //////////////// 80 | //SD_DAT, // SD Card Data 81 | SD_WP_N, // SD Write protect 82 | SD_CMD, // SD Card Command Signal 83 | SD_CLK, // SD Card Clock 84 | //////////////////// USB JTAG link //////////////////// 85 | TDI, // CPLD -> FPGA (data in) 86 | TCK, // CPLD -> FPGA (clk) 87 | TCS, // CPLD -> FPGA (CS) 88 | TDO, // FPGA -> CPLD (data out) 89 | //////////////////// I2C //////////////////////////// 90 | I2C_SDAT, // I2C Data 91 | I2C_SCLK, // I2C Clock 92 | //////////////////// PS2 //////////////////////////// 93 | PS2_DAT, // PS2 Data 94 | PS2_CLK, // PS2 Clock 95 | //////////////////// VGA //////////////////////////// 96 | VGA_CLK, // VGA Clock 97 | VGA_HS, // VGA H_SYNC 98 | VGA_VS, // VGA V_SYNC 99 | VGA_BLANK, // VGA BLANK 100 | VGA_SYNC, // VGA SYNC 101 | VGA_R, // VGA Red[9:0] 102 | VGA_G, // VGA Green[9:0] 103 | VGA_B, // VGA Blue[9:0] 104 | //////////// Ethernet Interface //////////////////////// 105 | ENET_DATA, // DM9000A DATA bus 16Bits 106 | ENET_CMD, // DM9000A Command/Data Select, 0 = Command, 1 = Data 107 | ENET_CS_N, // DM9000A Chip Select 108 | ENET_WR_N, // DM9000A Write 109 | ENET_RD_N, // DM9000A Read 110 | ENET_RST_N, // DM9000A Reset 111 | ENET_INT, // DM9000A Interrupt 112 | ENET_CLK, // DM9000A Clock 25 MHz 113 | //////////////// Audio CODEC //////////////////////// 114 | AUD_ADCLRCK, // Audio CODEC ADC LR Clock 115 | AUD_ADCDAT, // Audio CODEC ADC Data 116 | AUD_DACLRCK, // Audio CODEC DAC LR Clock 117 | AUD_DACDAT, // Audio CODEC DAC Data 118 | AUD_BCLK, // Audio CODEC Bit-Stream Clock 119 | AUD_XCK, // Audio CODEC Chip Clock 120 | //////////////// TV Decoder //////////////////////// 121 | TD_DATA, // TV Decoder Data bus 8 bits 122 | TD_HS, // TV Decoder H_SYNC 123 | TD_VS, // TV Decoder V_SYNC 124 | TD_RESET, // TV Decoder Reset 125 | TD_CLK27, // TV Decoder 27MHz CLK 126 | //////////////////// GPIO //////////////////////////// 127 | GPIO_0, // GPIO Connection 0 128 | GPIO_1 // GPIO Connection 1 129 | ); 130 | 131 | //////////////////////// Clock Input //////////////////////// 132 | input CLOCK_27; // 27 MHz 133 | input CLOCK_50; // 50 MHz 134 | input EXT_CLOCK; // External Clock 135 | //////////////////////// Push Button //////////////////////// 136 | input [3:0] KEY; // Pushbutton[3:0] 137 | //////////////////////// DPDT Switch //////////////////////// 138 | input [17:0] SW; // Toggle Switch[17:0] 139 | //////////////////////// 7-SEG Dispaly //////////////////////// 140 | output [6:0] HEX0; // Seven Segment Digit 0 141 | output [6:0] HEX1; // Seven Segment Digit 1 142 | output [6:0] HEX2; // Seven Segment Digit 2 143 | output [6:0] HEX3; // Seven Segment Digit 3 144 | output [6:0] HEX4; // Seven Segment Digit 4 145 | output [6:0] HEX5; // Seven Segment Digit 5 146 | output [6:0] HEX6; // Seven Segment Digit 6 147 | output [6:0] HEX7; // Seven Segment Digit 7 148 | //////////////////////////// LED //////////////////////////// 149 | output [8:0] LEDG; // LED Green[8:0] 150 | output [17:0] LEDR; // LED Red[17:0] 151 | //////////////////////////// UART //////////////////////////// 152 | output UART_TXD; // UART Transmitter 153 | input UART_RXD; // UART Receiver 154 | //////////////////////////// IRDA //////////////////////////// 155 | //output IRDA_TXD; // IRDA Transmitter 156 | //input IRDA_RXD; // IRDA Receiver 157 | /////////////////////// SDRAM Interface //////////////////////// 158 | inout [15:0] DRAM_DQ; // SDRAM Data bus 16 Bits 159 | output [11:0] DRAM_ADDR; // SDRAM Address bus 12 Bits 160 | output DRAM_LDQM; // SDRAM Low-byte Data Mask 161 | output DRAM_UDQM; // SDRAM High-byte Data Mask 162 | output DRAM_WE_N; // SDRAM Write Enable 163 | output DRAM_CAS_N; // SDRAM Column Address Strobe 164 | output DRAM_RAS_N; // SDRAM Row Address Strobe 165 | output DRAM_CS_N; // SDRAM Chip Select 166 | output DRAM_BA_0; // SDRAM Bank Address 0 167 | output DRAM_BA_1; // SDRAM Bank Address 0 168 | output DRAM_CLK; // SDRAM Clock 169 | output DRAM_CKE; // SDRAM Clock Enable 170 | //////////////////////// Flash Interface //////////////////////// 171 | inout [7:0] FL_DQ; // FLASH Data bus 8 Bits 172 | output [21:0] FL_ADDR; // FLASH Address bus 22 Bits 173 | output FL_WE_N; // FLASH Write Enable 174 | output FL_RST_N; // FLASH Reset 175 | output FL_OE_N; // FLASH Output Enable 176 | output FL_CE_N; // FLASH Chip Enable 177 | //////////////////////// SRAM Interface //////////////////////// 178 | inout [15:0] SRAM_DQ; // SRAM Data bus 16 Bits 179 | output [17:0] SRAM_ADDR; // SRAM Address bus 18 Bits 180 | output SRAM_UB_N; // SRAM High-byte Data Mask 181 | output SRAM_LB_N; // SRAM Low-byte Data Mask 182 | output SRAM_WE_N; // SRAM Write Enable 183 | output SRAM_CE_N; // SRAM Chip Enable 184 | output SRAM_OE_N; // SRAM Output Enable 185 | //////////////////// ISP1362 Interface //////////////////////// 186 | inout [15:0] OTG_DATA; // ISP1362 Data bus 16 Bits 187 | output [1:0] OTG_ADDR; // ISP1362 Address 2 Bits 188 | output OTG_CS_N; // ISP1362 Chip Select 189 | output OTG_RD_N; // ISP1362 Write 190 | output OTG_WR_N; // ISP1362 Read 191 | output OTG_RST_N; // ISP1362 Reset 192 | output OTG_FSPEED; // USB Full Speed, 0 = Enable, Z = Disable 193 | output OTG_LSPEED; // USB Low Speed, 0 = Enable, Z = Disable 194 | input OTG_INT0; // ISP1362 Interrupt 0 195 | input OTG_INT1; // ISP1362 Interrupt 1 196 | input OTG_DREQ0; // ISP1362 DMA Request 0 197 | input OTG_DREQ1; // ISP1362 DMA Request 1 198 | output OTG_DACK0_N; // ISP1362 DMA Acknowledge 0 199 | output OTG_DACK1_N; // ISP1362 DMA Acknowledge 1 200 | //////////////////// LCD Module 16X2 //////////////////////////// 201 | inout [7:0] LCD_DATA; // LCD Data bus 8 bits 202 | output LCD_ON; // LCD Power ON/OFF 203 | output LCD_BLON; // LCD Back Light ON/OFF 204 | output LCD_RW; // LCD Read/Write Select, 0 = Write, 1 = Read 205 | output LCD_EN; // LCD Enable 206 | output LCD_RS; // LCD Command/Data Select, 0 = Command, 1 = Data 207 | //////////////////// SD Card Interface //////////////////////// 208 | //inout [3:0] SD_DAT; // SD Card Data 209 | input SD_WP_N; // SD write protect 210 | inout SD_CMD; // SD Card Command Signal 211 | output SD_CLK; // SD Card Clock 212 | //////////////////////// I2C //////////////////////////////// 213 | inout I2C_SDAT; // I2C Data 214 | output I2C_SCLK; // I2C Clock 215 | //////////////////////// PS2 //////////////////////////////// 216 | input PS2_DAT; // PS2 Data 217 | input PS2_CLK; // PS2 Clock 218 | //////////////////// USB JTAG link //////////////////////////// 219 | input TDI; // CPLD -> FPGA (data in) 220 | input TCK; // CPLD -> FPGA (clk) 221 | input TCS; // CPLD -> FPGA (CS) 222 | output TDO; // FPGA -> CPLD (data out) 223 | //////////////////////// VGA //////////////////////////// 224 | output VGA_CLK; // VGA Clock 225 | output VGA_HS; // VGA H_SYNC 226 | output VGA_VS; // VGA V_SYNC 227 | output VGA_BLANK; // VGA BLANK 228 | output VGA_SYNC; // VGA SYNC 229 | output [9:0] VGA_R; // VGA Red[9:0] 230 | output [9:0] VGA_G; // VGA Green[9:0] 231 | output [9:0] VGA_B; // VGA Blue[9:0] 232 | //////////////// Ethernet Interface //////////////////////////// 233 | inout [15:0] ENET_DATA; // DM9000A DATA bus 16Bits 234 | output ENET_CMD; // DM9000A Command/Data Select, 0 = Command, 1 = Data 235 | output ENET_CS_N; // DM9000A Chip Select 236 | output ENET_WR_N; // DM9000A Write 237 | output ENET_RD_N; // DM9000A Read 238 | output ENET_RST_N; // DM9000A Reset 239 | input ENET_INT; // DM9000A Interrupt 240 | output ENET_CLK; // DM9000A Clock 25 MHz 241 | //////////////////// Audio CODEC //////////////////////////// 242 | inout AUD_ADCLRCK; // Audio CODEC ADC LR Clock 243 | input AUD_ADCDAT; // Audio CODEC ADC Data 244 | inout AUD_DACLRCK; // Audio CODEC DAC LR Clock 245 | output AUD_DACDAT; // Audio CODEC DAC Data 246 | inout AUD_BCLK; // Audio CODEC Bit-Stream Clock 247 | output AUD_XCK; // Audio CODEC Chip Clock 248 | //////////////////// TV Devoder //////////////////////////// 249 | input [7:0] TD_DATA; // TV Decoder Data bus 8 bits 250 | input TD_HS; // TV Decoder H_SYNC 251 | input TD_VS; // TV Decoder V_SYNC 252 | output TD_RESET; // TV Decoder Reset 253 | input TD_CLK27; // TV Decoder 27MHz CLK 254 | //////////////////////// GPIO //////////////////////////////// 255 | inout [35:0] GPIO_0; // GPIO Connection 0 256 | inout [35:0] GPIO_1; // GPIO Connection 1 257 | wire clock = CLOCK_50; 258 | wire [31:0] PC_IF, PC_ID, PC_EXE, PC_MEM; 259 | wire [31:0] inst_IF, inst_ID; 260 | wire [31:0] reg1_ID, reg2_ID, ST_value_EXE, ST_value_EXE2MEM, ST_value_MEM; 261 | wire [31:0] val1_ID, val1_EXE; 262 | wire [31:0] val2_ID, val2_EXE; 263 | wire [31:0] ALURes_EXE, ALURes_MEM, ALURes_WB; 264 | wire [31:0] dataMem_out_MEM, dataMem_out_WB; 265 | wire [31:0] WB_result; 266 | wire [4:0] dest_EXE, dest_MEM, dest_WB; // dest_ID = instruction[25:21] thus nothing declared 267 | wire [4:0] src1_ID, src2_regFile_ID, src2_forw_ID, src2_forw_EXE, src1_forw_EXE; 268 | wire [3:0] EXE_CMD_ID, EXE_CMD_EXE; 269 | wire [1:0] val1_sel, val2_sel, ST_val_sel; 270 | wire [1:0] branch_comm; 271 | wire Br_Taken_ID, IF_Flush, Br_Taken_EXE; 272 | wire MEM_R_EN_ID, MEM_R_EN_EXE, MEM_R_EN_MEM, MEM_R_EN_WB; 273 | wire MEM_W_EN_ID, MEM_W_EN_EXE, MEM_W_EN_MEM; 274 | wire WB_EN_ID, WB_EN_EXE, WB_EN_MEM, WB_EN_WB; 275 | wire hazard_detected, is_imm, ST_or_BNE; 276 | 277 | regFile regFile( 278 | // INPUTS 279 | .clk(clock), 280 | .rst(SW[0]), 281 | .src1(src1_ID), 282 | .src2(src2_regFile_ID), 283 | .dest(dest_WB), 284 | .writeVal(WB_result), 285 | .writeEn(WB_EN_WB), 286 | // OUTPUTS 287 | .reg1(reg1_ID), 288 | .reg2(reg2_ID) 289 | ); 290 | 291 | hazard_detection hazard ( 292 | // INPUTS 293 | .forward_EN(SW[1]), 294 | .is_imm(is_imm), 295 | .ST_or_BNE(ST_or_BNE), 296 | .src1_ID(src1_ID), 297 | .src2_ID(src2_regFile_ID), 298 | .dest_EXE(dest_EXE), 299 | .dest_MEM(dest_MEM), 300 | .WB_EN_EXE(WB_EN_EXE), 301 | .WB_EN_MEM(WB_EN_MEM), 302 | .MEM_R_EN_EXE(MEM_R_EN_EXE), 303 | // OUTPUTS 304 | .branch_comm(branch_comm), 305 | .hazard_detected(hazard_detected) 306 | ); 307 | 308 | forwarding_EXE forwrding_EXE ( 309 | .src1_EXE(src1_forw_EXE), 310 | .src2_EXE(src2_forw_EXE), 311 | .ST_src_EXE(dest_EXE), 312 | .dest_MEM(dest_MEM), 313 | .dest_WB(dest_WB), 314 | .WB_EN_MEM(WB_EN_MEM), 315 | .WB_EN_WB(WB_EN_WB), 316 | .val1_sel(val1_sel), 317 | .val2_sel(val2_sel), 318 | .ST_val_sel(ST_val_sel) 319 | ); 320 | 321 | //########################### 322 | //##### PIPLINE STAGES ###### 323 | //########################### 324 | IFStage IFStage ( 325 | // INPUTS 326 | .clk(clock), 327 | .rst(SW[0]), 328 | .freeze(hazard_detected), 329 | .brTaken(Br_Taken_ID), 330 | .brOffset(val2_ID), 331 | // OUTPUTS 332 | .instruction(inst_IF), 333 | .PC(PC_IF) 334 | ); 335 | 336 | IDStage IDStage ( 337 | // INPUTS 338 | .clk(clock), 339 | .rst(SW[0]), 340 | .hazard_detected_in(hazard_detected), 341 | .instruction(inst_ID), 342 | .reg1(reg1_ID), 343 | .reg2(reg2_ID), 344 | // OUTPUTS 345 | .src1(src1_ID), 346 | .src2_reg_file(src2_regFile_ID), 347 | .src2_forw(src2_forw_ID), 348 | .val1(val1_ID), 349 | .val2(val2_ID), 350 | .brTaken(Br_Taken_ID), 351 | .EXE_CMD(EXE_CMD_ID), 352 | .MEM_R_EN(MEM_R_EN_ID), 353 | .MEM_W_EN(MEM_W_EN_ID), 354 | .WB_EN(WB_EN_ID), 355 | .is_imm_out(is_imm), 356 | .ST_or_BNE_out(ST_or_BNE), 357 | .branch_comm(branch_comm) 358 | ); 359 | 360 | EXEStage EXEStage ( 361 | // INPUTS 362 | .clk(clock), 363 | .EXE_CMD(EXE_CMD_EXE), 364 | .val1_sel(val1_sel), 365 | .val2_sel(val2_sel), 366 | .ST_val_sel(ST_val_sel), 367 | .val1(val1_EXE), 368 | .val2(val2_EXE), 369 | .ALU_res_MEM(ALURes_MEM), 370 | .result_WB(WB_result), 371 | .ST_value_in(ST_value_EXE), 372 | // OUTPUTS 373 | .ALUResult(ALURes_EXE), 374 | .ST_value_out(ST_value_EXE2MEM) 375 | ); 376 | 377 | MEMStage MEMStage ( 378 | // INPUTS 379 | .clk(clock), 380 | .rst(SW[0]), 381 | .MEM_R_EN(MEM_R_EN_MEM), 382 | .MEM_W_EN(MEM_W_EN_MEM), 383 | .ALU_res(ALURes_MEM), 384 | .ST_value(ST_value_MEM), 385 | // OUTPUTS 386 | .dataMem_out(dataMem_out_MEM) 387 | ); 388 | 389 | WBStage WBStage ( 390 | // INPUTS 391 | .MEM_R_EN(MEM_R_EN_WB), 392 | .memData(dataMem_out_WB), 393 | .aluRes(ALURes_WB), 394 | // OUTPUTS 395 | .WB_res(WB_result) 396 | ); 397 | 398 | //########################### 399 | //#### PIPLINE REISTERS ##### 400 | //########################### 401 | IF2ID IF2IDReg ( 402 | // INPUTS 403 | .clk(clock), 404 | .rst(SW[0]), 405 | .flush(IF_Flush), 406 | .freeze(hazard_detected), 407 | .PCIn(PC_IF), 408 | .instructionIn(inst_IF), 409 | // OUTPUTS 410 | .PC(PC_ID), 411 | .instruction(inst_ID) 412 | ); 413 | 414 | ID2EXE ID2EXEReg ( 415 | .clk(clock), 416 | .rst(SW[0]), 417 | // INPUTS 418 | .destIn(inst_ID[25:21]), 419 | .src1_in(src1_ID), 420 | .src2_in(src2_forw_ID), 421 | .reg2In(reg2_ID), 422 | .val1In(val1_ID), 423 | .val2In(val2_ID), 424 | .PCIn(PC_ID), 425 | .EXE_CMD_IN(EXE_CMD_ID), 426 | .MEM_R_EN_IN(MEM_R_EN_ID), 427 | .MEM_W_EN_IN(MEM_W_EN_ID), 428 | .WB_EN_IN(WB_EN_ID), 429 | .brTaken_in(Br_Taken_ID), 430 | // OUTPUTS 431 | .src1_out(src1_forw_EXE), 432 | .src2_out(src2_forw_EXE), 433 | .dest(dest_EXE), 434 | .ST_value(ST_value_EXE), 435 | .val1(val1_EXE), 436 | .val2(val2_EXE), 437 | .PC(PC_EXE), 438 | .EXE_CMD(EXE_CMD_EXE), 439 | .MEM_R_EN(MEM_R_EN_EXE), 440 | .MEM_W_EN(MEM_W_EN_EXE), 441 | .WB_EN(WB_EN_EXE), 442 | .brTaken_out(Br_Taken_EXE) 443 | ); 444 | 445 | EXE2MEM EXE2MEMReg ( 446 | .clk(clock), 447 | .rst(SW[0]), 448 | // INPUTS 449 | .WB_EN_IN(WB_EN_EXE), 450 | .MEM_R_EN_IN(MEM_R_EN_EXE), 451 | .MEM_W_EN_IN(MEM_W_EN_EXE), 452 | .PCIn(PC_EXE), 453 | .ALUResIn(ALURes_EXE), 454 | .STValIn(ST_value_EXE2MEM), 455 | .destIn(dest_EXE), 456 | // OUTPUTS 457 | .WB_EN(WB_EN_MEM), 458 | .MEM_R_EN(MEM_R_EN_MEM), 459 | .MEM_W_EN(MEM_W_EN_MEM), 460 | .PC(PC_MEM), 461 | .ALURes(ALURes_MEM), 462 | .STVal(ST_value_MEM), 463 | .dest(dest_MEM) 464 | ); 465 | 466 | MEM2WB MEM2WB( 467 | .clk(clock), 468 | .rst(SW[0]), 469 | // INPUTS 470 | .WB_EN_IN(WB_EN_MEM), 471 | .MEM_R_EN_IN(MEM_R_EN_MEM), 472 | .ALUResIn(ALURes_MEM), 473 | .memReadValIn(dataMem_out_MEM), 474 | .destIn(dest_MEM), 475 | // OUTPUTS 476 | .WB_EN(WB_EN_WB), 477 | .MEM_R_EN(MEM_R_EN_WB), 478 | .ALURes(ALURes_WB), 479 | .memReadVal(dataMem_out_WB), 480 | .dest(dest_WB) 481 | ); 482 | 483 | assign IF_Flush = Br_Taken_ID; 484 | endmodule 485 | --------------------------------------------------------------------------------