├── .gitignore ├── LICENSE ├── README.md ├── pipelined-zanpu.srcs ├── sim_1 │ └── new │ │ └── testbench.v └── sources_1 │ └── new │ ├── alu.v │ ├── branch_judge.v │ ├── control_unit.v │ ├── data_memory.v │ ├── definitions.vh │ ├── extend.v │ ├── forwarding_unit.v │ ├── instruction_memory.v │ ├── mux.v │ ├── npc.v │ ├── pc.v │ ├── reg_ex_mem.v │ ├── reg_id_ex.v │ ├── reg_if_id.v │ ├── reg_mem_wb.v │ ├── register_file.v │ ├── stall_unit.v │ └── zanpu_top.v ├── pipelined-zanpu.tbcode ├── data_memory.txt ├── instructions.txt └── register.txt └── pipelined-zanpu.xpr /.gitignore: -------------------------------------------------------------------------------- 1 | pipelined-zanpu.cache 2 | pipelined-zanpu.hw 3 | pipelined-zanpu.ip_user_files 4 | pipelined-zanpu.sim 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 ZanPU 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 🧮 Pipelined ZanPU 4 | 5 | **Pipelined ZanPU** is a simple implementation of a classic five stage RISC pipeline CPU. 6 | 7 | This project is the team project of BIT's 2019 summer CPU-building lecture. ZanPU's architecture shares the one mentioned in: [Classic RISC pipeline - Wikipedia](https://en.wikipedia.org/wiki/Classic_RISC_pipeline). 8 | 9 | ## Usage 10 | 11 | - Open Vivado 12 | - Run sythesis, implementation 13 | - Program board 14 | - Profit. 15 | 16 | ## Source Code 17 | 18 | All source codes are available at [pipelined-zanpu.srcs](./pipelined-zanpu.srcs). 19 | 20 | - [Design Sources](./pipelined-zanpu.srcs/sources_1/new) 21 | - [Simulation Sources](./pipelined-zanpu.srcs/sim_1/new) 22 | 23 | Instruction, data memory and register files are initialized at [pipelined-zanpu.tbcode](./pipelined-zanpu.tbcode). 24 | 25 | --- 26 | 27 | 🧮 **Pipelined ZanPU** ©2019 ZanPU. Released under the [MIT License](./LICENSE). 28 | 29 | Authored and maintained by Team ZanPU. 30 | 31 | Created with love ♥ from BIT, Beijing. 32 | 33 | [@BIT](https://www.bit.edu.cn) · [@GitHub](https://github.com/zan-pu) · [Documentation](https://zanpu.spencerwoo.com) 34 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sim_1/new/testbench.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | /* 4 | * Testbench 5 | */ 6 | 7 | module testbench(); 8 | reg clk; 9 | reg rst; 10 | zanpu_top u_zanpu_top( 11 | .clk (clk ), 12 | .rst (rst ) 13 | ); 14 | 15 | initial begin 16 | // Load instructions 17 | $readmemh("../../../pipelined-zanpu.tbcode/instructions.txt", u_zanpu_top.u_instruction_memory.im); 18 | // Load register initial values 19 | $readmemh("../../../pipelined-zanpu.tbcode/register.txt", u_zanpu_top.u_register_file.gpr); 20 | // Load memory data initial values 21 | $readmemh("../../../pipelined-zanpu.tbcode/data_memory.txt", u_zanpu_top.u_data_memory.dm); 22 | 23 | rst = 1; 24 | clk = 0; 25 | 26 | #30 rst = 0; 27 | // #80 $display("$10 value: %h", ZAN_TOP.ZAN_REG_FILE.gpr[10]); 28 | #500 $stop; 29 | end 30 | 31 | always 32 | #20 clk = ~clk; 33 | endmodule 34 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/alu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU ALU 6 | * 7 | * Input: .alu_input_1 .alu_input_2 .cu_alu_op 8 | * Output: .alu_result 9 | */ 10 | 11 | module alu( 12 | input wire[31:0] alu_input_1, 13 | input wire[31:0] alu_input_2, 14 | input wire[4:0] sa, 15 | input wire[`ALU_OP_LENGTH - 1:0] cu_alu_op, 16 | 17 | output wire[31:0] alu_result, 18 | output wire overflow 19 | ); 20 | 21 | reg[32:0] alu_temp_result; 22 | assign alu_result = alu_temp_result[31:0]; 23 | 24 | // detect overflow 25 | assign overflow = (alu_temp_result[32] != alu_temp_result[31]) ? `OVERFLOW_TRUE : `OVERFLOW_FALSE; 26 | 27 | // displacement defined by sa or rs 28 | wire[4:0] displacement; 29 | assign displacement = 30 | (cu_alu_op == `ALU_OP_SLL || 31 | cu_alu_op == `ALU_OP_SRL || 32 | cu_alu_op == `ALU_OP_SRA) ? sa : alu_input_1[4:0]; 33 | 34 | // compare rs and rt 35 | wire[31:0] diff; 36 | assign diff = (alu_input_1 < alu_input_2) ? 32'h00000001 : 32'h00000000; 37 | 38 | always @ (*) begin 39 | case (cu_alu_op) 40 | // normal arithmetic operations 41 | `ALU_OP_ADD: 42 | alu_temp_result <= {alu_input_1[31], alu_input_1} + {alu_input_2[31], alu_input_2}; 43 | `ALU_OP_SUB: 44 | alu_temp_result <= {alu_input_1[31], alu_input_1} - {alu_input_2[31], alu_input_2}; 45 | 46 | `ALU_OP_SLT: 47 | alu_temp_result <= diff; 48 | 49 | // bit operations 50 | `ALU_OP_AND: 51 | alu_temp_result <= {alu_input_1[31], alu_input_1} & {alu_input_2[31], alu_input_2}; 52 | `ALU_OP_OR : 53 | alu_temp_result <= {alu_input_1[31], alu_input_1} | {alu_input_2[31], alu_input_2}; 54 | `ALU_OP_NOR: 55 | alu_temp_result <= (({alu_input_1[31], alu_input_1} & ~{alu_input_2[31], alu_input_2}) | 56 | (~{alu_input_1[31], alu_input_1} & {alu_input_2[31], alu_input_2})); 57 | `ALU_OP_XOR: 58 | alu_temp_result <= {alu_input_1[31], alu_input_1} ^ {alu_input_2[31], alu_input_2}; 59 | 60 | // shift left logically 61 | `ALU_OP_SLL: 62 | alu_temp_result <= {alu_input_2[31], alu_input_2} << displacement; 63 | `ALU_OP_SLLV: 64 | alu_temp_result <= {alu_input_2[31], alu_input_2} << displacement; 65 | 66 | // shift right logically 67 | `ALU_OP_SRL: 68 | alu_temp_result <= {alu_input_2[31], alu_input_2} >> displacement; 69 | `ALU_OP_SRLV: 70 | alu_temp_result <= {alu_input_2[31], alu_input_2} >> displacement; 71 | 72 | // shift right arithmetically 73 | `ALU_OP_SRA: 74 | alu_temp_result <= ({{31{alu_input_2[31]}}, 1'b0} << (~displacement)) | (alu_input_2 >> displacement); 75 | `ALU_OP_SRAV: 76 | alu_temp_result <= ({{31{alu_input_2[31]}}, 1'b0} << (~displacement)) | (alu_input_2 >> displacement); 77 | 78 | `ALU_OP_DEFAULT: 79 | alu_temp_result <= {alu_input_2[31], alu_input_2}; 80 | endcase 81 | end 82 | endmodule 83 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/branch_judge.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Branch Judge 6 | * 7 | * Input: .reg1_data .reg2_data 8 | * Output: .zero 9 | */ 10 | 11 | module branch_judge( 12 | input wire[31:0] reg1_data, 13 | input wire[31:0] reg2_data, 14 | 15 | output wire zero // Calculate whether rs - rt is zero 16 | ); 17 | 18 | // rs - rt = diff 19 | wire[32:0] diff; 20 | 21 | assign diff = {reg1_data[31], reg1_data} - {reg2_data[31], reg2_data}; 22 | assign zero = (diff == 0) ? `BRANCH_TRUE : `BRANCH_FALSE; 23 | endmodule 24 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/control_unit.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Control Unit 6 | */ 7 | 8 | module control_unit( 9 | input wire rst, 10 | input wire[5:0] opcode, // Instruction opcode 11 | input wire[4:0] sa, // Shift operation operand 12 | input wire[5:0] func, // R-Type instruction function 13 | input wire zero, 14 | 15 | output wire en_reg_write, 16 | output wire[`EXT_OP_LENGTH - 1:0] cu_ext_op, 17 | output wire cu_alu_src, 18 | output wire[`ALU_OP_LENGTH - 1:0] cu_alu_op, 19 | output wire en_mem_write, 20 | output wire[`REG_SRC_LENGTH - 1:0] cu_reg_src, 21 | output wire[`REG_DST_LENGTH - 1:0] cu_reg_dst, 22 | output wire[`NPC_OP_LENGTH - 1:0] cu_npc_op, 23 | output wire en_lw 24 | ); 25 | 26 | // Init instruction signals 27 | wire type_r, inst_add, inst_addu, inst_sub, inst_subu, inst_slt; 28 | wire inst_sltu, inst_and, inst_or, inst_nor, inst_xor, inst_sll; 29 | wire inst_srl, inst_sra, inst_sllv, inst_srlv, inst_srav, inst_jr; 30 | wire inst_jalr, inst_addi, inst_addiu, inst_sltiu; 31 | wire inst_andi, inst_ori, inst_xori, inst_lui, inst_lw, inst_sw; 32 | wire inst_beq, inst_bne, inst_j, inst_jal; 33 | 34 | /* --- Decode instructions --- */ 35 | 36 | // Whether instruction is R-Type 37 | assign type_r = (opcode == `INST_R_TYPE ) ? 1 : 0; 38 | // R-Type instructions 39 | assign inst_add = (type_r && func == `FUNC_ADD ) ? 1 : 0; 40 | assign inst_addu = (type_r && func == `FUNC_ADDU ) ? 1 : 0; 41 | assign inst_sub = (type_r && func == `FUNC_SUB ) ? 1 : 0; 42 | assign inst_subu = (type_r && func == `FUNC_SUBU ) ? 1 : 0; 43 | assign inst_slt = (type_r && func == `FUNC_SLT ) ? 1 : 0; 44 | assign inst_sltu = (type_r && func == `FUNC_SLTU ) ? 1 : 0; 45 | assign inst_and = (type_r && func == `FUNC_AND ) ? 1 : 0; 46 | assign inst_or = (type_r && func == `FUNC_OR ) ? 1 : 0; 47 | assign inst_nor = (type_r && func == `FUNC_NOR ) ? 1 : 0; 48 | assign inst_xor = (type_r && func == `FUNC_XOR ) ? 1 : 0; 49 | assign inst_sll = (type_r && func == `FUNC_SLL ) ? 1 : 0; 50 | assign inst_srl = (type_r && func == `FUNC_SRL ) ? 1 : 0; 51 | assign inst_sra = (type_r && func == `FUNC_SRA ) ? 1 : 0; 52 | assign inst_sllv = (type_r && func == `FUNC_SLLV ) ? 1 : 0; 53 | assign inst_srlv = (type_r && func == `FUNC_SRLV ) ? 1 : 0; 54 | assign inst_srav = (type_r && func == `FUNC_SRAV ) ? 1 : 0; 55 | assign inst_jr = (type_r && func == `FUNC_JR ) ? 1 : 0; 56 | assign inst_jalr = (type_r && func == `FUNC_JALR ) ? 1 : 0; 57 | 58 | // I-Type Instructions 59 | assign inst_addi = (opcode == `INST_ADDI ) ? 1 : 0; 60 | assign inst_addiu = (opcode == `INST_ADDIU ) ? 1 : 0; 61 | assign inst_sltiu = (opcode == `INST_SLTIU ) ? 1 : 0; 62 | assign inst_andi = (opcode == `INST_ANDI ) ? 1 : 0; 63 | assign inst_ori = (opcode == `INST_ORI ) ? 1 : 0; 64 | assign inst_xori = (opcode == `INST_XORI ) ? 1 : 0; 65 | assign inst_lui = (opcode == `INST_LUI ) ? 1 : 0; 66 | assign inst_lw = (opcode == `INST_LW ) ? 1 : 0; 67 | assign inst_sw = (opcode == `INST_SW ) ? 1 : 0; 68 | assign inst_beq = (opcode == `INST_BEQ ) ? 1 : 0; 69 | assign inst_bne = (opcode == `INST_BNE ) ? 1 : 0; 70 | 71 | // J-Type Instructions 72 | assign inst_j = (opcode == `INST_J ) ? 1 : 0; 73 | assign inst_jal = (opcode == `INST_JAL ) ? 1 : 0; 74 | 75 | /* --- Determine control signals --- */ 76 | 77 | // LW 78 | assign en_lw = inst_lw ? 1 : 0; 79 | 80 | // ALUOp 81 | assign cu_alu_op = 82 | (inst_addi || inst_addiu || inst_add || 83 | inst_addu || inst_lw || inst_sw ) ? `ALU_OP_ADD : // ADD 84 | (inst_sub || inst_subu || inst_beq ) ? `ALU_OP_SUB : // SUB 85 | (inst_slt || inst_sltu || inst_sltiu ) ? `ALU_OP_SLT : // SLT 86 | (inst_and || inst_andi ) ? `ALU_OP_AND : // AND 87 | (inst_or || inst_ori ) ? `ALU_OP_OR : // OR 88 | (inst_xor || inst_xori ) ? `ALU_OP_XOR : // XOR 89 | (inst_nor ) ? `ALU_OP_NOR : // NOR 90 | (inst_sll ) ? `ALU_OP_SLL : // SLL 91 | (inst_srl ) ? `ALU_OP_SRL : // SRL 92 | (inst_sra ) ? `ALU_OP_SRA : // SRA 93 | (inst_sllv ) ? `ALU_OP_SLLV : // SLLV 94 | (inst_srlv ) ? `ALU_OP_SRLV : // SRLV 95 | (inst_srav ) ? `ALU_OP_SRAV : // SRAV 96 | `ALU_OP_DEFAULT; // Default ALU operand (output the second ALU input) 97 | 98 | // RegDst 99 | assign cu_reg_dst = 100 | (inst_add || inst_addu || inst_sub || inst_subu || 101 | inst_slt || inst_sltu || inst_and || inst_or || 102 | inst_nor || inst_xor || inst_sll || inst_srl || 103 | inst_sra || inst_sllv || inst_srlv || inst_srav || 104 | inst_jalr ) ? `REG_DST_RD : 105 | (inst_lui || inst_addi || inst_addiu || inst_sltiu || 106 | inst_andi || inst_ori || inst_xori || inst_lw ) ? `REG_DST_RT : 107 | (inst_jal) ? `REG_DST_REG_31 : `REG_DST_DEFAULT; 108 | // ALUSrc 109 | assign cu_alu_src = 110 | (inst_addi || inst_addiu || inst_sltiu || inst_andi || 111 | inst_ori || inst_xori || inst_lw || inst_sw ) ? 1 : 0; 112 | 113 | // RegWrite 114 | assign en_reg_write = 115 | (inst_lui || type_r || inst_addi || inst_addiu || 116 | inst_sltiu || inst_andi || inst_ori || inst_xori || 117 | inst_add || inst_addu || inst_sub || inst_subu || 118 | inst_slt || inst_sltu || inst_and || inst_or || 119 | inst_nor || inst_xor || inst_sll || inst_srl || 120 | inst_sra || inst_sllv || inst_srlv || inst_srav || 121 | inst_lw || inst_jal || inst_jalr ) ? 1 : 0; 122 | 123 | // MemWrite 124 | assign en_mem_write = (inst_sw) ? 1 : 0; 125 | 126 | // RegSrc 127 | assign cu_reg_src = 128 | // Extended immediate 129 | (inst_lui ) ? `REG_SRC_IMM : 130 | 131 | // ALU result 132 | (inst_addi || inst_addiu || inst_sltiu || inst_andi || 133 | inst_ori || inst_xori || inst_add || inst_addu || 134 | inst_sub || inst_subu || inst_slt || inst_sltu || 135 | inst_and || inst_or || inst_nor || inst_xor || 136 | inst_sll || inst_srl || inst_sra || inst_sllv || 137 | inst_srlv || inst_srav ) ? `REG_SRC_ALU : 138 | 139 | // Data memory 140 | (inst_lw ) ? `REG_SRC_MEM : 141 | (inst_jal || inst_jalr ) ? `REG_SRC_JMP_DST : `REG_SRC_DEFAULT; 142 | 143 | // ExtOp 144 | assign cu_ext_op = 145 | // shift left 16 146 | (inst_lui ) ? `EXT_OP_SFT16 : 147 | // signed extend 148 | (inst_add || inst_addiu || inst_sltiu ) ? `EXT_OP_SIGNED : 149 | // unsigned extend 150 | (inst_andi || inst_ori || inst_xori || 151 | inst_lw || inst_sw ) ? `EXT_OP_UNSIGNED : `EXT_OP_DEFAULT; 152 | 153 | // NPCOp 154 | assign cu_npc_op = 155 | // normal: next instruction 156 | (inst_lui || inst_lw || inst_sw || inst_addi || 157 | inst_addiu || inst_sltiu || inst_andi || inst_ori || 158 | inst_xori || inst_add || inst_addu || inst_sub || 159 | inst_subu || inst_slt || inst_sltu || inst_and || 160 | inst_or || inst_nor || inst_xor || inst_sll || 161 | inst_srl || inst_sra || inst_sllv || inst_srlv || 162 | inst_srav ) ? `NPC_OP_NEXT : 163 | 164 | // BEQ 165 | // normal: next instruction 166 | (inst_beq && !zero) ? `NPC_OP_NEXT : 167 | // jump to target 168 | (inst_beq && zero) ? `NPC_OP_OFFSET : 169 | 170 | // BNE 171 | // normal: next instruction 172 | (inst_bne && zero) ? `NPC_OP_NEXT : 173 | // jump to target 174 | (inst_bne && !zero) ? `NPC_OP_OFFSET : 175 | 176 | // jump to instr_index 177 | (inst_j || inst_jal) ? `NPC_OP_JUMP : 178 | // jump to rs data 179 | (inst_jr || inst_jalr) ? `NPC_OP_RS : `NPC_OP_DEFAULT; 180 | endmodule 181 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/data_memory.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Data Memory 6 | * 7 | * Input: .clk .en_mem_write .mem_addr .write_mem_data 8 | * Output: .read_mem_data 9 | */ 10 | 11 | module data_memory( 12 | input wire clk, 13 | input wire en_mem_write, // enable memory write 14 | 15 | input wire[11:2] mem_addr, // memory target address 16 | input wire[31:0] write_mem_data, // write data to data memory 17 | 18 | output wire[31:0] read_mem_data // read data from data memory 19 | 20 | ); 21 | 22 | // Data Memory Storage 23 | reg[31:0] dm[`DM_LENGTH:0]; 24 | assign read_mem_data = dm[mem_addr]; 25 | 26 | always @ (posedge clk) begin 27 | if (en_mem_write) begin 28 | dm[mem_addr] <= write_mem_data; 29 | end 30 | end 31 | endmodule 32 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/definitions.vh: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | /* 4 | * Module: ZanPU Definition File 5 | */ 6 | 7 | /* --- Micellanenous --- */ 8 | 9 | // Instruction Memory Length 10 | `define IM_LENGTH 1023 11 | `define DM_LENGTH 1023 12 | 13 | `define REG_31_ADDR 5'b11111 14 | 15 | // Init reg/wire with zeros 16 | `define INIT_4 4'b0000 17 | `define INIT_5 5'b00000 18 | `define INIT_16 16'h0000 19 | `define INIT_32 32'h00000000 20 | 21 | /* --- Instruction Decode --- */ 22 | 23 | // R-Type instructions 24 | `define INST_R_TYPE 6'b000000 // R-Type opcode 25 | 26 | // func code 27 | `define FUNC_ADD 6'b100000 // ADD 28 | `define FUNC_ADDU 6'b100001 // ADDU 29 | `define FUNC_SUB 6'b100010 // SUB 30 | `define FUNC_SUBU 6'b100011 // SUBU 31 | `define FUNC_SLT 6'b101010 // SLT 32 | `define FUNC_SLTU 6'b101011 // SLTU 33 | `define FUNC_AND 6'b100100 // AND 34 | `define FUNC_OR 6'b100101 // OR 35 | `define FUNC_NOR 6'b100111 // NOR 36 | `define FUNC_XOR 6'b100110 // XOR 37 | `define FUNC_SLL 6'b000000 // SLL 38 | `define FUNC_SRL 6'b000010 // SRL 39 | `define FUNC_SRA 6'b000011 // SRA 40 | `define FUNC_SLLV 6'b000100 // SLLV 41 | `define FUNC_SRLV 6'b000110 // SRLV 42 | `define FUNC_SRAV 6'b000111 // SRAV 43 | 44 | `define FUNC_JR 6'b001000 // JR 45 | `define FUNC_JALR 6'b001001 // JALR 46 | 47 | // I-Type instructions 48 | `define INST_ADDI 6'b001000 // ADDI 49 | `define INST_ADDIU 6'b001001 // ADDIU 50 | `define INST_SLTIU 6'b001011 // SLTIU 51 | `define INST_ANDI 6'b001100 // ANDI 52 | `define INST_ORI 6'b001101 // ORI 53 | `define INST_XORI 6'b001110 // XORI 54 | `define INST_LUI 6'b001111 // LUI 55 | `define INST_LW 6'b100011 // LW 56 | `define INST_SW 6'b101011 // SW 57 | `define INST_BEQ 6'b000100 // BEQ 58 | `define INST_BNE 6'b000101 // BNE 59 | 60 | // J-Type instructions 61 | `define INST_J 6'b000010 // J 62 | `define INST_JAL 6'b000011 // JAL 63 | 64 | /* --- Control Signals --- */ 65 | 66 | // Register Write EN 67 | `define REG_WRITE_EN 1'b1 // Enable register write 68 | `define REG_WRITE_DIS 1'b0 // Disable register write 69 | 70 | // ExtOp Control Signals 71 | `define EXT_OP_LENGTH 2 // Length of Signal ExtOp 72 | `define EXT_OP_DEFAULT 2'b00 // ExtOp default value 73 | `define EXT_OP_SFT16 2'b01 // LUI: Shift Left 16 74 | `define EXT_OP_SIGNED 2'b10 // ADDIU: `imm16` signed extended to 32 bit 75 | `define EXT_OP_UNSIGNED 2'b11 // LW, SW: `imm16` unsigned extended to 32 bit 76 | 77 | // ALUSrc Control Signals 78 | `define ALU_SRC_REG 1'b0 // ALU source: register file 79 | `define ALU_SRC_IMM 1'b1 // ALU Source: immediate 80 | 81 | // ALU Control Signals 82 | `define ALU_OP_LENGTH 4 // Length of signal ALUOp 83 | `define ALU_OP_DEFAULT 4'b0000 // ALUOp default value 84 | `define ALU_OP_ADD 4'b0001 // ALU add 85 | `define ALU_OP_SUB 4'b0010 // ALU sub 86 | `define ALU_OP_SLT 4'b0011 // ALU slt 87 | `define ALU_OP_AND 4'b0100 // ALU and 88 | `define ALU_OP_OR 4'b0101 // ALU or 89 | `define ALU_OP_XOR 4'b0110 // ALU xor 90 | `define ALU_OP_NOR 4'b0111 // ALU nor 91 | `define ALU_OP_SLL 4'b1000 // ALU sll, with respect to sa 92 | `define ALU_OP_SRL 4'b1001 // ALU srl, with respect to sa 93 | `define ALU_OP_SRA 4'b1010 // ALU sra, with respect to sa 94 | `define ALU_OP_SLLV 4'b1011 // ALU sllv, with respect to rs 95 | `define ALU_OP_SRLV 4'b1100 // ALU srlv, with respect to rs 96 | `define ALU_OP_SRAV 4'b1101 // ALU srav, with respect to rs 97 | 98 | `define OVERFLOW_TRUE 1'b1 99 | `define OVERFLOW_FALSE 1'b0 100 | 101 | // Memory Write EN 102 | `define MEM_WRITE_EN 1'b1 // Enable memory write 103 | `define MEM_WRITE_DIS 1'b0 // Disable memory write 104 | 105 | // RegSrc Control Signals 106 | `define REG_SRC_LENGTH 3 // Length of signal RegSrc 107 | `define REG_SRC_DEFAULT 3'b000 // Register default value 108 | `define REG_SRC_ALU 3'b001 // Register write source: ALU 109 | `define REG_SRC_MEM 3'b010 // Register write source: Data Memory 110 | `define REG_SRC_IMM 3'b011 // Register write source: Extended immediate 111 | `define REG_SRC_JMP_DST 3'b100 // Register write source: Jump destination 112 | 113 | // RegDst Control Signals 114 | `define REG_DST_LENGTH 2 115 | `define REG_DST_DEFAULT 2'b00 // Register write destination: default 116 | `define REG_DST_RT 2'b01 // Register write destination: rt 117 | `define REG_DST_RD 2'b10 // Register write destination: rd 118 | `define REG_DST_REG_31 2'b11 // Register write destination: 31 bit gpr 119 | 120 | // NPCOp Control Signals 121 | `define NPC_OP_LENGTH 3 // Length of NPCOp 122 | `define NPC_OP_DEFAULT 3'b000 // NPCOp default value 123 | `define NPC_OP_NEXT 3'b001 // Next instruction: {PC + 4} 124 | `define NPC_OP_JUMP 3'b010 // Next instruction: {PC[31:28], instr_index, 2'b00} 125 | `define NPC_OP_OFFSET 3'b011 // Next instruction: {PC + 4 + offset} 126 | `define NPC_OP_RS 3'b100 // Next instruction: {rs} 127 | 128 | // Branching signals 129 | `define BRANCH_TRUE 1'b1 // Branch to true 130 | `define BRANCH_FALSE 1'b0 // Branch to false 131 | 132 | /* --- Hazard Control --- */ 133 | 134 | // Forward Control Signals 135 | `define FORWARD_ONE_CYCLE 2'b10 136 | `define FORWARD_TWO_CYCLE 2'b01 137 | 138 | // Stall IN Signals 139 | `define EXE_REGW 2'b01 140 | `define MEM_REGW 2'b10 141 | `define NON_REGW 2'b00 142 | 143 | // Stall Control Signals 144 | `define EXE_STALL 4'b0111 145 | `define MEM_STALL 4'b1111 146 | `define NON_STALL 4'b0000 147 | 148 | // LW init 149 | `define EN_LW_DEFAULT 1'b0 -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/extend.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Extend 6 | * 7 | * Input: .imm16 .cu_ext_op 8 | * Output: .extended_imm 9 | */ 10 | 11 | module extend( 12 | input wire[15:0] imm16, 13 | input wire[`EXT_OP_LENGTH - 1:0] cu_ext_op, 14 | 15 | output wire[31:0] extended_imm 16 | ); 17 | 18 | assign extended_imm = 19 | (cu_ext_op == `EXT_OP_SFT16) ? {imm16, 16'b0} : // LUI: shift left 16 20 | (cu_ext_op == `EXT_OP_SIGNED) ? {{16{imm16[15]}}, imm16} : // ADDIU: signed sign extend of imm16 21 | {16'b0, imm16}; // LW, SW: unsigned sign extend of imm16 22 | endmodule 23 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/forwarding_unit.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Forwarding Unit 6 | * 7 | * Input: 8 | * Output: 9 | */ 10 | 11 | module forwarding_unit( 12 | input wire en_ex_mem_regwrite, 13 | input wire[4:0] ex_mem_regdes, 14 | input wire[4:0] id_ex_rs, 15 | input wire[4:0] id_ex_rt, 16 | input wire en_mem_wb_regwrite, 17 | input wire[4:0] mem_wb_regdes, 18 | 19 | output wire[1:0] forward_A, 20 | output wire[1:0] forward_B 21 | ); 22 | 23 | assign forward_A = (en_ex_mem_regwrite == 1 && ex_mem_regdes == id_ex_rs) ? 2'b10: 24 | (en_mem_wb_regwrite == 1 && mem_wb_regdes == id_ex_rs && 25 | (ex_mem_regdes != id_ex_rs || en_ex_mem_regwrite == 0)) ? 2'b01 : 2'b00; 26 | 27 | assign forward_B = (en_ex_mem_regwrite == 1 && ex_mem_regdes == id_ex_rt) ? 2'b10: 28 | (en_mem_wb_regwrite == 1 && mem_wb_regdes == id_ex_rt && 29 | (ex_mem_regdes != id_ex_rt || en_ex_mem_regwrite == 0)) ? 2'b01 : 2'b00; 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/instruction_memory.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Instruction Memory 6 | * 7 | * Input: .instruction_addr 8 | * Output: .instruction 9 | */ 10 | 11 | module instruction_memory( 12 | input wire[11:2] instruction_addr, // PC fetch instruction address 13 | 14 | output wire[31:0] instruction // IM fetch instruction from register 15 | ); 16 | 17 | reg[31:0] im[`IM_LENGTH:0]; 18 | assign instruction = im[instruction_addr]; 19 | endmodule 20 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/mux.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Multiplexers 6 | */ 7 | 8 | module reg_dst_mux( 9 | input wire[`REG_DST_LENGTH - 1:0] cu_reg_dst, 10 | input wire[4:0] rt, 11 | input wire[4:0] rd, 12 | 13 | output wire[4:0] mux_out 14 | ); 15 | wire[4:0] reg_31; 16 | assign reg_31 = `REG_31_ADDR; 17 | 18 | assign mux_out = 19 | (cu_reg_dst == `REG_DST_RT ) ? rt : 20 | (cu_reg_dst == `REG_DST_RD ) ? rd : 21 | (cu_reg_dst == `REG_DST_REG_31) ? reg_31 : 22 | rt; 23 | endmodule 24 | 25 | module alu_src_mux( 26 | input wire cu_alu_src, 27 | input wire[31:0] rt, 28 | input wire[31:0] imm, 29 | 30 | output wire[31:0] mux_out 31 | ); 32 | 33 | assign mux_out = (cu_alu_src == `ALU_SRC_REG) ? rt : imm; 34 | endmodule 35 | 36 | module reg_src_mux( 37 | input wire[`REG_SRC_LENGTH - 1:0] cu_reg_src, 38 | input wire[31:0] alu_result, 39 | input wire[31:0] read_mem_data, 40 | input wire[31:0] extend_imm, 41 | input wire[31:0] jmp_dst, 42 | 43 | output wire[31:0] mux_out 44 | ); 45 | 46 | assign mux_out = 47 | (cu_reg_src == `REG_SRC_ALU ) ? alu_result : 48 | (cu_reg_src == `REG_SRC_MEM ) ? read_mem_data : 49 | (cu_reg_src == `REG_SRC_IMM ) ? extend_imm : 50 | (cu_reg_src == `REG_SRC_JMP_DST) ? jmp_dst : 51 | alu_result; 52 | endmodule 53 | 54 | module forward_mux( 55 | input wire[1:0] forward_C, 56 | input wire[31:0] rs_rt_imm, 57 | input wire[31:0] write_data, 58 | input wire[31:0] alu_result, 59 | 60 | output wire[31:0] mux_out 61 | ); 62 | 63 | assign mux_out = 64 | (forward_C == `FORWARD_ONE_CYCLE) ? alu_result : 65 | (forward_C == `FORWARD_TWO_CYCLE) ? write_data : 66 | rs_rt_imm; 67 | endmodule 68 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/npc.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Next Program Counter 6 | * 7 | * Input: .clk .pc .imm16 .imm26 .en_npc_op 8 | * Output: .npc 9 | */ 10 | 11 | module npc( 12 | input wire[31:0] pc, 13 | input wire[15:0] imm16, // 16 bit immediate 14 | input wire[25:0] imm26, // 26 bit immediate 15 | input wire[31:0] reg1_data, // rs data 16 | 17 | input wire[`NPC_OP_LENGTH - 1:0] cu_npc_op, // NPC control signal 18 | 19 | output wire[31:0] npc, // next program counter 20 | output wire[31:0] jmp_dst // JAL, JAJR jump dst 21 | ); 22 | 23 | wire[31:0] pc_4; 24 | assign pc_4 = pc + 32'h4; 25 | 26 | assign jmp_dst = pc + 32'h8; 27 | 28 | assign npc = 29 | (cu_npc_op == `NPC_OP_NEXT ) ? pc_4 : // pc + 4 30 | (cu_npc_op == `NPC_OP_JUMP ) ? {pc[31:28], imm26, 2'b00} : // pc = target 31 | (cu_npc_op == `NPC_OP_OFFSET) ? {pc_4 + {{14{imm16[15]}}, {imm16, 2'b00}}} : // pc + 4 + offset 32 | (cu_npc_op == `NPC_OP_RS ) ? reg1_data : // pc = rs data 33 | pc_4; // fallback mode: pc + 4 34 | endmodule 35 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/pc.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU PC 6 | * 7 | * Input: .clk .rst .npc 8 | * Output: .pc 9 | */ 10 | 11 | module pc( 12 | input wire clk, 13 | input wire rst, 14 | input wire[31:0] npc, 15 | 16 | input wire[3:0] stall_C, 17 | 18 | output reg[31:0] pc 19 | ); 20 | 21 | always @ (posedge clk or posedge rst) begin 22 | if (rst) begin 23 | pc <= `INIT_32; 24 | end 25 | else if(stall_C[0] == 0) begin 26 | pc <= npc; 27 | end 28 | else begin 29 | 30 | end 31 | end 32 | endmodule 33 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/reg_ex_mem.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU EX/MEM Register 6 | * 7 | * Input: 8 | * Output: 9 | */ 10 | 11 | module reg_ex_mem( 12 | input wire clk, 13 | input wire rst, 14 | input wire[31:0] alu_result_in, 15 | input wire[31:0] reg2_data_in, 16 | input wire[31:0] jmp_dst_in, 17 | input wire[31:0] extended_imm_in, 18 | input wire[4:0] destination_reg_in, 19 | 20 | input wire en_mem_write_in, 21 | input wire[`REG_SRC_LENGTH - 1:0] cu_reg_src_in, 22 | input wire en_reg_write_in, 23 | input wire en_lw_ex_mem_in, 24 | input wire[3:0] stall_C, 25 | 26 | output reg[31:0] alu_result_out, 27 | output reg[31:0] reg2_data_out, 28 | output reg[31:0] jmp_dst_out, 29 | output reg[31:0] extended_imm_out, 30 | output reg[4:0] destination_reg_out, 31 | 32 | output reg en_mem_write_out, 33 | output reg[`REG_SRC_LENGTH - 1:0] cu_reg_src_out, 34 | output reg en_reg_write_out, 35 | output reg en_lw_ex_mem_out 36 | ); 37 | 38 | // if rst/halt, zeroize all registers 39 | wire zeroize; 40 | assign zeroize = rst; 41 | 42 | always @ (posedge clk) begin 43 | if (zeroize) begin 44 | alu_result_out <= `INIT_32; 45 | reg2_data_out <= `INIT_32; 46 | jmp_dst_out <= `INIT_32; 47 | extended_imm_out <= `INIT_32; 48 | destination_reg_out <= `INIT_5; 49 | en_mem_write_out <= `MEM_WRITE_DIS; 50 | cu_reg_src_out <= `REG_SRC_DEFAULT; 51 | en_reg_write_out <= `REG_WRITE_DIS; 52 | en_lw_ex_mem_out <= `EN_LW_DEFAULT; 53 | end 54 | else if(stall_C[3] == 0) begin 55 | alu_result_out <= alu_result_in; 56 | reg2_data_out <= reg2_data_in; 57 | jmp_dst_out <= jmp_dst_in; 58 | extended_imm_out <= extended_imm_in; 59 | destination_reg_out <= destination_reg_in; 60 | en_mem_write_out <= en_mem_write_in; 61 | cu_reg_src_out <= cu_reg_src_in; 62 | en_reg_write_out <= en_reg_write_in; 63 | en_lw_ex_mem_out <= en_lw_ex_mem_in; 64 | end 65 | else begin 66 | alu_result_out <= `INIT_32; 67 | reg2_data_out <= `INIT_32; 68 | jmp_dst_out <= `INIT_32; 69 | extended_imm_out <= `INIT_32; 70 | destination_reg_out <= `INIT_5; 71 | en_mem_write_out <= `MEM_WRITE_DIS; 72 | cu_reg_src_out <= `REG_SRC_DEFAULT; 73 | en_reg_write_out <= `REG_WRITE_DIS; 74 | en_lw_ex_mem_out <= `EN_LW_DEFAULT; 75 | end 76 | end 77 | 78 | 79 | endmodule 80 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/reg_id_ex.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU ID/EX Register 6 | * 7 | * Input: 8 | * Output: 9 | */ 10 | 11 | module reg_id_ex( 12 | input wire clk, 13 | input wire rst, 14 | input wire[31:0] reg1_data_in, 15 | input wire[31:0] reg2_data_in, 16 | input wire[31:0] jmp_dst_in, 17 | input wire[4:0] rs_in, 18 | input wire[4:0] rt_in, 19 | input wire[4:0] rd_in, 20 | input wire[4:0] sa_in, 21 | input wire[15:0] imm16_in, 22 | 23 | input wire en_reg_write_in, 24 | input wire en_lw_id_ex_in, 25 | input wire[`EXT_OP_LENGTH - 1:0] cu_ext_op_in, 26 | input wire cu_alu_src_in, 27 | input wire[`ALU_OP_LENGTH - 1:0] cu_alu_op_in, 28 | input wire en_mem_write_in, 29 | input wire[`REG_SRC_LENGTH - 1:0] cu_reg_src_in, 30 | input wire[`REG_DST_LENGTH - 1:0] cu_reg_dst_in, 31 | input wire[3:0] stall_C, 32 | input wire[31:0] lw_stall_data, 33 | input wire[4:0] lw_mem_addr, 34 | 35 | output reg[31:0] reg1_data_out, 36 | output reg[31:0] reg2_data_out, 37 | output reg[31:0] jmp_dst_out, 38 | output reg[4:0] rs_out, 39 | output reg[4:0] rt_out, 40 | output reg[4:0] rd_out, 41 | output reg[4:0] sa_out, 42 | output reg[15:0] imm16_out, 43 | 44 | output reg en_reg_write_out, 45 | output reg en_lw_id_ex_out, 46 | output reg[`EXT_OP_LENGTH - 1:0] cu_ext_op_out, 47 | output reg cu_alu_src_out, 48 | output reg[`ALU_OP_LENGTH - 1:0] cu_alu_op_out, 49 | output reg en_mem_write_out, 50 | output reg[`REG_SRC_LENGTH - 1:0] cu_reg_src_out, 51 | output reg[`REG_DST_LENGTH - 1:0] cu_reg_dst_out 52 | ); 53 | 54 | // if rst/halt, zeroize all registers 55 | wire zeroize; 56 | assign zeroize = rst; 57 | 58 | // state machine for stalling 59 | reg[1:0] temp_state; 60 | reg[31:0] tempdata_1; 61 | reg[31:0] tempdata_2; 62 | 63 | always @ (posedge clk) begin 64 | if (stall_C[2] == 1 && stall_C[3] == 1 && lw_mem_addr == rs_in) begin 65 | tempdata_1 <= lw_stall_data; 66 | temp_state <= 2'b01; 67 | end 68 | if (stall_C[2] == 1 && stall_C[3] == 1 && lw_mem_addr == rt_in) begin 69 | tempdata_2 <= lw_stall_data; 70 | temp_state <= 2'b10; 71 | end 72 | 73 | if (zeroize) begin 74 | reg1_data_out <= `INIT_32; 75 | reg2_data_out <= `INIT_32; 76 | jmp_dst_out <= `INIT_32; 77 | rs_out <= `INIT_5; 78 | rt_out <= `INIT_5; 79 | rd_out <= `INIT_5; 80 | sa_out <= `INIT_5; 81 | imm16_out <= `INIT_16; 82 | 83 | en_reg_write_out <= `REG_WRITE_DIS; 84 | en_lw_id_ex_out <= `EN_LW_DEFAULT; 85 | cu_ext_op_out <= `EXT_OP_DEFAULT; 86 | cu_alu_src_out <= `ALU_SRC_REG; 87 | cu_alu_op_out <= `ALU_OP_DEFAULT; 88 | en_mem_write_out <= `MEM_WRITE_DIS; 89 | cu_reg_src_out <= `REG_SRC_DEFAULT; 90 | cu_reg_dst_out <= `REG_DST_DEFAULT; 91 | tempdata_1 <= `INIT_32; 92 | tempdata_2 <= `INIT_32; 93 | temp_state <= 2'b00; 94 | end 95 | else if(stall_C[2] == 0) begin 96 | if (temp_state == 2'b01) begin 97 | reg1_data_out <= tempdata_1; 98 | reg2_data_out <= reg2_data_in; 99 | temp_state <= 2'b00; 100 | end 101 | else if(temp_state == 2'b10) begin 102 | reg1_data_out <= reg1_data_in; 103 | reg2_data_out <= tempdata_2; 104 | temp_state <= 2'b00; 105 | end 106 | else begin 107 | reg1_data_out <= reg1_data_in; 108 | reg2_data_out <= reg2_data_in; 109 | end 110 | 111 | jmp_dst_out <= jmp_dst_in; 112 | rs_out <= rs_in; 113 | rt_out <= rt_in; 114 | rd_out <= rd_in; 115 | sa_out <= sa_in; 116 | imm16_out <= imm16_in; 117 | 118 | en_reg_write_out <= en_reg_write_in; 119 | en_lw_id_ex_out <= en_lw_id_ex_in; 120 | cu_ext_op_out <= cu_ext_op_in; 121 | cu_alu_src_out <= cu_alu_src_in; 122 | cu_alu_op_out <= cu_alu_op_in; 123 | en_mem_write_out <= en_mem_write_in; 124 | cu_reg_src_out <= cu_reg_src_in; 125 | cu_reg_dst_out <= cu_reg_dst_in; 126 | end 127 | else if(stall_C[2] == 1 && stall_C[3] == 0) begin 128 | reg1_data_out <= `INIT_32; 129 | reg2_data_out <= `INIT_32; 130 | jmp_dst_out <= `INIT_32; 131 | rs_out <= `INIT_5; 132 | rt_out <= `INIT_5; 133 | rd_out <= `INIT_5; 134 | sa_out <= `INIT_5; 135 | imm16_out <= `INIT_16; 136 | 137 | en_reg_write_out <= `REG_WRITE_DIS; 138 | en_lw_id_ex_out <= `EN_LW_DEFAULT; 139 | cu_ext_op_out <= `EXT_OP_DEFAULT; 140 | cu_alu_src_out <= `ALU_SRC_REG; 141 | cu_alu_op_out <= `ALU_OP_DEFAULT; 142 | en_mem_write_out <= `MEM_WRITE_DIS; 143 | cu_reg_src_out <= `REG_SRC_DEFAULT; 144 | cu_reg_dst_out <= `REG_DST_DEFAULT; 145 | end 146 | else begin 147 | // do nothing 148 | end 149 | end 150 | 151 | endmodule 152 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/reg_if_id.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU IF/ID Register 6 | * 7 | * Input: .clk .rst .pc_in .instructions_in 8 | * Output: .pc_out .instructions_out 9 | */ 10 | 11 | module reg_if_id( 12 | input wire clk, 13 | input wire rst, 14 | input wire[31:0] instructions_in, 15 | input wire[3:0] stall_C, 16 | 17 | output reg[31:0] instructions_out 18 | ); 19 | 20 | // if rst/halt, zeroize all registers 21 | wire zeroize; 22 | assign zeroize = rst; 23 | 24 | always @ (posedge clk) begin 25 | if (zeroize) begin 26 | instructions_out <= `INIT_32; 27 | end 28 | else if(stall_C[1] == 0) begin 29 | instructions_out <= instructions_in; 30 | end 31 | else begin 32 | // do nothing 33 | end 34 | end 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/reg_mem_wb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU MEM/WB Register 6 | * 7 | * Input: 8 | * Output: 9 | */ 10 | 11 | module reg_mem_wb( 12 | input wire clk, 13 | input wire rst, 14 | input wire[31:0] alu_result_in, 15 | input wire[31:0] read_mem_data_in, 16 | input wire[31:0] jmp_dst_in, 17 | input wire[31:0] extended_imm_in, 18 | input wire[4:0] destination_reg_in, 19 | 20 | input wire[`REG_SRC_LENGTH - 1:0] cu_reg_src_in, 21 | input wire en_reg_write_in, 22 | input wire en_lw_mem_wb_in, 23 | 24 | output reg[31:0] alu_result_out, 25 | output reg[31:0] read_mem_data_out, 26 | output reg[31:0] jmp_dst_out, 27 | output reg[31:0] extended_imm_out, 28 | output reg[4:0] destination_reg_out, 29 | 30 | output reg[`REG_SRC_LENGTH - 1:0] cu_reg_src_out, 31 | output reg en_reg_write_out, 32 | output reg en_lw_mem_wb_out 33 | ); 34 | 35 | 36 | // if rst/halt, zeroize all registers 37 | wire zeroize; 38 | assign zeroize = rst; 39 | 40 | always @ (posedge clk) begin 41 | if (zeroize) begin 42 | alu_result_out <= `INIT_32; 43 | read_mem_data_out <= `INIT_32; 44 | jmp_dst_out <= `INIT_32; 45 | extended_imm_out <= `INIT_32; 46 | destination_reg_out <= `INIT_32; 47 | cu_reg_src_out <= `REG_SRC_DEFAULT; 48 | en_reg_write_out <= `REG_WRITE_DIS; 49 | en_lw_mem_wb_out <= `EN_LW_DEFAULT; 50 | end 51 | else begin 52 | alu_result_out <= alu_result_in; 53 | read_mem_data_out <= read_mem_data_in; 54 | jmp_dst_out <= jmp_dst_in; 55 | extended_imm_out <= extended_imm_in; 56 | destination_reg_out <= destination_reg_in; 57 | cu_reg_src_out <= cu_reg_src_in; 58 | en_reg_write_out <= en_reg_write_in; 59 | en_lw_mem_wb_out <= en_lw_mem_wb_in; 60 | end 61 | end 62 | endmodule 63 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/register_file.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Register File 6 | * 7 | * Input: 8 | * Output: 9 | */ 10 | 11 | module register_file( 12 | input wire clk, 13 | input wire[4:0] rs, 14 | input wire[4:0] rt, 15 | input wire[4:0] write_reg_addr, // rs or rd, defined in WB stage 16 | input wire[31:0] write_data, // write data back to dest reg 17 | input wire[4:0] dst_reg_exe, // dst_reg in stage-ex 18 | input wire[4:0] dst_reg_mem, // dst_reg in stage-mem 19 | 20 | input wire en_reg_write, // enable register write 21 | input wire en_reg_write_exe, 22 | input wire en_reg_write_mem, 23 | input wire en_lw_exe, 24 | input wire en_lw_mem, 25 | 26 | output wire[31:0] reg1_data, 27 | output wire[31:0] reg2_data, 28 | output wire[1:0] stall_signal 29 | ); 30 | 31 | // Register file general purpose register 32 | reg[31:0] gpr[31:0]; 33 | 34 | // Get register data from GPR 35 | assign reg1_data = (rs == `INIT_5) ? `INIT_32 : gpr[rs]; 36 | assign reg2_data = (rt == `INIT_5) ? `INIT_32 : gpr[rt]; 37 | 38 | // Write data back to register 39 | always @ (posedge clk) begin 40 | if (en_reg_write) begin 41 | gpr[write_reg_addr] = write_data; 42 | end 43 | end 44 | 45 | assign stall_signal = ((en_reg_write_mem && en_lw_mem) && (dst_reg_mem == rs)) ? `MEM_REGW : 46 | ((en_reg_write_mem && en_lw_mem) && (dst_reg_mem == rt)) ? `MEM_REGW : 47 | ((en_reg_write_exe && en_lw_exe) && (dst_reg_exe == rs)) ? `EXE_REGW : 48 | ((en_reg_write_exe && en_lw_exe) && (dst_reg_exe == rt)) ? `EXE_REGW : 49 | `NON_REGW; 50 | 51 | endmodule 52 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/stall_unit.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Stall Unit 6 | * 7 | * Input: 8 | * Output: 9 | */ 10 | 11 | module stall_unit( 12 | input wire[1:0] stall_in, 13 | output wire[3:0] stall_C 14 | ); 15 | 16 | assign stall_C = 17 | (stall_in == `EXE_REGW) ? `EXE_STALL : 18 | (stall_in == `MEM_REGW) ? `MEM_STALL : `NON_STALL; 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /pipelined-zanpu.srcs/sources_1/new/zanpu_top.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `include "definitions.vh" 3 | 4 | /* 5 | * Module: ZanPU Top Module 6 | * 7 | * Input: .clk .rst 8 | * Output: 9 | */ 10 | 11 | module zanpu_top( 12 | input wire clk, 13 | input wire rst 14 | ); 15 | 16 | /* 17 | * Instantiate modules 18 | */ 19 | 20 | /* --- Stage 1: Instruction Fetch --- */ 21 | 22 | /* pc, npc and instruction_memory */ 23 | 24 | wire[31:0] pc; 25 | wire[31:0] npc; 26 | wire[31:0] instruction; 27 | wire[3:0] stall_C; 28 | wire[1:0] stall_op; 29 | 30 | pc u_pc( 31 | .clk (clk ), 32 | .rst (rst ), 33 | .npc (npc ), 34 | .stall_C (stall_C), 35 | .pc (pc ) 36 | ); 37 | 38 | instruction_memory u_instruction_memory( 39 | .instruction_addr (pc[11:2] ), 40 | .instruction (instruction ) 41 | ); 42 | 43 | 44 | 45 | /* id/id register */ 46 | 47 | wire[31:0] instruction_out; 48 | 49 | reg_if_id u_reg_if_id( 50 | .clk (clk ), 51 | .rst (rst ), 52 | .instructions_in (instruction ), 53 | .stall_C (stall_C ), 54 | .instructions_out (instruction_out ) 55 | ); 56 | 57 | /* --- Stage 2: Instruction Decode --- */ 58 | 59 | // Decode instruction type and function 60 | wire[5:0] opcode; 61 | wire[5:0] func; 62 | 63 | // Decode registers 64 | wire[4:0] rs; 65 | wire[4:0] rt; 66 | wire[4:0] rd; 67 | wire[4:0] sa; 68 | 69 | // Decode 16 bit and 26 bit immediates 70 | wire[15:0] imm16; 71 | wire[25:0] imm26; 72 | 73 | // Assign decoded instruction to variables 74 | assign opcode = instruction[31:26]; 75 | assign func = instruction[5:0]; 76 | assign rs = instruction[25:21]; 77 | assign rt = instruction[20:16]; 78 | assign rd = instruction[15:11]; 79 | assign sa = instruction[10:6]; 80 | assign imm16 = instruction[15:0]; 81 | assign imm26 = instruction[25:0]; 82 | 83 | wire[4:0] write_reg_addr; 84 | wire[31:0] write_data; 85 | wire[31:0] reg1_data; 86 | wire[31:0] reg2_data; 87 | 88 | wire zero; 89 | wire en_reg_write; 90 | wire[`EXT_OP_LENGTH - 1:0] cu_ext_op; 91 | wire cu_alu_src; 92 | wire[`ALU_OP_LENGTH - 1:0] cu_alu_op; 93 | wire en_mem_write; 94 | wire[`REG_SRC_LENGTH - 1:0] cu_reg_src; 95 | wire[`REG_DST_LENGTH - 1:0] cu_reg_dst; 96 | wire[`NPC_OP_LENGTH - 1:0] cu_npc_op; 97 | wire en_lw; 98 | 99 | control_unit u_control_unit( 100 | .rst (rst ), 101 | .opcode (opcode ), 102 | .sa (sa ), 103 | .func (func ), 104 | .zero (zero ), 105 | .en_reg_write (en_reg_write ), 106 | .cu_ext_op (cu_ext_op ), 107 | .cu_alu_src (cu_alu_src ), 108 | .cu_alu_op (cu_alu_op ), 109 | .en_mem_write (en_mem_write ), 110 | .cu_reg_src (cu_reg_src ), 111 | .cu_reg_dst (cu_reg_dst ), 112 | .cu_npc_op (cu_npc_op ), 113 | .en_lw (en_lw) 114 | ); 115 | 116 | wire[4:0] destination_reg_wb; 117 | wire en_reg_write_wb; 118 | wire[4:0] destination_reg; 119 | wire[4:0] destination_reg_out; 120 | wire en_reg_write_out; 121 | wire en_reg_write_mem; 122 | wire en_lw_id_ex_out; 123 | wire en_lw_ex_mem_out; 124 | 125 | register_file u_register_file( 126 | .clk (clk ), 127 | .rs (rs ), 128 | .rt (rt ), 129 | .write_reg_addr (destination_reg_wb ), 130 | .write_data (write_data ), 131 | .dst_reg_exe (destination_reg ), 132 | .dst_reg_mem (destination_reg_out), 133 | .en_reg_write (en_reg_write_wb ), 134 | .en_reg_write_exe(en_reg_write_out ), 135 | .en_reg_write_mem(en_reg_write_mem ), 136 | .en_lw_exe (en_lw_id_ex_out ), 137 | .en_lw_mem (en_lw_ex_mem_out ), 138 | .reg1_data (reg1_data ), 139 | .reg2_data (reg2_data ), 140 | .stall_signal (stall_op ) 141 | ); 142 | 143 | wire[31:0] jmp_dst; 144 | 145 | stall_unit u_stall_unit( 146 | .stall_in (stall_op ), 147 | .stall_C (stall_C ) 148 | ); 149 | 150 | npc u_npc( 151 | .pc (pc ), 152 | .imm16 (imm16 ), 153 | .imm26 (imm26 ), 154 | .reg1_data (reg1_data ), 155 | .cu_npc_op (cu_npc_op ), 156 | .npc (npc ), 157 | .jmp_dst (jmp_dst ) 158 | ); 159 | 160 | branch_judge u_branch_judge( 161 | .reg1_data (reg1_data ), 162 | .reg2_data (reg2_data ), 163 | .zero (zero ) 164 | ); 165 | 166 | wire[31:0] reg1_data_out; 167 | wire[31:0] reg2_data_out; 168 | wire[31:0] jmp_dst_out; 169 | wire[4:0] rs_out; 170 | wire[4:0] rt_out; 171 | wire[4:0] rd_out; 172 | wire[4:0] sa_out; 173 | wire[15:0] imm16_out; 174 | wire[`EXT_OP_LENGTH - 1:0] cu_ext_op_out; 175 | wire cu_alu_src_out; 176 | wire[`ALU_OP_LENGTH - 1:0] cu_alu_op_out; 177 | wire en_mem_write_out; 178 | wire[`REG_SRC_LENGTH - 1:0] cu_reg_src_out; 179 | wire[`REG_DST_LENGTH - 1:0] cu_reg_dst_out; 180 | wire[31:0] read_mem_data; 181 | wire[31:0] read_mem_data_out; 182 | 183 | reg_id_ex u_reg_id_ex( 184 | .clk (clk ), 185 | .rst (rst ), 186 | .reg1_data_in (reg1_data ), 187 | .reg2_data_in (reg2_data ), 188 | .jmp_dst_in (jmp_dst ), 189 | .rs_in (rs ), 190 | .rt_in (rt ), 191 | .rd_in (rd ), 192 | .sa_in (sa ), 193 | .imm16_in (imm16 ), 194 | .en_reg_write_in (en_reg_write ), 195 | .en_lw_id_ex_in (en_lw ), 196 | .cu_ext_op_in (cu_ext_op ), 197 | .cu_alu_src_in (cu_alu_src ), 198 | .cu_alu_op_in (cu_alu_op ), 199 | .en_mem_write_in (en_mem_write ), 200 | .cu_reg_src_in (cu_reg_src ), 201 | .cu_reg_dst_in (cu_reg_dst ), 202 | .stall_C (stall_C ), 203 | .lw_stall_data (read_mem_data ), 204 | .lw_mem_addr (destination_reg_out), 205 | .reg1_data_out (reg1_data_out ), 206 | .reg2_data_out (reg2_data_out ), 207 | .jmp_dst_out (jmp_dst_out ), 208 | .rs_out (rs_out ), 209 | .rt_out (rt_out ), 210 | .rd_out (rd_out ), 211 | .sa_out (sa_out ), 212 | .imm16_out (imm16_out ), 213 | .en_reg_write_out (en_reg_write_out ), 214 | .en_lw_id_ex_out (en_lw_id_ex_out ), 215 | .cu_ext_op_out (cu_ext_op_out ), 216 | .cu_alu_src_out (cu_alu_src_out ), 217 | .cu_alu_op_out (cu_alu_op_out ), 218 | .en_mem_write_out (en_mem_write_out ), 219 | .cu_reg_src_out (cu_reg_src_out ), 220 | .cu_reg_dst_out (cu_reg_dst_out ) 221 | ); 222 | 223 | /* --- Stage 3: Execution --- */ 224 | 225 | wire[31:0] extended_imm; 226 | 227 | extend u_extend( 228 | .imm16 (imm16_out ), 229 | .cu_ext_op (cu_ext_op_out ), 230 | .extended_imm (extended_imm ) 231 | ); 232 | 233 | 234 | reg_dst_mux u_reg_dst_mux( 235 | .cu_reg_dst (cu_reg_dst_out ), 236 | .rt (rt_out ), 237 | .rd (rd_out ), 238 | .mux_out (destination_reg ) 239 | ); 240 | 241 | wire[31:0] alu_src_mux_out; 242 | wire[31:0] alu_result; 243 | wire[31:0] forward_mux_out_1; 244 | wire[31:0] forward_mux_out_2; 245 | 246 | alu_src_mux u_alu_src_mux( 247 | .cu_alu_src (cu_alu_src_out ), 248 | .rt (forward_mux_out_2 ), 249 | .imm (extended_imm ), 250 | .mux_out (alu_src_mux_out ) 251 | ); 252 | 253 | 254 | alu u_alu( 255 | .alu_input_1 (forward_mux_out_1 ), 256 | .alu_input_2 (alu_src_mux_out ), 257 | .sa (sa_out ), 258 | .cu_alu_op (cu_alu_op_out ), 259 | .alu_result (alu_result ) 260 | ); 261 | 262 | wire[1:0] forward_A; 263 | wire[1:0] forward_B; 264 | 265 | // control signals to be forwarded to MEM stage 266 | wire en_mem_write_mem; 267 | wire[`REG_SRC_LENGTH - 1:0] cu_reg_src_mem; 268 | 269 | wire[31:0] alu_result_out; 270 | wire[31:0] reg2_data_mem; 271 | wire[31:0] extended_imm_out; 272 | 273 | forwarding_unit u_forwarding_unit( 274 | .en_ex_mem_regwrite (en_reg_write_mem ), 275 | .ex_mem_regdes (destination_reg_out ), 276 | .id_ex_rs (rs_out ), 277 | .id_ex_rt (rt_out ), 278 | .en_mem_wb_regwrite (en_reg_write_wb ), 279 | .mem_wb_regdes (destination_reg_wb ), 280 | .forward_A (forward_A ), 281 | .forward_B (forward_B ) 282 | ); 283 | 284 | forward_mux u_forward_mux_1( 285 | .forward_C (forward_A ), 286 | .rs_rt_imm (reg1_data_out ), 287 | .write_data (write_data ), 288 | .alu_result (alu_result_out ), 289 | .mux_out (forward_mux_out_1 ) 290 | ); 291 | 292 | forward_mux u_forward_mux_2( 293 | .forward_C (forward_B ), 294 | .rs_rt_imm (reg2_data_out ), 295 | .write_data (write_data ), 296 | .alu_result (alu_result_out ), 297 | .mux_out (forward_mux_out_2 ) 298 | ); 299 | 300 | wire[31:0] jmp_dst_mem; 301 | 302 | reg_ex_mem u_reg_ex_mem( 303 | .clk (clk ), 304 | .rst (rst ), 305 | .alu_result_in (alu_result ), 306 | .reg2_data_in (reg2_data_out ), 307 | .jmp_dst_in (jmp_dst_out ), 308 | .extended_imm_in (extended_imm ), 309 | .destination_reg_in (destination_reg ), 310 | .en_mem_write_in (en_mem_write ), 311 | .cu_reg_src_in (cu_reg_src_out ), 312 | .en_reg_write_in (en_reg_write_out ), 313 | .en_lw_ex_mem_in (en_lw_id_ex_out ), 314 | .stall_C (stall_C ), 315 | .alu_result_out (alu_result_out ), 316 | .reg2_data_out (reg2_data_mem ), 317 | .jmp_dst_out (jmp_dst_mem ), 318 | .extended_imm_out (extended_imm_out ), 319 | .destination_reg_out (destination_reg_out ), 320 | .en_mem_write_out (en_mem_write_mem ), 321 | .cu_reg_src_out (cu_reg_src_mem ), 322 | .en_reg_write_out (en_reg_write_mem ), 323 | .en_lw_ex_mem_out (en_lw_ex_mem_out ) 324 | ); 325 | 326 | /* --- Stage 4: Memory --- */ 327 | 328 | data_memory u_data_memory( 329 | .clk (clk ), 330 | .en_mem_write (en_mem_write_mem ), 331 | .mem_addr (alu_result_out[11:2] ), 332 | .write_mem_data (reg2_data_mem ), 333 | .read_mem_data (read_mem_data ) 334 | ); 335 | 336 | wire[31:0] alu_result_wb; 337 | wire[31:0] extended_imm_wb; 338 | wire[`REG_SRC_LENGTH - 1:0] cu_reg_src_wb; 339 | 340 | wire[31:0] jmp_dst_wb; 341 | wire en_lw_mem_wb_out; 342 | 343 | reg_mem_wb u_reg_mem_wb( 344 | .clk (clk ), 345 | .rst (rst ), 346 | .alu_result_in (alu_result_out ), 347 | .read_mem_data_in (read_mem_data ), 348 | .jmp_dst_in (jmp_dst_mem ), 349 | .extended_imm_in (extended_imm_out ), 350 | .destination_reg_in (destination_reg_out ), 351 | .en_lw_mem_wb_in (en_lw_ex_mem_out ), 352 | .cu_reg_src_in (cu_reg_src_mem ), 353 | .en_reg_write_in (en_reg_write_mem ), 354 | .alu_result_out (alu_result_wb ), 355 | .read_mem_data_out (read_mem_data_out ), 356 | .jmp_dst_out (jmp_dst_wb ), 357 | .extended_imm_out (extended_imm_wb ), 358 | .destination_reg_out (destination_reg_wb ), 359 | .cu_reg_src_out (cu_reg_src_wb ), 360 | .en_reg_write_out (en_reg_write_wb ), 361 | .en_lw_mem_wb_out (en_lw_mem_wb_out ) 362 | ); 363 | 364 | /* --- Stage 5: Writeback --- */ 365 | 366 | reg_src_mux u_reg_src_mux( 367 | .cu_reg_src (cu_reg_src_wb ), 368 | .alu_result (alu_result_wb ), 369 | .read_mem_data (read_mem_data_out ), 370 | .extend_imm (extended_imm_wb ), 371 | .jmp_dst (jmp_dst_wb ), 372 | .mux_out (write_data ) 373 | ); 374 | endmodule 375 | -------------------------------------------------------------------------------- /pipelined-zanpu.tbcode/data_memory.txt: -------------------------------------------------------------------------------- 1 | 0x00000001 2 | 0x00000002 3 | 0x00000003 4 | 0x00000004 5 | 0x00000005 6 | 0x00000006 7 | 0x00000007 8 | 0x00000008 9 | 0x00000009 10 | 0x0000000a 11 | -------------------------------------------------------------------------------- /pipelined-zanpu.tbcode/instructions.txt: -------------------------------------------------------------------------------- 1 | 0x00223020 2 | 0x8c620004 3 | 0x00455024 4 | 0x01414827 5 | 0x0c100007 6 | 0x00000000 7 | 0x3c0b1011 8 | 0x3c081028 9 | -------------------------------------------------------------------------------- /pipelined-zanpu.tbcode/register.txt: -------------------------------------------------------------------------------- 1 | 0x00000000 2 | 0x00000001 3 | 0x00000002 4 | 0x00000004 5 | 0x00000006 6 | 0x00000007 7 | 0x00000008 8 | 0x00000009 9 | 0x00000000 10 | 0x00000000 11 | 0x00000000 12 | 0x00000000 13 | -------------------------------------------------------------------------------- /pipelined-zanpu.xpr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 177 | 178 | 179 | 180 | 181 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 202 | 203 | 204 | 205 | 206 | 209 | 210 | 212 | 213 | 215 | 216 | 218 | 219 | 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 | 247 | 248 | 249 | --------------------------------------------------------------------------------