├── .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 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
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 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
--------------------------------------------------------------------------------